Rename QL elements that refer to local classes

This commit is contained in:
Chris Smowton
2021-09-02 12:30:54 +01:00
parent 0a5410c2d3
commit 608d24f75e
11 changed files with 48 additions and 24 deletions

View File

@@ -1,2 +1,2 @@
lgtm,codescanning
* `Class.isLocal` has been replaced with `ClassOrInterface.isLocal`. This is because as of Java 16, interfaces can be declared method-local. Accordingly, `LocalClassDeclStmt.getLocalClass` now returns a `ClassOrInterface`. `BusinessInterface`, declared in `EJB.qll`, has had its `isRemote` and `isLocal` methods renamed `isDeclaredLocal` and `isDeclaredRemote` to avoid a name clash.
* `Class.isLocal` has been replaced with `ClassOrInterface.isLocal`. This is because as of Java 16, interfaces can be declared method-local. Accordingly, `LocalClassDeclStmt.getLocalClass` is renamed `LocalTypeDeclStmt.getLocalType` and now returns a `ClassOrInterface`. `BusinessInterface`, declared in `EJB.qll`, has had its `isRemote` and `isLocal` methods renamed `isDeclaredLocal` and `isDeclaredRemote` to avoid a name clash.

View File

@@ -456,7 +456,7 @@ private module ControlFlowGraphImpl {
or
this instanceof EmptyStmt
or
this instanceof LocalClassDeclStmt
this instanceof LocalTypeDeclStmt
or
this instanceof AssertStmt
}

View File

@@ -45,7 +45,7 @@ class Member extends Element, Annotatable, Modifiable, @member {
Callable getEnclosingCallable() {
exists(NestedClass nc | this.getDeclaringType() = nc |
nc.(AnonymousClass).getClassInstanceExpr().getEnclosingCallable() = result or
nc.(LocalClassOrInterface).getLocalClassDeclStmt().getEnclosingCallable() = result
nc.(LocalClassOrInterface).getLocalTypeDeclStmt().getEnclosingCallable() = result
)
}
}

View File

