diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Expression.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Expression.java index 0d6bd13b404..81a585d7278 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Expression.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Expression.java @@ -1240,7 +1240,7 @@ public boolean forcedToBeRaw(ReferenceContext referenceContext) { } } else if (this instanceof SwitchExpression) { SwitchExpression se = (SwitchExpression) this; - for (Expression e : se.resultExpressions) { + for (Expression e : se.resultExpressions()) { if (e.forcedToBeRaw(referenceContext)) return true; } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java index 98bf2aac2d9..bf9055eb85a 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/FakedTrackingVariable.java @@ -241,7 +241,7 @@ else if (expression instanceof ConditionalExpression) { return getMoreUnsafeFromBranches((ConditionalExpression)expression, flowInfo, branch -> getCloseTrackingVariable(branch, flowInfo, flowContext, useAnnotations)); } else if (expression instanceof SwitchExpression) { - for (Expression re : ((SwitchExpression) expression).resultExpressions) { + for (Expression re : ((SwitchExpression) expression).resultExpressions()) { FakedTrackingVariable fakedTrackingVariable = getCloseTrackingVariable(re, flowInfo, flowContext, useAnnotations); if (fakedTrackingVariable != null) { return fakedTrackingVariable; @@ -344,7 +344,7 @@ public static FakedTrackingVariable preConnectTrackerAcrossAssignment(ASTNode lo } private static boolean containsAllocation(SwitchExpression location) { - for (Expression re : location.resultExpressions) { + for (Expression re : location.resultExpressions()) { if (containsAllocation(re)) return true; } @@ -391,7 +391,7 @@ private static void preConnectTrackerAcrossAssignment(ASTNode location, LocalVar private static void preConnectTrackerAcrossAssignment(ASTNode location, LocalVariableBinding local, FlowInfo flowInfo, SwitchExpression se, FakedTrackingVariable closeTracker, boolean useAnnotations) { - for (Expression re : se.resultExpressions) { + for (Expression re : se.resultExpressions()) { preConnectTrackerAcrossAssignment(location, local, flowInfo, closeTracker, re, useAnnotations); } } @@ -887,7 +887,7 @@ else if (expression instanceof CastExpression) local, location, branch, previousTracker)); } else if (expression instanceof SwitchExpression) { FakedTrackingVariable mostRisky = null; - for (Expression result : ((SwitchExpression) expression).resultExpressions) { + for (Expression result : ((SwitchExpression) expression).resultExpressions()) { FakedTrackingVariable current = analyseCloseableExpression(scope, flowInfo, flowContext, useAnnotations, local, location, result, previousTracker); if (mostRisky == null) diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java index a6192e74d70..a9d08ee11fa 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/LocalDeclaration.java @@ -245,7 +245,7 @@ private static Expression findPolyExpression(Expression e) { } if (e instanceof SwitchExpression) { SwitchExpression se = (SwitchExpression)e; - for (Expression re : se.resultExpressions) { + for (Expression re : se.resultExpressions()) { Expression candidate = findPolyExpression(re); if (candidate != null) return candidate; } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java index eea8d2cec77..53015ed9e70 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/NullAnnotationMatching.java @@ -156,7 +156,7 @@ public static int checkAssignment(BlockScope currentScope, FlowContext flowConte } else if (expression instanceof SwitchExpression && expression.isPolyExpression()) { // drill into all the branches: SwitchExpression se = ((SwitchExpression) expression); - Expression[] resExprs = se.resultExpressions.toArray(new Expression[0]); + Expression[] resExprs = se.resultExpressions().toArray(new Expression[0]); Expression re = resExprs[0]; int status0 = NullAnnotationMatching.checkAssignment(currentScope, flowContext, var, flowInfo, re.nullStatus(flowInfo, flowContext), re, re.resolvedType); boolean identicalStatus = true; diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Statement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Statement.java index 214b4437e33..20e8566d346 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Statement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/Statement.java @@ -194,7 +194,7 @@ void analyseOneArgument18(BlockScope currentScope, FlowContext flowContext, Flow return; } else if (argument instanceof SwitchExpression && argument.isPolyExpression()) { SwitchExpression se = (SwitchExpression) argument; - for (int i = 0; i < se.resultExpressions.size(); i++) { + for (int i = 0; i < se.resultExpressions().size(); i++) { se.internalAnalyseOneArgument18(currentScope, flowContext, expectedType, se.resultExpressions.get(i), flowInfo, se.resultExpressionNullStatus.get(i), expectedNonNullness, originalExpected); @@ -261,7 +261,7 @@ protected void checkAgainstNullTypeAnnotation(BlockScope scope, TypeBinding requ return; } else if (expression instanceof SwitchExpression && expression.isPolyExpression()) { SwitchExpression se = (SwitchExpression) expression; - for (int i = 0; i < se.resultExpressions.size(); i++) { + for (int i = 0; i < se.resultExpressions().size(); i++) { internalCheckAgainstNullTypeAnnotation(scope, requiredType, se.resultExpressions.get(i), se.resultExpressionNullStatus.get(i), flowContext, flowInfo); diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java index cd28cff55d0..09c44834c68 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/SwitchExpression.java @@ -43,8 +43,6 @@ public class SwitchExpression extends SwitchStatement implements IPolyExpression /* package */ TypeBinding expectedType; ExpressionContext expressionContext = VANILLA_CONTEXT; - private TypeBinding[] originalValueResultExpressionTypes; - private TypeBinding[] finalValueResultExpressionTypes; private int nullStatus = FlowInfo.UNKNOWN; public List resultExpressions = new ArrayList<>(0); @@ -132,7 +130,11 @@ private TypeBinding resultType() { * @return a flag indicating the overall well-formedness of result expression set. */ public boolean add(/*@NonNull*/ Expression rxpression) { - this.rExpressions.add(rxpression); + + if (!this.rExpressions.contains(rxpression)) { + this.rExpressions.add(rxpression); + SwitchExpression.this.resultExpressions.add(rxpression); // dual book keeping now for external references + } TypeBinding rxpressionType = rxpression.resolvedType; if (rxpressionType == null || !rxpressionType.isValidBinding()) @@ -212,7 +214,7 @@ private void computeNullStatus(FlowInfo flowInfo, FlowContext flowContext) { this.resultExpressionNullStatus.add(this.resultExpressions.get(0).nullStatus(flowInfo, flowContext)); int status = this.resultExpressions.get(0).nullStatus(flowInfo, flowContext); int combinedStatus = status; boolean identicalStatus = true; - for (int i = 1, l = this.resultExpressions.size(); i < l; ++i) { + for (int i = 1, l = this.resultExpressions().size(); i < l; ++i) { if (!precomputed) this.resultExpressionNullStatus.add(this.resultExpressions.get(i).nullStatus(flowInfo, flowContext)); int tmp = this.resultExpressions.get(i).nullStatus(flowInfo, flowContext); @@ -236,7 +238,7 @@ protected boolean needToCheckFlowInAbsenceOfDefaultBranch() { // JLS 12 16.1.8 @Override public Expression[] getPolyExpressions() { List polys = new ArrayList<>(); - for (Expression e : this.resultExpressions) { + for (Expression e : this.results.rExpressions) { Expression[] ea = e.getPolyExpressions(); if (ea == null || ea.length ==0) continue; polys.addAll(Arrays.asList(ea)); @@ -245,7 +247,7 @@ public Expression[] getPolyExpressions() { } @Override public boolean isPertinentToApplicability(TypeBinding targetType, MethodBinding method) { - for (Expression e : this.resultExpressions) { + for (Expression e : this.results.rExpressions) { if (!e.isPertinentToApplicability(targetType, method)) return false; } @@ -253,7 +255,7 @@ public boolean isPertinentToApplicability(TypeBinding targetType, MethodBinding } @Override public boolean isPotentiallyCompatibleWith(TypeBinding targetType, Scope scope1) { - for (Expression e : this.resultExpressions) { + for (Expression e : this.results.rExpressions) { if (!e.isPotentiallyCompatibleWith(targetType, scope1)) return false; } @@ -261,7 +263,7 @@ public boolean isPotentiallyCompatibleWith(TypeBinding targetType, Scope scope1) } @Override public boolean isFunctionalType() { - for (Expression e : this.resultExpressions) { + for (Expression e : this.results.rExpressions) { if (e.isFunctionalType()) // return true even for one functional type return true; } @@ -395,40 +397,29 @@ public void resolve(BlockScope upperScope) { @Override public TypeBinding resolveType(BlockScope upperScope) { try { - int resultExpressionsCount; if (this.constant != Constant.NotAConstant) { this.constant = Constant.NotAConstant; super.resolve(upperScope); - resultExpressionsCount = this.resultExpressions.size(); - if (resultExpressionsCount == 0) { + if (this.results.rExpressions.size() == 0) { upperScope.problemReporter().unyieldingSwitchExpression(this); return this.resolvedType = null; } - this.originalValueResultExpressionTypes = new TypeBinding[resultExpressionsCount]; - this.finalValueResultExpressionTypes = new TypeBinding[resultExpressionsCount]; - for (int i = 0; i < resultExpressionsCount; ++i) { - this.finalValueResultExpressionTypes[i] = this.originalValueResultExpressionTypes[i] = this.resultExpressions.get(i).resolvedType; - } - - if (isPolyExpression()) { //The type of a poly switch expression is the same as its target type. + if (isPolyExpression()) { if (this.expectedType == null || !this.expectedType.isProperType(true)) { return new PolyTypeBinding(this); } return this.resolvedType = computeConversions(this.scope, this.expectedType) ? this.expectedType : null; } } else { // re-resolving of poly expression: - resultExpressionsCount = this.resultExpressions.size(); boolean yieldErrors = false; - for (int i = 0; i < resultExpressionsCount; i++) { - Expression resultExpr = this.resultExpressions.get(i); - if (resultExpr.isPolyExpression()) { - this.finalValueResultExpressionTypes[i] = this.originalValueResultExpressionTypes[i] = - resultExpr.resolveTypeExpecting(upperScope, this.expectedType); + for (Expression rExpression : this.results.rExpressions) { + if (rExpression.isPolyExpression()) { + rExpression.resolveTypeExpecting(upperScope, this.expectedType); } - if (resultExpr.resolvedType == null || !resultExpr.resolvedType.isValidBinding()) + if (rExpression.resolvedType == null || !rExpression.resolvedType.isValidBinding()) yieldErrors = true; } if (yieldErrors) @@ -441,7 +432,7 @@ public TypeBinding resolveType(BlockScope upperScope) { this.resolvedType = this.results.resultType(); if (this.resolvedType != null) { - for (Expression rExpression : this.resultExpressions) + for (Expression rExpression : this.results.rExpressions) rExpression.computeConversion(upperScope, this.resolvedType, rExpression.resolvedType); } return this.resolvedType; @@ -499,7 +490,7 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl this.resultExpressionNullStatus = new ArrayList<>(0); final CompilerOptions compilerOptions = currentScope.compilerOptions(); if (compilerOptions.enableSyntacticNullAnalysisForFields) { - for (Expression re : this.resultExpressions) { + for (Expression re : this.results.rExpressions) { this.resultExpressionNullStatus.add(re.nullStatus(flowInfo, flowContext)); // wipe information that was meant only for this result expression: flowContext.expireNullCheckedFieldInfo(); @@ -522,7 +513,7 @@ public boolean isCompatibleWith(TypeBinding left, Scope skope) { if (!isPolyExpression()) return super.isCompatibleWith(left, skope); - for (Expression e : this.resultExpressions) { + for (Expression e : this.results.rExpressions) { if (!e.isCompatibleWith(left, skope)) return false; } @@ -533,7 +524,7 @@ public boolean isBoxingCompatibleWith(TypeBinding targetType, Scope skope) { if (!isPolyExpression()) return super.isBoxingCompatibleWith(targetType, skope); - for (Expression e : this.resultExpressions) { + for (Expression e : this.results.rExpressions) { if (!(e.isCompatibleWith(targetType, skope) || e.isBoxingCompatibleWith(targetType, skope))) return false; } @@ -545,7 +536,7 @@ public boolean sIsMoreSpecific(TypeBinding s, TypeBinding t, Scope skope) { return true; if (!isPolyExpression()) return false; - for (Expression e : this.resultExpressions) { + for (Expression e : this.results.rExpressions) { if (!e.sIsMoreSpecific(s, t, skope)) return false; } @@ -566,4 +557,8 @@ public StringBuilder printExpression(int tab, StringBuilder output, boolean make public TypeBinding expectedType() { return this.expectedType; } + + public Set resultExpressions() { + return this.results.rExpressions; + } } \ No newline at end of file diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/YieldStatement.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/YieldStatement.java index f6e536f36f2..ef6cde4239d 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/YieldStatement.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/ast/YieldStatement.java @@ -210,7 +210,6 @@ public void resolve(BlockScope scope) { this.expression.resolveType(scope); if (this.switchExpression != null) { - this.switchExpression.resultExpressions.add(this.expression); this.switchExpression.results.add(this.expression); } diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java index a4974f8522a..3ee7f51ec05 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/ConstraintExpressionFormula.java @@ -148,9 +148,9 @@ public Object reduce(InferenceContext18 inferenceContext) throws InferenceFailur }; } else if (this.left instanceof SwitchExpression) { SwitchExpression se = (SwitchExpression) this.left; - ConstraintFormula[] cfs = new ConstraintFormula[se.resultExpressions.size()]; + ConstraintFormula[] cfs = new ConstraintFormula[se.resultExpressions().size()]; int i = 0; - for (Expression re : se.resultExpressions) { + for (Expression re : se.resultExpressions()) { cfs[i++] = new ConstraintExpressionFormula(re, this.right, this.relation, this.isSoft); } return cfs; @@ -542,7 +542,7 @@ Collection inputVariables(final InferenceContext18 context) { } else if (this.left instanceof SwitchExpression && this.left.isPolyExpression()) { SwitchExpression expr = (SwitchExpression) this.left; Set variables = new LinkedHashSet<>(); - for (Expression re : expr.resultExpressions) { + for (Expression re : expr.resultExpressions()) { variables.addAll(new ConstraintExpressionFormula(re, this.right, COMPATIBLE).inputVariables(context)); } return variables; diff --git a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java index b7ce7e2d39b..f3ff9a39ece 100644 --- a/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java +++ b/org.eclipse.jdt.core.compiler.batch/src/org/eclipse/jdt/internal/compiler/lookup/InferenceContext18.java @@ -579,7 +579,7 @@ private ReductionResult addJDK_8153748ConstraintsFromExpression(Expression argum } else if (argument instanceof SwitchExpression) { SwitchExpression se = (SwitchExpression) argument; ReductionResult result = ReductionResult.FALSE; - for (Expression re : se.resultExpressions) { + for (Expression re : se.resultExpressions()) { result = addJDK_8153748ConstraintsFromExpression(re, parameter, method, substitution); if (result == ReductionResult.FALSE) break; @@ -723,7 +723,7 @@ private boolean addConstraintsToC_OneExpr(Expression expri, Set