diff options
author | Ron Shapiro <shapiro.rd@gmail.com> | 2018-08-21 21:12:33 -0400 |
---|---|---|
committer | Jesse Wilson <jesse@swank.ca> | 2018-08-21 21:12:33 -0400 |
commit | b879b58254804b953c6280d05d7882a89ec3b7c8 (patch) | |
tree | f76a13da6cae00ee55733c6c6497c1b5e10a7aa2 /src/main/java/com | |
parent | dfb5bc6c4e0c33f0d40d02c9702089da8a848d2f (diff) | |
download | javapoet-b879b58254804b953c6280d05d7882a89ec3b7c8.tar.gz |
Qualify types masked by type variables (#657)
* Use fully qualified names if a type variable masks a type name, even if it is in the same package
* Add a makeshift multiset to handle https://github.com/square/javapoet/pull/657\#discussion_r205514292
Diffstat (limited to 'src/main/java/com')
-rw-r--r-- | src/main/java/com/squareup/javapoet/CodeWriter.java | 37 | ||||
-rw-r--r-- | src/main/java/com/squareup/javapoet/MethodSpec.java | 1 | ||||
-rw-r--r-- | src/main/java/com/squareup/javapoet/TypeSpec.java | 1 |
3 files changed, 38 insertions, 1 deletions
diff --git a/src/main/java/com/squareup/javapoet/CodeWriter.java b/src/main/java/com/squareup/javapoet/CodeWriter.java index 542f434..ac8178f 100644 --- a/src/main/java/com/squareup/javapoet/CodeWriter.java +++ b/src/main/java/com/squareup/javapoet/CodeWriter.java @@ -57,6 +57,7 @@ final class CodeWriter { private final Map<String, ClassName> importedTypes; private final Map<String, ClassName> importableTypes = new LinkedHashMap<>(); private final Set<String> referencedNames = new LinkedHashSet<>(); + private final Multiset<String> currentTypeVariables = new Multiset<>(); private boolean trailingNewline; /** @@ -187,6 +188,8 @@ final class CodeWriter { public void emitTypeVariables(List<TypeVariableName> typeVariables) throws IOException { if (typeVariables.isEmpty()) return; + typeVariables.forEach(typeVariable -> currentTypeVariables.add(typeVariable.name)); + emit("<"); boolean firstTypeVariable = true; for (TypeVariableName typeVariable : typeVariables) { @@ -203,6 +206,10 @@ final class CodeWriter { emit(">"); } + public void popTypeVariables(List<TypeVariableName> typeVariables) throws IOException { + typeVariables.forEach(typeVariable -> currentTypeVariables.remove(typeVariable.name)); + } + public CodeWriter emit(String s) throws IOException { return emitAndIndent(s); } @@ -353,6 +360,12 @@ final class CodeWriter { * names visible due to inheritance. */ String lookupName(ClassName className) { + // If the top level simple name is masked by a current type variable, use the canonical name. + String topLevelSimpleName = className.topLevelClassName().simpleName(); + if (currentTypeVariables.contains(topLevelSimpleName)) { + return className.canonicalName; + } + // Find the shortest suffix of className that resolves to className. This uses both local type // names (so `Entry` in `Map` refers to `Map.Entry`). Also uses imports. boolean nameResolved = false; @@ -374,7 +387,7 @@ final class CodeWriter { // If the class is in the same package, we're done. if (Objects.equals(packageName, className.packageName())) { - referencedNames.add(className.topLevelClassName().simpleName()); + referencedNames.add(topLevelSimpleName); return join(".", className.simpleNames()); } @@ -494,4 +507,26 @@ final class CodeWriter { result.keySet().removeAll(referencedNames); return result; } + + // A makeshift multi-set implementation + private static final class Multiset<T> { + private final Map<T, Integer> map = new LinkedHashMap<>(); + + void add(T t) { + int count = map.getOrDefault(t, 0); + map.put(t, count + 1); + } + + void remove(T t) { + int count = map.getOrDefault(t, 0); + if (count == 0) { + throw new IllegalStateException(t + " is not in the multiset"); + } + map.put(t, count - 1); + } + + boolean contains(T t) { + return map.getOrDefault(t, 0) > 0; + } + } } diff --git a/src/main/java/com/squareup/javapoet/MethodSpec.java b/src/main/java/com/squareup/javapoet/MethodSpec.java index a2c7c43..52b41e7 100644 --- a/src/main/java/com/squareup/javapoet/MethodSpec.java +++ b/src/main/java/com/squareup/javapoet/MethodSpec.java @@ -137,6 +137,7 @@ public final class MethodSpec { codeWriter.emit("}\n"); } + codeWriter.popTypeVariables(typeVariables); } public boolean hasModifier(Modifier modifier) { diff --git a/src/main/java/com/squareup/javapoet/TypeSpec.java b/src/main/java/com/squareup/javapoet/TypeSpec.java index 46de3a5..c315579 100644 --- a/src/main/java/com/squareup/javapoet/TypeSpec.java +++ b/src/main/java/com/squareup/javapoet/TypeSpec.java @@ -316,6 +316,7 @@ public final class TypeSpec { codeWriter.unindent(); codeWriter.popType(); + codeWriter.popTypeVariables(typeVariables); codeWriter.emit("}"); if (enumName == null && anonymousTypeArguments == null) { |