[Checkers] <@ReadOnly Object> generic type (fwd)
Telmo
telmo at MIT.EDU
Tue Mar 25 22:23:07 EDT 2008
The compiler API sees the type
List<@ReadOnly Object>
as
List<@ReadOnly Object extends Object>
, causing the framework to emit an error, since @ReadOnly Object is not a
subtype of Object.
I have two possible ideas to fix this bug:
1. Check on BaseTypeVisitor if the upper bound is Object, and if so, do not
call commonAssignmentCheck
2. Modify the local (javari) version of commonAssignmentCheck, to add the
@ReadOnly annotation to the upperbound if it is object and if the error key is
"generic.argument.invalid".
For both fixes, if the user were to explicitly write the generic argument
"@ReadOnly Object extends Object", no errors would be thrown. The first
solution causes a modification to the framework, while the second solution
causes dependency on the error key for this test, which is not part of the
specification.
The first one has the following diff:
===================================================================
--- checkers/basetype/BaseTypeVisitor.java (revision 2018)
+++ checkers/basetype/BaseTypeVisitor.java (working copy)
@@ -279,10 +279,14 @@
// TODO skip wildcards for now to prevent a crash
if (typearg.getKind() == TypeKind.WILDCARD) continue;
- if (typeVar.getUpperBound() != null)
- commonAssignmentCheck(typeVar.getUpperBound(), typearg,
- typeargTrees.get(typeargs.indexOf(typearg)),
- "generic.argument.invalid", p);
+ if (typeVar.getUpperBound() != null) {
+ String s =
typeVar.getUpperBound().getUnderlyingType().toString();
+ if
(!typeVar.getUpperBound().getUnderlyingType().toString().equals("java.lang.Object"))
{
+ commonAssignmentCheck(typeVar.getUpperBound(), typearg,
+ typeargTrees.get(typeargs.indexOf(typearg)),
+ "generic.argument.invalid", p);
+ }
+ }
}
}
All tests on interned-checker and igj-checker pass. The nonnull tests do not
all pass either before or after the fix, but they generate distinct outputs,
possibly because its suit has the only test that checks for generic args
explicitly.
before change:
[java] JUnit version 4.4
[java] ............E....
[java] Time: 9.976
[java] There was 1 failure:
[java] 1) testGenericArgs(tests.NonNullTest)
[java] java.lang.AssertionError: 5 out of 6 expected diagnostics were
found.
[java] 1 expected diagnostic was not found:
[java] :33: (type.incompatible)
[java] 1 unexpected diagnostic was found:
[java] :33: (generic.argument.invalid)
after change:
[java] JUnit version 4.4
[java] ............E....
[java] Time: 9.564
[java] There was 1 failure:
[java] 1) testGenericArgs(tests.NonNullTest)
[java] java.lang.AssertionError: 2 out of 6 expected diagnostics were
found.
[java] 4 expected diagnostics were not found:
[java] :24: (generic.argument.invalid)
[java] :32: (generic.argument.invalid)
[java] :33: (type.incompatible)
[java] :43: (generic.argument.invalid)
The second one has the following diff:
===================================================================
--- checkers/javari/JavariVisitor.java (revision 2018)
+++ checkers/javari/JavariVisitor.java (working copy)
@@ -202,6 +202,16 @@
}
+ @Override
+ protected void commonAssignmentCheck(AnnotatedTypeMirror varType,
+ AnnotatedTypeMirror valueType, Tree valueTree, String errorKey,
Void p) {
+ if (errorKey.equals("generic.argument.invalid")
+ &&
varType.getUnderlyingType().toString().equals("java.lang.Object"))
+ return;
+
+ super.commonAssignmentCheck(varType, valueType, valueTree, errorKey,
p);
+ }
+
and, as expected, it doesn't affect the other checkers, but depends upon
something out of BaseTypeVisitor specification.
Any suggestions on how to deal with this are welcome.
-Telmo
More information about the checkers
mailing list