Add support for live literals

This commit is contained in:
Tony Torralba
2022-03-21 14:13:59 +01:00
committed by Ian Lynagh
parent 1f812f856c
commit 3920b64d62
2 changed files with 45 additions and 4 deletions

View File

@@ -2,10 +2,8 @@
* Provides classes for working with Java expressions.
*/
import Member
import Type
import Variable
import Statement
import java
import semmle.code.java.frameworks.android.Compose
/** A common super-class that represents all kinds of expressions. */
class Expr extends ExprParent, @expr {
@@ -161,6 +159,8 @@ class CompileTimeConstantExpr extends Expr {
v.isFinal() and
v.getInitializer().isCompileTimeConstant()
)
or
this instanceof LiveLiteral
)
}
@@ -185,6 +185,8 @@ class CompileTimeConstantExpr extends Expr {
exists(Variable v | this = v.getAnAccess() |
result = v.getInitializer().(CompileTimeConstantExpr).getStringValue()
)
or
result = this.(LiveLiteral).getValue().getStringValue()
}
/**
@@ -297,6 +299,8 @@ class CompileTimeConstantExpr extends Expr {
exists(Variable v | this = v.getAnAccess() |
result = v.getInitializer().(CompileTimeConstantExpr).getBooleanValue()
)
or
result = this.(LiveLiteral).getValue().getBooleanValue()
}
/**
@@ -377,6 +381,8 @@ class CompileTimeConstantExpr extends Expr {
result = v.getInitializer().(CompileTimeConstantExpr).getIntValue()
)
)
or
result = this.(LiveLiteral).getValue().getIntValue()
}
}

View File

@@ -0,0 +1,35 @@
/**
* Provides classes and predicates for working with components generated by the Android's Jetpack Compose compiler.
*/
import java
/**
* A call to a live literal method.
* This always returns a constant expression and can be considered as such.
*/
class LiveLiteral extends MethodAccess {
CompileTimeConstantExpr value;
LiveLiteral() {
this.getMethod() instanceof LiveLiteralMethod and
not this.getEnclosingCallable() instanceof LiveLiteralMethod
}
/** Gets the constant value that backs this live literal. */
CompileTimeConstantExpr getValue() {
result =
any(ReturnStmt r | this.getMethod().calls*(r.getEnclosingCallable()))
.getResult()
.(VarAccess)
.getVariable()
.getInitializer()
}
override string toString() { result = this.getValue().toString() }
}
/** A live literal method. */
class LiveLiteralMethod extends Method {
LiveLiteralMethod() { this.getDeclaringType().getName().matches("LiveLiterals$%") }
}