diff --git a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacBindingResolver.java b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacBindingResolver.java index 4f435bd745e..cc49bb13bd0 100644 --- a/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacBindingResolver.java +++ b/org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacBindingResolver.java @@ -11,6 +11,7 @@ package org.eclipse.jdt.core.dom; import java.io.IOException; +import java.lang.reflect.Field; import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -162,6 +163,10 @@ public JavacLambdaBinding getLambdaBinding(JavacMethodBinding javacMethodBinding } public IBinding getBinding(final Symbol owner, final com.sun.tools.javac.code.Type type) { + Symbol recoveredSymbol = getRecoveredSymbol(type); + if (recoveredSymbol != null) { + return getBinding(recoveredSymbol, recoveredSymbol.type); + } if (owner instanceof final PackageSymbol other) { return getPackageBinding(other); } else if (owner instanceof ModuleSymbol typeSymbol) { @@ -693,6 +698,17 @@ public ITypeBinding resolveExpressionType(Expression expr) { if (jcExpr.type instanceof PackageType) { return null; } + Symbol recoveredSymbol = getRecoveredSymbol(jcExpr.type); + if (recoveredSymbol != null) { + IBinding recoveredBinding = this.bindings.getBinding(recoveredSymbol, recoveredSymbol.type); + switch (recoveredBinding) { + case IVariableBinding variableBinding: return variableBinding.getType(); + case ITypeBinding typeBinding: return typeBinding; + case IMethodBinding methodBinding: return methodBinding.getReturnType(); + default: + return null; + } + } return this.bindings.getTypeBinding(jcExpr.type); } return null; @@ -921,5 +937,20 @@ IBinding resolveReference(MemberRef ref) { } return null; } + private static Symbol getRecoveredSymbol(com.sun.tools.javac.code.Type type) { + if (type instanceof ErrorType) { + try { + Field candidateSymbolField = type.getClass().getField("candidateSymbol"); + candidateSymbolField.setAccessible(true); + Object symbolFieldValue = candidateSymbolField.get(type); + if (symbolFieldValue instanceof Symbol symbol) { + return symbol; + } + } catch (NoSuchFieldException | IllegalAccessException unused) { + // fall through to null + } + } + return null; + } }