Skip to content

Commit

Permalink
Improve modeling of parameterized erroneous types
Browse files Browse the repository at this point in the history
This is similar to improvements made to javac in https://bugs.openjdk.org/browse/JDK-8338678, previously type arguments were ignored if the parameterized type could not be resolved.

PiperOrigin-RevId: 677951199
  • Loading branch information
cushon authored and Javac Team committed Sep 23, 2024
1 parent 67aca02 commit 99442e8
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 16 deletions.
2 changes: 1 addition & 1 deletion java/com/google/turbine/binder/ConstEvaluator.java
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ private Type resolveClass(ClassTy classTy) {
LookupResult result = scope.lookup(new LookupKey(ImmutableList.copyOf(flat)));
if (result == null) {
log.error(classTy.position(), ErrorKind.CANNOT_RESOLVE, flat.getFirst());
return Type.ErrorTy.create(flat);
return Type.ErrorTy.create(flat, ImmutableList.of());
}
if (result.sym().symKind() != Symbol.Kind.CLASS) {
throw error(classTy.position(), ErrorKind.UNEXPECTED_TYPE_PARAMETER, flat.getFirst());
Expand Down
10 changes: 5 additions & 5 deletions java/com/google/turbine/binder/TypeBinder.java
Original file line number Diff line number Diff line change
Expand Up @@ -971,7 +971,7 @@ private Type bindClassTy(CompoundScope scope, Tree.ClassTy t) {
LookupResult result = scope.lookup(new LookupKey(names));
if (result == null || result.sym() == null) {
log.error(names.get(0).position(), ErrorKind.CANNOT_RESOLVE, Joiner.on('.').join(names));
return Type.ErrorTy.create(names);
return Type.ErrorTy.create(names, bindTyArgs(scope, t.tyargs()));
}
Symbol sym = result.sym();
int annoIdx = flat.size() - result.remaining().size() - 1;
Expand All @@ -983,7 +983,7 @@ private Type bindClassTy(CompoundScope scope, Tree.ClassTy t) {
case TY_PARAM:
if (!result.remaining().isEmpty()) {
log.error(t.position(), ErrorKind.TYPE_PARAMETER_QUALIFIER);
return Type.ErrorTy.create(names);
return Type.ErrorTy.create(names, ImmutableList.of());
}
return Type.TyVar.create((TyVarSymbol) sym, annos);
default:
Expand All @@ -1006,14 +1006,14 @@ private Type bindClassTyRest(
for (; idx < flat.size(); idx++) {
Tree.ClassTy curr = flat.get(idx);
ClassSymbol next = resolveNext(sym, curr.name());
ImmutableList<Type> targs = bindTyArgs(scope, curr.tyargs());
if (next == null) {
return Type.ErrorTy.create(bits);
return Type.ErrorTy.create(bits, targs);
}
sym = next;

annotations = bindAnnotations(scope, curr.annos());
classes.add(
Type.ClassTy.SimpleClassTy.create(sym, bindTyArgs(scope, curr.tyargs()), annotations));
classes.add(Type.ClassTy.SimpleClassTy.create(sym, targs, annotations));
}
return Type.ClassTy.create(classes.build());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ private TurbineAnnotationMirror(ModelFactory factory, TurbineAnnotationValue val
public DeclaredType get() {
if (anno.sym() == null) {
return (ErrorType)
factory.asTypeMirror(ErrorTy.create(getLast(anno.tree().name()).value()));
factory.asTypeMirror(
ErrorTy.create(getLast(anno.tree().name()).value(), ImmutableList.of()));
}
return (DeclaredType) factory.typeElement(anno.sym()).asType();
}
Expand Down
2 changes: 1 addition & 1 deletion java/com/google/turbine/processing/TurbineElement.java
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ public TypeMirror get() {
Type asGenericType(ClassSymbol symbol) {
TypeBoundClass info = info();
if (info == null) {
return ErrorTy.create(getQualifiedName().toString());
return ErrorTy.create(getQualifiedName().toString(), ImmutableList.of());
}
Deque<Type.ClassTy.SimpleClassTy> simples = new ArrayDeque<>();
simples.addFirst(simple(symbol, info));
Expand Down
2 changes: 1 addition & 1 deletion java/com/google/turbine/processing/TurbineTypeMirror.java
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ public TypeMirror getEnclosingType() {

@Override
public List<? extends TypeMirror> getTypeArguments() {
return ImmutableList.of();
return factory.asTypeMirrors(type.targs());
}

@Override
Expand Down
25 changes: 19 additions & 6 deletions java/com/google/turbine/type/Type.java
Original file line number Diff line number Diff line change
Expand Up @@ -544,9 +544,11 @@ public final String toString() {
final class ErrorTy implements Type {

private final String name;
private final ImmutableList<Type> targs;

private ErrorTy(String name) {
private ErrorTy(String name, ImmutableList<Type> targs) {
this.name = requireNonNull(name);
this.targs = requireNonNull(targs);
}

/**
Expand All @@ -557,16 +559,20 @@ public String name() {
return name;
}

public static ErrorTy create(Iterable<Tree.Ident> names) {
public ImmutableList<Type> targs() {
return targs;
}

public static ErrorTy create(Iterable<Tree.Ident> names, ImmutableList<Type> targs) {
List<String> bits = new ArrayList<>();
for (Tree.Ident ident : names) {
bits.add(ident.value());
}
return create(Joiner.on('.').join(bits));
return create(Joiner.on('.').join(bits), targs);
}

public static ErrorTy create(String name) {
return new ErrorTy(name);
public static ErrorTy create(String name, ImmutableList<Type> targs) {
return new ErrorTy(name, targs);
}

@Override
Expand All @@ -576,7 +582,14 @@ public TyKind tyKind() {

@Override
public final String toString() {
return name();
StringBuilder sb = new StringBuilder();
sb.append(name());
if (!targs().isEmpty()) {
sb.append('<');
Joiner.on(',').appendTo(sb, targs());
sb.append('>');
}
return sb.toString();
}

@Override
Expand Down
3 changes: 3 additions & 0 deletions javatests/com/google/turbine/binder/BinderErrorTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,9 @@ public static Iterable<Object[]> parameters() {
"<>:3: error: symbol not found java.util.Map$Entry$NoSuch", //
" Map.Entry.NoSuch<List> ys;",
" ^",
"<>:3: error: could not resolve List",
" Map.Entry.NoSuch<List> ys;",
" ^",
},
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.joining;
import static javax.lang.model.util.ElementFilter.fieldsIn;
import static javax.lang.model.util.ElementFilter.methodsIn;
import static javax.lang.model.util.ElementFilter.typesIn;
import static org.junit.Assert.assertThrows;
Expand Down Expand Up @@ -70,6 +71,7 @@
import javax.lang.model.element.RecordComponentElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.ErrorType;
import javax.lang.model.type.ExecutableType;
import javax.lang.model.util.ElementFilter;
import javax.tools.Diagnostic;
Expand Down Expand Up @@ -933,6 +935,80 @@ public void permits() {
.containsExactly("I [J, K]", "J []", "K []");
}

@SupportedAnnotationTypes("*")
public static class MissingParameterizedTypeProcessor extends AbstractProcessor {
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}

private boolean first = true;

@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (!first) {
return false;
}
first = false;
for (Element root : roundEnv.getRootElements()) {
ErrorType superClass = (ErrorType) ((TypeElement) root).getSuperclass();
processingEnv
.getMessager()
.printMessage(
Diagnostic.Kind.ERROR,
String.format(
"%s supertype: %s, arguments: %s, enclosing: %s",
root,
superClass,
superClass.getTypeArguments(),
superClass.getEnclosingType()));
for (Element field : fieldsIn(root.getEnclosedElements())) {
ErrorType type = (ErrorType) field.asType();
processingEnv
.getMessager()
.printMessage(
Diagnostic.Kind.ERROR,
String.format(
"%s supertype: %s, arguments: %s, enclosing: %s",
field, type, type.getTypeArguments(), type.getEnclosingType()));
}
}
return false;
}
}

@Test
public void missingParamterizedType() throws IOException {
ImmutableList<Tree.CompUnit> units =
parseUnit(
"=== T.java ===", //
"""
class T extends M<N> {
A a;
B<C, D> b;
B<C, D>.E<F> c;
}
""");
TurbineError e = runProcessors(units, new MissingParameterizedTypeProcessor());
assertThat(
e.diagnostics().stream()
.filter(d -> d.severity().equals(Diagnostic.Kind.ERROR))
.map(d -> d.message()))
.containsExactly(
"could not resolve M",
"could not resolve N",
"could not resolve A",
"could not resolve B",
"could not resolve B.E",
"could not resolve C",
"could not resolve D",
"could not resolve F",
"T supertype: M<N>, arguments: [N], enclosing: none",
"a supertype: A, arguments: [], enclosing: none",
"b supertype: B<C,D>, arguments: [C, D], enclosing: none",
"c supertype: B.E<F>, arguments: [F], enclosing: none");
}

private TurbineError runProcessors(ImmutableList<Tree.CompUnit> units, Processor... processors) {
return assertThrows(
TurbineError.class,
Expand Down
3 changes: 2 additions & 1 deletion javatests/com/google/turbine/type/TypeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ public void error() {
ImmutableList.of(
new Ident(NO_POSITION, "com"),
new Ident(NO_POSITION, "foo"),
new Ident(NO_POSITION, "Bar")))
new Ident(NO_POSITION, "Bar")),
ImmutableList.of())
.name())
.isEqualTo("com.foo.Bar");
}
Expand Down

0 comments on commit 99442e8

Please sign in to comment.