diff options
author | Liam Miller-Cushon <cushon@google.com> | 2023-01-23 13:42:46 -0800 |
---|---|---|
committer | Javac Team <javac-team+copybara@google.com> | 2023-01-23 13:43:42 -0800 |
commit | 52699ff1ba8f358a02842b894dc10337def0e7fc (patch) | |
tree | 652a9b13be894e0f6fc89e2aa3732056fe752e47 | |
parent | f4370dd3fd8474ea1a78ded7da0d9cd6d3f22406 (diff) | |
download | turbine-52699ff1ba8f358a02842b894dc10337def0e7fc.tar.gz |
Don't crash on duplicate type parameter declarations
PiperOrigin-RevId: 504070824
-rw-r--r-- | java/com/google/turbine/binder/HierarchyBinder.java | 11 | ||||
-rw-r--r-- | java/com/google/turbine/binder/TypeBinder.java | 20 | ||||
-rw-r--r-- | javatests/com/google/turbine/binder/BinderErrorTest.java | 19 | ||||
-rw-r--r-- | pom.xml | 2 |
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); } @@ -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> |