Skip to content

Commit

Permalink
* Rewire RecordPattern to extend Pattern rather than TypePattern
Browse files Browse the repository at this point in the history
* Fixes #2043
  • Loading branch information
srikanth-sankaran committed Mar 5, 2024
1 parent 3d8e00d commit ca70935
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import org.eclipse.jdt.internal.compiler.codegen.CodeStream;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;

public abstract class Pattern extends Expression {
Expand Down Expand Up @@ -52,7 +53,9 @@ public boolean isUnnamed() {
* @return whether pattern covers the given type or not
*/
public boolean coversType(TypeBinding type) {
return false;
if (type == null || this.resolvedType == null)
return false;
return (type.isSubtypeOf(this.resolvedType, false));
}

public boolean isAlwaysTrue() {
Expand All @@ -61,12 +64,39 @@ public boolean isAlwaysTrue() {

public abstract void generateCode(BlockScope currentScope, CodeStream codeStream, BranchLabel trueLabel, BranchLabel falseLabel);

@Override
public boolean checkUnsafeCast(Scope scope, TypeBinding castType, TypeBinding expressionType, TypeBinding match, boolean isNarrowing) {
if (!castType.isReifiable())
return CastExpression.checkUnsafeCast(this, scope, castType, expressionType, match, isNarrowing);
else
return super.checkUnsafeCast(scope, castType, expressionType, match, isNarrowing);
}

public TypeReference getType() {
return null;
}

// 14.30.3 Properties of Patterns: A pattern p is said to be applicable at a type T if ...
protected abstract boolean isApplicable(TypeBinding other, BlockScope scope);
protected boolean isApplicable(TypeBinding other, BlockScope scope) {
TypeBinding patternType = this.resolvedType;
if (patternType == null) // ill resolved pattern
return false;
// 14.30.3 Properties of Patterns doesn't allow boxing nor unboxing, primitive widening/narrowing.
if (patternType.isBaseType() != other.isBaseType()) {
scope.problemReporter().incompatiblePatternType(this, other, patternType);
return false;
}
if (patternType.isBaseType()) {
if (!TypeBinding.equalsEquals(other, patternType)) {
scope.problemReporter().incompatiblePatternType(this, other, patternType);
return false;
}
} else if (!checkCastTypesCompatibility(scope, other, patternType, null, true)) {
scope.problemReporter().incompatiblePatternType(this, other, patternType);
return false;
}
return true;
}

public abstract boolean dominates(Pattern p);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,14 @@
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;

public class RecordPattern extends TypePattern {
public class RecordPattern extends Pattern {

public Pattern[] patterns;
public TypeReference type;

private TypeBinding expectedType; // for record pattern type inference

public RecordPattern(TypeReference type, int sourceStart, int sourceEnd) {
super(null); // no local declaration with record patterns
this.type = type;
this.sourceStart = sourceStart;
this.sourceEnd = sourceEnd;
Expand Down Expand Up @@ -143,22 +142,22 @@ public TypeBinding resolveType(BlockScope scope) {
RecordComponentBinding[] components = this.resolvedType.capture(scope, this.sourceStart, this.sourceEnd).components();
for (int i = 0; i < components.length; i++) {
Pattern p1 = this.patterns[i];
RecordComponentBinding componentBinding = components[i];
if (p1 instanceof TypePattern tp) {
RecordComponentBinding componentBinding = components[i];
if (p1.getType() == null || p1.getType().isTypeNameVar(scope)) {
if (tp.getType() == null || tp.getType().isTypeNameVar(scope)) {
if (tp.local.binding != null) // rewrite with the inferred type
tp.local.binding.type = componentBinding.type;
}
TypeBinding expressionType = componentBinding.type;
if (p1.isApplicable(expressionType, scope)) {
p1.isTotalTypeNode = p1.coversType(componentBinding.type);
MethodBinding[] methods = this.resolvedType.getMethods(componentBinding.name);
if (methods != null && methods.length > 0) {
p1.accessorMethod = methods[0];
}
}
TypeBinding expressionType = componentBinding.type;
if (p1.isApplicable(expressionType, scope)) {
p1.isTotalTypeNode = p1.coversType(componentBinding.type);
MethodBinding[] methods = this.resolvedType.getMethods(componentBinding.name);
if (methods != null && methods.length > 0) {
p1.accessorMethod = methods[0];
}
this.isTotalTypeNode &= p1.isTotalTypeNode;
}
this.isTotalTypeNode &= p1.isTotalTypeNode;
}
return this.resolvedType;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.RecordComponentBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.eclipse.jdt.internal.compiler.lookup.TagBits;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
Expand Down Expand Up @@ -58,14 +57,6 @@ public LocalVariableBinding[] bindingsWhenTrue() {
return this.isUnnamed() || this.local.binding == null ? NO_VARIABLES : new LocalVariableBinding[] { this.local.binding };
}

@Override
public boolean checkUnsafeCast(Scope scope, TypeBinding castType, TypeBinding expressionType, TypeBinding match, boolean isNarrowing) {
if (!castType.isReifiable())
return CastExpression.checkUnsafeCast(this, scope, castType, expressionType, match, isNarrowing);
else
return super.checkUnsafeCast(scope, castType, expressionType, match, isNarrowing);
}

@Override
public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {
flowInfo = this.local.analyseCode(currentScope, flowContext, flowInfo);
Expand Down Expand Up @@ -111,35 +102,6 @@ public void generateCode(BlockScope currentScope, CodeStream codeStream, BranchL
}
}

@Override
public boolean coversType(TypeBinding type) {
if (type == null || this.resolvedType == null)
return false;
return (type.isSubtypeOf(this.resolvedType, false));
}

@Override
protected boolean isApplicable(TypeBinding other, BlockScope scope) {
TypeBinding patternType = this.resolvedType;
if (patternType == null) // ill resolved pattern
return false;
// 14.30.3 Properties of Patterns doesn't allow boxing nor unboxing, primitive widening/narrowing.
if (patternType.isBaseType() != other.isBaseType()) {
scope.problemReporter().incompatiblePatternType(this, other, patternType);
return false;
}
if (patternType.isBaseType()) {
if (!TypeBinding.equalsEquals(other, patternType)) {
scope.problemReporter().incompatiblePatternType(this, other, patternType);
return false;
}
} else if (!checkCastTypesCompatibility(scope, other, patternType, null, true)) {
scope.problemReporter().incompatiblePatternType(this, other, patternType);
return false;
}
return true;
}

@Override
public boolean dominates(Pattern p) {
if (p.resolvedType == null || this.resolvedType == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@
import org.eclipse.jdt.internal.compiler.ast.ModuleDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ModuleReference;
import org.eclipse.jdt.internal.compiler.ast.NameReference;
import org.eclipse.jdt.internal.compiler.ast.RecordPattern;
import org.eclipse.jdt.internal.compiler.ast.RequiresStatement;
import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.SuperReference;
Expand Down Expand Up @@ -373,16 +372,6 @@ public RecoveredElement buildInitialRecoveryState(){
// and leaves it in the astStack
final List<LocalDeclaration> locals = new ArrayList<>();
node.traverse(new ASTVisitor() {
@SuppressWarnings("synthetic-access")
@Override
public boolean visit(RecordPattern pattern, BlockScope scope) {
LocalDeclaration local = pattern.local;
if (local == null)
return true;
locals.add(local);
AssistParser.this.lastCheckPoint = local.declarationSourceEnd + 1;
return true;
}
@SuppressWarnings("synthetic-access")
@Override
public boolean visit(TypePattern pattern, BlockScope scope) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2285,12 +2285,7 @@ public Pattern convert(org.eclipse.jdt.internal.compiler.ast.RecordPattern patte
int startPosition = pattern.sourceStart;
int sourceEnd= pattern.sourceEnd;
recordPattern.setSourceRange(startPosition, sourceEnd - startPosition + 1);
if (pattern.local != null) {
recordPattern.setPatternType(convertType(pattern.local.type));
SimpleName patternName = new SimpleName(this.ast);
patternName.internalSetIdentifier(new String(pattern.local.name));
patternName.setSourceRange(pattern.local.nameSourceStart(), pattern.local.nameSourceEnd() - pattern.local.nameSourceStart() + 1);
} else if (pattern.type != null) {
if (pattern.type != null) {
recordPattern.setPatternType(convertType(pattern.type));
}
List<Pattern> patterns = recordPattern.patterns();
Expand Down

0 comments on commit ca70935

Please sign in to comment.