1 | package de.uka.ipd.sdq.stoex.analyser.visitors; |
2 | |
3 | import java.util.ArrayList; |
4 | import java.util.Collection; |
5 | |
6 | import de.uka.ipd.sdq.errorhandling.IIssue; |
7 | import de.uka.ipd.sdq.stoex.BooleanOperatorExpression; |
8 | import de.uka.ipd.sdq.stoex.IfElseExpression; |
9 | import de.uka.ipd.sdq.stoex.NotExpression; |
10 | import de.uka.ipd.sdq.stoex.ProductExpression; |
11 | import de.uka.ipd.sdq.stoex.TermExpression; |
12 | import de.uka.ipd.sdq.stoex.analyser.exceptions.ExpectedTypeMismatchIssue; |
13 | import de.uka.ipd.sdq.stoex.util.StoexSwitch; |
14 | |
15 | public class TypeCheckVisitor extends StoexSwitch<Object> { |
16 | |
17 | private ExpressionInferTypeVisitor typeVisitor; |
18 | private ArrayList<IIssue> issues = new ArrayList<IIssue>(); |
19 | |
20 | public TypeCheckVisitor(NonProbabilisticExpressionInferTypeVisitor typeVisitor) { |
21 | this.typeVisitor = typeVisitor; |
22 | } |
23 | |
24 | @Override |
25 | public Object caseBooleanOperatorExpression(BooleanOperatorExpression object) { |
26 | if (!typesCompatible(typeVisitor.getType(object.getLeft()),TypeEnum.BOOL)) |
27 | issues.add(new ExpectedTypeMismatchIssue(TypeEnum.BOOL,typeVisitor.getType(object.getLeft()))); |
28 | if (!typesCompatible(typeVisitor.getType(object.getRight()),TypeEnum.BOOL)) |
29 | issues.add(new ExpectedTypeMismatchIssue(TypeEnum.BOOL,typeVisitor.getType(object.getRight()))); |
30 | return super.caseBooleanOperatorExpression(object); |
31 | } |
32 | |
33 | @Override |
34 | public Object caseIfElseExpression(IfElseExpression object) { |
35 | if (!typesCompatible(typeVisitor.getType(object.getConditionExpression()),TypeEnum.BOOL)) |
36 | issues.add(new ExpectedTypeMismatchIssue(TypeEnum.BOOL,typeVisitor.getType(object.getConditionExpression()))); |
37 | return super.caseIfElseExpression(object); |
38 | } |
39 | |
40 | @Override |
41 | public Object caseNotExpression(NotExpression object) { |
42 | if (!typesCompatible(typeVisitor.getType(object.getInner()),TypeEnum.BOOL)) |
43 | issues.add(new ExpectedTypeMismatchIssue(TypeEnum.BOOL,typeVisitor.getType(object.getInner()))); |
44 | return super.caseNotExpression(object); |
45 | } |
46 | |
47 | @Override |
48 | public Object caseProductExpression(ProductExpression object) { |
49 | if (!isNummericType(typeVisitor.getType(object.getLeft()))) |
50 | issues.add(new ExpectedTypeMismatchIssue("Numeric",typeVisitor.getType(object.getLeft()))); |
51 | if (!isNummericType(typeVisitor.getType(object.getRight()))) |
52 | issues.add(new ExpectedTypeMismatchIssue("Numeric",typeVisitor.getType(object.getRight()))); |
53 | return super.caseProductExpression(object); |
54 | } |
55 | |
56 | @Override |
57 | public Object caseTermExpression(TermExpression object) { |
58 | if (!isNummericType(typeVisitor.getType(object.getLeft()))) |
59 | issues.add(new ExpectedTypeMismatchIssue("Numeric",typeVisitor.getType(object.getLeft()))); |
60 | if (!isNummericType(typeVisitor.getType(object.getRight()))) |
61 | issues.add(new ExpectedTypeMismatchIssue("Numeric",typeVisitor.getType(object.getRight()))); |
62 | return super.caseTermExpression(object); |
63 | } |
64 | |
65 | public static boolean typesCompatible(TypeEnum expectedType, TypeEnum foundType) { |
66 | if (expectedType == TypeEnum.ANY) |
67 | return true; |
68 | if (expectedType == foundType) |
69 | return true; |
70 | if (foundType == TypeEnum.ANY) // Can only decide at run time... |
71 | return true; |
72 | if (expectedType == TypeEnum.DOUBLE && (foundType == TypeEnum.INT || foundType == TypeEnum.DOUBLE)) |
73 | return true; |
74 | return false; |
75 | } |
76 | |
77 | private boolean isNummericType(TypeEnum type) { |
78 | if (type == TypeEnum.INT || |
79 | type == TypeEnum.DOUBLE || |
80 | type == TypeEnum.ANY) |
81 | return true; |
82 | return false; |
83 | } |
84 | |
85 | public Collection<IIssue> getIssues() { |
86 | return this.issues; |
87 | } |
88 | |
89 | } |