Commit 7edbf2b2 authored by Dimitri van Heesch's avatar Dimitri van Heesch

Bug 731363 - Callgraphs for C# only generated for methods inside the same class

parent 352f9b01
...@@ -329,44 +329,44 @@ class CallContext ...@@ -329,44 +329,44 @@ class CallContext
public: public:
struct Ctx struct Ctx
{ {
Ctx() : name(g_name), type(g_type), cd(0) {} Ctx() : name(g_name), type(g_type), d(0) {}
QCString name; QCString name;
QCString type; QCString type;
ClassDef *cd; Definition *d;
}; };
CallContext() CallContext()
{ {
m_classList.append(new Ctx); m_defList.append(new Ctx);
m_classList.setAutoDelete(TRUE); m_defList.setAutoDelete(TRUE);
} }
virtual ~CallContext() {} virtual ~CallContext() {}
void setClass(ClassDef *cd) void setScope(Definition *d)
{ {
Ctx *ctx = m_classList.getLast(); Ctx *ctx = m_defList.getLast();
if (ctx) if (ctx)
{ {
DBG_CTX((stderr,"** Set call context %s (%p)\n",cd==0 ? "<null>" : cd->name().data(),cd)); DBG_CTX((stderr,"** Set call context %s (%p)\n",d==0 ? "<null>" : d->name().data(),d));
ctx->cd=cd; ctx->d=d;
} }
} }
void pushScope() void pushScope()
{ {
m_classList.append(new Ctx); m_defList.append(new Ctx);
DBG_CTX((stderr,"** Push call context %d\n",m_classList.count())); DBG_CTX((stderr,"** Push call context %d\n",m_defList.count()));
} }
void popScope() void popScope()
{ {
if (m_classList.count()>1) if (m_defList.count()>1)
{ {
DBG_CTX((stderr,"** Pop call context %d\n",m_classList.count())); DBG_CTX((stderr,"** Pop call context %d\n",m_defList.count()));
Ctx *ctx = m_classList.getLast(); Ctx *ctx = m_defList.getLast();
if (ctx) if (ctx)
{ {
g_name = ctx->name; g_name = ctx->name;
g_type = ctx->type; g_type = ctx->type;
} }
m_classList.removeLast(); m_defList.removeLast();
} }
else else
{ {
...@@ -376,17 +376,17 @@ class CallContext ...@@ -376,17 +376,17 @@ class CallContext
void clear() void clear()
{ {
DBG_CTX((stderr,"** Clear call context\n")); DBG_CTX((stderr,"** Clear call context\n"));
m_classList.clear(); m_defList.clear();
m_classList.append(new Ctx); m_defList.append(new Ctx);
} }
ClassDef *getClass() const Definition *getScope() const
{ {
Ctx *ctx = m_classList.getLast(); Ctx *ctx = m_defList.getLast();
if (ctx) return ctx->cd; else return 0; if (ctx) return ctx->d; else return 0;
} }
private: private:
QList<Ctx> m_classList; QList<Ctx> m_defList;
}; };
static CallContext g_theCallContext; static CallContext g_theCallContext;
...@@ -732,7 +732,7 @@ static MemberDef *setCallContextForVar(const QCString &name) ...@@ -732,7 +732,7 @@ static MemberDef *setCallContextForVar(const QCString &name)
if (md) if (md)
{ {
//printf("name=%s scope=%s\n",locName.data(),scope.data()); //printf("name=%s scope=%s\n",locName.data(),scope.data());
g_theCallContext.setClass(stripClassName(md->typeString(),md->getOuterScope())); g_theCallContext.setScope(stripClassName(md->typeString(),md->getOuterScope()));
return md; return md;
} }
} }
...@@ -745,7 +745,7 @@ static MemberDef *setCallContextForVar(const QCString &name) ...@@ -745,7 +745,7 @@ static MemberDef *setCallContextForVar(const QCString &name)
if (md) if (md)
{ {
//printf("name=%s scope=%s\n",locName.data(),scope.data()); //printf("name=%s scope=%s\n",locName.data(),scope.data());
g_theCallContext.setClass(stripClassName(md->typeString(),md->getOuterScope())); g_theCallContext.setScope(stripClassName(md->typeString(),md->getOuterScope()));
return md; return md;
} }
} }
...@@ -760,7 +760,7 @@ static MemberDef *setCallContextForVar(const QCString &name) ...@@ -760,7 +760,7 @@ static MemberDef *setCallContextForVar(const QCString &name)
if (mcd!=VariableContext::dummyContext) if (mcd!=VariableContext::dummyContext)
{ {
DBG_CTX((stderr,"local var `%s' mcd=%s\n",name.data(),mcd->name().data())); DBG_CTX((stderr,"local var `%s' mcd=%s\n",name.data(),mcd->name().data()));
g_theCallContext.setClass(mcd); g_theCallContext.setScope(mcd);
} }
} }
else else
...@@ -778,7 +778,7 @@ static MemberDef *setCallContextForVar(const QCString &name) ...@@ -778,7 +778,7 @@ static MemberDef *setCallContextForVar(const QCString &name)
if (g_scopeStack.top()!=CLASSBLOCK) if (g_scopeStack.top()!=CLASSBLOCK)
{ {
DBG_CTX((stderr,"class member `%s' mcd=%s\n",name.data(),mcd->name().data())); DBG_CTX((stderr,"class member `%s' mcd=%s\n",name.data(),mcd->name().data()));
g_theCallContext.setClass(stripClassName(md->typeString(),md->getOuterScope())); g_theCallContext.setScope(stripClassName(md->typeString(),md->getOuterScope()));
} }
return md; return md;
} }
...@@ -794,7 +794,7 @@ static MemberDef *setCallContextForVar(const QCString &name) ...@@ -794,7 +794,7 @@ static MemberDef *setCallContextForVar(const QCString &name)
MemberDef *md=mn->getFirst(); MemberDef *md=mn->getFirst();
if (!md->isStatic() || md->getBodyDef()==g_sourceFileDef) if (!md->isStatic() || md->getBodyDef()==g_sourceFileDef)
{ {
g_theCallContext.setClass(stripClassName(md->typeString(),md->getOuterScope())); g_theCallContext.setScope(stripClassName(md->typeString(),md->getOuterScope()));
return md; return md;
} }
return 0; return 0;
...@@ -816,7 +816,7 @@ static MemberDef *setCallContextForVar(const QCString &name) ...@@ -816,7 +816,7 @@ static MemberDef *setCallContextForVar(const QCString &name)
(g_forceTagReference.isEmpty() || g_forceTagReference==md->getReference()) (g_forceTagReference.isEmpty() || g_forceTagReference==md->getReference())
) )
{ {
g_theCallContext.setClass(stripClassName(md->typeString(),md->getOuterScope())); g_theCallContext.setScope(stripClassName(md->typeString(),md->getOuterScope()));
//printf("returning member %s in source file %s\n",md->name().data(),g_sourceFileDef->name().data()); //printf("returning member %s in source file %s\n",md->name().data(),g_sourceFileDef->name().data());
return md; return md;
} }
...@@ -829,15 +829,15 @@ static MemberDef *setCallContextForVar(const QCString &name) ...@@ -829,15 +829,15 @@ static MemberDef *setCallContextForVar(const QCString &name)
static void updateCallContextForSmartPointer() static void updateCallContextForSmartPointer()
{ {
ClassDef *cd = g_theCallContext.getClass(); Definition *d = g_theCallContext.getScope();
//printf("updateCallContextForSmartPointer() cd=%s\n",cd ? cd->name().data() : "<none>"); //printf("updateCallContextForSmartPointer() cd=%s\n",cd ? d->name().data() : "<none>");
MemberDef *md; MemberDef *md;
if (cd && (md=cd->isSmartPointer())) if (d && d->definitionType()==Definition::TypeClass && (md=((ClassDef*)d)->isSmartPointer()))
{ {
ClassDef *ncd = stripClassName(md->typeString(),md->getOuterScope()); ClassDef *ncd = stripClassName(md->typeString(),md->getOuterScope());
if (ncd) if (ncd)
{ {
g_theCallContext.setClass(ncd); g_theCallContext.setScope(ncd);
//printf("Found smart pointer call %s->%s!\n",cd->name().data(),ncd->name().data()); //printf("Found smart pointer call %s->%s!\n",cd->name().data(),ncd->name().data());
} }
} }
...@@ -879,7 +879,7 @@ static bool getLinkInScope(const QCString &c, // scope ...@@ -879,7 +879,7 @@ static bool getLinkInScope(const QCString &c, // scope
if (md->getGroupDef()) d = md->getGroupDef(); if (md->getGroupDef()) d = md->getGroupDef();
if (d && d->isLinkable()) if (d && d->isLinkable())
{ {
g_theCallContext.setClass(stripClassName(md->typeString(),md->getOuterScope())); g_theCallContext.setScope(stripClassName(md->typeString(),md->getOuterScope()));
//printf("g_currentDefinition=%p g_currentMemberDef=%p g_insideBody=%d\n", //printf("g_currentDefinition=%p g_currentMemberDef=%p g_insideBody=%d\n",
// g_currentDefinition,g_currentMemberDef,g_insideBody); // g_currentDefinition,g_currentMemberDef,g_insideBody);
...@@ -965,8 +965,18 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName ...@@ -965,8 +965,18 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName
cd=getResolvedClass(d,g_sourceFileDef,bareName,&md); // try unspecialized version cd=getResolvedClass(d,g_sourceFileDef,bareName,&md); // try unspecialized version
} }
} }
NamespaceDef *nd = getResolvedNamespace(className);
if (nd)
{
g_theCallContext.setScope(nd);
addToSearchIndex(className);
writeMultiLineCodeLink(*g_code,nd,clName);
return;
}
//printf("md=%s\n",md?md->name().data():"<none>"); //printf("md=%s\n",md?md->name().data():"<none>");
DBG_CTX((stderr,"is found as a type %s\n",cd?cd->name().data():"<null>")); DBG_CTX((stderr,"is found as a type cd=%s nd=%s\n",
cd?cd->name().data():"<null>",
nd?nd->name().data():"<null>"));
if (cd==0 && md==0) // also see if it is variable or enum or enum value if (cd==0 && md==0) // also see if it is variable or enum or enum value
{ {
if (getLink(g_classScope,clName,ol,clName,varOnly)) if (getLink(g_classScope,clName,ol,clName,varOnly))
...@@ -981,7 +991,7 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName ...@@ -981,7 +991,7 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName
if (lcd!=VariableContext::dummyContext) if (lcd!=VariableContext::dummyContext)
{ {
//printf("non-dummy context lcd=%s!\n",lcd->name().data()); //printf("non-dummy context lcd=%s!\n",lcd->name().data());
g_theCallContext.setClass(lcd); g_theCallContext.setScope(lcd);
// to following is needed for links to a global variable, but is // to following is needed for links to a global variable, but is
// no good for a link to a local variable that is also a global symbol. // no good for a link to a local variable that is also a global symbol.
...@@ -1011,7 +1021,7 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName ...@@ -1011,7 +1021,7 @@ static void generateClassOrGlobalLink(CodeOutputInterface &ol,const char *clName
} }
writeMultiLineCodeLink(ol,cd,clName); writeMultiLineCodeLink(ol,cd,clName);
addToSearchIndex(className); addToSearchIndex(className);
g_theCallContext.setClass(cd); g_theCallContext.setScope(cd);
if (md) if (md)
{ {
Definition *d = md->getOuterScope()==Doxygen::globalScope ? Definition *d = md->getOuterScope()==Doxygen::globalScope ?
...@@ -1111,7 +1121,7 @@ static bool generateClassMemberLink(CodeOutputInterface &ol,MemberDef *xmd,const ...@@ -1111,7 +1121,7 @@ static bool generateClassMemberLink(CodeOutputInterface &ol,MemberDef *xmd,const
ClassDef *typeClass = stripClassName(removeAnonymousScopes(xmd->typeString()),xmd->getOuterScope()); ClassDef *typeClass = stripClassName(removeAnonymousScopes(xmd->typeString()),xmd->getOuterScope());
DBG_CTX((stderr,"%s -> typeName=%p\n",xmd->typeString(),typeClass)); DBG_CTX((stderr,"%s -> typeName=%p\n",xmd->typeString(),typeClass));
g_theCallContext.setClass(typeClass); g_theCallContext.setScope(typeClass);
Definition *xd = xmd->getOuterScope()==Doxygen::globalScope ? Definition *xd = xmd->getOuterScope()==Doxygen::globalScope ?
xmd->getFileDef() : xmd->getOuterScope(); xmd->getFileDef() : xmd->getOuterScope();
...@@ -1142,18 +1152,42 @@ static bool generateClassMemberLink(CodeOutputInterface &ol,MemberDef *xmd,const ...@@ -1142,18 +1152,42 @@ static bool generateClassMemberLink(CodeOutputInterface &ol,MemberDef *xmd,const
return FALSE; return FALSE;
} }
static bool generateClassMemberLink(CodeOutputInterface &ol,ClassDef *mcd,const char *memName) static bool generateClassMemberLink(CodeOutputInterface &ol,Definition *def,const char *memName)
{ {
if (mcd) if (def && def->definitionType()==Definition::TypeClass)
{ {
MemberDef *xmd = mcd->getMemberByName(memName); ClassDef *cd = (ClassDef*)def;
//printf("generateClassMemberLink(class=%s,member=%s)=%p\n",mcd->name().data(),memName,xmd); MemberDef *xmd = cd->getMemberByName(memName);
//printf("generateClassMemberLink(class=%s,member=%s)=%p\n",def->name().data(),memName,xmd);
if (xmd) if (xmd)
{ {
return generateClassMemberLink(ol,xmd,memName); return generateClassMemberLink(ol,xmd,memName);
} }
else
{
Definition *innerDef = cd->findInnerCompound(memName);
if (innerDef)
{
g_theCallContext.setScope(innerDef);
addToSearchIndex(memName);
writeMultiLineCodeLink(*g_code,innerDef,memName);
return TRUE;
}
}
}
else if (def && def->definitionType()==Definition::TypeNamespace)
{
NamespaceDef *nd = (NamespaceDef*)def;
//printf("Looking for %s inside namespace %s\n",memName,nd->name().data());
Definition *innerDef = nd->findInnerCompound(memName);
if (innerDef)
{
g_theCallContext.setScope(innerDef);
addToSearchIndex(memName);
writeMultiLineCodeLink(*g_code,innerDef,memName);
return TRUE;
}
} }
return FALSE; return FALSE;
} }
...@@ -1743,9 +1777,7 @@ B [ \t] ...@@ -1743,9 +1777,7 @@ B [ \t]
BN [ \t\n\r] BN [ \t\n\r]
ID "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]* ID "$"?[a-z_A-Z\x80-\xFF][a-z_A-Z0-9\x80-\xFF]*
SEP ("::"|"\\") SEP ("::"|"\\")
SEPCS (".")
SCOPENAME ({SEP}{BN}*)?({ID}{BN}*{SEP}{BN}*)*("~"{BN}*)?{ID} SCOPENAME ({SEP}{BN}*)?({ID}{BN}*{SEP}{BN}*)*("~"{BN}*)?{ID}
SCOPENAMECS ({SEPCS}{BN}*)?({ID}{BN}*{SEPCS}{BN}*)*("~"{BN}*)?{ID}
TEMPLIST "<"[^\"\}\{\(\)\/\n\>]*">" TEMPLIST "<"[^\"\}\{\(\)\/\n\>]*">"
SCOPETNAME (((({ID}{TEMPLIST}?){BN}*)?{SEP}{BN}*)*)((~{BN}*)?{ID}) SCOPETNAME (((({ID}{TEMPLIST}?){BN}*)?{SEP}{BN}*)*)((~{BN}*)?{ID})
SCOPEPREFIX ({ID}{TEMPLIST}?{BN}*{SEP}{BN}*)+ SCOPEPREFIX ({ID}{TEMPLIST}?{BN}*{SEP}{BN}*)+
...@@ -2490,20 +2522,6 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" ...@@ -2490,20 +2522,6 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\"
generateClassOrGlobalLink(*g_code,yytext); generateClassOrGlobalLink(*g_code,yytext);
g_name+=yytext; g_name+=yytext;
} }
<Body>{SCOPENAMECS}/{BN}*[;,)\]] { // "int var;" or "var, var2" or "debug(f) macro"
if (!g_insideCS && !g_insideJava)
{
REJECT;
}
else
{
addType();
// changed this to generateFunctionLink, see bug 624514
//generateClassOrGlobalLink(*g_code,yytext,FALSE,TRUE);
generateFunctionLink(*g_code,yytext);
g_name+=yytext;
}
}
<Body>{SCOPENAME}/{BN}*[;,)\]] { // "int var;" or "var, var2" or "debug(f) macro" <Body>{SCOPENAME}/{BN}*[;,)\]] { // "int var;" or "var, var2" or "debug(f) macro"
addType(); addType();
// changed this to generateFunctionLink, see bug 624514 // changed this to generateFunctionLink, see bug 624514
...@@ -2511,18 +2529,6 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" ...@@ -2511,18 +2529,6 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\"
generateFunctionLink(*g_code,yytext); generateFunctionLink(*g_code,yytext);
g_name+=yytext; g_name+=yytext;
} }
<Body>{SCOPENAMECS}/{B}* { // p->func()
if (!g_insideCS && !g_insideJava)
{
REJECT;
}
else
{
addType();
generateClassOrGlobalLink(*g_code,yytext);
g_name+=yytext;
}
}
<Body>{SCOPENAME}/{B}* { // p->func() <Body>{SCOPENAME}/{B}* { // p->func()
addType(); addType();
generateClassOrGlobalLink(*g_code,yytext); generateClassOrGlobalLink(*g_code,yytext);
...@@ -2657,9 +2663,9 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" ...@@ -2657,9 +2663,9 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\"
BEGIN( MemberCall ); BEGIN( MemberCall );
} }
<MemberCall>{SCOPETNAME}/{BN}*"(" { <MemberCall>{SCOPETNAME}/{BN}*"(" {
if (g_theCallContext.getClass()) if (g_theCallContext.getScope())
{ {
if (!generateClassMemberLink(*g_code,g_theCallContext.getClass(),yytext)) if (!generateClassMemberLink(*g_code,g_theCallContext.getScope(),yytext))
{ {
g_code->codify(yytext); g_code->codify(yytext);
addToSearchIndex(yytext); addToSearchIndex(yytext);
...@@ -2684,10 +2690,10 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" ...@@ -2684,10 +2690,10 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\"
} }
} }
<MemberCall>{SCOPENAME}/{B}* { <MemberCall>{SCOPENAME}/{B}* {
if (g_theCallContext.getClass()) if (g_theCallContext.getScope())
{ {
DBG_CTX((stderr,"g_theCallContext.getClass()=%p\n",g_theCallContext.getClass())); DBG_CTX((stderr,"g_theCallContext.getClass()=%p\n",g_theCallContext.getScope()));
if (!generateClassMemberLink(*g_code,g_theCallContext.getClass(),yytext)) if (!generateClassMemberLink(*g_code,g_theCallContext.getScope(),yytext))
{ {
g_code->codify(yytext); g_code->codify(yytext);
addToSearchIndex(yytext); addToSearchIndex(yytext);
...@@ -2733,7 +2739,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" ...@@ -2733,7 +2739,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\"
if (*yytext!='[' && !g_type.isEmpty()) if (*yytext!='[' && !g_type.isEmpty())
{ {
//printf("g_scopeStack.bottom()=%p\n",g_scopeStack.bottom()); //printf("g_scopeStack.bottom()=%p\n",g_scopeStack.bottom());
if (g_scopeStack.top()!=CLASSBLOCK) //if (g_scopeStack.top()!=CLASSBLOCK) // commented out for bug731363
{ {
//printf("AddVariable: '%s' '%s' context=%d\n", //printf("AddVariable: '%s' '%s' context=%d\n",
// g_type.data(),g_name.data(),g_theVarContext.count()); // g_type.data(),g_name.data(),g_theVarContext.count());
...@@ -3008,7 +3014,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\" ...@@ -3008,7 +3014,7 @@ RAWEND ")"[^ \t\(\)\\]{0,16}\"
g_theVarContext.addVariable(g_type,g_name); g_theVarContext.addVariable(g_type,g_name);
} }
g_parmType.resize(0);g_parmName.resize(0); g_parmType.resize(0);g_parmName.resize(0);
g_theCallContext.setClass(0); g_theCallContext.setScope(0);
if (*yytext==';' || g_insideBody) if (*yytext==';' || g_insideBody)
{ {
if (!g_insideBody) if (!g_insideBody)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment