Skip to content

Commit

Permalink
Fix error popups when class extends itself
Browse files Browse the repository at this point in the history
Mostly null checks in bindings,
plus override type translation to prevent trying to access the broken
class.

Fixes #919

Signed-off-by: David Thompson <davthomp@redhat.com>
  • Loading branch information
datho7561 committed Nov 27, 2024
1 parent 1995b89 commit 5655498
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ public JavacMethodBinding getMethodBinding(MethodType methodType, MethodSymbol s
}

public JavacMethodBinding getMethodBinding(MethodType methodType, MethodSymbol methodSymbol, com.sun.tools.javac.code.Type parentType, boolean isDeclaration) {
if (methodSymbol.owner == null || methodSymbol.owner.type == com.sun.tools.javac.code.Type.noType) {
return null;
}
JavacMethodBinding newInstance = new JavacMethodBinding(methodType, methodSymbol, parentType, JavacBindingResolver.this, false, isDeclaration) { };
return insertAndReturn(newInstance);
}
Expand Down Expand Up @@ -329,7 +332,7 @@ public JavacTypeVariableBinding getTypeVariableBinding(TypeVar typeVar) {
//
private Map<String, JavacVariableBinding> variableBindings = new HashMap<>();
public JavacVariableBinding getVariableBinding(VarSymbol varSymbol) {
if (varSymbol == null) {
if (varSymbol == null || varSymbol.owner == null || varSymbol.owner.type == com.sun.tools.javac.code.Type.noType) {
return null;
}
JavacVariableBinding newInstance = new JavacVariableBinding(varSymbol, JavacBindingResolver.this) { };
Expand Down Expand Up @@ -357,8 +360,8 @@ public IBinding getBinding(final Symbol owner, final com.sun.tools.javac.code.Ty
if (recoveredSymbol != null) {
return getBinding(recoveredSymbol, recoveredSymbol.type);
}
if (type instanceof ErrorType || owner.owner == null || owner.owner.type == com.sun.tools.javac.code.Type.noType) {
if (type.getOriginalType() instanceof MethodType missingMethodType) {
if (type instanceof ErrorType) {
if (type != null && type.getOriginalType() instanceof MethodType missingMethodType) {
return getErrorMethodBinding(missingMethodType, owner);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
import static com.sun.tools.javac.jvm.ByteCodes.athrow;

import com.sun.tools.javac.code.Kinds.Kind;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Type.ErrorType;
import com.sun.tools.javac.comp.Attr;
import com.sun.tools.javac.jvm.Gen;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.JCTree.JCArrayAccess;
import com.sun.tools.javac.tree.JCTree.JCAssign;
import com.sun.tools.javac.tree.JCTree.JCErroneous;
Expand All @@ -27,6 +27,7 @@
import com.sun.tools.javac.tree.JCTree.JCLiteral;
import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
import com.sun.tools.javac.tree.JCTree.JCNewClass;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Names;
Expand Down Expand Up @@ -93,7 +94,7 @@ public void visitNewClass(JCNewClass tree) {

@Override
public void visitApply(JCMethodInvocation tree) {
if (tree.type.isErroneous()) {
if (tree.type.isErroneous() || !(tree.meth.type instanceof Type.MethodType)) {
visitErroneous(null);
} else {
super.visitApply(tree);
Expand All @@ -111,7 +112,7 @@ public void visitSelect(JCFieldAccess tree) {

@Override
public void visitExec(JCExpressionStatement tree) {
if (tree.expr == null || tree.expr instanceof JCErroneous || tree.expr.type.isErroneous()) {
if (tree.expr == null || tree.expr instanceof JCErroneous || tree.expr.type.isErroneous() || tree.expr.type instanceof Type.UnknownType) {
visitErroneous(null);
} else {
super.visitExec(tree);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@

import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Type.ClassType;
import com.sun.tools.javac.code.Type.ErrorType;
import com.sun.tools.javac.comp.TransTypes;
import com.sun.tools.javac.tree.TreeInfo;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCIdent;
import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
import com.sun.tools.javac.tree.TreeInfo;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Context.Factory;

Expand All @@ -37,9 +41,31 @@ public void visitApply(JCMethodInvocation tree) {
Symbol meth = TreeInfo.symbol(tree.meth);
if (!(meth.baseSymbol() instanceof MethodSymbol)) {
//workaround: guard against ClassCastException when referencing non existing member
result = tree;
return;
}
super.visitApply(tree);
}

@Override
public void visitClassDef(JCClassDecl tree) {
if (tree.sym.type.isErroneous() && tree.sym.type instanceof ErrorType errorType) {
// HACK: likely a cyclic dependency chain. Remove the inheritance and replace the symbol's type with a boring one.
tree.extending = null;
ClassType classType = new ClassType(errorType.getEnclosingType(), com.sun.tools.javac.util.List.nil(), tree.sym);
tree.sym.type = classType;
tree.setType(classType);
}
super.visitClassDef(tree);
}

@Override
public void visitIdent(JCIdent tree) {
if (tree.sym.type.getEnclosingType() == null) {
result = tree;
return;
}
super.visitIdent(tree);
}

}

0 comments on commit 5655498

Please sign in to comment.