Merge pull request #10741 from hvitved/ruby/no-full-fast-tc

Ruby: Avoid computing full `fastTC` for `AstNode::getParent`
This commit is contained in:
Tom Hvitved
2022-10-10 14:01:56 +02:00
committed by GitHub
3 changed files with 29 additions and 15 deletions

View File

@@ -486,12 +486,15 @@ private import ResolveImpl
* methods evaluate the block in the context of some other module/class instead of
* the enclosing one.
*/
private ModuleBase enclosingModule(AstNode node) { result = parent*(node).getParent() }
private AstNode parent(AstNode n) {
result = n.getParent() and
not result instanceof ModuleBase and
not result instanceof Block
private ModuleBase enclosingModule(AstNode node) {
result = node.getParent()
or
exists(AstNode mid |
result = enclosingModule(mid) and
mid = node.getParent() and
not mid instanceof ModuleBase and
not mid instanceof Block
)
}
private Module getAncestors(Module m) {

View File

@@ -118,7 +118,11 @@ class Synthesis extends TSynthesis {
private class Desugared extends AstNode {
Desugared() { this = any(AstNode sugar).getDesugared() }
AstNode getADescendant() { result = this.getAChild*() }
AstNode getADescendant() {
result = this
or
result = this.getADescendant().getAChild()
}
}
/**
@@ -132,7 +136,10 @@ int desugarLevel(AstNode n) { result = count(Desugared desugared | n = desugared
* Holds if `n` appears in a context that is desugared. That is, a
* transitive, reflexive parent of `n` is a desugared node.
*/
predicate isInDesugaredContext(AstNode n) { n = any(AstNode sugar).getDesugared().getAChild*() }
predicate isInDesugaredContext(AstNode n) {
n = any(AstNode sugar).getDesugared() or
n = any(AstNode mid | isInDesugaredContext(mid)).getAChild()
}
/**
* Holds if `n` is a node that only exists as a result of desugaring some

View File

@@ -71,18 +71,22 @@ private predicate completionIsValidForStmt(AstNode n, Completion c) {
c = TReturnCompletion()
}
private AstNode getARescuableBodyChild() {
exists(Trees::BodyStmtTree bst | result = bst.getBodyChild(_, true) |
exists(bst.getARescue())
or
exists(bst.getEnsure())
)
or
result = getARescuableBodyChild().getAChild()
}
/**
* Holds if `c` happens in an exception-aware context, that is, it may be
* `rescue`d or `ensure`d. In such cases, we assume that the target of `c`
* may raise an exception (in addition to evaluating normally).
*/
private predicate mayRaise(Call c) {
exists(Trees::BodyStmtTree bst | c = bst.getBodyChild(_, true).getAChild*() |
exists(bst.getARescue())
or
exists(bst.getEnsure())
)
}
private predicate mayRaise(Call c) { c = getARescuableBodyChild() }
/** A completion of a statement or an expression. */
abstract class Completion extends TCompletion {