aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLiam Miller-Cushon <cushon@google.com>2023-01-23 13:42:46 -0800
committerJavac Team <javac-team+copybara@google.com>2023-01-23 13:43:42 -0800
commit52699ff1ba8f358a02842b894dc10337def0e7fc (patch)
tree652a9b13be894e0f6fc89e2aa3732056fe752e47
parentf4370dd3fd8474ea1a78ded7da0d9cd6d3f22406 (diff)
downloadturbine-52699ff1ba8f358a02842b894dc10337def0e7fc.tar.gz
Don't crash on duplicate type parameter declarations
PiperOrigin-RevId: 504070824
-rw-r--r--java/com/google/turbine/binder/HierarchyBinder.java11
-rw-r--r--java/com/google/turbine/binder/TypeBinder.java20
-rw-r--r--javatests/com/google/turbine/binder/BinderErrorTest.java19
-rw-r--r--pom.xml2
4 files changed, 38 insertions, 14 deletions
diff --git a/java/com/google/turbine/binder/HierarchyBinder.java b/java/com/google/turbine/binder/HierarchyBinder.java
index ac2c840..3117d4e 100644
--- a/java/com/google/turbine/binder/HierarchyBinder.java
+++ b/java/com/google/turbine/binder/HierarchyBinder.java
@@ -34,6 +34,7 @@ import com.google.turbine.model.TurbineTyKind;
import com.google.turbine.tree.Tree;
import com.google.turbine.tree.Tree.ClassTy;
import java.util.ArrayDeque;
+import java.util.LinkedHashMap;
import org.jspecify.nullness.Nullable;
/** Type hierarchy binding. */
@@ -109,13 +110,17 @@ public class HierarchyBinder {
}
}
- ImmutableMap.Builder<String, TyVarSymbol> typeParameters = ImmutableMap.builder();
+ LinkedHashMap<String, TyVarSymbol> typeParameters = new LinkedHashMap<>();
for (Tree.TyParam p : decl.typarams()) {
- typeParameters.put(p.name().value(), new TyVarSymbol(origin, p.name().value()));
+ TyVarSymbol existing =
+ typeParameters.putIfAbsent(p.name().value(), new TyVarSymbol(origin, p.name().value()));
+ if (existing != null) {
+ log.error(p.position(), ErrorKind.DUPLICATE_DECLARATION, p.name());
+ }
}
return new SourceHeaderBoundClass(
- base, superclass, interfaces.build(), typeParameters.buildOrThrow());
+ base, superclass, interfaces.build(), ImmutableMap.copyOf(typeParameters));
}
/**
diff --git a/java/com/google/turbine/binder/TypeBinder.java b/java/com/google/turbine/binder/TypeBinder.java
index 39c7089..edfacba 100644
--- a/java/com/google/turbine/binder/TypeBinder.java
+++ b/java/com/google/turbine/binder/TypeBinder.java
@@ -64,6 +64,7 @@ import com.google.turbine.types.Deannotate;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.HashSet;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -627,7 +628,7 @@ public class TypeBinder {
/** Bind type parameter types. */
private ImmutableMap<TyVarSymbol, TyVarInfo> bindTyParams(
ImmutableList<Tree.TyParam> trees, CompoundScope scope, Map<String, TyVarSymbol> symbols) {
- ImmutableMap.Builder<TyVarSymbol, TyVarInfo> result = ImmutableMap.builder();
+ LinkedHashMap<TyVarSymbol, TyVarInfo> result = new LinkedHashMap<>();
for (Tree.TyParam tree : trees) {
// `symbols` is constructed to guarantee the requireNonNull call is safe.
TyVarSymbol sym = requireNonNull(symbols.get(tree.name().value()));
@@ -636,12 +637,16 @@ public class TypeBinder {
bounds.add(bindTy(scope, bound));
}
ImmutableList<AnnoInfo> annotations = bindAnnotations(scope, tree.annos());
- result.put(
- sym,
- new TyVarInfo(
- IntersectionTy.create(bounds.build()), /* lowerBound= */ null, annotations));
+ TyVarInfo existing =
+ result.putIfAbsent(
+ sym,
+ new TyVarInfo(
+ IntersectionTy.create(bounds.build()), /* lowerBound= */ null, annotations));
+ if (existing != null) {
+ log.error(tree.position(), ErrorKind.DUPLICATE_DECLARATION, tree.name());
+ }
}
- return result.buildOrThrow();
+ return ImmutableMap.copyOf(result);
}
private List<MethodInfo> bindMethods(
@@ -669,7 +674,8 @@ public class TypeBinder {
for (Tree.TyParam pt : t.typarams()) {
builder.put(pt.name().value(), new TyVarSymbol(sym, pt.name().value()));
}
- typeParameters = builder.buildOrThrow();
+ // errors for duplicates are reported in bindTyParams
+ typeParameters = builder.buildKeepingLast();
}
// type parameters can refer to each other in f-bounds, so update the scope first
diff --git a/javatests/com/google/turbine/binder/BinderErrorTest.java b/javatests/com/google/turbine/binder/BinderErrorTest.java
index 6766470..1a83f0d 100644
--- a/javatests/com/google/turbine/binder/BinderErrorTest.java
+++ b/javatests/com/google/turbine/binder/BinderErrorTest.java
@@ -768,9 +768,7 @@ public class BinderErrorTest {
"@interface Test {}",
},
{
- "<>:3: error: missing required annotation argument: value",
- "@Retention",
- "^",
+ "<>:3: error: missing required annotation argument: value", "@Retention", "^",
},
},
{
@@ -958,6 +956,21 @@ public class BinderErrorTest {
" ^",
},
},
+ {
+ {
+ "class T<X, X> {", //
+ " <Y, Y> void f() {}",
+ "}",
+ },
+ {
+ "<>:1: error: duplicate declaration of X",
+ "class T<X, X> {",
+ " ^",
+ "<>:2: error: duplicate declaration of Y",
+ " <Y, Y> void f() {}",
+ " ^",
+ },
+ },
};
return Arrays.asList((Object[][]) testCases);
}
diff --git a/pom.xml b/pom.xml
index a2bf088..c96551f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -31,7 +31,7 @@
<properties>
<asm.version>9.4</asm.version>
- <guava.version>31.0.1-jre</guava.version>
+ <guava.version>31.1-jre</guava.version>
<errorprone.version>2.16</errorprone.version>
<maven-javadoc-plugin.version>3.3.1</maven-javadoc-plugin.version>
<maven-source-plugin.version>3.2.1</maven-source-plugin.version>