Source code for glud.matchers

from clang.cindex import CursorKind
from .predicates import *
from .internal import *

__all__ = [
    'allOf', 'anyOf', 'hasType', 'anything', 'hasAnyParameter', 'builtinType',
    'classTemplateDecl', 'cxxRecordDecl', 'cxxConstructorDecl',
    'cxxDestructorDecl', 'cxxMethodDecl', 'decl', 'enumDecl', 'fieldDecl',
    'functionDecl', 'has', 'hasName', 'hasReturnType', 'hasStaticStorageDuration',
    'hasTypename', 'isDerivedFrom', 'isSameOrDerivedFrom', 'namespaceDecl',
    'recordDecl', 'stmt', 'typedefDecl', 'unless', 'isDefinition', 'hasAncestor',
    'isExpansionInFileMatching', 'varDecl', 'hasParent', 'parameterCountIs',
    'hasCanonicalType', 'isStruct', 'isClass', 'isPublic', 'isProtected', 'isPrivate',
    'pointerType', 'pointee', 'hasParameter'
]


[docs]def allOf(*args): """Matches if all of the argument matchers match >>> from glud import * >>> config = ''' ... class X; ... class Y; ... ''' >>> m = allOf(cxxRecordDecl(), hasName('X')) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) X """ return AllOfMatcher(*args)
def makeKindMatcher(kinds, *args): inner = [ PredMatcher(is_kind(k)) for k in kinds ] inner += list(args) return allOf(*inner)
[docs]def anyOf(*args): """Matches if any of the argument matchers match >>> from glud import * >>> config = ''' ... int x; ... class Y {}; ... enum Z {}; ... ''' >>> m = anyOf(varDecl(), isClass()) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) x Y """ return AnyOfMatcher(*args)
[docs]def anything(): """Matches anything >>> from glud import * >>> config = ''' ... namespace W { ... int x; ... class Y; ... enum Z {}; ... } ... ''' >>> m = allOf(anything(), hasParent(namespaceDecl())) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) x Y Z """ return TrueMatcher()
[docs]def builtinType(*args): """Matches builtin primitive types (eg/ integers, booleans and float) >>> from glud import * >>> config = ''' ... int x; ... bool y; ... ''' >>> m = varDecl(hasType(builtinType())) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) x y """ return AllOfTypeMatcher(is_builtin, *args)
[docs]def classTemplateDecl(*args): """Match C++ template class declarations >>> from glud import * >>> config = ''' ... template<typename T> class X {}; ... class Y {}; ... ''' >>> m = classTemplateDecl() >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) X """ return makeKindMatcher([CursorKind.CLASS_TEMPLATE], *args)
[docs]def cxxConstructorDecl(*args): """Match C++ constructors >>> from glud import * >>> config = ''' ... class X { ... X(); ... }; ... class Y {}; ... ''' >>> m = cxxConstructorDecl() >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) X """ return makeKindMatcher([CursorKind.CONSTRUCTOR], *args)
[docs]def cxxDestructorDecl(*args): """Match C++ destructors >>> from glud import * >>> config = ''' ... class X { ... ~X(); ... }; ... class Y {}; ... ''' >>> m = cxxDestructorDecl() >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) ~X """ return makeKindMatcher([CursorKind.DESTRUCTOR], *args)
[docs]def cxxMethodDecl(*args): """Match C++ methods >>> from glud import * >>> config = ''' ... class X { ... void u(); ... void v(); ... }; ... ''' >>> m = cxxMethodDecl() >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) u v """ return makeKindMatcher([CursorKind.CXX_METHOD], *args)
[docs]def cxxRecordDecl(*args): """Matches C++ class declarations. >>> from glud import * >>> config = ''' ... class W; ... template<typename T> class X {}; ... struct Y {}; ... union Z {}; ... ''' >>> m = cxxRecordDecl() >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) W X """ kinds = [ CursorKind.CLASS_DECL, CursorKind.CLASS_TEMPLATE, ] inner = [ PredMatcher(is_kind(k)) for k in kinds ] return allOf(anyOf(*inner), *args)
[docs]def decl(*args): """Match any declaration >>> from glud import * >>> config = ''' ... class X {}; ... struct Y {}; ... enum Z {}; ... ''' >>> m = decl() >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) X Y Z """ return allOf(PredMatcher(is_decl), *args)
[docs]def enumDecl(*args): """Match enumerations >>> from glud import * >>> config = ''' ... enum X {}; ... enum class Y {}; ... ''' >>> m = enumDecl() >>> args = '-x c++ -std=c++11'.split() >>> for c in walk(m, parse_string(config, args=args).cursor): ... print(c.spelling) X Y """ return makeKindMatcher([CursorKind.ENUM_DECL], *args)
[docs]def fieldDecl(*args): """Match struct / class fields >>> from glud import * >>> config = ''' ... struct X { ... int u; ... int v; ... }; ... ''' >>> m = fieldDecl() >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) u v """ return makeKindMatcher([CursorKind.FIELD_DECL], *args)
[docs]def functionDecl(*args): """Match function declarations >>> from glud import * >>> config = ''' ... int u(); ... int v(); ... ''' >>> m = functionDecl() >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) u v """ return makeKindMatcher([CursorKind.FUNCTION_DECL], *args)
[docs]def has(*args): """Match if a cursor has a child that matches >>> from glud import * >>> config = ''' ... class X { ... void f(); ... }; ... class Y; ... ''' >>> m = cxxRecordDecl(has(cxxMethodDecl())) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) X """ return ChildAnyOfMatcher(*args)
[docs]def hasAncestor(matcher): """Matches if the current cursor has an ancestor that matches >>> from glud import * >>> config = ''' ... namespace X { ... class Y {}; ... } ... class Z {}; ... ''' >>> m = cxxRecordDecl( ... hasName('Y'), ... hasAncestor(namespaceDecl(hasName('X')))) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) Y """ return AncestorMatcher(matcher)
[docs]def hasAnyParameter(matcher): """Match if any method or function argument matches >>> from glud import * >>> config = ''' ... void f(); ... void g(int); ... ''' >>> m = functionDecl(hasAnyParameter(hasType(builtinType()))) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) g """ return AnyParameterMatcher(matcher)
[docs]def hasCanonicalType(m): """Matches if a cursor has the specified number of arguments >>> from glud import * >>> config = ''' ... namespace X { ... struct Y; ... Y f(); ... } ... ''' >>> m = functionDecl(hasReturnType(hasCanonicalType(hasName('X::Y')))) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) f """ return CanonicalTypeTraversalMatcher(m)
[docs]def hasName(name): """Match a cursors spelling against a pattern >>> from glud import * >>> config = ''' ... class X {}; ... class Y {}; ... ''' >>> m = cxxRecordDecl(hasName('X')) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) X """ return NameMatcher(name)
[docs]def hasParameter(N, inner): """Matches if the N-th parameter matches the inner matcher >>> from glud import * >>> config = ''' ... void f(int x); ... void g(int y, int x); ... void h(); ... ''' >>> m = functionDecl(hasParameter(1, hasName('x'))) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) g """ return ParameterMatcher(N, inner)
[docs]def hasParent(*args): """Matches if the direct parent node matches >>> from glud import * >>> config = ''' ... namespace X { ... int a; ... } ... int b; ... ''' >>> m = varDecl(hasParent(namespaceDecl(hasName('X')))) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) a """ return ParentMatcher(*args)
[docs]def hasReturnType(matcher): """Match a function/method with a specified return type >>> from glud import * >>> config = ''' ... class X {}; ... X u(); ... int v(); ... ''' >>> m = functionDecl(hasReturnType(builtinType())) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) v """ return ReturnTypeTraversalMatcher(matcher)
[docs]def hasStaticStorageDuration(): """Match an item has static storage duration >>> from glud import * >>> config = ''' ... class X { ... static void u(); ... void v(); ... }; ... ''' >>> m = cxxMethodDecl( ... hasStaticStorageDuration()) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) u """ return PredMatcher(has_storage_class(clang.cindex.StorageClass.STATIC))
[docs]def hasType(matcher): """Matches if the type associated with the current cursor matches >>> from glud import * >>> config = ''' ... int x; ... long y; ... ''' >>> m = varDecl(hasType(hasName('int'))) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) x """ return TypeTraversalMatcher(matcher)
[docs]def hasTypename(typename): """Match if the spelling of the type of a cursor matches a pattern >>> from glud import * >>> config = ''' ... namespace X { ... class Y {}; ... } ... class Y {}; ... ''' >>> m = cxxRecordDecl(hasTypename('X::Y')) >>> for c in walk(m, parse_string(config).cursor): ... print(c.type.spelling) X::Y """ return TypenameMatcher(typename)
[docs]def isClass(): """Matches if a cursor is a class >>> from glud import * >>> config = ''' ... class X; ... struct Y; ... ''' >>> m = isClass() >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) X """ return PredMatcher(is_kind(CursorKind.CLASS_DECL))
[docs]def isDefinition(): """Matches if the cursor is a definition >>> from glud import * >>> config = ''' ... class X {}; ... class Y; ... ''' >>> m = cxxRecordDecl(isDefinition()) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) X """ return PredMatcher(is_definition)
[docs]def isDerivedFrom(name): """Match if a C++ type inherits from a named class >>> from glud import * >>> config = ''' ... class X {}; ... class Y : public X {}; ... class Z : public Y {}; ... ''' >>> m = cxxRecordDecl(isDerivedFrom('X')) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) Y Z """ return AnyBaseClassMatcher(hasTypename(name))
[docs]def isExpansionInFileMatching(pattern): """Matches if the nodes location matches a pattern >>> from glud import * >>> config = ''' ... class X; ... ''' >>> m = isExpansionInFileMatching('tmp.cpp') >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) X """ return LocationMatcher(pattern)
[docs]def isPrivate(): """Test if a cursor is private >>> from glud import * >>> config = ''' ... class X { ... private: ... int y; ... }; ... ''' >>> m = fieldDecl(isPrivate()) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) y """ return PredMatcher(has_access(AccessSpecifier.PRIVATE))
[docs]def isProtected(): """Test if a cursor is protected >>> from glud import * >>> config = ''' ... class X { ... protected: ... int y; ... }; ... ''' >>> m = fieldDecl(isProtected()) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) y """ return PredMatcher(has_access(AccessSpecifier.PROTECTED))
[docs]def isPublic(): """Test if a cursor is public >>> from glud import * >>> config = ''' ... class X { ... public: ... int y; ... }; ... ''' >>> m = fieldDecl(isPublic()) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) y """ return PredMatcher(has_access(AccessSpecifier.PUBLIC))
[docs]def isSameOrDerivedFrom(name): """Match if derives-from (or is-a) class with a given name >>> from glud import * >>> config = ''' ... class X {}; ... class Y : public X {}; ... class Z : public Y {}; ... ''' >>> m = cxxRecordDecl(isSameOrDerivedFrom('X')) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) X Y Z """ return anyOf(hasTypename(name), isDerivedFrom(name))
[docs]def isStruct(): """Matches if a cursor is a struct >>> from glud import * >>> config = ''' ... class X; ... struct Y; ... ''' >>> m = isStruct() >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) Y """ return PredMatcher(is_kind(CursorKind.STRUCT_DECL))
[docs]def namespaceDecl(*args): """Match a C++ namespace declaration >>> from glud import * >>> config = ''' ... namespace X { } ... ''' >>> m = namespaceDecl() >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) X """ return allOf(PredMatcher(is_kind(CursorKind.NAMESPACE)), *args)
[docs]def parameterCountIs(N): """Matches if a cursor has the specified number of arguments >>> from glud import * >>> config = ''' ... int f(); ... int g(int); ... int h(int, int); ... ''' >>> m = functionDecl(parameterCountIs(1)) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) g """ return ParameterCountMatcher(N)
[docs]def pointee(inner): """Traverse from a pointer to the dereferenced type >>> from glud import * >>> config = ''' ... int *x; ... void *y; ... ''' >>> m = varDecl(hasType(pointerType(pointee(hasName('int'))))) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) x """ return PointeeTypeTraversalMatcher(inner)
[docs]def pointerType(*args): """Test if a cursor has pointer type >>> from glud import * >>> config = ''' ... int w; ... int* x; ... int** y; ... int& z = w; ... ''' >>> m = varDecl(hasType(pointerType())) >>> for c in parse_string(config, args='-x c++ -std=c++11'.split()).cursor.walk_preorder(): ... if m(c): ... print(c.spelling) x y """ return AllOfTypeMatcher(is_kind(TypeKind.POINTER), *args)
[docs]def recordDecl(*args): """Matches class, struct, and union declarations. >>> from glud import * >>> config = ''' ... class W; ... template<typename T> class X {}; ... struct Y {}; ... union Z {}; ... ''' >>> m = recordDecl() >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) W X Y Z """ kinds = [ CursorKind.STRUCT_DECL, CursorKind.UNION_DECL, CursorKind.CLASS_DECL, CursorKind.CLASS_TEMPLATE, ] inner = [ PredMatcher(is_kind(k)) for k in kinds ] return allOf(anyOf(*inner), *args)
[docs]def stmt(*args): """Matches statements >>> from glud import * >>> config = ''' ... void f() { } ... ''' >>> m = stmt() >>> i = 0 >>> for c in parse_string(config).cursor.walk_preorder(): ... if m(c): ... i += 1 >>> print(i) 1 """ return allOf(PredMatcher(is_stmt), *args)
[docs]def typedefDecl(*args): """Matches typedef declarations >>> from glud import * >>> config = ''' ... typedef int X; ... ''' >>> m = typedefDecl() >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) X """ return allOf(PredMatcher(is_kind(CursorKind.TYPEDEF_DECL)), *args)
[docs]def unless(*args): """Inverts the match of the children >>> from glud import * >>> config = ''' ... class X { }; ... class Y {}; ... class Z {}; ... ''' >>> m = cxxRecordDecl(unless(hasName('Y'))) >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) X Z """ return UnlessMatcher(*args)
[docs]def varDecl(*args): """Matches variable declarations >>> from glud import * >>> config = ''' ... int a; ... ''' >>> m = varDecl() >>> for c in walk(m, parse_string(config).cursor): ... print(c.spelling) a """ return allOf(PredMatcher(is_kind(CursorKind.VAR_DECL)), *args)