mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
Java: Add Annotation value convenience predicates
This commit is contained in:
committed by
Chris Smowton
parent
3165babc88
commit
536f5c7f89
@@ -50,6 +50,50 @@ class Annotation extends @annotation, Expr {
|
||||
/** Gets the value of the annotation element with the specified `name`. */
|
||||
Expr getValue(string name) { filteredAnnotValue(this, this.getAnnotationElement(name), result) }
|
||||
|
||||
/**
|
||||
* If the value type of the annotation element with the specified `name` is an enum type,
|
||||
* gets the enum constant used as value for that element.
|
||||
*/
|
||||
EnumConstant getValueEnumConstant(string name) {
|
||||
result = getValue(name).(FieldRead).getField()
|
||||
}
|
||||
|
||||
/**
|
||||
* If the value type of the annotation element with the specified `name` is `String`,
|
||||
* gets the string value used for that element.
|
||||
*/
|
||||
string getValueString(string name) {
|
||||
// Uses CompileTimeConstantExpr instead of StringLiteral because value can
|
||||
// be read of final variable as well
|
||||
result = getValue(name).(CompileTimeConstantExpr).getStringValue()
|
||||
}
|
||||
|
||||
/**
|
||||
* If the value type of the annotation element with the specified `name` is `int`,
|
||||
* gets the int value used for that element.
|
||||
*/
|
||||
int getValueInt(string name) {
|
||||
// Uses CompileTimeConstantExpr instead of IntegerLiteral because value can
|
||||
// be read of final variable as well
|
||||
result = getValue(name).(CompileTimeConstantExpr).getIntValue()
|
||||
}
|
||||
|
||||
/**
|
||||
* If the value type of the annotation element with the specified `name` is `boolean`,
|
||||
* gets the boolean value used for that element.
|
||||
*/
|
||||
boolean getValueBoolean(string name) {
|
||||
// Uses CompileTimeConstantExpr instead of BooleanLiteral because value can
|
||||
// be read of final variable as well
|
||||
result = getValue(name).(CompileTimeConstantExpr).getBooleanValue()
|
||||
}
|
||||
|
||||
/**
|
||||
* If the annotation element with the specified `name` has a Java `Class` as value type,
|
||||
* gets the referenced type used as value for that element.
|
||||
*/
|
||||
Type getValueClass(string name) { result = getValue(name).(TypeLiteral).getReferencedType() }
|
||||
|
||||
/** Gets the element being annotated. */
|
||||
Element getTarget() { result = this.getAnnotatedElement() }
|
||||
|
||||
@@ -66,10 +110,24 @@ class Annotation extends @annotation, Expr {
|
||||
* be one of the elements of that array. Otherwise, the returned value will be the single
|
||||
* expression defined for the value.
|
||||
*/
|
||||
Expr getAValue(string name) {
|
||||
Expr getAValue(string name) { result = getAValue(name, _) }
|
||||
|
||||
/**
|
||||
* Gets the value at a given index of the annotation element with the specified `name`, which must be
|
||||
* declared as an array type.
|
||||
*
|
||||
* If the annotation element is defined with an array initializer, then the returned value will
|
||||
* be the elements at the given index of that array. Otherwise, if the index is 0 the returned value
|
||||
* will be the single expression defined for the value.
|
||||
*/
|
||||
Expr getAValue(string name, int index) {
|
||||
this.getType().getAnnotationElement(name).getType() instanceof Array and
|
||||
exists(Expr value | value = this.getValue(name) |
|
||||
if value instanceof ArrayInit then result = value.(ArrayInit).getAnInit() else result = value
|
||||
if value instanceof ArrayInit
|
||||
then result = value.(ArrayInit).getInit(index)
|
||||
else (
|
||||
index = 0 and result = value
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -18,14 +18,18 @@ class OverrideAnnotation extends Annotation {
|
||||
class SuppressWarningsAnnotation extends Annotation {
|
||||
SuppressWarningsAnnotation() { this.getType().hasQualifiedName("java.lang", "SuppressWarnings") }
|
||||
|
||||
/** Gets the `StringLiteral` of a warning suppressed by this annotation. */
|
||||
StringLiteral getASuppressedWarningLiteral() {
|
||||
result = this.getAValue() or
|
||||
result = this.getAValue().(ArrayInit).getAnInit()
|
||||
}
|
||||
/**
|
||||
* Gets the `StringLiteral` of a warning suppressed by this annotation. To get the name of a suppressed
|
||||
* warning, prefer `getASuppressedWarning()`. That predicate considers more cases because it does not
|
||||
* restrict results to `StringLiteral`.
|
||||
*/
|
||||
StringLiteral getASuppressedWarningLiteral() { result = this.getAValue(_) }
|
||||
|
||||
/** Gets the name of a warning suppressed by this annotation. */
|
||||
string getASuppressedWarning() { result = this.getASuppressedWarningLiteral().getValue() }
|
||||
string getASuppressedWarning() {
|
||||
// Use CompileTimeConstantExpr because that covers more than StringLiteral result of getASuppressedWarningLiteral()
|
||||
result = this.getAValue(_).(CompileTimeConstantExpr).getStringValue()
|
||||
}
|
||||
}
|
||||
|
||||
/** A `@Target` annotation. */
|
||||
@@ -40,10 +44,7 @@ class TargetAnnotation extends Annotation {
|
||||
*/
|
||||
Expr getATargetExpression() {
|
||||
not result instanceof ArrayInit and
|
||||
(
|
||||
result = this.getAValue() or
|
||||
result = this.getAValue().(ArrayInit).getAnInit()
|
||||
)
|
||||
result = this.getAValue(_)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,7 +55,7 @@ class TargetAnnotation extends Annotation {
|
||||
*/
|
||||
string getATargetElementType() {
|
||||
exists(EnumConstant ec |
|
||||
ec = this.getATargetExpression().(VarAccess).getVariable() and
|
||||
ec = this.getATargetExpression().(FieldRead).getField() and
|
||||
ec.getDeclaringType().hasQualifiedName("java.lang.annotation", "ElementType")
|
||||
|
|
||||
result = ec.getName()
|
||||
@@ -82,7 +83,7 @@ class RetentionAnnotation extends Annotation {
|
||||
*/
|
||||
string getRetentionPolicy() {
|
||||
exists(EnumConstant ec |
|
||||
ec = this.getRetentionPolicyExpression().(VarAccess).getVariable() and
|
||||
ec = this.getRetentionPolicyExpression().(FieldRead).getField() and
|
||||
ec.getDeclaringType().hasQualifiedName("java.lang.annotation", "RetentionPolicy")
|
||||
|
|
||||
result = ec.getName()
|
||||
|
||||
@@ -161,15 +161,13 @@ class TestNGTestMethod extends Method {
|
||||
exists(TestNGTestAnnotation testAnnotation |
|
||||
testAnnotation = this.getAnAnnotation() and
|
||||
// The data provider must have the same name as the referenced data provider
|
||||
result.getDataProviderName() =
|
||||
testAnnotation.getValue("dataProvider").(StringLiteral).getValue()
|
||||
result.getDataProviderName() = testAnnotation.getValueString("dataProvider")
|
||||
|
|
||||
// Either the data provider should be on the current class, or a supertype
|
||||
this.getDeclaringType().getAnAncestor() = result.getDeclaringType()
|
||||
or
|
||||
// Or the data provider class should be declared
|
||||
result.getDeclaringType() =
|
||||
testAnnotation.getValue("dataProviderClass").(TypeLiteral).getReferencedType()
|
||||
result.getDeclaringType() = testAnnotation.getValueClass("dataProviderClass")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ class JaxbType extends Class {
|
||||
this.getAnAnnotation() = a and
|
||||
a.getType().(JaxbAnnotationType).hasName("XmlAccessorType")
|
||||
|
|
||||
result.getAnAccess() = a.getValue("value")
|
||||
result = a.getValueEnumConstant("value")
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -64,5 +64,5 @@ class RunWithAnnotation extends Annotation {
|
||||
/**
|
||||
* Gets the runner that will be used.
|
||||
*/
|
||||
Type getRunner() { result = this.getValue("value").(TypeLiteral).getReferencedType() }
|
||||
Type getRunner() { result = this.getValueClass("value") }
|
||||
}
|
||||
|
||||
@@ -37,8 +37,7 @@ class PersistentEntity extends RefType {
|
||||
*/
|
||||
string getAccessTypeFromAnnotation() {
|
||||
exists(AccessAnnotation accessType | accessType = this.getAnAnnotation() |
|
||||
result =
|
||||
accessType.getValue("value").(FieldRead).getField().(EnumConstant).getName().toLowerCase()
|
||||
result = accessType.getValueEnumConstant("value").getName().toLowerCase()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,9 +311,7 @@ class SpringQualifierDefinitionAnnotation extends Annotation {
|
||||
/**
|
||||
* Gets the value of the qualifier field for this qualifier.
|
||||
*/
|
||||
string getQualifierValue() {
|
||||
result = this.getValue("value").(CompileTimeConstantExpr).getStringValue()
|
||||
}
|
||||
string getQualifierValue() { result = this.getValueString("value") }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -325,9 +323,7 @@ class SpringQualifierAnnotation extends Annotation {
|
||||
/**
|
||||
* Gets the value of the qualifier field for this qualifier.
|
||||
*/
|
||||
string getQualifierValue() {
|
||||
result = this.getValue("value").(CompileTimeConstantExpr).getStringValue()
|
||||
}
|
||||
string getQualifierValue() { result = getValueString("value") }
|
||||
|
||||
/**
|
||||
* Gets the bean definition in an XML file that this qualifier resolves to, if any.
|
||||
@@ -350,9 +346,7 @@ class SpringResourceAnnotation extends Annotation {
|
||||
/**
|
||||
* Gets the specified name value, if any.
|
||||
*/
|
||||
string getNameValue() {
|
||||
result = this.getValue("name").(CompileTimeConstantExpr).getStringValue()
|
||||
}
|
||||
string getNameValue() { result = getValueString("name") }
|
||||
|
||||
/**
|
||||
* Gets the bean definition in an XML file that the resource resolves to, if any.
|
||||
|
||||
@@ -144,8 +144,7 @@ class SpringComponent extends RefType {
|
||||
if exists(this.getComponentAnnotation().getValue("value"))
|
||||
then
|
||||
// If the name has been specified in the component annotation, use that.
|
||||
result =
|
||||
this.getComponentAnnotation().getValue("value").(CompileTimeConstantExpr).getStringValue()
|
||||
result = getComponentAnnotation().getValueString("value")
|
||||
else
|
||||
// Otherwise use the name of the class, with the initial letter lower cased.
|
||||
exists(string name | name = this.getName() |
|
||||
|
||||
@@ -155,7 +155,7 @@ class SpringRequestMappingMethod extends SpringControllerMethod {
|
||||
|
||||
/** Gets the "value" @RequestMapping annotation value, if present. */
|
||||
string getValue() {
|
||||
result = requestMappingAnnotation.getValue("value").(CompileTimeConstantExpr).getStringValue()
|
||||
result = requestMappingAnnotation.getValueString("value")
|
||||
}
|
||||
|
||||
/** Holds if this is considered an `@ResponseBody` method. */
|
||||
|
||||
@@ -23,7 +23,7 @@ class SuppressionAnnotation extends SuppressWarningsAnnotation {
|
||||
string text;
|
||||
|
||||
SuppressionAnnotation() {
|
||||
text = this.getASuppressedWarningLiteral().getValue() and
|
||||
text = this.getASuppressedWarning() and
|
||||
exists(getAnnotationText(text))
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ class SpringControllerRequestMappingGetMethod extends SpringControllerGetMethod
|
||||
.getType()
|
||||
.hasQualifiedName("org.springframework.web.bind.annotation", "RequestMapping") and
|
||||
(
|
||||
this.getAnAnnotation().getValue("method").(VarAccess).getVariable().getName() = "GET" or
|
||||
this.getAnAnnotation().getValueEnumConstant("method").getName() = "GET" or
|
||||
this.getAnAnnotation().getValue("method").(ArrayInit).getSize() = 0 //Java code example: @RequestMapping(value = "test")
|
||||
) and
|
||||
not this.getAParamType().getName() = "MultipartFile"
|
||||
|
||||
Reference in New Issue
Block a user