Infer String/Integer for patterns

This commit is contained in:
Daniel Holle 2023-08-17 15:22:53 +02:00
parent 93d7aca9e6
commit 6025e17186
2 changed files with 29 additions and 9 deletions

View File

@ -8,6 +8,7 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import de.dhbwstuttgart.syntaxtree.type.Void;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
@ -397,7 +398,7 @@ public class StatementGenerator {
} }
case LabeledRuleDefaultContext def -> { case LabeledRuleDefaultContext def -> {
isDefault = true; isDefault = true;
yield Arrays.asList(new SwitchLabel(TypePlaceholder.fresh(def.getStart()), def.getStart())); yield Arrays.asList(new SwitchLabel(new Void(def.getStart()), def.getStart()));
} }
default -> throw new NotImplementedException(); default -> throw new NotImplementedException();
}; };
@ -434,6 +435,7 @@ public class StatementGenerator {
} }
private SwitchLabel convert(SwitchLabelContext switchLabel) { private SwitchLabel convert(SwitchLabelContext switchLabel) {
RefTypeOrTPHOrWildcardOrGeneric type = null;
Expression caseExpression = switch (switchLabel) { Expression caseExpression = switch (switchLabel) {
case SwitchLabelConstContext cons -> { case SwitchLabelConstContext cons -> {
yield convert(cons.constantExpression); yield convert(cons.constantExpression);
@ -442,13 +444,16 @@ public class StatementGenerator {
yield convert(pattern.pattern()); yield convert(pattern.pattern());
} }
case SwitchLabelDefaultContext def -> { case SwitchLabelDefaultContext def -> {
type = new Void(switchLabel.getStart());
yield null; yield null;
} }
default -> throw new NotImplementedException(); default -> throw new NotImplementedException();
}; };
Token offset = switchLabel.getStart(); Token offset = switchLabel.getStart();
if (Objects.isNull(caseExpression)) { if (Objects.isNull(caseExpression)) {
return new SwitchLabel(TypePlaceholder.fresh(offset), offset); if (type == null)
type = TypePlaceholder.fresh(offset);
return new SwitchLabel(type, offset);
} else { } else {
return new SwitchLabel(caseExpression, caseExpression.getType(), offset); return new SwitchLabel(caseExpression, caseExpression.getType(), offset);
} }

View File

@ -61,6 +61,7 @@ import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption; import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
import de.dhbwstuttgart.typeinference.assumptions.FunNClass; import de.dhbwstuttgart.typeinference.assumptions.FunNClass;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption; import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
@ -734,18 +735,32 @@ public class TYPEStmt implements StatementVisitor {
@Override @Override
public void visit(Switch switchStmt) { public void visit(Switch switchStmt) {
switchStack.push(switchStmt); switchStack.push(switchStmt);
RefTypeOrTPHOrWildcardOrGeneric caseExpressionType = null;
for (var child : switchStmt.getBlocks()) { for (var child : switchStmt.getBlocks()) {
for (var label : child.getLabels()) { for (var label : child.getLabels()) {
if (label.getExpression() instanceof Pattern) { if (!(label.getExpression() instanceof Pattern) && !(label.getType() instanceof Void)) {
constraintsSet.addUndConstraint(new Pair(label.getExpression().getType(), switchStmt.getSwitch().getType(), PairOperator.SMALLERDOT)); if (caseExpressionType != null && !caseExpressionType.equals(label.getType()))
} else { throw new TypeinferenceException("Case labels must all have the same Type if they are expressions", label);
constraintsSet.addUndConstraint(new Pair(label.getType(), switchStmt.getSwitch().getType(), PairOperator.SMALLERDOT)); caseExpressionType = label.getType();
} }
} }
child.accept(this);
constraintsSet.addUndConstraint(new Pair(child.getType(), switchStmt.getType(), PairOperator.SMALLERDOT));
} }
if (caseExpressionType == null) {
for (var child : switchStmt.getBlocks()) {
for (var label : child.getLabels()) {
if (label.getExpression() instanceof Pattern) {
constraintsSet.addUndConstraint(new Pair(label.getExpression().getType(), switchStmt.getSwitch().getType(), PairOperator.SMALLERDOT));
}
}
child.accept(this);
constraintsSet.addUndConstraint(new Pair(child.getType(), switchStmt.getType(), PairOperator.SMALLERDOT));
}
} else {
constraintsSet.addUndConstraint(new Pair(caseExpressionType, switchStmt.getSwitch().getType(), PairOperator.EQUALSDOT));
}
switchStack.pop(); switchStack.pop();
} }