1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Parser of the API/interface XML files
4 // Author: Francesco Montorsi
6 // Copyright: (c) 2008 Francesco Montorsi
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
14 #include <wx/txtstrm.h>
15 #include <wx/dynarray.h>
16 #include <wx/xml/xml.h>
17 #include <wx/platinfo.h>
25 Any fix aimed to reduce "false positives" which involves
26 references to a specific wxWidgets class is marked in
27 ifacecheck sources with the string:
30 // ...fix description...
33 // NOTE: all messages in this way are printed on the stderr
34 //#define wxLogWarning wxLogMessage
37 // ----------------------------------------------------------------------------
38 // Represents a type with or without const/static/ qualifier
39 // and with or without & and * operators
40 // ----------------------------------------------------------------------------
45 wxType(const wxString
& type
)
46 { SetTypeFromString(type
); }
48 void SetTypeFromString(const wxString
& t
);
49 wxString
GetAsString() const
52 // returns this type _without_ any decoration,
53 // including the & (which indicates this is a reference),
54 // the * (which indicates this is a pointer), etc.
55 wxString
GetAsCleanString() const
56 { return m_strTypeClean
; }
59 { return m_strType
.Contains("const"); }
61 { return m_strType
.Contains("static"); }
62 bool IsPointer() const
63 { return m_strType
.Contains("*"); }
64 bool IsReference() const
65 { return m_strType
.Contains("&"); }
67 bool operator==(const wxType
& m
) const;
68 bool operator!=(const wxType
& m
) const
69 { return !(*this == m
); }
75 m_strTypeClean
; // m_strType "cleaned" of its attributes
76 // (only for internal use)
79 extern wxType wxEmptyType
;
80 WX_DECLARE_OBJARRAY(wxType
, wxTypeArray
);
83 // ----------------------------------------------------------------------------
84 // Represents a type used as argument for some wxMethod
85 // ----------------------------------------------------------------------------
86 class wxArgumentType
: public wxType
90 wxArgumentType(const wxString
& type
, const wxString
& defVal
,
91 const wxString
& argName
= wxEmptyString
)
92 { SetTypeFromString(type
); SetDefaultValue(defVal
); m_strArgName
= argName
; }
94 void SetArgumentName(const wxString
& name
)
95 { m_strArgName
=name
.Strip(wxString::both
); }
96 wxString
GetArgumentName() const
97 { return m_strArgName
; }
99 void SetDefaultValue(const wxString
& defval
,
100 const wxString
& defvalForCmp
= wxEmptyString
);
101 wxString
GetDefaultValue() const
102 { return m_strDefaultValue
; }
104 // returns the default value used for comparisons
105 wxString
GetDefaultCleanValue() const
106 { return m_strDefaultValueForCmp
; }
108 bool HasDefaultValue() const
109 { return !m_strDefaultValue
.IsEmpty(); }
111 bool operator==(const wxArgumentType
& m
) const;
112 bool operator!=(const wxArgumentType
& m
) const
113 { return !(*this == m
); }
116 wxString m_strDefaultValue
;
118 // this string may differ from m_strDefaultValue if there were
119 // preprocessor substitutions or other "replacements" done to
120 // avoid false errors.
121 wxString m_strDefaultValueForCmp
;
124 wxString m_strArgName
;
127 extern wxArgumentType wxEmptyArgumentType
;
128 WX_DECLARE_OBJARRAY(wxArgumentType
, wxArgumentTypeArray
);
131 enum wxMethodAccessSpecifier
138 // ----------------------------------------------------------------------------
139 // Represents a single prototype of a class' member.
140 // ----------------------------------------------------------------------------
145 { m_bConst
=m_bVirtual
=m_bPureVirtual
=m_bStatic
=m_bDeprecated
=false;
146 m_nLine
=-1; m_nAvailability
=wxPORT_UNKNOWN
; m_access
=wxMAS_PUBLIC
; }
148 wxMethod(const wxType
& rettype
, const wxString
& name
,
149 const wxArgumentTypeArray
& arguments
,
150 bool isConst
, bool isStatic
, bool isVirtual
)
151 : m_retType(rettype
), m_strName(name
.Strip(wxString::both
)),
152 m_bConst(isConst
), m_bStatic(isStatic
), m_bVirtual(isVirtual
)
153 { SetArgumentTypes(arguments
); m_nLine
=-1; }
158 // bWithArgumentNames = output argument names?
159 // bCleanDefaultValues = output clean argument default values?
160 // bDeprecated = output [deprecated] next to deprecated methods?
161 // bAccessSpec = output [public], [protected] or [private] next to method?
163 // TODO: convert to readable flags this set of bools
164 wxString
GetAsString(bool bWithArgumentNames
= true,
165 bool bCleanDefaultValues
= false,
166 bool bDeprecated
= false,
167 bool bAccessSpec
= false) const;
169 // parser of the prototype:
170 // all these functions return strings with spaces stripped
171 wxType
GetReturnType() const
172 { return m_retType
; }
173 wxString
GetName() const
174 { return m_strName
; }
175 const wxArgumentTypeArray
& GetArgumentTypes() const
177 wxArgumentTypeArray
& GetArgumentTypes()
179 int GetLocation() const
181 int GetAvailability() const
182 { return m_nAvailability
; }
183 wxMethodAccessSpecifier
GetAccessSpecifier() const
188 bool IsStatic() const
189 { return m_bStatic
; }
190 bool IsVirtual() const
191 { return m_bVirtual
; }
192 bool IsPureVirtual() const
193 { return m_bPureVirtual
; }
197 { return m_retType
==wxEmptyType
&& !m_strName
.StartsWith("~"); }
199 { return m_retType
==wxEmptyType
&& m_strName
.StartsWith("~"); }
200 bool IsOperator() const
201 { return m_strName
.StartsWith("operator"); }
203 bool IsDeprecated() const
204 { return m_bDeprecated
; }
210 void SetReturnType(const wxType
& t
)
212 void SetName(const wxString
& name
)
214 void SetArgumentTypes(const wxArgumentTypeArray
& arr
)
216 void SetConst(bool c
= true)
218 void SetStatic(bool c
= true)
220 void SetVirtual(bool c
= true)
222 void SetPureVirtual(bool c
= true)
225 if (c
) m_bVirtual
=c
; // pure virtual => virtual
227 void SetDeprecated(bool c
= true)
229 void SetLocation(int lineNumber
)
230 { m_nLine
=lineNumber
; }
231 void SetAvailability(int nAvail
)
232 { m_nAvailability
=nAvail
; }
233 void SetAccessSpecifier(wxMethodAccessSpecifier spec
)
238 bool operator==(const wxMethod
&) const;
239 bool operator!=(const wxMethod
& m
) const
240 { return !(*this == m
); }
242 // this function works like operator== but tests everything:
246 // except for the method attributes (const,static,virtual,pureVirtual,deprecated)
247 bool MatchesExceptForAttributes(const wxMethod
& m
) const;
249 // returns true if this is a ctor which has default values for all its
250 // argument, thus is able to act also as default ctor
251 bool ActsAsDefaultCtor() const;
253 // dumps the contents of this class in the given stream
254 void Dump(wxTextOutputStream
& stream
) const;
259 wxArgumentTypeArray m_args
;
268 // m_nLine can be -1 if no location infos are available
271 // this is a combination of wxPORT_* flags (see wxPortId) or wxPORT_UNKNOWN
272 // if this method should be available for all wxWidgets ports.
273 // NOTE: this is not used for comparing wxMethod objects
274 // (gccXML never gives this kind of info).
277 // the access specifier for this method
278 wxMethodAccessSpecifier m_access
;
281 WX_DECLARE_OBJARRAY(wxMethod
, wxMethodArray
);
282 WX_DEFINE_ARRAY(const wxMethod
*, wxMethodPtrArray
);
285 // we need wxClassPtrArray to be defined _before_ wxClass itself,
286 // since wxClass uses wxClassPtrArray.
288 WX_DEFINE_ARRAY(const wxClass
*, wxClassPtrArray
);
290 class wxXmlInterface
;
293 // ----------------------------------------------------------------------------
294 // Represents a class of the wx API/interface.
295 // ----------------------------------------------------------------------------
300 wxClass(const wxString
& name
, const wxString
& headername
)
301 : m_strName(name
), m_strHeader(headername
) {}
306 void SetHeader(const wxString
& header
)
307 { m_strHeader
=header
; }
308 void SetName(const wxString
& name
)
310 void SetAvailability(int nAvail
)
311 { m_nAvailability
=nAvail
; }
312 void SetParent(unsigned int k
, const wxString
& name
)
313 { m_parents
[k
]=name
; }
318 { return !m_strName
.IsEmpty() && !m_methods
.IsEmpty(); }
320 bool IsValidCtorForThisClass(const wxMethod
& m
) const;
321 bool IsValidDtorForThisClass(const wxMethod
& m
) const;
323 wxString
GetName() const
324 { return m_strName
; }
325 wxString
GetHeader() const
326 { return m_strHeader
; }
327 wxString
GetNameWithoutTemplate() const;
329 unsigned int GetMethodCount() const
330 { return m_methods
.GetCount(); }
331 wxMethod
& GetMethod(unsigned int n
) const
332 { return m_methods
[n
]; }
333 wxMethod
& GetLastMethod() const
334 { return m_methods
.Last(); }
336 int GetAvailability() const
337 { return m_nAvailability
; }
339 //const wxClass *GetParent(unsigned int i) const
340 const wxString
& GetParent(unsigned int i
) const
341 { return m_parents
[i
]; }
342 unsigned int GetParentCount() const
343 { return m_parents
.GetCount(); }
347 void AddMethod(const wxMethod
& func
)
348 { m_methods
.Add(func
); }
350 void AddParent(const wxString
& parent
)//wxClass* parent)
351 { m_parents
.Add(parent
); }
353 // returns a single result (the first, which is also the only
354 // one if CheckConsistency() return true)
355 const wxMethod
* FindMethod(const wxMethod
& m
) const;
357 // like FindMethod() but this one searches also recursively in
358 // the parents of this class.
359 const wxMethod
* RecursiveUpwardFindMethod(const wxMethod
& m
,
360 const wxXmlInterface
* allclasses
) const;
362 // returns an array of pointers to the overloaded methods with the
364 wxMethodPtrArray
FindMethodsNamed(const wxString
& name
) const;
366 // like FindMethodsNamed() but this one searches also recursively in
367 // the parents of this class.
368 wxMethodPtrArray
RecursiveUpwardFindMethodsNamed(const wxString
& name
,
369 const wxXmlInterface
* allclasses
) const;
371 // dumps all methods to the given output stream
372 void Dump(wxTextOutputStream
& stream
) const;
375 bool CheckConsistency() const;
379 wxString m_strHeader
;
380 wxMethodArray m_methods
;
382 // name of the base classes: we store the names and not the pointers
383 // because this makes _much_ easier the parsing process!
384 // (basically because when parsing class X which derives from Y,
385 // we may have not parsed yet class Y!)
386 wxArrayString m_parents
;
388 // see the wxMethod::m_nAvailability field for more info
392 WX_DECLARE_OBJARRAY(wxClass
, wxClassArray
);
396 // ----------------------------------------------------------------------------
398 // ----------------------------------------------------------------------------
404 const wxClass
* FindClass(const wxString
& classname
) const
406 for (unsigned int i
=0; i
<m_classes
.GetCount(); i
++)
407 if (m_classes
[i
].GetName() == classname
)
408 return &m_classes
[i
];
412 void Dump(const wxString
& filename
);
414 const wxClassArray
& GetClasses() const
415 { return m_classes
; }
417 unsigned int GetClassesCount() const
418 { return m_classes
.GetCount(); }
420 unsigned int GetMethodCount() const
422 unsigned int methods
= 0;
423 for (unsigned i
=0; i
< m_classes
.GetCount(); i
++)
424 methods
+= m_classes
[i
].GetMethodCount();
428 // pass a full-path header filename:
429 wxClassPtrArray
FindClassesDefinedIn(const wxString
& headerfile
) const;
432 { /*wxFprintf(stderr, ".");*/ }
434 // is this interface coherent?
435 bool CheckConsistency() const;
438 wxClassArray m_classes
;
442 // for wxTypeIdHashMap, keys == gccxml IDs and values == associated type strings
443 // e.g. key = "0x123f" and value = "const wxAboutDialogInfo&"
444 WX_DECLARE_HASH_MAP( unsigned long, wxString
,
445 wxIntegerHash
, wxIntegerEqual
,
448 WX_DECLARE_STRING_HASH_MAP( wxString
, wxStringHashMap
);
451 typedef std::basic_string
<char> stlString
;
452 typedef std::map
<unsigned long, stlString
> wxTypeIdHashMap
;
456 // ----------------------------------------------------------------------------
457 // Represents the real interface of wxWidgets
458 // Loads it from the XML produced by gccXML: http://www.gccxml.org
459 // ----------------------------------------------------------------------------
460 class wxXmlGccInterface
: public wxXmlInterface
465 // FIXME: we should retrieve this from the XML file!
466 // here we suppose the XML was created for the currently-running port
467 m_portId
= wxPlatformInfo::Get().GetPortId();
470 bool Parse(const wxString
& filename
);
471 bool ParseMethod(const wxXmlNode
*p
,
472 const wxTypeIdHashMap
& types
,
475 wxPortId
GetInterfacePort() const
478 wxString
GetInterfacePortName() const
479 { return wxPlatformInfo::GetPortIdName(m_portId
, false); }
482 // the port for which the gcc XML was generated
487 // ----------------------------------------------------------------------------
488 // Represents the interface of the doxygen headers of wxWidgets
489 // Loads it from the XML produced by Doxygen: http://www.doxygen.org
490 // ----------------------------------------------------------------------------
491 class wxXmlDoxygenInterface
: public wxXmlInterface
494 wxXmlDoxygenInterface() {}
497 // Using wxXmlDocument::Load as is, the entire XML file is parsed
498 // and an entire tree of wxXmlNodes is built in memory.
499 // We need however only small portions of the Doxygen-generated XML: to speedup the
500 // processing we could detach the expat callbacks when we detect the beginning of a
501 // node we're not interested about, or just don't create a wxXmlNode for it!
502 // This needs a modification of wxXml API.
504 bool Parse(const wxString
& filename
);
505 bool ParseCompoundDefinition(const wxString
& filename
);
506 bool ParseMethod(const wxXmlNode
*, wxMethod
&, wxString
& header
);
508 // this class can take advantage of the preprocessor output to give
509 // a minor number of false positive warnings in the final comparison
510 void AddPreprocessorValue(const wxString
& name
, const wxString
& val
)
511 { m_preproc
[name
]=val
; }
514 wxStringHashMap m_preproc
;
519 #endif // _XMLPARSER_H_