// @(#)root/tree:$Name: $:$Id: TMethodBrowsable.cxx,v 1.5 2004/12/17 07:20:54 brun Exp $
// Author: Axel Naumann 14/10/2004
/*************************************************************************
* Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
* All rights reserved. *
* *
* For the licensing terms see $ROOTSYS/LICENSE. *
* For the list of contributors see $ROOTSYS/README/CREDITS. *
*************************************************************************/
//////////////////////////////////////////////////////////////////////////
// //
// TMethodBrowsable //
// //
// A helper object to browse methods (see //
// TBranchElement::GetBrowsableMethods) //
//////////////////////////////////////////////////////////////////////////
#include "TMethodBrowsable.h"
#include "TBranchElement.h"
#include "TMethod.h"
#include "TBrowser.h"
#include "TTree.h"
#include "TPad.h"
#include "TClass.h"
#include "TBaseClass.h"
#include "TDataMember.h"
ClassImp(TMethodBrowsable);
//______________________________________________________________________________
TMethodBrowsable::TMethodBrowsable(TBranchElement* be, TMethod* m,
TMethodBrowsable* parent /* =0 */):
fBranchElement(be), fParent(parent), fMethod(m),
fReturnClass(0), fReturnLeafs(0), fReturnIsPointer(kFALSE) {
// standard constructor.
// Links a TBranchElement with a TMethod, allowing the TBrowser to
// Browser simple methods.
//
// The c'tor sets the name for a method "Class::Method(params) const"
// to "Method(params)", title to TMethod::GetPrototype
TString name(m->GetName());
name+="()";
if (name.EndsWith(" const")) name.Remove(name.Length()-6);
SetName(name);
name=m->GetPrototype();
if (m->GetCommentString() && strlen(m->GetCommentString()))
name.Append(" // ").Append(m->GetCommentString());
SetTitle(name);
TString plainReturnType(m->GetReturnTypeName());
if (plainReturnType.EndsWith("*")) {
fReturnIsPointer=kTRUE;
plainReturnType.Remove(plainReturnType.Length()-1);
plainReturnType.Strip();
if(plainReturnType.BeginsWith("const")) {
plainReturnType.Remove(0,5);
plainReturnType.Strip();
}
}
fReturnClass=gROOT->GetClass(plainReturnType);
}
//______________________________________________________________________________
void TMethodBrowsable::Browse(TBrowser *b) {
// Calls TTree::Draw on the method if return type is not a class;
// otherwise expands returned object's "folder"
if (!fReturnClass) {
TString name;
GetScope(name);
fBranchElement->GetTree()->Draw(name, "", b ? b->GetDrawOption() : "");
if (gPad) gPad->Update();
} else {
if (!fReturnLeafs)
fReturnLeafs=GetMethodBrowsables(fBranchElement, fReturnClass, this);
if (fReturnLeafs)
fReturnLeafs->Browse(b);
}
}
//______________________________________________________________________________
TList* TMethodBrowsable::GetMethodBrowsables(TBranchElement* be, TClass* cl,
TMethodBrowsable* parent /* =0 */) {
// Given a class, this methods returns a list of TMethodBrowsables
// for the class and its base classes.
// This list has to be deleted by the caller!
if (!cl) return 0;
TList allClasses;
allClasses.Add(cl);
for(TObjLink* lnk=allClasses.FirstLink();
lnk; lnk=lnk->Next()){
cl=(TClass*)lnk->GetObject();
TList* bases=cl->GetListOfBases();
TBaseClass* base;
TIter iB(bases);
while ((base=(TBaseClass*)iB())) {
TClass* bc=base->GetClassPointer();
if (bc) allClasses.Add(bc);
}
}
TList allMethods;
TIter iC(&allClasses);
while ((cl=(TClass*)iC())) {
TList* methods=cl->GetListOfMethods();
if (!methods) continue;
TMethod* method=0;
TIter iM(methods);
while ((method=(TMethod*)iM()))
if (method && !allMethods.FindObject(method->GetName()))
allMethods.Add(method);
}
TIter iM(&allMethods);
TMethod* m=0;
TList* browsableMethods=new TList();
browsableMethods->SetOwner();
while ((m=(TMethod*)iM()))
if (TMethodBrowsable::IsMethodBrowsable(m))
browsableMethods->Add(new TMethodBrowsable(be, m, parent));
return browsableMethods;
}
//______________________________________________________________________________
void TMethodBrowsable::GetScope(TString & scope) {
// Returns the full name for TTree::Draw to draw *this.
// Recursively appends, starting form the top TBranchElement,
// all method names with proper reference operators (->, .)
// depending on fReturnIsPointer.
if (fParent)
fParent->GetScope(scope);
else {
scope=fBranchElement->GetName();
scope+=".";
TBranch* mother=fBranchElement;
while (mother != mother->GetMother() && (mother=mother->GetMother()))
scope.Prepend(".").Prepend(mother->GetName());
}
scope+=GetName();
if (fReturnClass) // otherwise we're a leaf, and we are the one drawn
if (fReturnIsPointer)
scope+="->";
else scope+=".";
}
//______________________________________________________________________________
Bool_t TMethodBrowsable::IsMethodBrowsable(TMethod* m) {
// A TMethod is browsable if it is const, public and not pure virtual,
// if does not have any parameter without default value, and if it has
// a (non-void) return value.
// A method called *, Get*, or get* will not be browsable if there is a
// persistent data member called f*, _*, or m*, as data member access is
// faster than method access. Examples: if one of fX, _X, or mX is a
// persistent data member, the methods GetX(), getX(), and X() will not
// be browsable.
if (m->GetNargs()-m->GetNargsOpt()==0
&& (m->Property() & kIsConstant
& ~kIsPrivate & ~kIsProtected & ~kIsPureVirtual )
&& m->GetReturnTypeName()
&& strcmp("void",m->GetReturnTypeName())
&& !strstr(m->GetName(),"DeclFile")
&& !strstr(m->GetName(),"ImplFile")
&& strcmp(m->GetName(),"IsA")
&& strcmp(m->GetName(),"Class")
&& strcmp(m->GetName(),"CanBypassStreamer")
&& strcmp(m->GetName(),"Class_Name")
&& strcmp(m->GetName(),"ClassName")
&& strcmp(m->GetName(),"Clone")
&& strcmp(m->GetName(),"DrawClone")
&& strcmp(m->GetName(),"GetName")
&& strcmp(m->GetName(),"GetDrawOption")
&& strcmp(m->GetName(),"GetIconName")
&& strcmp(m->GetName(),"GetOption")
&& strcmp(m->GetName(),"GetTitle")
&& strcmp(m->GetName(),"GetUniqueID")
&& strcmp(m->GetName(),"Hash")
&& strcmp(m->GetName(),"IsFolder")
&& strcmp(m->GetName(),"IsOnHeap")
&& strcmp(m->GetName(),"IsSortable")
&& strcmp(m->GetName(),"IsZombie")) {
// look for matching data member
TClass* cl=m->GetClass();
if (!cl) return kTRUE;
TList* members=cl->GetListOfDataMembers();
if (!members) return kTRUE;
const char* baseName=m->GetName();
if (!strncmp(m->GetName(), "Get", 3) ||
!strncmp(m->GetName(), "get", 3))
baseName+=3;
if (!baseName[0]) return kTRUE;
TObject* mem=0;
const char* arrMemberNames[3]={"f%s","_%s","m%s"};
for (Int_t i=0; !mem && i<3; i++)
mem=members->FindObject(Form(arrMemberNames[i],baseName));
return (!mem ||! ((TDataMember*)mem)->IsPersistent());
};
return kFALSE;
}
ROOT page - Class index - Class Hierarchy - Top of the page
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.