diff --git a/pom.xml b/pom.xml
index 0a9c8bc2..9fe538f9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -243,7 +243,7 @@
org.rascalmpl
rascal
- 0.40.13-BOOT2
+ 0.40.16
diff --git a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectDeclaration.rsc b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectDeclaration.rsc
index 075d757a..24b0a271 100644
--- a/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectDeclaration.rsc
+++ b/src/org/rascalmpl/core/library/lang/rascalcore/check/CollectDeclaration.rsc
@@ -31,6 +31,7 @@ import Set;
import String;
import util::Reflective;
+import util::IDEServices;
// ---- Utilities -------------------------------------------------------------
@@ -327,20 +328,25 @@ void collect(current: (FunctionDeclaration) ``, Collec
if(decl is abstract){
if("javaClass" in tagsMap){
if("java" notin modifiers){
- c.report(warning(decl.signature, "Missing modifier `java`"));
+ c.report(warning(decl.signature, "Missing modifier `java`", fixes=[addJavaModifier(decl)]));
}
if("test" in modifiers){
c.report(warning(decl.signature, "Modifier `test` cannot be used for Java functions"));
}
- } else {
- c.report(warning(decl, "Empty function body"));
- }
+ }
+ else if ("java" in modifiers && "javaClass" notin tagsMap) {
+ c.report(warning(decl.signature, "Missing @javaClass tag with Java function", fixes=javaClassProposals(decl)));
+ }
+ else {
+ c.report(warning(decl, "Empty function body, without a `java` modifier or @javaClass tag.",
+ fixes=[addJavaModifier(decl), *javaClassProposals(decl)]));
+ }
} else {
if("javaClass" in tagsMap){
- c.report(warning(decl.signature, "Redundant tag `javaClass`"));
+ c.report(warning(decl.signature, "Redundant tag `javaClass`", fixes=[removeJavaClass(decl)]));
}
if("java" in modifiers){
- c.report(warning(decl.signature, "Redundant modifier `java`"));
+ c.report(warning(decl.signature, "Redundant modifier `java`", fixes=[removeJavaModifier(decl)]));
}
}
@@ -731,4 +737,29 @@ void collect (current: (Declaration) ` alias
endUseTypeParameters(c);
-}
\ No newline at end of file
+}
+
+/* Here are some quickfixes used above */
+
+CodeAction addJavaModifier(FunctionDeclaration decl) = action(
+ title="add `java` modifier",
+ edits=[changed([insertBefore(decl.signature.modifiers@\loc, "java")])]
+);
+
+CodeAction removeJavaModifier(FunctionDeclaration decl) = action(
+ title="remove `java` modifier",
+ edits=[changed([delete(l@\loc) | /l:(FunctionModifier) `java` := decl])]
+);
+
+CodeAction removeJavaClass(FunctionDeclaration decl) = action(
+ title="remove ",
+ edits=[changed([delete(l@\loc) | /l:(Tag) `@javaClass` := decl])]
+);
+
+list[CodeAction] javaClassProposals(FunctionDeclaration decl) = [
+ action(
+ title="add missing ",
+ edits=[changed([insertBefore(decl.tags@\loc, "", separator="\n")])]
+ )
+ | str a <- sort({"" | /t:(Tag) `@javaClass` := parseModule(decl@\loc.top)})
+];
\ No newline at end of file