@@ -877,8 +877,8 @@ private class PpLocalVariableDeclStmt extends PpAst, LocalVariableDeclStmt {
}
}
private class PpLocalClassDeclStmt extends PpAst, LocalClassDeclStmt {
override PpAst getChild(int i) { i = 0 and result = this.getLocalClass() }
private class PpLocalTypeDeclStmt extends PpAst, LocalTypeDeclStmt {
override PpAst getChild(int i) { i = 0 and result = this.getLocalType() }
}
/*

View File

@@ -303,19 +303,25 @@ final class ClassInstanceExprNode extends ExprStmtNode {
}
/**
* A node representing a `LocalClassDeclStmt`.
* A node representing a `LocalTypeDeclStmt`.
*/
final class LocalClassDeclStmtNode extends ExprStmtNode {
LocalClassDeclStmtNode() { element instanceof LocalClassDeclStmt }
final class LocalTypeDeclStmtNode extends ExprStmtNode {
LocalTypeDeclStmtNode() { element instanceof LocalTypeDeclStmt }
override ElementNode getChild(int childIndex) {
result = super.getChild(childIndex)
or
childIndex = 0 and
result.getElement() = element.(LocalClassDeclStmt).getLocalClass()
result.getElement() = element.(LocalTypeDeclStmt).getLocalType()
}
}
/**
* DEPRECATED: Renamed `LocalTypeDeclStmtNode` to reflect the fact that
* as of Java 16 interfaces can also be declared locally, not just classes.
*/
deprecated class LocalClassDeclStmtNode = LocalTypeDeclStmtNode;
/**
* A node representing a `ForStmt`.
*/

View File

@@ -787,25 +787,37 @@ class LocalVariableDeclStmt extends Stmt, @localvariabledeclstmt {
}
/** A statement that declares a local class or interface. */
class LocalClassDeclStmt extends Stmt, @localclassdeclstmt {
/** Gets the local class declared by this statement. */
LocalClassOrInterface getLocalClass() { isLocalClass(result, this) }
class LocalTypeDeclStmt extends Stmt, @localclassdeclstmt {
/** Gets the local type declared by this statement. */
LocalClassOrInterface getLocalType() { isLocalClass(result, this) }
/**
* DEPRECATED: Renamed `getLocalType` to reflect the fact that
* as of Java 16 interfaces can also be declared locally, not just classes.
*/
deprecated LocalClassOrInterface getLocalClass() { result = this.getLocalType() }
private string getDeclKeyword() {
result = "class" and this.getLocalClass() instanceof Class
result = "class" and this.getLocalType() instanceof Class
or
result = "interface" and this.getLocalClass() instanceof Interface
result = "interface" and this.getLocalType() instanceof Interface
}
override string pp() { result = this.getDeclKeyword() + " " + this.getLocalClass().toString() }
override string pp() { result = this.getDeclKeyword() + " " + this.getLocalType().toString() }
override string toString() { result = this.getDeclKeyword() + " ..." }
override string getHalsteadID() { result = "LocalClassDeclStmt" }
override string getHalsteadID() { result = "LocalTypeDeclStmt" }
override string getAPrimaryQlClass() { result = "LocalClassDeclStmt" }
override string getAPrimaryQlClass() { result = "LocalTypeDeclStmt" }
}
/**
* DEPRECATED: Renamed `LocalTypeDeclStmt` to reflect the fact that
* as of Java 16 interfaces can also be declared locally, not just classes.
*/
deprecated class LocalClassDeclStmt = LocalTypeDeclStmt;
/** An explicit `this(...)` constructor invocation. */
class ThisConstructorInvocationStmt extends Stmt, ConstructorCall, @constructorinvocationstmt {
/** Gets an argument of this constructor invocation. */

View File

@@ -722,7 +722,13 @@ class LocalClassOrInterface extends NestedType, ClassOrInterface {
LocalClassOrInterface() { this.isLocal() }
/** Gets the statement that declares this local class. */
LocalClassDeclStmt getLocalClassDeclStmt() { isLocalClass(this, result) }
LocalTypeDeclStmt getLocalTypeDeclStmt() { isLocalClass(this, result) }
/**
* DEPRECATED: renamed `getLocalTypeDeclStmt` to reflect the fact that
* as of Java 16 interfaces can also be declared locally.
*/
deprecated LocalTypeDeclStmt getLocalClassDeclStmt() { result = this.getLocalTypeDeclStmt() }
override string getAPrimaryQlClass() { result = "LocalClassOrInterface" }
}
@@ -839,7 +845,7 @@ class InnerClass extends NestedClass {
predicate hasEnclosingInstance() {
// JLS 15.9.2. Determining Enclosing Instances
not this.(AnonymousClass).getClassInstanceExpr().isInStaticContext() and
not this.(LocalClass).getLocalClassDeclStmt().getEnclosingCallable().isStatic()
not this.(LocalClass).getLocalTypeDeclStmt().getEnclosingCallable().isStatic()
}
}

View File

@@ -238,7 +238,7 @@ private module SsaImpl {
/** Gets the definition point of a nested class in the parent scope. */
private ControlFlowNode parentDef(NestedClass nc) {
nc.(AnonymousClass).getClassInstanceExpr() = result or
nc.(LocalClass).getLocalClassDeclStmt() = result
nc.(LocalClass).getLocalTypeDeclStmt() = result
}
/**

View File

@@ -79,7 +79,7 @@ private module SsaImpl {
/** Gets the definition point of a nested class in the parent scope. */
private ControlFlowNode parentDef(NestedClass nc) {
nc.(AnonymousClass).getClassInstanceExpr() = result or
nc.(LocalClass).getLocalClassDeclStmt() = result
nc.(LocalClass).getLocalTypeDeclStmt() = result
}
/**

View File

@@ -38,7 +38,7 @@ where
// class. We keep anonymous class counts, because anonymous classes are not reported
// separately.
sum(LocalClassOrInterface localClass |
localClass.getLocalClassDeclStmt().getEnclosingCallable() = deadMethod
localClass.getLocalTypeDeclStmt().getEnclosingCallable() = deadMethod
|
localClass.getNumberOfLinesOfCode()
)

View File

@@ -122,8 +122,8 @@ where
not abortsControlFlow(s) and
// Exclude the double semicolon case `if (cond) s;;`.
not t instanceof EmptyStmt and
// `LocalClassDeclStmt`s yield false positives since their `Location` doesn't include the `class` keyword.
not t instanceof LocalClassDeclStmt
// `LocalTypeDeclStmt`s yield false positives since their `Location` doesn't include the `class` keyword.
not t instanceof LocalTypeDeclStmt
select s,
"Indentation suggests that $@ belongs to $@, but this is not the case; consider adding braces or adjusting indentation.",
t, "the next statement", c, "the control structure"