mirror of
https://github.com/github/codeql.git
synced 2026-05-02 12:15:17 +02:00
add explicit this to all member calls
This commit is contained in:
@@ -39,14 +39,14 @@ import javascript
|
||||
class Function extends @function, Parameterized, TypeParameterized, StmtContainer, Documentable,
|
||||
AST::ValueNode {
|
||||
/** Gets the `i`th parameter of this function. */
|
||||
Parameter getParameter(int i) { result = getChildExpr(i) }
|
||||
Parameter getParameter(int i) { result = this.getChildExpr(i) }
|
||||
|
||||
/** Gets a parameter of this function. */
|
||||
override Parameter getAParameter() { exists(int idx | result = getParameter(idx)) }
|
||||
override Parameter getAParameter() { exists(int idx | result = this.getParameter(idx)) }
|
||||
|
||||
/** Gets the parameter named `name` of this function, if any. */
|
||||
SimpleParameter getParameterByName(string name) {
|
||||
result = getAParameter() and
|
||||
result = this.getAParameter() and
|
||||
result.getName() = name
|
||||
}
|
||||
|
||||
@@ -72,9 +72,9 @@ class Function extends @function, Parameterized, TypeParameterized, StmtContaine
|
||||
* `this` parameter types are specific to TypeScript.
|
||||
*/
|
||||
TypeAnnotation getThisTypeAnnotation() {
|
||||
result = getChildTypeExpr(-4)
|
||||
result = this.getChildTypeExpr(-4)
|
||||
or
|
||||
result = getDocumentation().getATagByTitle("this").getType()
|
||||
result = this.getDocumentation().getATagByTitle("this").getType()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,10 +82,10 @@ class Function extends @function, Parameterized, TypeParameterized, StmtContaine
|
||||
*
|
||||
* Gets the identifier specifying the name of this function, if any.
|
||||
*/
|
||||
deprecated VarDecl getId() { result = getIdentifier() }
|
||||
deprecated VarDecl getId() { result = this.getIdentifier() }
|
||||
|
||||
/** Gets the identifier specifying the name of this function, if any. */
|
||||
VarDecl getIdentifier() { result = getChildExpr(-1) }
|
||||
VarDecl getIdentifier() { result = this.getChildExpr(-1) }
|
||||
|
||||
/**
|
||||
* Gets the name of this function if it has one, or a name inferred from its context.
|
||||
@@ -96,9 +96,9 @@ class Function extends @function, Parameterized, TypeParameterized, StmtContaine
|
||||
* can be inferred, there is no result.
|
||||
*/
|
||||
string getName() {
|
||||
result = getIdentifier().getName()
|
||||
result = this.getIdentifier().getName()
|
||||
or
|
||||
not exists(getIdentifier()) and
|
||||
not exists(this.getIdentifier()) and
|
||||
(
|
||||
exists(VarDef vd | this = vd.getSource() | result = vd.getTarget().(VarRef).getName())
|
||||
or
|
||||
@@ -118,17 +118,17 @@ class Function extends @function, Parameterized, TypeParameterized, StmtContaine
|
||||
}
|
||||
|
||||
/** Gets the variable holding this function. */
|
||||
Variable getVariable() { result = getIdentifier().getVariable() }
|
||||
Variable getVariable() { result = this.getIdentifier().getVariable() }
|
||||
|
||||
/** Gets the `arguments` variable of this function, if any. */
|
||||
ArgumentsVariable getArgumentsVariable() { result.getFunction() = this }
|
||||
|
||||
/** Holds if the body of this function refers to the function's `arguments` variable. */
|
||||
predicate usesArgumentsObject() {
|
||||
exists(getArgumentsVariable().getAnAccess())
|
||||
exists(this.getArgumentsVariable().getAnAccess())
|
||||
or
|
||||
exists(PropAccess read |
|
||||
read.getBase() = getVariable().getAnAccess() and
|
||||
read.getBase() = this.getVariable().getAnAccess() and
|
||||
read.getPropertyName() = "arguments"
|
||||
)
|
||||
}
|
||||
@@ -136,29 +136,31 @@ class Function extends @function, Parameterized, TypeParameterized, StmtContaine
|
||||
/**
|
||||
* Holds if this function declares a parameter or local variable named `arguments`.
|
||||
*/
|
||||
predicate declaresArguments() { exists(getScope().getVariable("arguments").getADeclaration()) }
|
||||
predicate declaresArguments() {
|
||||
exists(this.getScope().getVariable("arguments").getADeclaration())
|
||||
}
|
||||
|
||||
/** Gets the statement enclosing this function, if any. */
|
||||
Stmt getEnclosingStmt() { none() }
|
||||
|
||||
/** Gets the body of this function. */
|
||||
override ExprOrStmt getBody() { result = getChild(-2) }
|
||||
override ExprOrStmt getBody() { result = this.getChild(-2) }
|
||||
|
||||
/** Gets the `i`th statement in the body of this function. */
|
||||
Stmt getBodyStmt(int i) { result = getBody().(BlockStmt).getStmt(i) }
|
||||
Stmt getBodyStmt(int i) { result = this.getBody().(BlockStmt).getStmt(i) }
|
||||
|
||||
/** Gets a statement in the body of this function. */
|
||||
Stmt getABodyStmt() { result = getBodyStmt(_) }
|
||||
Stmt getABodyStmt() { result = this.getBodyStmt(_) }
|
||||
|
||||
/** Gets the number of statements in the body of this function. */
|
||||
int getNumBodyStmt() { result = count(getABodyStmt()) }
|
||||
int getNumBodyStmt() { result = count(this.getABodyStmt()) }
|
||||
|
||||
/** Gets the return type annotation on this function, if any. */
|
||||
TypeAnnotation getReturnTypeAnnotation() {
|
||||
typeexprs(result, _, this, -3, _)
|
||||
or
|
||||
exists(string title | title = "return" or title = "returns" |
|
||||
result = getDocumentation().getATagByTitle(title).getType()
|
||||
result = this.getDocumentation().getATagByTitle(title).getType()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -179,7 +181,7 @@ class Function extends @function, Parameterized, TypeParameterized, StmtContaine
|
||||
*/
|
||||
private Token lastTokenOfParameterList() {
|
||||
// if there are any parameters, it's the last token of the last parameter
|
||||
exists(Parameter lastParam | lastParam = getParameter(getNumParameter() - 1) |
|
||||
exists(Parameter lastParam | lastParam = this.getParameter(this.getNumParameter() - 1) |
|
||||
result = lastParam.getDefault().getLastToken()
|
||||
or
|
||||
not exists(lastParam.getDefault()) and result = lastParam.getLastToken()
|
||||
@@ -187,32 +189,34 @@ class Function extends @function, Parameterized, TypeParameterized, StmtContaine
|
||||
or
|
||||
// otherwise we have an empty parameter list `()`, and
|
||||
// we want to return the opening parenthesis
|
||||
not exists(getAParameter()) and
|
||||
not exists(this.getAParameter()) and
|
||||
(
|
||||
// if the function has a name, the opening parenthesis comes right after it
|
||||
result = getIdentifier().getLastToken().getNextToken()
|
||||
result = this.getIdentifier().getLastToken().getNextToken()
|
||||
or
|
||||
// otherwise this must be an arrow function with no parameters, so the opening
|
||||
// parenthesis is the very first token of the function
|
||||
not exists(getIdentifier()) and result = getFirstToken()
|
||||
not exists(this.getIdentifier()) and result = this.getFirstToken()
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if the parameter list of this function has a trailing comma. */
|
||||
predicate hasTrailingComma() { lastTokenOfParameterList().getNextToken().getValue() = "," }
|
||||
predicate hasTrailingComma() { this.lastTokenOfParameterList().getNextToken().getValue() = "," }
|
||||
|
||||
/** Holds if this function is an asynchronous function. */
|
||||
predicate isAsync() { is_async(this) }
|
||||
|
||||
/** Holds if this function is asynchronous or a generator. */
|
||||
predicate isAsyncOrGenerator() { isAsync() or isGenerator() }
|
||||
predicate isAsyncOrGenerator() { this.isAsync() or this.isGenerator() }
|
||||
|
||||
/** Gets the enclosing function or toplevel of this function. */
|
||||
override StmtContainer getEnclosingContainer() { result = getEnclosingStmt().getContainer() }
|
||||
override StmtContainer getEnclosingContainer() { result = this.getEnclosingStmt().getContainer() }
|
||||
|
||||
/** Gets the number of lines in this function. */
|
||||
int getNumberOfLines() {
|
||||
exists(int sl, int el | getLocation().hasLocationInfo(_, sl, _, el, _) | result = el - sl + 1)
|
||||
exists(int sl, int el | this.getLocation().hasLocationInfo(_, sl, _, el, _) |
|
||||
result = el - sl + 1
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the number of lines containing code in this function. */
|
||||
@@ -247,8 +251,8 @@ class Function extends @function, Parameterized, TypeParameterized, StmtContaine
|
||||
|
||||
/** Gets an expression that could be returned by this function, if any. */
|
||||
Expr getAReturnedExpr() {
|
||||
result = getBody() or
|
||||
result = getAReturnStmt().getExpr()
|
||||
result = this.getBody() or
|
||||
result = this.getAReturnStmt().getExpr()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -262,10 +266,10 @@ class Function extends @function, Parameterized, TypeParameterized, StmtContaine
|
||||
* which is the nearest enclosing non-arrow function or top-level.
|
||||
*/
|
||||
StmtContainer getThisBindingContainer() {
|
||||
result = getThisBinder()
|
||||
result = this.getThisBinder()
|
||||
or
|
||||
not exists(getThisBinder()) and
|
||||
result = getTopLevel()
|
||||
not exists(this.getThisBinder()) and
|
||||
result = this.getTopLevel()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -276,12 +280,12 @@ class Function extends @function, Parameterized, TypeParameterized, StmtContaine
|
||||
* parameter, no parameter default values, and no destructuring parameters.
|
||||
*/
|
||||
predicate hasMappedArgumentsVariable() {
|
||||
exists(getArgumentsVariable()) and
|
||||
not isStrict() and
|
||||
forall(Parameter p | p = getAParameter() |
|
||||
exists(this.getArgumentsVariable()) and
|
||||
not this.isStrict() and
|
||||
forall(Parameter p | p = this.getAParameter() |
|
||||
p instanceof SimpleParameter and not exists(p.getDefault())
|
||||
) and
|
||||
not hasRestParameter()
|
||||
not this.hasRestParameter()
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -293,23 +297,23 @@ class Function extends @function, Parameterized, TypeParameterized, StmtContaine
|
||||
* can be inferred, the result is "anonymous function".
|
||||
*/
|
||||
override string describe() {
|
||||
if exists(inferNameFromVarDef())
|
||||
then result = inferNameFromVarDef()
|
||||
if exists(this.inferNameFromVarDef())
|
||||
then result = this.inferNameFromVarDef()
|
||||
else
|
||||
if exists(inferNameFromProp())
|
||||
then result = inferNameFromProp()
|
||||
if exists(this.inferNameFromProp())
|
||||
then result = this.inferNameFromProp()
|
||||
else
|
||||
if exists(inferNameFromMemberDef())
|
||||
then result = inferNameFromMemberDef()
|
||||
if exists(this.inferNameFromMemberDef())
|
||||
then result = this.inferNameFromMemberDef()
|
||||
else
|
||||
if exists(inferNameFromCallSig())
|
||||
then result = inferNameFromCallSig()
|
||||
if exists(this.inferNameFromCallSig())
|
||||
then result = this.inferNameFromCallSig()
|
||||
else
|
||||
if exists(inferNameFromIndexSig())
|
||||
then result = inferNameFromIndexSig()
|
||||
if exists(this.inferNameFromIndexSig())
|
||||
then result = this.inferNameFromIndexSig()
|
||||
else
|
||||
if exists(inferNameFromFunctionType())
|
||||
then result = inferNameFromFunctionType()
|
||||
if exists(this.inferNameFromFunctionType())
|
||||
then result = this.inferNameFromFunctionType()
|
||||
else result = "anonymous function"
|
||||
}
|
||||
|
||||
@@ -319,8 +323,8 @@ class Function extends @function, Parameterized, TypeParameterized, StmtContaine
|
||||
*/
|
||||
private string inferNameFromVarDef() {
|
||||
// in ambiguous cases like `var f = function g() {}`, prefer `g` to `f`
|
||||
if exists(getIdentifier())
|
||||
then result = "function " + getIdentifier().getName()
|
||||
if exists(this.getIdentifier())
|
||||
then result = "function " + this.getIdentifier().getName()
|
||||
else
|
||||
exists(VarDef vd | this = vd.getSource() |
|
||||
result = "function " + vd.getTarget().(VarRef).getName()
|
||||
@@ -400,7 +404,7 @@ class Function extends @function, Parameterized, TypeParameterized, StmtContaine
|
||||
*
|
||||
* A JavaScript function always has a body.
|
||||
*/
|
||||
predicate hasBody() { exists(getBody()) }
|
||||
predicate hasBody() { exists(this.getBody()) }
|
||||
|
||||
/**
|
||||
* Holds if this function is part of an abstract class member.
|
||||
@@ -419,10 +423,10 @@ class Function extends @function, Parameterized, TypeParameterized, StmtContaine
|
||||
this instanceof ArrowFunctionExpr and
|
||||
kind = "an arrow function"
|
||||
or
|
||||
isGenerator() and
|
||||
this.isGenerator() and
|
||||
kind = "a generator function"
|
||||
or
|
||||
isAsync() and
|
||||
this.isAsync() and
|
||||
kind = "an async function"
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user