mirror of
https://github.com/github/codeql.git
synced 2026-02-20 08:53:49 +01:00
Create synthetic self nodes for calls without explicit receivers
This commit is contained in:
@@ -32,14 +32,16 @@ class AstNode extends TAstNode {
|
||||
/** Gets the enclosing module, if any. */
|
||||
ModuleBase getEnclosingModule() {
|
||||
exists(Scope::Range s |
|
||||
s = scopeOf(toGenerated(this)) and toGenerated(result) = s.getEnclosingModule()
|
||||
s = scopeOf(toGeneratedInclSynth(this)) and
|
||||
toGeneratedInclSynth(result) = s.getEnclosingModule()
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the enclosing method, if any. */
|
||||
MethodBase getEnclosingMethod() {
|
||||
exists(Scope::Range s |
|
||||
s = scopeOf(toGenerated(this)) and toGenerated(result) = s.getEnclosingMethod()
|
||||
s = scopeOf(toGeneratedInclSynth(this)) and
|
||||
toGeneratedInclSynth(result) = s.getEnclosingMethod()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -48,7 +50,7 @@ class AstNode extends TAstNode {
|
||||
string toString() { none() }
|
||||
|
||||
/** Gets the location of this node. */
|
||||
Location getLocation() { result = toGenerated(this).getLocation() }
|
||||
Location getLocation() { result = toGeneratedInclSynth(this).getLocation() }
|
||||
|
||||
/** Gets a child node of this `AstNode`. */
|
||||
final AstNode getAChild() { result = this.getAChild(_) }
|
||||
|
||||
@@ -136,6 +136,8 @@ private class IdentifierMethodCall extends MethodCall, TIdentifierMethodCall {
|
||||
IdentifierMethodCall() { this = TIdentifierMethodCall(g) }
|
||||
|
||||
final override string getMethodName() { result = getMethodName(this, g.getValue()) }
|
||||
|
||||
final override Self getReceiver() { result = TIdentifierMethodCallImplicitSelf(g) }
|
||||
}
|
||||
|
||||
private class ScopeResolutionMethodCall extends MethodCall, TScopeResolutionMethodCall {
|
||||
@@ -159,6 +161,10 @@ private class RegularMethodCall extends MethodCall, TRegularMethodCall {
|
||||
or
|
||||
not exists(g.getReceiver()) and
|
||||
toGenerated(result) = g.getMethod().(Generated::ScopeResolution).getScope()
|
||||
or
|
||||
not exists(g.getReceiver()) and
|
||||
not exists(g.getMethod().(Generated::ScopeResolution).getScope()) and
|
||||
result = TRegularMethodCallImplicitSelf(g)
|
||||
}
|
||||
|
||||
final override string getMethodName() {
|
||||
|
||||
@@ -14,6 +14,10 @@ class Expr extends Stmt, TExpr { }
|
||||
* - `self == other`
|
||||
* - `self.method_name`
|
||||
* - `def self.method_name ... end`
|
||||
*
|
||||
* This also includes implicit references to the current object in method
|
||||
* calls. For example, the method call `foo(123)` has an implicit `self`
|
||||
* receiver, and is equivalent to the explicit `self.foo(123)`.
|
||||
*/
|
||||
class Self extends Expr, TSelf {
|
||||
final override string getAPrimaryQlClass() { result = "Self" }
|
||||
|
||||
@@ -103,6 +103,7 @@ private module Cached {
|
||||
TEndBlock(Generated::EndBlock g) or
|
||||
TEnsure(Generated::Ensure g) or
|
||||
TEqExpr(Generated::Binary g) { g instanceof @binary_equalequal } or
|
||||
TExplicitSelf(Generated::Self g) or
|
||||
TExponentExpr(Generated::Binary g) { g instanceof @binary_starstar } or
|
||||
TFalseLiteral(Generated::False g) or
|
||||
TFloatLiteral(Generated::Float g) { not any(Generated::Rational r).getChild() = g } or
|
||||
@@ -119,6 +120,7 @@ private module Cached {
|
||||
THashSplatParameter(Generated::HashSplatParameter g) or
|
||||
THereDoc(Generated::HeredocBeginning g) or
|
||||
TIdentifierMethodCall(Generated::Identifier g) { vcall(g) and not access(g, _) } or
|
||||
TIdentifierMethodCallImplicitSelf(Generated::Identifier g) { vcall(g) and not access(g, _) } or
|
||||
TIf(Generated::If g) or
|
||||
TIfModifierExpr(Generated::IfModifier g) or
|
||||
TInstanceVariableAccess(Generated::InstanceVariable g, AST::InstanceVariable v) {
|
||||
@@ -158,6 +160,11 @@ private module Cached {
|
||||
TRegexMatchExpr(Generated::Binary g) { g instanceof @binary_equaltilde } or
|
||||
TRegularArrayLiteral(Generated::Array g) or
|
||||
TRegularMethodCall(Generated::Call g) { not g.getMethod() instanceof Generated::Super } or
|
||||
TRegularMethodCallImplicitSelf(Generated::Call g) {
|
||||
not g.getMethod() instanceof Generated::Super and
|
||||
not exists(g.getReceiver()) and
|
||||
not exists(g.getMethod().(Generated::ScopeResolution).getScope())
|
||||
} or
|
||||
TRegularStringLiteral(Generated::String g) or
|
||||
TRegularSuperCall(Generated::Call g) { g.getMethod() instanceof Generated::Super } or
|
||||
TRescueClause(Generated::Rescue g) or
|
||||
@@ -179,7 +186,6 @@ private module Cached {
|
||||
i = g.getName() and
|
||||
not exists(Generated::Call c | c.getMethod() = g)
|
||||
} or
|
||||
TSelf(Generated::Self g) or
|
||||
TSimpleParameter(Generated::Identifier g) { g instanceof Parameter::Range } or
|
||||
TSimpleSymbolLiteral(Generated::SimpleSymbol g) or
|
||||
TSingletonClass(Generated::SingletonClass g) or
|
||||
@@ -223,7 +229,11 @@ private module Cached {
|
||||
TWhileModifierExpr(Generated::WhileModifier g) or
|
||||
TYieldCall(Generated::Yield g)
|
||||
|
||||
/** Gets the underlying TreeSitter entity for a given AST node. */
|
||||
/**
|
||||
* Gets the underlying TreeSitter entity for a given AST node. This does not
|
||||
* include synthesized AST nodes, because they are not the primary AST node
|
||||
* for any given generated node.
|
||||
*/
|
||||
cached
|
||||
Generated::AstNode toGenerated(AST::AstNode n) {
|
||||
n = TAddExpr(result) or
|
||||
@@ -274,6 +284,7 @@ private module Cached {
|
||||
n = TEndBlock(result) or
|
||||
n = TEnsure(result) or
|
||||
n = TEqExpr(result) or
|
||||
n = TExplicitSelf(result) or
|
||||
n = TExponentExpr(result) or
|
||||
n = TFalseLiteral(result) or
|
||||
n = TFloatLiteral(result) or
|
||||
@@ -329,7 +340,6 @@ private module Cached {
|
||||
n = TReturnStmt(result) or
|
||||
n = TScopeResolutionConstantAccess(result, _) or
|
||||
n = TScopeResolutionMethodCall(result, _) or
|
||||
n = TSelf(result) or
|
||||
n = TSimpleParameter(result) or
|
||||
n = TSimpleSymbolLiteral(result) or
|
||||
n = TSingletonClass(result) or
|
||||
@@ -365,12 +375,25 @@ private module Cached {
|
||||
n = TWhileModifierExpr(result) or
|
||||
n = TYieldCall(result)
|
||||
}
|
||||
|
||||
/**
|
||||
* Like `toGenerated`, but also returns generated nodes for synthesized AST
|
||||
* nodes.
|
||||
*/
|
||||
cached
|
||||
Generated::AstNode toGeneratedInclSynth(AST::AstNode n) {
|
||||
result = toGenerated(n) or
|
||||
n = TIdentifierMethodCallImplicitSelf(result) or
|
||||
n = TRegularMethodCallImplicitSelf(result)
|
||||
}
|
||||
}
|
||||
|
||||
import Cached
|
||||
|
||||
TAstNode fromGenerated(Generated::AstNode n) { n = toGenerated(result) }
|
||||
|
||||
TAstNode fromGeneratedInclSynth(Generated::AstNode n) { n = toGeneratedInclSynth(result) }
|
||||
|
||||
class TCall = TMethodCall or TYieldCall;
|
||||
|
||||
class TMethodCall =
|
||||
@@ -392,6 +415,8 @@ class TConditionalLoop = TWhileExpr or TUntilExpr or TWhileModifierExpr or TUnti
|
||||
|
||||
class TLoop = TConditionalLoop or TForExpr;
|
||||
|
||||
class TSelf = TExplicitSelf or TIdentifierMethodCallImplicitSelf or TRegularMethodCallImplicitSelf;
|
||||
|
||||
class TExpr =
|
||||
TSelf or TArgumentList or TRescueClause or TRescueModifierExpr or TPair or TStringConcatenation or
|
||||
TCall or TBlockArgument or TSplatArgument or THashSplatArgument or TConstantAccess or
|
||||
|
||||
@@ -358,9 +358,9 @@ private module JoinBlockPredecessors {
|
||||
private predicate idOf(Generated::AstNode x, int y) = equivalenceRelation(id/2)(x, y)
|
||||
|
||||
int getId(JoinBlockPredecessor jbp) {
|
||||
idOf(toGenerated(jbp.getFirstNode().(AstCfgNode).getNode()), result)
|
||||
idOf(toGeneratedInclSynth(jbp.getFirstNode().(AstCfgNode).getNode()), result)
|
||||
or
|
||||
idOf(toGenerated(jbp.(EntryBasicBlock).getScope()), result)
|
||||
idOf(toGeneratedInclSynth(jbp.(EntryBasicBlock).getScope()), result)
|
||||
}
|
||||
|
||||
string getSplitString(JoinBlockPredecessor jbp) {
|
||||
|
||||
@@ -1318,7 +1318,8 @@ private module Cached {
|
||||
/** Gets the CFG scope of node `n`. */
|
||||
cached
|
||||
CfgScope getCfgScopeImpl(AstNode n) {
|
||||
result = parent*(ASTInternal::fromGenerated(scopeOf(ASTInternal::toGenerated(n))))
|
||||
result =
|
||||
parent*(ASTInternal::fromGeneratedInclSynth(scopeOf(ASTInternal::toGeneratedInclSynth(n))))
|
||||
}
|
||||
|
||||
private predicate isAbnormalExitType(SuccessorType t) {
|
||||
|
||||
Reference in New Issue
Block a user