Add support for Annotation types stub generation

This commit is contained in:
Tony Torralba
2022-04-07 15:25:08 +02:00
parent 3d00a61dac
commit eda676df3e
3 changed files with 52 additions and 19 deletions

View File

@@ -20,6 +20,8 @@ class UsedInSource extends GeneratedDeclaration {
this = any(RefType t | t.fromSource())
or
this = any(TypeAccess ta | ta.fromSource())
or
this = any(Annotation a | a.getAnnotatedElement().fromSource()).getType()
)
}
}

View File

@@ -16,7 +16,12 @@ abstract private class GeneratedType extends ClassOrInterface {
}
private string stubKeyword() {
this instanceof Interface and result = "interface"
this instanceof Interface and
(
this instanceof AnnotationType and result = "@interface"
or
result = "interface"
)
or
this instanceof Class and
(if this instanceof EnumType then result = "enum" else result = "class")
@@ -27,19 +32,24 @@ abstract private class GeneratedType extends ClassOrInterface {
}
private string stubStaticModifier() {
if this.isStatic() then result = "static " else result = ""
if this.(NestedType).isStatic() then result = "static " else result = ""
}
private string stubAccessibilityModifier() {
if this.isPublic() then result = "public " else result = ""
}
private string stubAnnotations() {
result = concat("@" + stubAnnotation(this.(AnnotationType).getAnAnnotation()) + "\n")
}
/** Gets the entire Java stub code for this type. */
final string getStub() {
result =
this.stubAbstractModifier() + this.stubStaticModifier() + this.stubAccessibilityModifier() +
this.stubKeyword() + " " + this.getName() + stubGenericArguments(this, true) +
this.stubBaseTypesString() + "\n{\n" + this.stubMembers() + "}"
this.stubAnnotations() + this.stubAbstractModifier() + this.stubStaticModifier() +
this.stubAccessibilityModifier() + this.stubKeyword() + " " + this.getName() +
stubGenericArguments(this, true) + this.stubBaseTypesString() + "\n{\n" + this.stubMembers()
+ "}"
}
private RefType getAnInterestingBaseType() {
@@ -60,7 +70,9 @@ abstract private class GeneratedType extends ClassOrInterface {
else cls = ""
) and
(
if exists(this.getAnInterestingBaseType().(Interface))
if
exists(this.getAnInterestingBaseType().(Interface)) and
not this instanceof AnnotationType
then (
(if this instanceof Class then int_kw = " implements " else int_kw = " extends ") and
interface = concat(stubTypeName(this.getAnInterestingBaseType().(Interface)), ", ")
@@ -96,15 +108,14 @@ abstract private class GeneratedType extends ClassOrInterface {
}
final Type getAGeneratedType() {
result = this.getAnInterestingBaseType()
or
result = this.getAGeneratedMember().(Callable).getReturnType()
or
result = this.getAGeneratedMember().(Callable).getAParameter().getType()
or
result = this.getAGeneratedMember().(Field).getType()
or
result = this.getAGeneratedMember().(NestedType)
result = this.getAnInterestingBaseType() or
result = this.getAGeneratedMember().(Callable).getReturnType() or
result = this.getAGeneratedMember().(Callable).getAParameter().getType() or
result = this.getAGeneratedMember().(Field).getType() or
result = this.getAGeneratedMember().(NestedType) or
result = this.(AnnotationType).getAnAnnotation().getType() or
result = this.(AnnotationType).getAnAnnotation().getAValue().getType() or
result = this.(AnnotationType).getAnAnnotation().getAValue().(ArrayInit).getAnInit().getType()
}
}
@@ -391,6 +402,24 @@ private string stubMember(Member m) {
)
}
private string stubAnnotation(Annotation a) {
if exists(a.getAValue())
then result = a.toString() + "(" + concat(stubAnnotationValue(a.getAValue()), ",") + ")"
else result = a.toString()
}
private string stubAnnotiationSimpleValue(Expr value) {
result = value.(FieldAccess).getField().getQualifiedName() or
result = value.(Literal).toString()
}
private string stubAnnotationValue(Expr value) {
result = stubAnnotiationSimpleValue(value)
or
value instanceof ArrayInit and
result = "{" + concat(stubAnnotiationSimpleValue(value.(ArrayInit).getAnInit()), ",") + "}"
}
bindingset[s]
private string indent(string s) { result = " " + s.replaceAll("\n", "\n ") + "\n" }

View File

@@ -99,8 +99,8 @@ else:
dbDir = os.path.join(workDir, "db")
def print_javac_output():
logFiles = glob.glob(os.path.join(dbDir, "log", "javac-output*"))
def print_javac_output(db_dir):
logFiles = glob.glob(os.path.join(db_dir, "log", "javac-output*"))
if not(logFiles):
print("\nNo javac output found.")
@@ -124,7 +124,7 @@ def run(cmd):
print("Stubbing qltest in", testDir)
if run(['codeql', 'database', 'create', '--language=java', '--source-root='+projectDir, dbDir]):
print_javac_output()
print_javac_output(dbDir)
print("codeql database create failed. Please fix up the test before proceeding.")
exit(1)
@@ -167,7 +167,9 @@ for (typ, stub) in results['#select']['tuples']:
print("Verifying stub correctness")
if run(['codeql', 'test', 'run', testDir]):
print_javac_output()
test_db_dir = glob.glob(os.path.join(testDir, "*.testproj"))
if test_db_dir:
print_javac_output(test_db_dir[0])
print('\nTest failed. You may need to fix up the generated stubs.')
exit(1)