mirror of
https://github.com/github/codeql.git
synced 2025-12-21 03:06:31 +01:00
Merge pull request #3297 from asger-semmle/js/isambient-refactor
Approved by esbena
This commit is contained in:
@@ -125,6 +125,42 @@ class ASTNode extends @ast_node, Locatable {
|
|||||||
/** Holds if this syntactic entity belongs to an externs file. */
|
/** Holds if this syntactic entity belongs to an externs file. */
|
||||||
predicate inExternsFile() { getTopLevel().isExterns() }
|
predicate inExternsFile() { getTopLevel().isExterns() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if this is an ambient node that is not a `TypeExpr` and is not inside a `.d.ts` file
|
||||||
|
*
|
||||||
|
* Since the overwhelming majority of ambient nodes are `TypeExpr` or inside `.d.ts` files,
|
||||||
|
* we avoid caching them.
|
||||||
|
*/
|
||||||
|
cached
|
||||||
|
private predicate isAmbientInternal() {
|
||||||
|
getParent().isAmbientInternal()
|
||||||
|
or
|
||||||
|
not isAmbientTopLevel(getTopLevel()) and
|
||||||
|
(
|
||||||
|
this instanceof ExternalModuleDeclaration
|
||||||
|
or
|
||||||
|
this instanceof GlobalAugmentationDeclaration
|
||||||
|
or
|
||||||
|
this instanceof ExportAsNamespaceDeclaration
|
||||||
|
or
|
||||||
|
this instanceof TypeAliasDeclaration
|
||||||
|
or
|
||||||
|
this instanceof InterfaceDeclaration
|
||||||
|
or
|
||||||
|
hasDeclareKeyword(this)
|
||||||
|
or
|
||||||
|
hasTypeKeyword(this)
|
||||||
|
or
|
||||||
|
// An export such as `export declare function f()` should be seen as ambient.
|
||||||
|
hasDeclareKeyword(this.(ExportNamedDeclaration).getOperand())
|
||||||
|
or
|
||||||
|
exists(Function f |
|
||||||
|
this = f and
|
||||||
|
not f.hasBody()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if this is part of an ambient declaration or type annotation in a TypeScript file.
|
* Holds if this is part of an ambient declaration or type annotation in a TypeScript file.
|
||||||
*
|
*
|
||||||
@@ -134,8 +170,21 @@ class ASTNode extends @ast_node, Locatable {
|
|||||||
* The TypeScript compiler emits no code for ambient declarations, but they
|
* The TypeScript compiler emits no code for ambient declarations, but they
|
||||||
* can affect name resolution and type checking at compile-time.
|
* can affect name resolution and type checking at compile-time.
|
||||||
*/
|
*/
|
||||||
predicate isAmbient() { getParent().isAmbient() }
|
pragma[inline]
|
||||||
|
predicate isAmbient() {
|
||||||
|
isAmbientInternal()
|
||||||
|
or
|
||||||
|
isAmbientTopLevel(getTopLevel())
|
||||||
|
or
|
||||||
|
this instanceof TypeExpr
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if the given file is a `.d.ts` file.
|
||||||
|
*/
|
||||||
|
cached
|
||||||
|
private predicate isAmbientTopLevel(TopLevel tl) { tl.getFile().getBaseName().matches("%.d.ts") }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A toplevel syntactic unit; that is, a stand-alone script, an inline script
|
* A toplevel syntactic unit; that is, a stand-alone script, an inline script
|
||||||
@@ -197,11 +246,6 @@ class TopLevel extends @toplevel, StmtContainer {
|
|||||||
override ControlFlowNode getFirstControlFlowNode() { result = getEntry() }
|
override ControlFlowNode getFirstControlFlowNode() { result = getEntry() }
|
||||||
|
|
||||||
override string toString() { result = "<toplevel>" }
|
override string toString() { result = "<toplevel>" }
|
||||||
|
|
||||||
override predicate isAmbient() {
|
|
||||||
getFile().getFileType().isTypeScript() and
|
|
||||||
getFile().getBaseName().matches("%.d.ts")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1059,12 +1059,6 @@ class FieldDeclaration extends MemberDeclaration, @field {
|
|||||||
|
|
||||||
/** Holds if this is a TypeScript field marked as definitely assigned with the `!` operator. */
|
/** Holds if this is a TypeScript field marked as definitely assigned with the `!` operator. */
|
||||||
predicate hasDefiniteAssignmentAssertion() { hasDefiniteAssignmentAssertion(this) }
|
predicate hasDefiniteAssignmentAssertion() { hasDefiniteAssignmentAssertion(this) }
|
||||||
|
|
||||||
override predicate isAmbient() {
|
|
||||||
hasDeclareKeyword(this)
|
|
||||||
or
|
|
||||||
getParent().isAmbient()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -79,11 +79,6 @@ class ImportDeclaration extends Stmt, Import, @importdeclaration {
|
|||||||
|
|
||||||
/** Holds if this is declared with the `type` keyword, so it only imports types. */
|
/** Holds if this is declared with the `type` keyword, so it only imports types. */
|
||||||
predicate isTypeOnly() { hasTypeKeyword(this) }
|
predicate isTypeOnly() { hasTypeKeyword(this) }
|
||||||
|
|
||||||
override predicate isAmbient() {
|
|
||||||
Stmt.super.isAmbient() or
|
|
||||||
isTypeOnly()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A literal path expression appearing in an `import` declaration. */
|
/** A literal path expression appearing in an `import` declaration. */
|
||||||
@@ -267,11 +262,6 @@ abstract class ExportDeclaration extends Stmt, @exportdeclaration {
|
|||||||
|
|
||||||
/** Holds if is declared with the `type` keyword, so only types are exported. */
|
/** Holds if is declared with the `type` keyword, so only types are exported. */
|
||||||
predicate isTypeOnly() { hasTypeKeyword(this) }
|
predicate isTypeOnly() { hasTypeKeyword(this) }
|
||||||
|
|
||||||
override predicate isAmbient() {
|
|
||||||
Stmt.super.isAmbient() or
|
|
||||||
isTypeOnly()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -422,11 +412,6 @@ class ExportNamedDeclaration extends ExportDeclaration, @exportnameddeclaration
|
|||||||
|
|
||||||
/** Gets an export specifier of this declaration. */
|
/** Gets an export specifier of this declaration. */
|
||||||
ExportSpecifier getASpecifier() { result = getSpecifier(_) }
|
ExportSpecifier getASpecifier() { result = getSpecifier(_) }
|
||||||
|
|
||||||
override predicate isAmbient() {
|
|
||||||
// An export such as `export declare function f()` should be seen as ambient.
|
|
||||||
hasDeclareKeyword(getOperand()) or getParent().isAmbient()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -397,8 +397,6 @@ class Function extends @function, Parameterized, TypeParameterized, StmtContaine
|
|||||||
*/
|
*/
|
||||||
predicate isAbstract() { exists(MethodDeclaration md | this = md.getBody() | md.isAbstract()) }
|
predicate isAbstract() { exists(MethodDeclaration md | this = md.getBody() | md.isAbstract()) }
|
||||||
|
|
||||||
override predicate isAmbient() { getParent().isAmbient() or not hasBody() }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if this function cannot be invoked using `new` because it
|
* Holds if this function cannot be invoked using `new` because it
|
||||||
* is of the given `kind`.
|
* is of the given `kind`.
|
||||||
|
|||||||
@@ -54,8 +54,6 @@ class Stmt extends @stmt, ExprOrStmt, Documentable {
|
|||||||
getContainer().(Expr).getEnclosingStmt().nestedIn(outer)
|
getContainer().(Expr).getEnclosingStmt().nestedIn(outer)
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate isAmbient() { hasDeclareKeyword(this) or getParent().isAmbient() }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the `try` statement with a catch block containing this statement without
|
* Gets the `try` statement with a catch block containing this statement without
|
||||||
* crossing function boundaries or other `try ` statements with catch blocks.
|
* crossing function boundaries or other `try ` statements with catch blocks.
|
||||||
@@ -931,8 +929,6 @@ class DebuggerStmt extends @debuggerstmt, Stmt {
|
|||||||
*/
|
*/
|
||||||
class FunctionDeclStmt extends @functiondeclstmt, Stmt, Function {
|
class FunctionDeclStmt extends @functiondeclstmt, Stmt, Function {
|
||||||
override Stmt getEnclosingStmt() { result = this }
|
override Stmt getEnclosingStmt() { result = this }
|
||||||
|
|
||||||
override predicate isAmbient() { Function.super.isAmbient() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -155,8 +155,6 @@ class ExternalModuleDeclaration extends Stmt, StmtContainer, @externalmoduledecl
|
|||||||
int getNumStmt() { result = count(getAStmt()) }
|
int getNumStmt() { result = count(getAStmt()) }
|
||||||
|
|
||||||
override StmtContainer getEnclosingContainer() { result = this.getContainer() }
|
override StmtContainer getEnclosingContainer() { result = this.getContainer() }
|
||||||
|
|
||||||
override predicate isAmbient() { any() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -176,8 +174,6 @@ class GlobalAugmentationDeclaration extends Stmt, StmtContainer, @globalaugmenta
|
|||||||
int getNumStmt() { result = count(getAStmt()) }
|
int getNumStmt() { result = count(getAStmt()) }
|
||||||
|
|
||||||
override StmtContainer getEnclosingContainer() { result = this.getContainer() }
|
override StmtContainer getEnclosingContainer() { result = this.getContainer() }
|
||||||
|
|
||||||
override predicate isAmbient() { any() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A TypeScript "import-equals" declaration. */
|
/** A TypeScript "import-equals" declaration. */
|
||||||
@@ -237,8 +233,6 @@ class ExportAsNamespaceDeclaration extends Stmt, @exportasnamespacedeclaration {
|
|||||||
* Gets the `X` in `export as namespace X`.
|
* Gets the `X` in `export as namespace X`.
|
||||||
*/
|
*/
|
||||||
Identifier getIdentifier() { result = getChildExpr(0) }
|
Identifier getIdentifier() { result = getChildExpr(0) }
|
||||||
|
|
||||||
override predicate isAmbient() { any() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -259,8 +253,6 @@ class TypeAliasDeclaration extends @typealiasdeclaration, TypeParameterized, Stm
|
|||||||
|
|
||||||
override string describe() { result = "type alias " + getName() }
|
override string describe() { result = "type alias " + getName() }
|
||||||
|
|
||||||
override predicate isAmbient() { any() }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the canonical name of the type being defined.
|
* Gets the canonical name of the type being defined.
|
||||||
*/
|
*/
|
||||||
@@ -286,8 +278,6 @@ class InterfaceDeclaration extends Stmt, InterfaceDefinition, @interfacedeclarat
|
|||||||
|
|
||||||
override StmtContainer getContainer() { result = Stmt.super.getContainer() }
|
override StmtContainer getContainer() { result = Stmt.super.getContainer() }
|
||||||
|
|
||||||
override predicate isAmbient() { any() }
|
|
||||||
|
|
||||||
override string describe() { result = "interface " + getName() }
|
override string describe() { result = "interface " + getName() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -533,8 +523,6 @@ class LocalNamespaceName extends @local_namespace_name, LexicalName {
|
|||||||
class TypeExpr extends ExprOrType, @typeexpr, TypeAnnotation {
|
class TypeExpr extends ExprOrType, @typeexpr, TypeAnnotation {
|
||||||
override string toString() { typeexprs(this, _, _, _, result) }
|
override string toString() { typeexprs(this, _, _, _, result) }
|
||||||
|
|
||||||
override predicate isAmbient() { any() }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the static type expressed by this type annotation.
|
* Gets the static type expressed by this type annotation.
|
||||||
*
|
*
|
||||||
@@ -1410,8 +1398,6 @@ class EnumDeclaration extends NamespaceDefinition, @enumdeclaration, AST::ValueN
|
|||||||
/** Holds if this enumeration is declared with the `const` keyword. */
|
/** Holds if this enumeration is declared with the `const` keyword. */
|
||||||
predicate isConst() { isConstEnum(this) }
|
predicate isConst() { isConstEnum(this) }
|
||||||
|
|
||||||
override predicate isAmbient() { hasDeclareKeyword(this) or getParent().isAmbient() }
|
|
||||||
|
|
||||||
override ControlFlowNode getFirstControlFlowNode() { result = getIdentifier() }
|
override ControlFlowNode getFirstControlFlowNode() { result = getIdentifier() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user