Permalink
Browse files

Added type constraint relations for Java generics to dot graphs and X…

…ML output
  • Loading branch information...
Dimitri van Heesch
Dimitri van Heesch committed Feb 21, 2015
1 parent 5bfda3d commit 080a465b1321ff93c05ce398cd18a577e0ebae4b
Showing with 244 additions and 40 deletions.
  1. +2 −0 src/arguments.cpp
  2. +21 −18 src/arguments.h
  3. +77 −8 src/classdef.cpp
  4. +62 −2 src/classdef.h
  5. +26 −5 src/defargs.l
  6. +43 −4 src/dot.cpp
  7. +1 −1 src/dot.h
  8. +1 −0 src/doxygen.cpp
  9. +1 −0 src/scanner.l
  10. +9 −2 src/util.cpp
  11. +1 −0 templates/xml/compound.xsd
@@ -54,6 +54,7 @@ ArgumentList *ArgumentList::unmarshal(StorageIntf *s)
a->array = unmarshalQCString(s);
a->defval = unmarshalQCString(s);
a->docs = unmarshalQCString(s);
a->typeConstraint = unmarshalQCString(s);
result->append(a);
}
result->constSpecifier = unmarshalBool(s);
@@ -85,6 +86,7 @@ void ArgumentList::marshal(StorageIntf *s,ArgumentList *argList)
marshalQCString(s,a->array);
marshalQCString(s,a->defval);
marshalQCString(s,a->docs);
marshalQCString(s,a->typeConstraint);
}
}
marshalBool(s,argList->constSpecifier);
@@ -30,44 +30,47 @@ struct Argument
/*! Construct a new argument. */
Argument() {}
/*! Copy an argument (does a deep copy of all strings). */
Argument(const Argument &a)
{
attrib=a.attrib.copy();
type=a.type.copy();
name=a.name.copy();
defval=a.defval.copy();
docs=a.docs.copy();
array=a.array.copy();
Argument(const Argument &a)
{
attrib=a.attrib;
type=a.type;
name=a.name;
array=a.array;
defval=a.defval;
docs=a.docs;
typeConstraint=a.typeConstraint;
}
/*! Assignment of an argument (does a deep copy of all strings). */
Argument &operator=(const Argument &a)
{
if (this!=&a)
{
attrib=a.attrib.copy();
type=a.type.copy();
name=a.name.copy();
defval=a.defval.copy();
docs=a.docs.copy();
array=a.array.copy();
attrib=a.attrib;
type=a.type;
name=a.name;
array=a.array;
defval=a.defval;
docs=a.docs;
typeConstraint=a.typeConstraint;
}
return *this;
}
/*! return TRUE if this argument is documentation and the argument has a
* non empty name.
*/
bool hasDocumentation() const
{
return !name.isEmpty() && !docs.isEmpty();
bool hasDocumentation() const
{
return !name.isEmpty() && !docs.isEmpty();
}
QCString attrib; /*!< Argument's attribute (IDL only) */
QCString type; /*!< Argument's type */
QCString canType; /*!< Cached value of canonical type (after type resolution). Empty initially. */
QCString name; /*!< Argument's name (may be empty) */
QCString array; /*!< Argument's array specifier (may be empty) */
QCString defval; /*!< Argument's default value (may be empty) */
QCString docs; /*!< Argument's documentation (may be empty) */
QCString typeConstraint; /*!< Used for Java generics: <T extends C> */
};
/*! \brief This class represents an function or template argument list.
@@ -118,6 +118,8 @@ class ClassDefImpl
UsesClassDict *usedByImplClassDict;
UsesClassDict *usesIntfClassDict;
ConstraintClassDict *constraintClassDict;
/*! Template instances that exists of this class, the key in the
* dictionary is the template argument list.
*/
@@ -216,6 +218,7 @@ void ClassDefImpl::init(const char *defFileName, const char *name,
usesImplClassDict=0;
usedByImplClassDict=0;
usesIntfClassDict=0;
constraintClassDict=0;
memberGroupSDict = 0;
innerClasses = 0;
subGrouping=Config_getBool("SUBGROUPING");
@@ -267,6 +270,7 @@ ClassDefImpl::~ClassDefImpl()
delete usesImplClassDict;
delete usedByImplClassDict;
delete usesIntfClassDict;
delete constraintClassDict;
delete incInfo;
delete memberGroupSDict;
delete innerClasses;
@@ -2526,20 +2530,66 @@ bool ClassDef::hasExamples() const
return result;
}
void ClassDef::addTypeConstraint(const QCString &typeConstraint,const QCString &type)
{
static bool hideUndocRelation = Config_getBool("HIDE_UNDOC_RELATIONS");
if (typeConstraint.isEmpty() || type.isEmpty()) return;
ClassDef *cd = getClass(typeConstraint);
if (cd==0 && !hideUndocRelation)
{
cd = new ClassDef(getDefFileName(),getDefLine(),getDefColumn(),typeConstraint,ClassDef::Class);
cd->setUsedOnly(TRUE);
cd->setLanguage(getLanguage());
Doxygen::hiddenClasses->append(typeConstraint,cd);
//printf("Adding undocumented constraint '%s' to class %s on type %s\n",
// typeConstraint.data(),name().data(),type.data());
}
if (cd)
{
if (m_impl->constraintClassDict==0)
{
m_impl->constraintClassDict = new ConstraintClassDict(17);
m_impl->constraintClassDict->setAutoDelete(TRUE);
}
ConstraintClassDef *ccd=m_impl->constraintClassDict->find(typeConstraint);
if (ccd==0)
{
ccd = new ConstraintClassDef(cd);
m_impl->constraintClassDict->insert(typeConstraint,ccd);
}
ccd->addAccessor(type);
//printf("Adding constraint '%s' to class %s on type %s\n",
// typeConstraint.data(),name().data(),type.data());
}
}
void ClassDef::setTemplateArguments(ArgumentList *al)
// Java Type Constrains: A<T extends C & I>
void ClassDef::addTypeConstraints()
{
if (al==0) return;
if (!m_impl->tempArgs) delete m_impl->tempArgs; // delete old list if needed
m_impl->tempArgs=new ArgumentList;
ArgumentListIterator ali(*al);
Argument *a;
for (;(a=ali.current());++ali)
if (m_impl->tempArgs)
{
m_impl->tempArgs->append(new Argument(*a));
ArgumentListIterator ali(*m_impl->tempArgs);
Argument *a;
for (;(a=ali.current());++ali)
{
if (!a->typeConstraint.isEmpty())
{
QCString typeConstraint;
int i=0,p=0;
while ((i=a->typeConstraint.find('&',p))!=-1) // typeConstraint="A &I" for C<T extends A & I>
{
typeConstraint = a->typeConstraint.mid(p,i-p).stripWhiteSpace();
addTypeConstraint(typeConstraint,a->type);
p=i+1;
}
typeConstraint = a->typeConstraint.right(a->typeConstraint.length()-p).stripWhiteSpace();
addTypeConstraint(typeConstraint,a->type);
}
}
}
}
// C# Type Constraints: D<T> where T : C, I
void ClassDef::setTypeConstraints(ArgumentList *al)
{
if (al==0) return;
@@ -2553,6 +2603,20 @@ void ClassDef::setTypeConstraints(ArgumentList *al)
}
}
void ClassDef::setTemplateArguments(ArgumentList *al)
{
if (al==0) return;
if (!m_impl->tempArgs) delete m_impl->tempArgs; // delete old list if needed
//printf("setting template args '%s' for '%s'\n",tempArgListToString(al,getLanguage()).data(),name().data());
m_impl->tempArgs=new ArgumentList;
ArgumentListIterator ali(*al);
Argument *a;
for (;(a=ali.current());++ali)
{
m_impl->tempArgs->append(new Argument(*a));
}
}
/*! Returns \c TRUE iff this class or a class inheriting from this class
* is \e not defined in an external tag file.
*/
@@ -4405,6 +4469,11 @@ UsesClassDict *ClassDef::usedInterfaceClasses() const
return m_impl->usesIntfClassDict;
}
ConstraintClassDict *ClassDef::templateTypeConstraints() const
{
return m_impl->constraintClassDict;
}
bool ClassDef::isTemplateArgument() const
{
return m_impl->isTemplArg;
@@ -24,6 +24,7 @@
#include "definition.h"
struct Argument;
class MemberDef;
class MemberList;
class MemberDict;
@@ -38,6 +39,7 @@ class MemberDef;
class ExampleSDict;
class MemberNameInfoSDict;
class UsesClassDict;
class ConstraintClassDict;
class MemberGroupSDict;
class QTextStream;
class PackageDef;
@@ -229,6 +231,8 @@ class ClassDef : public Definition
UsesClassDict *usedInterfaceClasses() const;
ConstraintClassDict *templateTypeConstraints() const;
bool isTemplateArgument() const;
/** Returns the definition of a nested compound if
@@ -371,6 +375,7 @@ class ClassDef : public Definition
void findSectionsInDocumentation();
void addMembersToMemberGroup();
void addListReferences();
void addTypeConstraints();
void computeAnchors();
void mergeMembers();
void sortMemberLists();
@@ -441,12 +446,13 @@ class ClassDef : public Definition
void getTitleForMemberListType(MemberListType type,
QCString &title,QCString &subtitle);
QCString includeStatement() const;
void addTypeConstraint(const QCString &typeConstraint,const QCString &type);
ClassDefImpl *m_impl;
};
//------------------------------------------------------------------------
/** Class that contains information about a usage relation.
*/
struct UsesClassDef
@@ -500,6 +506,8 @@ class UsesClassDictIterator : public QDictIterator<UsesClassDef>
~UsesClassDictIterator() {}
};
//------------------------------------------------------------------------
/** Class that contains information about an inheritance relation.
*/
struct BaseClassDef
@@ -558,4 +566,56 @@ class BaseClassListIterator : public QListIterator<BaseClassDef>
QListIterator<BaseClassDef>(bcl) {}
};
//------------------------------------------------------------------------
/** Class that contains information about a type constraint relations.
*/
struct ConstraintClassDef
{
ConstraintClassDef(ClassDef *cd) : classDef(cd)
{
accessors = new QDict<void>(17);
}
~ConstraintClassDef()
{
delete accessors;
}
void addAccessor(const char *s)
{
if (accessors->find(s)==0)
{
accessors->insert(s,(void *)666);
}
}
/** Class definition that this relation uses. */
ClassDef *classDef;
/** Dictionary of member types names that form the edge labels of the
* constraint relation.
*/
QDict<void> *accessors;
};
/** Dictionary of constraint relations.
*/
class ConstraintClassDict : public QDict<ConstraintClassDef>
{
public:
ConstraintClassDict(int size) : QDict<ConstraintClassDef>(size) {}
~ConstraintClassDict() {}
};
/** Iterator class to iterate over a dictionary of constraint relations.
*/
class ConstraintClassDictIterator : public QDictIterator<ConstraintClassDef>
{
public:
ConstraintClassDictIterator(const QDict<ConstraintClassDef> &d)
: QDictIterator<ConstraintClassDef>(d) {}
~ConstraintClassDictIterator() {}
};
//------------------------------------------------------------------------
#endif
Oops, something went wrong.

0 comments on commit 080a465

Please sign in to comment.