" }
}
/**
* A stand-alone file or script originating from an HTML `
* ```
*/
class Script extends TopLevel {
Script() { this instanceof @script or this instanceof @inline_script }
}
/**
* A stand-alone file or an external script originating from an HTML `
* ```
*/
class InlineScript extends @inline_script, Script { }
/**
* A code snippet originating from an HTML attribute value.
*
* Examples:
*
* ```
* Click me
* Click me
* ```
*/
class CodeInAttribute extends TopLevel {
CodeInAttribute() {
this instanceof @event_handler or
this instanceof @javascript_url or
this instanceof @template_toplevel
}
}
/**
* A code snippet originating from an event handler attribute.
*
* Example:
*
* ```
* Click me
* ```
*/
class EventHandlerCode extends @event_handler, CodeInAttribute { }
/**
* A code snippet originating from a URL with the `javascript:` URL scheme.
*
* Example:
*
* ```
* Click me
* ```
*/
class JavaScriptUrl extends @javascript_url, CodeInAttribute { }
/** DEPRECATED: Alias for JavaScriptUrl */
deprecated class JavaScriptURL = JavaScriptUrl;
/**
* A toplevel syntactic entity containing Closure-style externs definitions.
*
* Example:
*
*
* /** @externs */
* /** @typedef {String} */
* var MyString;
*
*/
class Externs extends TopLevel {
Externs() { this.isExterns() }
}
/**
* A program element that is either an expression or a statement.
*
* Examples:
*
* ```
* var i = 0;
* i = 9
* ```
*/
class ExprOrStmt extends @expr_or_stmt, ControlFlowNode, AstNode { }
/**
* A program element that contains statements, but isn't itself
* a statement, in other words a toplevel or a function.
*
* Example:
*
* ```
* function f() {
* g();
* }
* ```
*/
class StmtContainer extends @stmt_container, AstNode {
/** Gets the innermost enclosing container in which this container is nested. */
cached
StmtContainer getEnclosingContainer() { none() }
/**
* Gets the innermost enclosing function or top-level,
* possibly this container itself if it is a function or top-level.
*
* To get a strictly enclosing function or top-level, use
* `getEnclosingContainer().getFunctionBoundary()`.
*
* TypeScript namespace declarations are containers that are not considered
* function boundaries. In plain JavaScript, all containers are function boundaries.
*/
StmtContainer getFunctionBoundary() {
if this instanceof Function or this instanceof TopLevel
then result = this
else result = this.getEnclosingContainer().getFunctionBoundary()
}
/** Gets a statement that belongs to this container. */
Stmt getAStmt() { result.getContainer() = this }
/**
* Gets the body of this container.
*
* For scripts or modules, this is the container itself; for functions,
* it is the function body.
*/
AstNode getBody() { result = this }
/**
* Gets the (unique) entry node of the control flow graph for this toplevel or function.
*
* For most purposes, the start node should be used instead of the entry node;
* see predicate `getStart()`.
*/
ControlFlowEntryNode getEntry() { result.getContainer() = this }
/** Gets the (unique) exit node of the control flow graph for this toplevel or function. */
ControlFlowExitNode getExit() { result.getContainer() = this }
/**
* Gets the (unique) CFG node at which execution of this toplevel or function begins.
*
* Unlike the entry node, which is a synthetic construct, the start node corresponds to
* an actual program element, such as the first statement of a toplevel or the first
* parameter of a function.
*
* Empty toplevels do not have a start node.
*/
ConcreteControlFlowNode getStart() { successor(this.getEntry(), result) }
/**
* Gets the entry basic block of this function, that is, the basic block
* containing the entry node of its CFG.
*/
EntryBasicBlock getEntryBB() { result = this.getEntry() }
/**
* Gets the start basic block of this function, that is, the basic block
* containing the start node of its CFG.
*/
BasicBlock getStartBB() { result.getANode() = this.getStart() }
/** Gets the scope induced by this toplevel or function, if any. */
Scope getScope() { scopenodes(this, result) }
/**
* Holds if the code in this container is executed in ECMAScript strict mode.
*
* See Annex C of the ECMAScript language specification.
*/
predicate isStrict() { this.getEnclosingContainer().isStrict() }
}
/**
* Provides a class `ValueNode` encompassing all program elements that evaluate to
* a value at runtime.
*/
module AST {
/**
* A program element that evaluates to a value or destructures a value at runtime.
* This includes expressions and destructuring patterns, but also function and
* class declaration statements, as well as TypeScript namespace and enum declarations.
*
* Examples:
*
* ```
* 0 // expression
* (function id(x) { return x; }) // parenthesized function expression
* function id(x) { return x; } // function declaration
* ```
*/
class ValueNode extends AstNode, @dataflownode {
/** Gets type inference results for this element. */
DataFlow::AnalyzedNode analyze() { result = DataFlow::valueNode(this).analyze() }
/** Gets the data flow node associated with this program element. */
DataFlow::ValueNode flow() { result = DataFlow::valueNode(this) }
}
}