diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ExhaustivenessComputer.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ExhaustivenessComputer.java index a099d634073..e275b6a7849 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ExhaustivenessComputer.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ExhaustivenessComputer.java @@ -27,8 +27,6 @@ package com.sun.tools.javac.comp; import java.util.Map; import java.util.Map.Entry; -import java.util.HashMap; -import java.util.HashSet; import java.util.Set; import com.sun.tools.javac.code.*; import com.sun.tools.javac.tree.*; @@ -43,6 +41,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.SequencedSet; import java.util.function.Consumer; @@ -51,6 +50,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.toList; import static com.sun.tools.javac.code.Flags.RECORD; /** A class to compute exhaustiveness of set of switch cases. @@ -75,7 +75,7 @@ public class ExhaustivenessComputer { private final Types types; private final Check chk; private final Infer infer; - private final Map, Boolean> isSubtypeCache = new HashMap<>(); + private final Map, Boolean> isSubtypeCache = new LinkedHashMap<>(); private final long maxBaseChecks; private long baseChecks = NO_BASE_CHECKS_COUNTING; @@ -109,9 +109,9 @@ public class ExhaustivenessComputer { } public ExhaustivenessResult exhausts(JCExpression selector, List cases) { - Set patternSet = new HashSet<>(); - Map> enum2Constants = new HashMap<>(); - Set booleanLiterals = new HashSet<>(Set.of(0, 1)); + Set patternSet = new LinkedHashSet<>(); + Map> enum2Constants = new LinkedHashMap<>(); + Set booleanLiterals = new LinkedHashSet<>(Set.of(0, 1)); for (JCCase c : cases) { if (!TreeInfo.unguardedCase(c)) continue; @@ -129,7 +129,7 @@ public class ExhaustivenessComputer { Symbol s = TreeInfo.symbol(constantLabel.expr); if (s != null && s.isEnum()) { enum2Constants.computeIfAbsent(s.owner, x -> { - Set result = new HashSet<>(); + Set result = new LinkedHashSet<>(); s.owner.members() .getSymbols(sym -> sym.kind == Kind.VAR && sym.isEnum()) .forEach(result::add); @@ -167,7 +167,7 @@ public class ExhaustivenessComputer { return Stream.of(pd); } }) - .collect(Collectors.toSet()); + .collect(Collectors.toCollection(LinkedHashSet::new)); return ExhaustivenessResult.ofDetails(details); } catch (CompletionFailure cf) { @@ -184,7 +184,7 @@ public class ExhaustivenessComputer { */ private CoverageResult computeCoverage(Type selectorType, Set patterns, PatternEquivalence patternEquivalence) { Set updatedPatterns; - Set> seenPatterns = new HashSet<>(); + Set> seenPatterns = new LinkedHashSet<>(); boolean useHashes = true; boolean repeat = true; do { @@ -276,11 +276,11 @@ public class ExhaustivenessComputer { Set existingBindings = patterns.stream() .filter(pd -> pd instanceof BindingPattern) .map(pd -> ((BindingPattern) pd).type.tsym) - .collect(Collectors.toSet()); + .collect(Collectors.toCollection(LinkedHashSet::new)); for (PatternDescription pdOne : patterns) { if (pdOne instanceof BindingPattern bpOne) { - Set toAdd = new HashSet<>(); + Set toAdd = new LinkedHashSet<>(); for (Type sup : types.directSupertypes(bpOne.type)) { ClassSymbol clazz = (ClassSymbol) types.erasure(sup).tsym; @@ -301,7 +301,7 @@ public class ExhaustivenessComputer { Set permitted = allPermittedSubTypes(clazz, isApplicableSubtypePredicate(selectorType)); //the set of pending permitted subtypes needed to cover clazz: - Set pendingPermitted = new HashSet<>(permitted); + Set pendingPermitted = new LinkedHashSet<>(permitted); for (PatternDescription pdOther : patterns) { if (pdOther instanceof BindingPattern bpOther) { @@ -336,7 +336,7 @@ public class ExhaustivenessComputer { } if (!toAdd.isEmpty()) { - Set newPatterns = new HashSet<>(patterns); + Set newPatterns = new LinkedHashSet<>(patterns); newPatterns.addAll(toAdd); return newPatterns; } @@ -346,7 +346,7 @@ public class ExhaustivenessComputer { } private Set allPermittedSubTypes(TypeSymbol root, Predicate accept) { - Set permitted = new HashSet<>(); + Set permitted = new LinkedHashSet<>(); List permittedSubtypesClosure = baseClasses(root); while (permittedSubtypesClosure.nonEmpty()) { @@ -396,7 +396,7 @@ public class ExhaustivenessComputer { } private Set leafPermittedSubTypes(TypeSymbol root, Predicate accept) { - Set permitted = new HashSet<>(); + Set permitted = new LinkedHashSet<>(); List permittedSubtypesClosure = baseClasses(root); while (permittedSubtypesClosure.nonEmpty()) { @@ -470,11 +470,11 @@ public class ExhaustivenessComputer { patterns.stream() .filter(pd -> pd instanceof RecordPattern) .map(pd -> (RecordPattern) pd) - .collect(groupingBy(pd -> (ClassSymbol) pd.recordType.tsym)); + .collect(groupingBy(pd -> (ClassSymbol) pd.recordType.tsym, LinkedHashMap::new, toList())); for (var e : groupByRecordClass.entrySet()) { int nestedPatternsCount = e.getKey().getRecordComponents().size(); - Set current = new HashSet<>(e.getValue()); + Set current = new LinkedHashSet<>(e.getValue()); for (int mismatchingCandidate = 0; mismatchingCandidate < nestedPatternsCount; @@ -485,7 +485,7 @@ public class ExhaustivenessComputer { .stream() //error recovery, ignore patterns with incorrect number of nested patterns: .filter(pd -> pd.nested.length == nestedPatternsCount) - .collect(groupingBy(pd -> useHashes ? pd.hashCode(mismatchingCandidateFin) : 0)); + .collect(groupingBy(pd -> useHashes ? pd.hashCode(mismatchingCandidateFin) : 0, LinkedHashMap::new, toList())); for (var candidates : groupEquivalenceCandidates.values()) { var candidatesArr = candidates.toArray(RecordPattern[]::new); @@ -510,7 +510,7 @@ public class ExhaustivenessComputer { } } - var nestedPatterns = join.stream().map(rp -> rp.nested[mismatchingCandidateFin]).collect(Collectors.toSet()); + var nestedPatterns = join.stream().map(rp -> rp.nested[mismatchingCandidateFin]).collect(Collectors.toCollection(LinkedHashSet::new)); var updatedPatterns = reduceNestedPatterns(nestedPatterns, useHashes, patternEquivalence); updatedPatterns = reduceRecordPatterns(updatedPatterns); @@ -532,8 +532,8 @@ public class ExhaustivenessComputer { } } - if (!current.equals(new HashSet<>(e.getValue()))) { - Set result = new HashSet<>(patterns); + if (!current.equals(new LinkedHashSet<>(e.getValue()))) { + Set result = new LinkedHashSet<>(patterns); result.removeAll(e.getValue()); result.addAll(current); return result; @@ -639,7 +639,7 @@ public class ExhaustivenessComputer { * and replace those with a simple binding pattern over $record. */ private Set reduceRecordPatterns(Set patterns) { - var newPatterns = new HashSet(); + var newPatterns = new LinkedHashSet(); boolean modified = false; for (PatternDescription pd : patterns) { if (pd instanceof RecordPattern rpOne) { @@ -690,8 +690,8 @@ public class ExhaustivenessComputer { Set existingBindings = patterns.stream() .filter(pd -> pd instanceof BindingPattern) .map(pd -> ((BindingPattern) pd).type.tsym) - .collect(Collectors.toSet()); - Set result = new HashSet<>(patterns); + .collect(Collectors.toCollection(LinkedHashSet::new)); + Set result = new LinkedHashSet<>(patterns); for (Iterator it = result.iterator(); it.hasNext();) { PatternDescription pd = it.next(); @@ -1016,7 +1016,7 @@ public class ExhaustivenessComputer { private Set replace(Iterable in, PatternDescription what, Collection to) { - Set result = new HashSet<>(); + Set result = new LinkedHashSet<>(); for (PatternDescription pd : in) { Collection replaced = replace(pd, what, to); @@ -1040,7 +1040,7 @@ public class ExhaustivenessComputer { for (int c = 0; c < rp.nested.length; c++) { Collection replaced = replace(rp.nested[c], what, to); if (replaced != null) { - Set withReplaced = new HashSet<>(); + Set withReplaced = new LinkedHashSet<>(); generatePatternsWithReplacedNestedPattern(rp, c, replaced, Set.of(), withReplaced::add); @@ -1067,14 +1067,14 @@ public class ExhaustivenessComputer { for (Iterator it = candidates.iterator(); it.hasNext(); ) { PatternDescription current = it.next(); - Set reducedAdded = new HashSet<>(candidates); + Set reducedAdded = new LinkedHashSet<>(candidates); reducedAdded.remove(current); Set combinedPatterns = Stream.concat(basePatterns.stream(), replace(inMissingPatterns, toExpand, reducedAdded).stream()) - .collect(Collectors.toSet()); + .collect(Collectors.toCollection(LinkedHashSet::new)); if (computeCoverage(selectorType, combinedPatterns, PatternEquivalence.LOOSE).covered()) { it.remove(); @@ -1197,7 +1197,7 @@ public class ExhaustivenessComputer { .map(rp -> (RecordPattern) rp) .filter(rp -> types.isSameType(rp.recordType(), rootPatternRecord.recordType())) .map(rp -> rp.nested[indexFin]) - .collect(Collectors.toSet()); + .collect(Collectors.toCollection(LinkedHashSet::new)); return basePatternsHaveRecordPatternOnThisSpot(filteredBasePatterns, rootPatternRecord.nested[index], added); } diff --git a/test/langtools/tools/javac/patterns/Exhaustiveness.java b/test/langtools/tools/javac/patterns/Exhaustiveness.java index e1d6c61970e..ce5f63059d2 100644 --- a/test/langtools/tools/javac/patterns/Exhaustiveness.java +++ b/test/langtools/tools/javac/patterns/Exhaustiveness.java @@ -38,7 +38,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; -import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; @@ -63,6 +62,7 @@ public class Exhaustiveness extends TestRunner { tb = new ToolBox(); } + @Override public void runTests() throws Exception { runTests(m -> new Object[] { Paths.get(m.getName()) }); } @@ -1546,7 +1546,7 @@ public class Exhaustiveness extends TestRunner { variants.add("C _"); variants.add("R(I _, I _, I _)"); for (int n = 0; n < NESTING_CONSTANT; n++) { - Set newVariants = new HashSet<>(); + Set newVariants = new LinkedHashSet<>(); for (String variant : variants) { if (variant.contains(", I _")) { newVariants.add(variant.replaceFirst(", I _", ", C _")); @@ -1558,7 +1558,7 @@ public class Exhaustiveness extends TestRunner { variants = newVariants; } for (int n = 0; n < NESTING_CONSTANT; n++) { - Set newVariants = new HashSet<>(); + Set newVariants = new LinkedHashSet<>(); for (String variant : variants) { if (variant.contains("I _")) { newVariants.add(variant.replaceFirst("I _", "C _"));