Skip to content

Commit

Permalink
Various cleanups and refactorings in Pattern Matching implementation (e…
Browse files Browse the repository at this point in the history
  • Loading branch information
srikanth-sankaran authored Jan 23, 2024
1 parent 76d44c8 commit 3701e3c
Show file tree
Hide file tree
Showing 27 changed files with 127 additions and 180 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -274,10 +274,10 @@ public void generateOptimizedBoolean(BlockScope currentScope, CodeStream codeStr
}

@Override
public LocalVariableBinding[] getPatternVariablesWhenTrue() {
public LocalVariableBinding[] bindingsWhenTrue() {

LocalVariableBinding [] leftVars = this.left.getPatternVariablesWhenTrue();
LocalVariableBinding [] rightVars = this.right.getPatternVariablesWhenTrue();
LocalVariableBinding [] leftVars = this.left.bindingsWhenTrue();
LocalVariableBinding [] rightVars = this.right.bindingsWhenTrue();

if (leftVars == NO_VARIABLES)
return rightVars;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -724,8 +724,8 @@ public static void resolveStatements(Statement[] statements, BlockScope scope) {
LocalVariableBinding [] livePatternVariables = NO_VARIABLES;
for (int i = 0, length = statements.length; i < length; i++) {
final Statement stmt = statements[i];
stmt.resolveWithPatternVariablesInScope(livePatternVariables, scope);
livePatternVariables = LocalVariableBinding.merge(livePatternVariables, stmt.getPatternVariablesLiveUponCompletion());
stmt.resolveWithBindings(livePatternVariables, scope);
livePatternVariables = LocalVariableBinding.merge(livePatternVariables, stmt.bindingsWhenComplete());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1846,12 +1846,12 @@ public TypeBinding resolveType(BlockScope scope) {
if ((rightIsCast = this.right instanceof CastExpression) == true) this.right.bits |= ASTNode.DisableUnnecessaryCastCheck; // will check later on

LocalVariableBinding [] patternVars = switch ((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) {
case AND_AND -> this.left.getPatternVariablesWhenTrue();
case OR_OR -> this.left.getPatternVariablesWhenFalse();
case AND_AND -> this.left.bindingsWhenTrue();
case OR_OR -> this.left.bindingsWhenFalse();
default -> NO_VARIABLES;
};

TypeBinding rightType = this.right.resolveTypeWithPatternVariablesInScope(patternVars, scope);
TypeBinding rightType = this.right.resolveTypeWithBindings(patternVars, scope);

/*
* 6.3.1 Scope for Pattern Variables in Expressions
Expand All @@ -1877,10 +1877,10 @@ public TypeBinding resolveType(BlockScope scope) {
// We handle only the cases NOT already diagnosed in due course to avoid double jeopardy
switch ((this.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) {
case AND_AND -> {
Pattern.reportRedeclarations(scope, this.left.getPatternVariablesWhenFalse(), this.right.getPatternVariablesWhenFalse());
Pattern.reportRedeclarations(scope, this.left.bindingsWhenFalse(), this.right.bindingsWhenFalse());
}
case OR_OR -> {
Pattern.reportRedeclarations(scope, this.left.getPatternVariablesWhenTrue(), this.right.getPatternVariablesWhenTrue());
Pattern.reportRedeclarations(scope, this.left.bindingsWhenTrue(), this.right.bindingsWhenTrue());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
import org.eclipse.jdt.internal.compiler.impl.StringConstant;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
Expand Down Expand Up @@ -235,23 +234,6 @@ public String toString() {
return builder.toString();
}
}
public ResolvedCase[] resolveWithPatternVariablesInScope(LocalVariableBinding[] patternVariablesInScope,
BlockScope scope,
TypeBinding switchExpressionType,
SwitchStatement switchStatement) {
if (patternVariablesInScope != null) {
for (LocalVariableBinding binding : patternVariablesInScope) {
binding.modifiers &= ~ExtraCompilerModifiers.AccPatternVariable;
}
}
ResolvedCase[] cases = resolveCase(scope, switchExpressionType, switchStatement);
if (patternVariablesInScope != null) {
for (LocalVariableBinding binding : patternVariablesInScope) {
binding.modifiers |= ExtraCompilerModifiers.AccPatternVariable;
}
}
return cases;
}
private Expression getFirstValidExpression(BlockScope scope, SwitchStatement switchStatement) {
assert this.constantExpressions != null;
Expression ret = null;
Expand Down Expand Up @@ -357,7 +339,7 @@ public ResolvedCase[] resolveCase(BlockScope scope, TypeBinding switchExpression
}
}
}
this.resolveWithPatternVariablesInScope(this.getPatternVariablesWhenTrue(), scope);
this.resolveWithBindings(this.bindingsWhenTrue(), scope);
if (cases.size() > 0) {
return cases.toArray(new ResolvedCase[cases.size()]);
}
Expand All @@ -377,10 +359,10 @@ private void flagDuplicateDefault(BlockScope scope, SwitchStatement switchStatem
}
}
@Override
public LocalVariableBinding[] getPatternVariablesWhenTrue() {
public LocalVariableBinding[] bindingsWhenTrue() {
LocalVariableBinding [] variables = NO_VARIABLES;
for (Expression e : this.constantExpressions) {
variables = LocalVariableBinding.merge(variables, e.getPatternVariablesWhenTrue());
variables = LocalVariableBinding.merge(variables, e.bindingsWhenTrue());
}
return variables;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -492,9 +492,9 @@ public TypeBinding resolveType(BlockScope scope) {
this.condition.computeConversion(scope, TypeBinding.BOOLEAN, conditionType);

if (this.valueIfTrue instanceof CastExpression) this.valueIfTrue.bits |= DisableUnnecessaryCastCheck; // will check later on
this.originalValueIfTrueType = this.valueIfTrue.resolveTypeWithPatternVariablesInScope(this.condition.getPatternVariablesWhenTrue(), scope);
this.originalValueIfTrueType = this.valueIfTrue.resolveTypeWithBindings(this.condition.bindingsWhenTrue(), scope);
if (this.valueIfFalse instanceof CastExpression) this.valueIfFalse.bits |= DisableUnnecessaryCastCheck; // will check later on
this.originalValueIfFalseType = this.valueIfFalse.resolveTypeWithPatternVariablesInScope(this.condition.getPatternVariablesWhenFalse(), scope);
this.originalValueIfFalseType = this.valueIfFalse.resolveTypeWithBindings(this.condition.bindingsWhenFalse(), scope);

/*
*
Expand All @@ -514,12 +514,12 @@ public TypeBinding resolveType(BlockScope scope) {
• A pattern variable is both (i) introduced by b when false and (ii) introduced by
c when false.
*/
Pattern.reportRedeclarations(scope, this.condition.getPatternVariablesWhenTrue(), this.valueIfFalse.getPatternVariablesWhenTrue());
Pattern.reportRedeclarations(scope, this.condition.getPatternVariablesWhenTrue(), this.valueIfFalse.getPatternVariablesWhenFalse());
Pattern.reportRedeclarations(scope, this.condition.getPatternVariablesWhenFalse(), this.valueIfTrue.getPatternVariablesWhenTrue());
Pattern.reportRedeclarations(scope, this.condition.getPatternVariablesWhenFalse(), this.valueIfTrue.getPatternVariablesWhenFalse());
Pattern.reportRedeclarations(scope, this.valueIfTrue.getPatternVariablesWhenTrue(), this.valueIfFalse.getPatternVariablesWhenTrue());
Pattern.reportRedeclarations(scope, this.valueIfTrue.getPatternVariablesWhenFalse(), this.valueIfFalse.getPatternVariablesWhenFalse());
Pattern.reportRedeclarations(scope, this.condition.bindingsWhenTrue(), this.valueIfFalse.bindingsWhenTrue());
Pattern.reportRedeclarations(scope, this.condition.bindingsWhenTrue(), this.valueIfFalse.bindingsWhenFalse());
Pattern.reportRedeclarations(scope, this.condition.bindingsWhenFalse(), this.valueIfTrue.bindingsWhenTrue());
Pattern.reportRedeclarations(scope, this.condition.bindingsWhenFalse(), this.valueIfTrue.bindingsWhenFalse());
Pattern.reportRedeclarations(scope, this.valueIfTrue.bindingsWhenTrue(), this.valueIfFalse.bindingsWhenTrue());
Pattern.reportRedeclarations(scope, this.valueIfTrue.bindingsWhenFalse(), this.valueIfFalse.bindingsWhenFalse());


if (conditionType == null || this.originalValueIfTrueType == null || this.originalValueIfFalseType == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,9 @@ public StringBuilder printStatement(int indent, StringBuilder output) {
}

@Override
public LocalVariableBinding[] getPatternVariablesLiveUponCompletion() {
public LocalVariableBinding[] bindingsWhenComplete() {
return this.condition.containsPatternVariable() && this.action != null && !this.action.breaksOut(null) ?
this.condition.getPatternVariablesWhenFalse() : NO_VARIABLES;
this.condition.bindingsWhenFalse() : NO_VARIABLES;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.InferenceContext18;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
Expand Down Expand Up @@ -1133,35 +1132,22 @@ public TypeBinding resolveExpressionType(BlockScope scope) {
return resolveType(scope);
}

public TypeBinding resolveTypeWithPatternVariablesInScope(LocalVariableBinding[] patternVariablesInScope, BlockScope scope) {
if (patternVariablesInScope != null) {
for (LocalVariableBinding binding : patternVariablesInScope) {
binding.modifiers &= ~ExtraCompilerModifiers.AccPatternVariable;
}
}
TypeBinding retVal = this.resolveType(scope);
if (patternVariablesInScope != null) {
for (LocalVariableBinding binding : patternVariablesInScope) {
binding.modifiers |= ExtraCompilerModifiers.AccPatternVariable;
}
public TypeBinding resolveTypeWithBindings(LocalVariableBinding[] bindings, BlockScope scope) {
scope.include(bindings);
try {
return this.resolveType(scope);
} finally {
scope.exclude(bindings);
}
return retVal;
}

public TypeBinding resolveTypeExpectingWithPatternVariablesInScope(LocalVariableBinding[] patternVariablesInScope, BlockScope scope,
TypeBinding expectedType) {
if (patternVariablesInScope != null) {
for (LocalVariableBinding binding : patternVariablesInScope) {
binding.modifiers &= ~ExtraCompilerModifiers.AccPatternVariable;
}
}
TypeBinding retVal = this.resolveTypeExpecting(scope, expectedType);
if (patternVariablesInScope != null) {
for (LocalVariableBinding binding : patternVariablesInScope) {
binding.modifiers |= ExtraCompilerModifiers.AccPatternVariable;
}
public TypeBinding resolveTypeExpectingWithBindings(LocalVariableBinding[] bindings, BlockScope scope, TypeBinding expectedType) {
scope.include(bindings);
try {
return this.resolveTypeExpecting(scope, expectedType);
} finally {
scope.exclude(bindings);
}
return retVal;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -407,9 +407,9 @@ public StringBuilder printStatement(int tab, StringBuilder output) {
}

@Override
public LocalVariableBinding[] getPatternVariablesLiveUponCompletion() {
public LocalVariableBinding[] bindingsWhenComplete() {
return this.condition != null && this.condition.containsPatternVariable() && this.action != null && !this.action.breaksOut(null) ?
this.condition.getPatternVariablesWhenFalse() : NO_VARIABLES;
this.condition.bindingsWhenFalse() : NO_VARIABLES;
}

@Override
Expand All @@ -431,15 +431,15 @@ public void resolve(BlockScope upperScope) {
TypeBinding type = this.condition.resolveTypeExpecting(this.scope, TypeBinding.BOOLEAN);
this.scope.reparentLocals(false);
this.condition.computeConversion(this.scope, type, type);
patternVariablesInTrueScope = this.condition.getPatternVariablesWhenTrue();
patternVariablesInTrueScope = this.condition.bindingsWhenTrue();
}
if (this.increments != null)
for (int i = 0, length = this.increments.length; i < length; i++) {
this.increments[i].resolveWithPatternVariablesInScope(patternVariablesInTrueScope, this.scope);
this.increments[i].resolveWithBindings(patternVariablesInTrueScope, this.scope);
}

if (this.action != null) {
this.action.resolveWithPatternVariablesInScope(patternVariablesInTrueScope, this.scope);
this.action.resolveWithBindings(patternVariablesInTrueScope, this.scope);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -535,11 +535,9 @@ public void resolve(BlockScope upperScope) {
this.scope = new BlockScope(upperScope);
this.scope.blockStatement = this;
this.elementVariable.resolve(this.scope); // collection expression can see itemVariable
LocalVariableBinding[] patternVariablesInTrueScope = NO_VARIABLES;

if (this.pattern != null && JavaFeature.RECORD_PATTERNS.isSupported(upperScope.compilerOptions())) {
this.pattern.resolve(this.scope);
patternVariablesInTrueScope = this.pattern.getPatternVariablesWhenTrue();
}
TypeBinding elementType = this.elementVariable.type.resolvedType;
TypeBinding collectionType = this.collection == null ? null : this.collection.resolveType(upperScope);
Expand Down Expand Up @@ -729,7 +727,7 @@ public void resolve(BlockScope upperScope) {
}
}
if (this.action != null) {
this.action.resolveWithPatternVariablesInScope(patternVariablesInTrueScope, this.scope);
this.action.resolveWithBindings(this.pattern != null ? this.pattern.bindingsWhenTrue() : NO_VARIABLES, this.scope);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ public LocalDeclaration getPatternVariable() {
}

@Override
public LocalVariableBinding[] getPatternVariablesWhenTrue() {
return LocalVariableBinding.merge(this.primaryPattern.getPatternVariablesWhenTrue(),
this.condition.getPatternVariablesWhenTrue());
public LocalVariableBinding[] bindingsWhenTrue() {
return LocalVariableBinding.merge(this.primaryPattern.bindingsWhenTrue(),
this.condition.bindingsWhenTrue());
}

@Override
Expand Down Expand Up @@ -131,7 +131,7 @@ public TypeBinding resolveType(BlockScope scope) {
// The following call (as opposed to resolveType() ensures that
// the implicitConversion code is set properly and thus the correct
// unboxing calls are generated.
this.condition.resolveTypeExpectingWithPatternVariablesInScope(this.primaryPattern.getPatternVariablesWhenTrue(), scope, TypeBinding.BOOLEAN);
this.condition.resolveTypeExpectingWithBindings(this.primaryPattern.bindingsWhenTrue(), scope, TypeBinding.BOOLEAN);
Constant cst = this.condition.optimizedBooleanConstant();
if (cst.typeID() == TypeIds.T_boolean && cst.booleanValue() == false) {
scope.problemReporter().falseLiteralInGuard(this.condition);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,13 +302,13 @@ public StringBuilder printStatement(int indent, StringBuilder output) {
}

@Override
public LocalVariableBinding[] getPatternVariablesLiveUponCompletion() {
public LocalVariableBinding[] bindingsWhenComplete() {
if (!this.condition.containsPatternVariable() || doesNotCompleteNormally())
return NO_VARIABLES;
if (this.thenStatement != null && this.thenStatement.doesNotCompleteNormally())
return this.condition.getPatternVariablesWhenFalse();
return this.condition.bindingsWhenFalse();
if (this.elseStatement != null && this.elseStatement.doesNotCompleteNormally())
return this.condition.getPatternVariablesWhenTrue();
return this.condition.bindingsWhenTrue();
return NO_VARIABLES;
}
@Override
Expand All @@ -317,10 +317,10 @@ public void resolve(BlockScope scope) {
this.condition.computeConversion(scope, type, type);

if (this.thenStatement != null) {
this.thenStatement.resolveWithPatternVariablesInScope(this.condition.getPatternVariablesWhenTrue(), scope);
this.thenStatement.resolveWithBindings(this.condition.bindingsWhenTrue(), scope);
}
if (this.elseStatement != null) {
this.elseStatement.resolveWithPatternVariablesInScope(this.condition.getPatternVariablesWhenFalse(), scope);
this.elseStatement.resolveWithBindings(this.condition.bindingsWhenFalse(), scope);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, Fl
@Override
public void generateCode(BlockScope currentScope, CodeStream codeStream, boolean valueRequired) {
if (this.elementVariable != null && this.elementVariable.binding != null) {
this.elementVariable.binding.modifiers &= ~ExtraCompilerModifiers.AccPatternVariable;
this.elementVariable.binding.modifiers &= ~ExtraCompilerModifiers.AccOutOfFlowScope;
}
addPatternVariables(currentScope, codeStream);

Expand Down Expand Up @@ -266,12 +266,12 @@ public boolean resolvePatternVariable(BlockScope scope) {
this.pattern.resolve(scope);
if (this.elementVariable == null) return false;
if (this.elementVariable.binding == null) {
this.elementVariable.modifiers |= ExtraCompilerModifiers.AccPatternVariable;
this.elementVariable.modifiers |= ExtraCompilerModifiers.AccOutOfFlowScope;
this.elementVariable.resolve(scope, true);
// Kludge - to remove the AccBlankFinal added by the LocalDeclaration#resolve() due to the
// missing initializer
this.elementVariable.modifiers &= ~ExtraCompilerModifiers.AccBlankFinal;
this.elementVariable.binding.modifiers |= ExtraCompilerModifiers.AccPatternVariable;
this.elementVariable.binding.modifiers |= ExtraCompilerModifiers.AccOutOfFlowScope;
this.elementVariable.binding.useFlag = LocalVariableBinding.USED;
// Why cant this be done in the constructor?
this.type = this.elementVariable.type;
Expand All @@ -280,8 +280,8 @@ public boolean resolvePatternVariable(BlockScope scope) {
return true;
}
@Override
public LocalVariableBinding[] getPatternVariablesWhenTrue() {
return this.pattern != null ? this.pattern.getPatternVariablesWhenTrue() : NO_VARIABLES;
public LocalVariableBinding[] bindingsWhenTrue() {
return this.pattern != null ? this.pattern.bindingsWhenTrue() : NO_VARIABLES;
}
@Override
public boolean containsPatternVariable() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -252,17 +252,12 @@ public boolean kosherDescriptor(Scope currentScope, MethodBinding sam, boolean s
return super.kosherDescriptor(currentScope, sam, shouldChatter);
}

public void resolveWithPatternVariablesInScope(LocalVariableBinding[] patternVariablesInScope, BlockScope blockScope, boolean skipKosherCheck) {
if (patternVariablesInScope != null) {
for (LocalVariableBinding local : patternVariablesInScope) {
local.modifiers &= ~ExtraCompilerModifiers.AccPatternVariable;
}
}
this.resolveType(blockScope, skipKosherCheck);
if (patternVariablesInScope != null) {
for (LocalVariableBinding local : patternVariablesInScope) {
local.modifiers |= ExtraCompilerModifiers.AccPatternVariable;
}
public void resolveTypeWithBindings(LocalVariableBinding[] bindings, BlockScope blockScope, boolean skipKosherCheck) {
blockScope.include(bindings);
try {
this.resolveType(blockScope, skipKosherCheck);
} finally {
blockScope.exclude(bindings);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -340,8 +340,7 @@ public void markInitialized() {
};
} else {
// create a binding from the specified type
this.binding = new LocalVariableBinding(this, variableType, this.modifiers,
isPatternVariable ? TagBits.IsPatternBinding : 0);
this.binding = new LocalVariableBinding(this, variableType, this.modifiers, false /*isArgument*/);
}
scope.addLocalVariable(this.binding);
this.binding.setConstant(Constant.NotAConstant);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,10 +277,10 @@ public void generateOptimizedBoolean(BlockScope currentScope, CodeStream codeStr
}

@Override
public LocalVariableBinding[] getPatternVariablesWhenFalse() {
public LocalVariableBinding[] bindingsWhenFalse() {

LocalVariableBinding [] leftVars = this.left.getPatternVariablesWhenFalse();
LocalVariableBinding [] rightVars = this.right.getPatternVariablesWhenFalse();
LocalVariableBinding [] leftVars = this.left.bindingsWhenFalse();
LocalVariableBinding [] rightVars = this.right.bindingsWhenFalse();

if (leftVars == NO_VARIABLES)
return rightVars;
Expand Down
Loading

0 comments on commit 3701e3c

Please sign in to comment.