Skip to content

Commit

Permalink
Fixes for modifier quickfixes
Browse files Browse the repository at this point in the history
- `ModifierCorrectionsQuickFixTest.testAddPermitsToDirectSuperClass`
- `ModifierCorrectionsQuickFixTest.testAddSealedAsDirectSuperClass`
- `ModifierCorrectionsQuickFixTest.testAddSealedMissingClassModifierProposal`
- Fix id for "cannot inherit final" for anonymous classes

Signed-off-by: David Thompson <[email protected]>
  • Loading branch information
datho7561 authored and mickaelistria committed Jul 16, 2024
1 parent 49f1463 commit f752b35
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ IMethodBinding resolveMethod(MethodInvocation method) {
IMethodBinding resolveMethod(MethodDeclaration method) {
resolve();
JCTree javacElement = this.converter.domToJavac.get(method);
if (javacElement instanceof JCMethodDecl methodDecl) {
if (javacElement instanceof JCMethodDecl methodDecl && methodDecl.type != null) {
return this.bindings.getMethodBinding(methodDecl.type.asMethodType(), methodDecl.sym);
}
return null;
Expand Down Expand Up @@ -759,6 +759,7 @@ public ITypeBinding resolveExpressionType(Expression expr) {
IMethodBinding resolveConstructor(ClassInstanceCreation expression) {
resolve();
return this.converter.domToJavac.get(expression) instanceof JCNewClass jcExpr
&& jcExpr.constructor != null
&& !jcExpr.constructor.type.isErroneous()?
this.bindings.getMethodBinding(jcExpr.constructor.type.asMethodType(), (MethodSymbol)jcExpr.constructor) :
null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.tools.Diagnostic;
Expand All @@ -32,6 +35,7 @@
import com.sun.source.tree.Tree.Kind;
import com.sun.source.util.TreePath;
import com.sun.tools.javac.api.JavacTrees;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Kinds;
import com.sun.tools.javac.code.Kinds.KindName;
import com.sun.tools.javac.code.Symbol;
Expand Down Expand Up @@ -187,7 +191,26 @@ private org.eclipse.jface.text.Position getDiagnosticPosition(Diagnostic<? exten
while (diagnosticPath != null && !(diagnosticPath.getLeaf() instanceof JCClassDecl)) {
diagnosticPath = diagnosticPath.getParentPath();
}
} else if (problemId == IProblem.SealedSuperClassDoesNotPermit) {
// jdt expects the node in the extends clause with the name of the sealed class
if (diagnosticPath.getLeaf() instanceof JCTree.JCClassDecl classDecl) {
diagnosticPath = JavacTrees.instance(context).getPath(units.get(jcDiagnostic.getSource()), classDecl.getExtendsClause());
}
} else if (problemId == IProblem.SealedSuperInterfaceDoesNotPermit) {
// jdt expects the node in the implements clause with the name of the sealed class
if (diagnosticPath.getLeaf() instanceof JCTree.JCClassDecl classDecl) {
Symbol.ClassSymbol sym = getDiagnosticArgumentByType(jcDiagnostic, Symbol.ClassSymbol.class);
Optional<JCExpression> jcExpr = classDecl.getImplementsClause().stream() //
.filter(expression -> {
return expression instanceof JCIdent jcIdent && jcIdent.sym.equals(sym);
}) //
.findFirst();
if (jcExpr.isPresent()) {
diagnosticPath = JavacTrees.instance(context).getPath(units.get(jcDiagnostic.getSource()), jcExpr.get());
}
}
}

Tree element = diagnosticPath != null ? diagnosticPath.getLeaf() :
jcDiagnostic.getDiagnosticPosition() instanceof Tree tree ? tree :
null;
Expand All @@ -196,6 +219,7 @@ private org.eclipse.jface.text.Position getDiagnosticPosition(Diagnostic<? exten
case JCClassDecl jcClassDecl: return getDiagnosticPosition(jcDiagnostic, jcClassDecl);
case JCVariableDecl jcVariableDecl: return getDiagnosticPosition(jcDiagnostic, jcVariableDecl);
case JCMethodDecl jcMethodDecl: return getDiagnosticPosition(jcDiagnostic, jcMethodDecl, problemId);
case JCIdent jcIdent: return getDiagnosticPosition(jcDiagnostic, jcIdent);
case JCFieldAccess jcFieldAccess:
if (getDiagnosticArgumentByType(jcDiagnostic, KindName.class) != KindName.PACKAGE && getDiagnosticArgumentByType(jcDiagnostic, Symbol.PackageSymbol.class) == null) {
// TODO here, instead of recomputing a position, get the JDT DOM node and call the Name (which has a position)
Expand Down Expand Up @@ -241,6 +265,19 @@ private org.eclipse.jface.text.Position getDiagnosticPosition(JCDiagnostic jcDia
}
return getDefaultPosition(jcDiagnostic);
}
private static org.eclipse.jface.text.Position getDiagnosticPosition(JCDiagnostic jcDiagnostic,
JCIdent jcIdent) {
int startPosition = (int) jcDiagnostic.getPosition();
if (startPosition != Position.NOPOS) {
try {
String name = jcIdent.getName().toString();
return getDiagnosticPosition(name, startPosition, jcDiagnostic);
} catch (IOException ex) {
ILog.get().error(ex.getMessage(), ex);
}
}
return getDefaultPosition(jcDiagnostic);
}
private static org.eclipse.jface.text.Position getDefaultPosition(Diagnostic<? extends JavaFileObject> diagnostic) {
int start = (int) Math.min(diagnostic.getPosition(), diagnostic.getStartPosition());
int end = (int) Math.max(diagnostic.getEndPosition(), start);
Expand Down Expand Up @@ -373,9 +410,11 @@ private static org.eclipse.jface.text.Position getDiagnosticPosition(JCDiagnosti

private static org.eclipse.jface.text.Position getDiagnosticPosition(JCDiagnostic jcDiagnostic, JCClassDecl jcClassDecl) {
int startPosition = (int) jcDiagnostic.getPosition();
List<JCTree> realMembers = jcClassDecl.getMembers().stream() //
.filter(member -> !(member instanceof JCMethodDecl methodDecl && methodDecl.sym != null && (methodDecl.sym.flags() & Flags.GENERATEDCONSTR) != 0))
.collect(Collectors.toList());
if (startPosition != Position.NOPOS &&
(jcClassDecl.getMembers().isEmpty() ||
(!jcClassDecl.getMembers().isEmpty() && jcClassDecl.getStartPosition() != jcClassDecl.getMembers().get(0).getStartPosition()))) {
(realMembers.isEmpty() || jcClassDecl.getStartPosition() != jcClassDecl.getMembers().get(0).getStartPosition())) {
try {
String name = jcClassDecl.getSimpleName().toString();
return getDiagnosticPosition(name, startPosition, jcDiagnostic);
Expand Down Expand Up @@ -520,7 +559,6 @@ yield switch (rootCauseCode) {
case "compiler.err.mod.not.allowed.here" -> illegalModifier(diagnostic);
case "compiler.warn.strictfp" -> uselessStrictfp(diagnostic);
case "compiler.err.invalid.permits.clause" -> illegalModifier(diagnostic);
case "compiler.err.cant.inherit.from.sealed" -> IProblem.SealedSuperClassDoesNotPermit;
case "compiler.err.sealed.class.must.have.subclasses" -> IProblem.SealedSealedTypeMissingPermits;
case "compiler.err.feature.not.supported.in.source.plural" ->
diagnostic.getMessage(Locale.ENGLISH).contains("not supported in -source 8") ? IProblem.IllegalModifierForInterfaceMethod18 :
Expand Down Expand Up @@ -602,6 +640,18 @@ yield switch (rootCauseCode) {
}
case "compiler.warn.override.equals.but.not.hashcode" -> IProblem.ShouldImplementHashcode;
case "compiler.warn.unchecked.call.mbr.of.raw.type" -> IProblem.UnsafeRawMethodInvocation;
case "compiler.err.cant.inherit.from.sealed" -> {
Symbol.ClassSymbol sym = getDiagnosticArgumentByType(diagnostic, Symbol.ClassSymbol.class);
if (sym == null) {
yield 0;
}
if (sym.isInterface()) {
yield IProblem.SealedSuperInterfaceDoesNotPermit;
} else {
yield IProblem.SealedSuperClassDoesNotPermit;
}
}
case "compiler.err.non.sealed.sealed.or.final.expected" -> IProblem.SealedMissingClassModifier;
default -> {
ILog.get().error("Could not convert diagnostic (" + diagnostic.getCode() + ")\n" + diagnostic);
yield 0;
Expand Down

0 comments on commit f752b35

Please sign in to comment.