Skip to content

Commit 9f411bc

Browse files
committed
Basic JavacRecoveredTypeBinding
1 parent 9f6c8e0 commit 9f411bc

File tree

3 files changed

+140
-2
lines changed

3 files changed

+140
-2
lines changed

org.eclipse.jdt.core.javac/src/org/eclipse/jdt/core/dom/JavacBindingResolver.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.eclipse.jdt.internal.javac.dom.JavacMethodBinding;
4141
import org.eclipse.jdt.internal.javac.dom.JavacModuleBinding;
4242
import org.eclipse.jdt.internal.javac.dom.JavacPackageBinding;
43+
import org.eclipse.jdt.internal.javac.dom.JavacRecoveredTypeBinding;
4344
import org.eclipse.jdt.internal.javac.dom.JavacTypeBinding;
4445
import org.eclipse.jdt.internal.javac.dom.JavacTypeVariableBinding;
4546
import org.eclipse.jdt.internal.javac.dom.JavacVariableBinding;
@@ -330,6 +331,11 @@ public JavacTypeBinding getTypeBinding(com.sun.tools.javac.code.Type type, com.s
330331
typeBinding.putIfAbsent(newInstance, newInstance);
331332
return typeBinding.get(newInstance);
332333
}
334+
public JavacTypeBinding getRecoveredTypeBinding(com.sun.tools.javac.code.Type type, Type domType) {
335+
var res = new JavacRecoveredTypeBinding(type, domType, JavacBindingResolver.this);
336+
typeBinding.putIfAbsent(res, res);
337+
return typeBinding.get(res);
338+
}
333339
//
334340
private Map<JavacTypeVariableBinding, JavacTypeVariableBinding> typeVariableBindings = new HashMap<>();
335341
public JavacTypeVariableBinding getTypeVariableBinding(TypeVar typeVar, Symbol backupOwner) {
@@ -668,7 +674,11 @@ public ITypeBinding resolveType(Type type) {
668674
return this.bindings.getTypeBinding(primitive.type);
669675
}
670676
if (jcTree instanceof JCArrayTypeTree arrayType && arrayType.type != null) {
671-
return this.bindings.getTypeBinding(arrayType.type);
677+
if (!arrayType.type.isErroneous()) {
678+
return this.bindings.getTypeBinding(arrayType.type);
679+
} else if (type instanceof org.eclipse.jdt.core.dom.ArrayType domType) {
680+
return this.bindings.getRecoveredTypeBinding(arrayType.type, domType);
681+
}
672682
}
673683
if (jcTree instanceof JCWildcard wcType && wcType.type != null) {
674684
return this.bindings.getTypeBinding(wcType.type);
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025, Red Hat, Inc. and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*******************************************************************************/
11+
package org.eclipse.jdt.internal.javac.dom;
12+
13+
import java.util.Objects;
14+
15+
import org.eclipse.jdt.core.dom.ASTNode;
16+
import org.eclipse.jdt.core.dom.CompilationUnit;
17+
import org.eclipse.jdt.core.dom.IPackageBinding;
18+
import org.eclipse.jdt.core.dom.JavacBindingResolver;
19+
import org.eclipse.jdt.core.dom.ParameterizedType;
20+
import org.eclipse.jdt.core.dom.QualifiedName;
21+
import org.eclipse.jdt.core.dom.SimpleName;
22+
import org.eclipse.jdt.core.dom.SimpleType;
23+
24+
import com.sun.tools.javac.code.Type;
25+
import com.sun.tools.javac.code.Type.ArrayType;
26+
27+
public class JavacRecoveredTypeBinding extends JavacTypeBinding {
28+
29+
private final org.eclipse.jdt.core.dom.Type domType;
30+
31+
public JavacRecoveredTypeBinding(com.sun.tools.javac.code.Type type, org.eclipse.jdt.core.dom.Type domType, JavacBindingResolver resolver) {
32+
super(type, type.tsym, null, null, false, resolver);
33+
this.domType = domType;
34+
}
35+
36+
@Override
37+
public int hashCode() {
38+
return super.hashCode() ^ domType.toString().hashCode();
39+
}
40+
@Override
41+
public boolean equals(Object obj) {
42+
return obj instanceof JavacRecoveredTypeBinding recovered &&
43+
Objects.equals(recovered.domType.toString(), this.domType.toString()) &&
44+
Objects.equals(recovered.domType.getAST(), this.domType.getAST()) &&
45+
super.equals(obj);
46+
}
47+
48+
@Override
49+
public JavacTypeBinding getComponentType() {
50+
if (this.type instanceof ArrayType javacArrayType && javacArrayType.isErroneous()) {
51+
if (getDimensions() > 1) {
52+
return this.resolver.bindings.getRecoveredTypeBinding(javacArrayType.elemtype, this.domType);
53+
} else if (this.domType instanceof org.eclipse.jdt.core.dom.ArrayType domArrayType) {
54+
return this.resolver.bindings.getRecoveredTypeBinding(javacArrayType.elemtype, domArrayType.getElementType());
55+
}
56+
}
57+
return super.getComponentType();
58+
}
59+
60+
@Override
61+
public JavacTypeBinding getElementType() {
62+
var res = getElementType();
63+
if (res != null) {
64+
return res;
65+
}
66+
if (isArray() && this.domType instanceof org.eclipse.jdt.core.dom.ArrayType domArrayType) {
67+
Type t = this.types.elemtype(this.type);
68+
while (t instanceof Type.ArrayType) {
69+
t = this.types.elemtype(t);
70+
}
71+
if (t == null || t.isErroneous()) {
72+
return this.resolver.bindings.getRecoveredTypeBinding(t, domArrayType);
73+
}
74+
}
75+
return res;
76+
}
77+
78+
@Override
79+
public IPackageBinding getPackage() {
80+
if (isArray()) {
81+
return null;
82+
}
83+
if (this.type == null || this.type.isErroneous()) {
84+
SimpleType base = getBaseType();
85+
if (base.getName() instanceof QualifiedName qname) {
86+
return this.resolver.bindings.getPackageBinding(qname.getQualifier());
87+
} else {
88+
ASTNode current = this.domType;
89+
while (current != null) {
90+
if (current instanceof CompilationUnit unit && unit.getPackage() != null) {
91+
return unit.getPackage().resolveBinding();
92+
}
93+
current = current.getParent();
94+
}
95+
}
96+
return null;
97+
}
98+
return super.getPackage();
99+
}
100+
101+
private SimpleType getBaseType() {
102+
org.eclipse.jdt.core.dom.Type toConsider = this.domType;
103+
while (toConsider instanceof ParameterizedType parameterized) {
104+
toConsider = parameterized.getType();
105+
}
106+
return (SimpleType)toConsider;
107+
}
108+
109+
@Override
110+
public String getQualifiedName() {
111+
if (isArray()) {
112+
return getComponentType().getQualifiedName() + "[]";
113+
}
114+
if (this.type == null || this.type.isErroneous()) {
115+
StringBuilder res = new StringBuilder(getPackage().getName());
116+
if (!res.isEmpty()) {
117+
res.append('.');
118+
}
119+
var name = getBaseType().getName();
120+
String simpleName = name.isSimpleName() ?
121+
((SimpleName)name).getIdentifier() :
122+
((QualifiedName)name).getName().getIdentifier();
123+
res.append(simpleName);
124+
return res.toString();
125+
}
126+
return super.getQualifiedName();
127+
}
128+
}

org.eclipse.jdt.core.javac/src/org/eclipse/jdt/internal/javac/dom/JavacTypeBinding.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1246,7 +1246,7 @@ protected String getQualifiedNameImpl(Type type, TypeSymbol typeSymbol, Symbol o
12461246
if( type.tsym.isAnonymous()) {
12471247
return "";
12481248
}
1249-
JavacTypeBinding componentType = this.resolver.bindings.getTypeBinding(at.getComponentType());
1249+
JavacTypeBinding componentType = getComponentType();
12501250
return (componentType == null ? "" : componentType.getQualifiedName()) + "[]";
12511251
}
12521252
if (type instanceof WildcardType wt) {

0 commit comments

Comments
 (0)