Open maenu opened 7 years ago
Try to use JDT null analysis, plug in annotation in AST.
first attempt of AST rewriting:
package test1; public class X { public void foo() { String s = "sdf"; IntStream @Nullable, chars = s.chars(); } }
AST rewrite works. But document remains unsaved. Need to figure out a way to do the rewrite before the save operation.
possible solution: A save action is a special clean up that perform the requested modifications on save automatically. http://help.eclipse.org/mars/index.jsp?topic=%2Forg.eclipse.jdt.doc.isv%2Fguide%2Fjdt_api_contributing_a_cleanup.htm
changes in commit:
https://www.eclipse.org/forums/index.php/t/202641/
org.eclipse.jdt.internal.compiler.classfmt.MethodInfoWithTypeAnnotations
evtl. OSGI Hook Configurator to hook into the class loading process and then supplement API classes with Nullable information: osgi.hook.configurators.include
ok does not seem to work easily, especially with a plugin based attempt:
java.lang.ClassNotFoundException: ch.unibe.scg.methodnullabilityplugin.MyClassLoaderHookConfigurator
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:264)
at org.eclipse.osgi.internal.hookregistry.HookRegistry.loadConfigurators(HookRegistry.java:185)
at org.eclipse.osgi.internal.hookregistry.HookRegistry.initialize(HookRegistry.java:106)
at org.eclipse.osgi.internal.framework.EquinoxContainer.
it seems that OSGi HookRegistry is too global to serve for our plugin
cannot find hook/listener in org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment
extension point: CompilationParticipant. reconcile hook delivers a jdt.core.ICompilationUnit.
Potential approach: AnnotationUtils of org.eclipse.jst.ws.annotations.core.utils (only provisional API)
manually inserting an annotation into IMethod/BinaryMethod/ResolvedBinaryMethod or MethodBinding. Could potentially work but have not found a way to hook into creation of those objects.
NB: Bean Validation API (e.g. @Null) is part of Java EE (since v6) and not SE
another approach: use javassist to dynamically add Nullable annotation to e.g. IMethod instances
http://stackoverflow.com/questions/2944896/dynamically-add-annotation-to-an-existing-class
Managed to "inject" a Nullable annotation in the form of AnnotationBinding into a BinaryTypeBinding (return type of respective nullable method), but it would not show the warning.
This stackoverflow post suggests that the idea is practically infeasible (no extension points or alike available for such a kind of thing):
http://stackoverflow.com/questions/14867657/custom-compile-time-class-loading-in-eclipse
Idea below of @Nullable injection via reflection does not work as the underlying models are different between methods that have this annotation in the class file (cf. MethodInfoWithTypeAnnotations) and methods that don't (cf. MethodInfo, and MethodInfo.createMethod)
`
IMethodBinding methodBinding = node.resolveMethodBinding();
IJavaElement javaElement = methodBinding.getJavaElement();
ITypeBinding tb = methodBinding.getReturnType();
Field binding = tb.getClass().getDeclaredField("binding");
binding.setAccessible(true);
BinaryTypeBinding compilerMethodBinding = (BinaryTypeBinding) binding.get(tb);
AnnotationBinding[] typeAnnotations = compilerMethodBinding.getTypeAnnotations();
if (methodBinding.getName().equals("yesIAmNullable")) {
boolean containsIt = false;
for (AnnotationBinding ab : typeAnnotations) {
nullableAnnotation = ab;
}
yesIAmNullable = methodBinding;
} else if (methodBinding.getName().equals("noIAmNotNullable")) {
if (nullableAnnotation != null) {
AnnotationBinding[] newAb = new AnnotationBinding[1];
newAb[0] = nullableAnnotation;
compilerMethodBinding.setTypeAnnotations(newAb, true);
noIAmNotNullable = methodBinding;
}
}`
Last attempt: byte code injection via AspectJ or Javassist
Insert nullable annotation into sources, IR does not work. Assignments missing.
Annotate types in declarations for local variables (prio 1), fields (prio 2), parameters (prio 2)
Show warning only if: