/** * Provides a class that represents named elements in Java programs. */ overlay[local?] module; import CompilationUnit import semmle.code.Location import Javadoc /** A program element that has a name. */ class Element extends @element, Top { /** Holds if this element has the specified `name`. */ predicate hasName(string name) { hasName(this, name) } /** Gets the name of this element. */ string getName() { this.hasName(result) } /** * Holds if this element transitively contains the specified element `e`. */ predicate contains(Element e) { this.hasChildElement+(e) } /** * Holds if this element is the immediate parent of the specified element `e`. * * It is usually preferable to use more specific predicates such as * `getEnclosingCallable()`, `getDeclaringType()` and/or `getEnclosingType()` * instead of this general predicate. */ predicate hasChildElement(Element e) { hasChildElement(this, e) } /** * Holds if this element pertains to a source file. * * Elements pertaining to source files may include generated elements * not visible in source code, such as implicit default constructors. */ predicate fromSource() { this.getCompilationUnit().isSourceFile() } /** * Holds if this element is from source and classified as a stub implementation. * An implementation is considered a stub, if the the path to the * source file contains `/stubs/`. */ predicate isStub() { this.fromSource() and this.getFile().getAbsolutePath().matches("%/stubs/%") } /** Gets the compilation unit that this element belongs to. */ CompilationUnit getCompilationUnit() { result = this.getFile() } /** Cast this element to a `Documentable`. */ Documentable getDoc() { result = this } /** Holds if this is an auxiliary program element generated by the compiler. */ predicate isCompilerGenerated() { compiler_generated(this, _) } /** Gets the reason this element was generated by the compiler, if any. */ string compilerGeneratedReason() { exists(int i | compiler_generated(this, i) | i = 1 and result = "Declaring classes of adapter functions in Kotlin" or i = 2 and result = "Generated data class member" or i = 3 and result = "Default property accessor" or i = 4 and result = "Class initialisation method " or i = 5 and result = "Enum class special member" or i = 6 and result = "Getter for a Kotlin delegated property" or i = 7 and result = "Setter for a Kotlin delegated property" or i = 8 and result = "Proxy static method for a @JvmStatic-annotated function or property" or i = 9 and result = "Forwarder for a @JvmOverloads-annotated function" or i = 10 and result = "Forwarder for Kotlin calls that need default arguments filling in" or i = 11 and result = "Forwarder for a Kotlin class inheriting an interface default method" or i = 12 and result = "Argument for enum constructor call" or i = 13 and result = "The class around a local function, a lambda, or a function reference" ) } } /** * Holds if element `parent` is immediately above element `e` in the syntax tree. */ private predicate hasChildElement(Element parent, Element e) { cupackage(e, parent) or enclInReftype(e, parent) and not e instanceof LocalClassOrInterface or // Reasoning: any specialised instance of a local class is supposed to belong to the general // case of its enclosing method because we don't instantiate specialised variants of either generic // functions or function bodies, and therefore the local class cannot be specialised with respect // to its enclosing reftypes. e.(LocalClassOrInterface) .getSourceDeclaration() .(LocalClassOrInterface) .getLocalTypeDeclStmt() .getEnclosingCallable() = parent or not enclInReftype(e, _) and e.(Class).getCompilationUnit() = parent or not enclInReftype(e, _) and e.(Interface).getCompilationUnit() = parent or methods(e, _, _, _, parent, _) or constrs(e, _, _, _, parent, _) or params(e, _, _, parent, _) or fields(e, _, _, parent) or typeVars(e, _, _, parent) }