Skip to content

Commit

Permalink
[javac] fix quickfix to implement inherited abstract methods
Browse files Browse the repository at this point in the history
- add mapping for error id for missing abstract method implementations
- fixed an NPE that would prevent the error from being shown on
  anonymous classes
- fix binding logic for anonymous classes

example to try out: use the quickfix to add a stub implementation of
method() to the anonymous class:

```java
public class Parent {

  static interface IMethodable {
    void method();
  }

  public static void myMethod() {
    IMethodable methodable = new IMethodable() {
    };
    methodable.method();
  }

}
```

Future work: fix the diagnostic range on anonymous classes. We might
need access to the AST, since we ideally want to highlight `IMethodable`
from the constructor invocation.

Signed-off-by: David Thompson <[email protected]>
  • Loading branch information
datho7561 committed May 10, 2024
1 parent 06dd74c commit b861602
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,16 @@ ITypeBinding resolveType(EnumDeclaration enumDecl) {
return null;
}

@Override
ITypeBinding resolveType(AnonymousClassDeclaration anonymousClassDecl) {
resolve();
JCTree javacNode = this.converter.domToJavac.get(anonymousClassDecl);
if (javacNode instanceof JCClassDecl jcClassDecl) {
return new JavacTypeBinding(jcClassDecl.type, this);
}
return null;
}

public IBinding getBinding(final Symbol owner, final com.sun.tools.javac.code.Type type) {
if (owner instanceof final PackageSymbol other) {
return new JavacPackageBinding(other, this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,12 +246,14 @@ private ExportsDirective convert(JCExports javac) {
res.setName(toName(javac.getPackageName()));
commonSettings(res, javac);
List<JCExpression> mods = javac.getModuleNames();
Iterator<JCExpression> it = mods.iterator();
while(it.hasNext()) {
JCExpression jcpe = it.next();
Expression e = convertExpression(jcpe);
if( e != null )
res.modules().add(e);
if (mods != null) {
Iterator<JCExpression> it = mods.iterator();
while(it.hasNext()) {
JCExpression jcpe = it.next();
Expression e = convertExpression(jcpe);
if( e != null )
res.modules().add(e);
}
}
return res;
}
Expand Down Expand Up @@ -729,14 +731,14 @@ private MethodDeclaration convertMethodDecl(JCMethodDecl javac, ASTNode parent)
retType = convertToType(unwrapDimensions(jcatt, dims));
}
}

if( retType != null || isConstructor) {
if( this.ast.apiLevel != AST.JLS2_INTERNAL) {
res.setReturnType2(retType);
} else {
res.internalSetReturnType(retType);
}
}
}

javac.getParameters().stream().map(this::convertVariableDeclaration).forEach(res.parameters()::add);

Expand Down Expand Up @@ -790,7 +792,7 @@ private MethodDeclaration convertMethodDecl(JCMethodDecl javac, ASTNode parent)
}
return res;
}

private AbstractUnnamedTypeDeclaration findSurroundingTypeDeclaration(ASTNode parent) {
if( parent == null )
return null;
Expand Down Expand Up @@ -1415,7 +1417,7 @@ private AnonymousClassDeclaration createAnonymousClassDeclaration(JCClassDecl ja
private int countDimensions(JCArrayTypeTree tree) {
return countDimensionsAfterPosition(tree, 0);
}

private int countDimensionsAfterPosition(JCArrayTypeTree tree, int pos) {
int ret = 0;
JCTree elem = tree;
Expand All @@ -1426,7 +1428,7 @@ private int countDimensionsAfterPosition(JCArrayTypeTree tree, int pos) {
}
return ret;
}

private JCTree unwrapDimensions(JCArrayTypeTree tree, int count) {
JCTree elem = tree;
while (elem != null && elem.hasTag(TYPEARRAY) && count > 0) {
Expand Down Expand Up @@ -1829,7 +1831,7 @@ private Statement convertStatement(JCStatement javac, ASTNode parent) {
if( jcAssert.getDetail() != null ) {
Expression det = convertExpression(jcAssert.getDetail());
if( det != null )
res.setMessage(det);
res.setMessage(det);
}
return res;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ private static org.eclipse.jface.text.Position getDiagnosticPosition(JCDiagnosti

private static org.eclipse.jface.text.Position getDiagnosticPosition(String name, int startPosition, JCDiagnostic jcDiagnostic)
throws IOException {
if (name != null) {
if (name != null && !name.isEmpty()) {
DiagnosticSource source = jcDiagnostic.getDiagnosticSource();
JavaFileObject fileObject = source.getFile();
CharSequence charContent = fileObject.getCharContent(true);
Expand Down Expand Up @@ -194,6 +194,7 @@ public static int toProblemId(Diagnostic<? extends JavaFileObject> diagnostic) {
case "compiler.err.cant.apply.symbol" -> convertInApplicableSymbols(diagnostic);
case "compiler.err.premature.eof" -> IProblem.ParsingErrorUnexpectedEOF; // syntax error
case "compiler.err.report.access" -> convertNotVisibleAccess(diagnostic);
case "compiler.err.does.not.override.abstract" -> IProblem.AbstractMethodMustBeImplemented;
case COMPILER_WARN_MISSING_SVUID -> IProblem.MissingSerialVersion;
case COMPILER_WARN_NON_SERIALIZABLE_INSTANCE_FIELD -> 99999999; // JDT doesn't have this diagnostic
case "compiler.err.ref.ambiguous" -> convertAmbiguous(diagnostic);
Expand Down

0 comments on commit b861602

Please sign in to comment.