Package: TypeCheckerStmVisitor

TypeCheckerStmVisitor

nameinstructionbranchcomplexitylinemethod
TypeCheckerStmVisitor(IQuestionAnswer)
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
addOne(PTypeSet, PType)
M: 0 C: 26
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 8
100%
M: 0 C: 1
100%
addOneType(Set, PType)
M: 0 C: 18
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
caseAAlwaysStm(AAlwaysStm, TypeCheckInfo)
M: 0 C: 19
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
caseAAnnotatedStm(AAnnotatedStm, TypeCheckInfo)
M: 36 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 7 C: 0
0%
M: 1 C: 0
0%
caseAAssignmentStm(AAssignmentStm, TypeCheckInfo)
M: 0 C: 123
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 16
100%
M: 0 C: 1
100%
caseAAtomicStm(AAtomicStm, TypeCheckInfo)
M: 0 C: 26
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
caseABlockSimpleBlockStm(ABlockSimpleBlockStm, TypeCheckInfo)
M: 0 C: 95
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 11
100%
M: 0 C: 1
100%
caseACallObjectStm(ACallObjectStm, TypeCheckInfo)
M: 51 C: 421
89%
M: 7 C: 39
85%
M: 6 C: 18
75%
M: 8 C: 66
89%
M: 0 C: 1
100%
caseACallStm(ACallStm, TypeCheckInfo)
M: 28 C: 301
91%
M: 2 C: 32
94%
M: 2 C: 16
89%
M: 6 C: 48
89%
M: 0 C: 1
100%
caseACaseAlternativeStm(ACaseAlternativeStm, TypeCheckInfo)
M: 8 C: 142
95%
M: 2 C: 6
75%
M: 2 C: 3
60%
M: 1 C: 17
94%
M: 0 C: 1
100%
caseACasesStm(ACasesStm, TypeCheckInfo)
M: 0 C: 87
100%
M: 0 C: 10
100%
M: 0 C: 6
100%
M: 0 C: 14
100%
M: 0 C: 1
100%
caseAClassInvariantStm(AClassInvariantStm, TypeCheckInfo)
M: 0 C: 8
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
caseACyclesStm(ACyclesStm, TypeCheckInfo)
M: 15 C: 51
77%
M: 3 C: 3
50%
M: 3 C: 1
25%
M: 3 C: 7
70%
M: 0 C: 1
100%
caseADefPatternBind(ADefPatternBind, TypeCheckInfo)
M: 144 C: 0
0%
M: 12 C: 0
0%
M: 7 C: 0
0%
M: 26 C: 0
0%
M: 1 C: 0
0%
caseADurationStm(ADurationStm, TypeCheckInfo)
M: 15 C: 51
77%
M: 2 C: 4
67%
M: 2 C: 2
50%
M: 3 C: 7
70%
M: 0 C: 1
100%
caseAElseIfStm(AElseIfStm, TypeCheckInfo)
M: 0 C: 15
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
caseAErrorStm(AErrorStm, TypeCheckInfo)
M: 0 C: 8
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
caseAExitStm(AExitStm, TypeCheckInfo)
M: 0 C: 20
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
caseAForAllStm(AForAllStm, TypeCheckInfo)
M: 0 C: 111
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 15
100%
M: 0 C: 1
100%
caseAForIndexStm(AForIndexStm, TypeCheckInfo)
M: 0 C: 119
100%
M: 0 C: 8
100%
M: 0 C: 5
100%
M: 0 C: 17
100%
M: 0 C: 1
100%
caseAForPatternBindStm(AForPatternBindStm, TypeCheckInfo)
M: 0 C: 134
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 17
100%
M: 0 C: 1
100%
caseAIfStm(AIfStm, TypeCheckInfo)
M: 0 C: 18
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
caseALetBeStStm(ALetBeStStm, TypeCheckInfo)
M: 0 C: 27
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
caseALetStm(ALetStm, TypeCheckInfo)
M: 0 C: 20
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
caseANonDeterministicSimpleBlockStm(ANonDeterministicSimpleBlockStm, TypeCheckInfo)
M: 32 C: 72
69%
M: 8 C: 10
56%
M: 6 C: 4
40%
M: 8 C: 15
65%
M: 0 C: 1
100%
caseANotYetSpecifiedStm(ANotYetSpecifiedStm, TypeCheckInfo)
M: 0 C: 10
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
caseAPeriodicStm(APeriodicStm, TypeCheckInfo)
M: 110 C: 132
55%
M: 13 C: 9
41%
M: 9 C: 3
25%
M: 17 C: 25
60%
M: 0 C: 1
100%
caseAReturnStm(AReturnStm, TypeCheckInfo)
M: 0 C: 69
100%
M: 1 C: 9
90%
M: 1 C: 5
83%
M: 0 C: 14
100%
M: 0 C: 1
100%
caseASkipStm(ASkipStm, TypeCheckInfo)
M: 0 C: 18
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
caseASpecificationStm(ASpecificationStm, TypeCheckInfo)
M: 73 C: 134
65%
M: 10 C: 14
58%
M: 8 C: 5
38%
M: 10 C: 19
66%
M: 0 C: 1
100%
caseASporadicStm(ASporadicStm, TypeCheckInfo)
M: 242 C: 0
0%
M: 22 C: 0
0%
M: 12 C: 0
0%
M: 42 C: 0
0%
M: 1 C: 0
0%
caseAStartStm(AStartStm, TypeCheckInfo)
M: 39 C: 107
73%
M: 5 C: 9
64%
M: 5 C: 3
38%
M: 5 C: 14
74%
M: 0 C: 1
100%
caseAStopStm(AStopStm, TypeCheckInfo)
M: 129 C: 0
0%
M: 10 C: 0
0%
M: 6 C: 0
0%
M: 16 C: 0
0%
M: 1 C: 0
0%
caseASubclassResponsibilityStm(ASubclassResponsibilityStm, TypeCheckInfo)
M: 0 C: 8
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
caseATixeStm(ATixeStm, TypeCheckInfo)
M: 0 C: 48
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 10
100%
M: 0 C: 1
100%
caseATixeStmtAlternative(ATixeStmtAlternative, TypeCheckInfo)
M: 0 C: 77
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 10
100%
M: 0 C: 1
100%
caseATrapStm(ATrapStm, TypeCheckInfo)
M: 0 C: 114
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 19
100%
M: 0 C: 1
100%
caseAWhileStm(AWhileStm, TypeCheckInfo)
M: 14 C: 101
88%
M: 3 C: 13
81%
M: 3 C: 6
67%
M: 4 C: 19
83%
M: 0 C: 1
100%
checkArgTypes(ACallStm, PType, List, List, TypeCheckInfo)
M: 0 C: 67
100%
M: 0 C: 6
100%
M: 0 C: 4
100%
M: 0 C: 12
100%
M: 0 C: 1
100%
checkArgTypes(PType, List, List, TypeCheckInfo)
M: 35 C: 32
48%
M: 2 C: 4
67%
M: 2 C: 2
50%
M: 5 C: 7
58%
M: 0 C: 1
100%
defaultSSimpleBlockStm(SSimpleBlockStm, TypeCheckInfo)
M: 4 C: 128
97%
M: 3 C: 25
89%
M: 3 C: 12
80%
M: 0 C: 29
100%
M: 0 C: 1
100%
exitCheck(PStm, TypeCheckInfo)
M: 7 C: 9
56%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 2 C: 1
33%
M: 0 C: 1
100%
getArgTypes(List, IQuestionAnswer, TypeCheckInfo)
M: 0 C: 24
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
getDefinitions(ADefPatternBind)
M: 5 C: 8
62%
M: 2 C: 2
50%
M: 2 C: 1
33%
M: 0 C: 2
100%
M: 0 C: 1
100%
static {...}
M: 2 C: 6
75%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 0 C: 1
100%
M: 0 C: 1
100%
targetDefinition(PStateDesignator, TypeCheckInfo)
M: 2 C: 13
87%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 1 C: 3
75%
M: 0 C: 1
100%

Coverage

1: /*
2: * #%~
3: * The VDM Type Checker
4: * %%
5: * Copyright (C) 2008 - 2014 Overture
6: * %%
7: * This program is free software: you can redistribute it and/or modify
8: * it under the terms of the GNU General Public License as
9: * published by the Free Software Foundation, either version 3 of the
10: * License, or (at your option) any later version.
11: *
12: * This program is distributed in the hope that it will be useful,
13: * but WITHOUT ANY WARRANTY; without even the implied warranty of
14: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15: * GNU General Public License for more details.
16: *
17: * You should have received a copy of the GNU General Public
18: * License along with this program. If not, see
19: * <http://www.gnu.org/licenses/gpl-3.0.html>.
20: * #~%
21: */
22: package org.overture.typechecker.visitor;
23:
24: import java.util.Iterator;
25: import java.util.LinkedList;
26: import java.util.List;
27: import java.util.Set;
28: import java.util.Vector;
29: import java.util.Map.Entry;
30:
31: import org.overture.ast.analysis.AnalysisException;
32: import org.overture.ast.analysis.intf.IQuestionAnswer;
33: import org.overture.ast.definitions.AExplicitOperationDefinition;
34: import org.overture.ast.definitions.AImplicitOperationDefinition;
35: import org.overture.ast.definitions.AInstanceVariableDefinition;
36: import org.overture.ast.definitions.AMultiBindListDefinition;
37: import org.overture.ast.definitions.PDefinition;
38: import org.overture.ast.definitions.SClassDefinition;
39: import org.overture.ast.expressions.ABooleanConstExp;
40: import org.overture.ast.expressions.ASelfExp;
41: import org.overture.ast.expressions.AVariableExp;
42: import org.overture.ast.expressions.PExp;
43: import org.overture.ast.factory.AstFactory;
44: import org.overture.ast.intf.lex.ILexNameToken;
45: import org.overture.ast.lex.Dialect;
46: import org.overture.ast.lex.LexNameToken;
47: import org.overture.ast.lex.LexStringToken;
48: import org.overture.ast.patterns.ADefPatternBind;
49: import org.overture.ast.patterns.AExpressionPattern;
50: import org.overture.ast.patterns.ASetBind;
51: import org.overture.ast.patterns.ATypeBind;
52: import org.overture.ast.patterns.PBind;
53: import org.overture.ast.statements.AAlwaysStm;
54: import org.overture.ast.statements.AAnnotatedStm;
55: import org.overture.ast.statements.AAssignmentStm;
56: import org.overture.ast.statements.AAtomicStm;
57: import org.overture.ast.statements.ABlockSimpleBlockStm;
58: import org.overture.ast.statements.ACallObjectStm;
59: import org.overture.ast.statements.ACallStm;
60: import org.overture.ast.statements.ACaseAlternativeStm;
61: import org.overture.ast.statements.ACasesStm;
62: import org.overture.ast.statements.AClassInvariantStm;
63: import org.overture.ast.statements.ACyclesStm;
64: import org.overture.ast.statements.ADurationStm;
65: import org.overture.ast.statements.AElseIfStm;
66: import org.overture.ast.statements.AErrorCase;
67: import org.overture.ast.statements.AErrorStm;
68: import org.overture.ast.statements.AExitStm;
69: import org.overture.ast.statements.AExternalClause;
70: import org.overture.ast.statements.AForAllStm;
71: import org.overture.ast.statements.AForIndexStm;
72: import org.overture.ast.statements.AForPatternBindStm;
73: import org.overture.ast.statements.AIdentifierStateDesignator;
74: import org.overture.ast.statements.AIfStm;
75: import org.overture.ast.statements.ALetBeStStm;
76: import org.overture.ast.statements.ALetStm;
77: import org.overture.ast.statements.ANonDeterministicSimpleBlockStm;
78: import org.overture.ast.statements.ANotYetSpecifiedStm;
79: import org.overture.ast.statements.APeriodicStm;
80: import org.overture.ast.statements.AReturnStm;
81: import org.overture.ast.statements.ASkipStm;
82: import org.overture.ast.statements.ASpecificationStm;
83: import org.overture.ast.statements.ASporadicStm;
84: import org.overture.ast.statements.AStartStm;
85: import org.overture.ast.statements.AStopStm;
86: import org.overture.ast.statements.ASubclassResponsibilityStm;
87: import org.overture.ast.statements.ATixeStm;
88: import org.overture.ast.statements.ATixeStmtAlternative;
89: import org.overture.ast.statements.ATrapStm;
90: import org.overture.ast.statements.AWhileStm;
91: import org.overture.ast.statements.PStateDesignator;
92: import org.overture.ast.statements.PStm;
93: import org.overture.ast.statements.SSimpleBlockStm;
94: import org.overture.ast.typechecker.NameScope;
95: import org.overture.ast.types.ABooleanBasicType;
96: import org.overture.ast.types.AClassType;
97: import org.overture.ast.types.AFunctionType;
98: import org.overture.ast.types.AOperationType;
99: import org.overture.ast.types.ASeq1SeqType;
100: import org.overture.ast.types.ASet1SetType;
101: import org.overture.ast.types.SSetType;
102: import org.overture.ast.types.AUnionType;
103: import org.overture.ast.types.AUnknownType;
104: import org.overture.ast.types.AVoidReturnType;
105: import org.overture.ast.types.AVoidType;
106: import org.overture.ast.types.PType;
107: import org.overture.ast.util.PTypeSet;
108: import org.overture.config.Settings;
109: import org.overture.typechecker.Environment;
110: import org.overture.typechecker.FlatCheckedEnvironment;
111: import org.overture.typechecker.FlatEnvironment;
112: import org.overture.typechecker.PrivateClassEnvironment;
113: import org.overture.typechecker.PublicClassEnvironment;
114: import org.overture.typechecker.TypeCheckInfo;
115: import org.overture.typechecker.TypeCheckerErrors;
116: import org.overture.typechecker.assistant.type.AClassTypeAssistantTC;
117: import org.overture.typechecker.utilities.type.QualifiedDefinition;
118:
119:•public class TypeCheckerStmVisitor extends AbstractTypeCheckVisitor
120: {
121:
122:         public TypeCheckerStmVisitor(
123:                         IQuestionAnswer<TypeCheckInfo, PType> typeCheckVisitor)
124:         {
125:                 super(typeCheckVisitor);
126:
127:         }
128:
129:         @Override
130:         public PType caseAAlwaysStm(AAlwaysStm node, TypeCheckInfo question)
131:                         throws AnalysisException
132:         {
133:                 node.getAlways().apply(THIS, question);
134:                 node.setType(node.getBody().apply(THIS, question));
135:                 return node.getType();
136:         }
137:         
138:         @Override
139:         public PType caseAAnnotatedStm(AAnnotatedStm node, TypeCheckInfo question)
140:                         throws AnalysisException
141:         {
142:                 TypeCheckInfo unconstrained = question.newConstraint(null);
143:                 node.getAnnotation().apply(THIS, unconstrained);                // Check annotation first?
144:                 beforeAnnotation(node.getAnnotation(), node, unconstrained);
145:                 PType result = node.getStmt().apply(THIS, question);
146:                 afterAnnotation(node.getAnnotation(), node, unconstrained);
147:                 node.setType(result);
148:                 return result;
149:         }
150:
151:         @Override
152:         public PType caseAAssignmentStm(AAssignmentStm node, TypeCheckInfo question)
153:                         throws AnalysisException
154:         {
155:                 node.setTargetType(node.getTarget().apply(THIS, new TypeCheckInfo(question.assistantFactory, question.env)));
156:                 node.setExpType(node.getExp().apply(THIS, new TypeCheckInfo(question.assistantFactory, question.env, question.scope, null, node.getTargetType(), null, question.fromModule, question.mandatory)));
157:
158:•                if (!question.assistantFactory.getTypeComparator().compatible(node.getTargetType(), node.getExpType()))
159:                 {
160:                         TypeCheckerErrors.report(3239, "Incompatible types in assignment", node.getLocation(), node);
161:                         TypeCheckerErrors.detail2("Target", node.getTarget().getType(), "Expression", node.getExp().getType());
162:                 }
163:
164:                 node.setClassDefinition(question.env.findClassDefinition());
165:                 node.setStateDefinition(question.env.findStateDefinition());
166:                 
167:                 AClassTypeAssistantTC assist = question.assistantFactory.createAClassTypeAssistant();
168:                 node.setInConstructor(assist.inConstructor(question.env));
169:
170:•                if (node.getInConstructor())
171:                 {
172:                         // Mark assignment target as initialized (so no warnings)
173:                         PDefinition state;
174:                         state = targetDefinition(node.getTarget(), question);
175:
176:•                        if (state instanceof AInstanceVariableDefinition)
177:                         {
178:                                 AInstanceVariableDefinition iv = (AInstanceVariableDefinition) state;
179:                                 iv.setInitialized(true);
180:                         }
181:                 }
182:
183:                 node.setType(AstFactory.newAVoidType(node.getLocation()));
184:                 return question.assistantFactory.createPTypeAssistant().checkReturnType(question.returnType, node.getType(), question.mandatory, node.getLocation());
185:         }
186:
187:         @Override
188:         public PType caseAAtomicStm(AAtomicStm node, TypeCheckInfo question)
189:                         throws AnalysisException
190:         {
191:
192:•                for (AAssignmentStm stmt : node.getAssignments())
193:                 {
194:                         stmt.apply(THIS, question);
195:                 }
196:
197:                 node.setType(AstFactory.newAVoidType(node.getLocation()));
198:                 return node.getType();
199:         }
200:
201:         @Override
202:         public PType caseAForPatternBindStm(AForPatternBindStm node,
203:                         TypeCheckInfo question) throws AnalysisException
204:         {
205:
206:                 PType stype = node.getExp().apply(THIS, new TypeCheckInfo(question.assistantFactory, question.env, question.scope));
207:                 Environment local = question.env;
208:
209:•                if (question.assistantFactory.createPTypeAssistant().isSeq(stype, question.fromModule))
210:                 {
211:                         node.setSeqType(question.assistantFactory.createPTypeAssistant().getSeq(stype, question.fromModule));
212:                         node.getPatternBind().apply(THIS, new TypeCheckInfo(question.assistantFactory, question.env, question.scope));
213:                         List<PDefinition> defs = getDefinitions(node.getPatternBind());
214:                         question.assistantFactory.createPDefinitionListAssistant().typeCheck(defs, THIS, new TypeCheckInfo(question.assistantFactory, question.env, question.scope));
215:                         local = new FlatCheckedEnvironment(question.assistantFactory, defs, question.env, question.scope);
216:                         PType rt = node.getStatement().apply(THIS, new TypeCheckInfo(question.assistantFactory, local, question.scope));
217:
218:•                        if (!(node.getSeqType() instanceof ASeq1SeqType) &&!(rt instanceof AVoidType))
219:                         {
220:                                 // Add () to the return type, as we may not enter the loop at all
221:                                 rt = AstFactory.newAUnionType(node.getLocation(), rt, AstFactory.newAVoidType(node.getLocation()));
222:                         }
223:                         
224:                         local.unusedCheck();
225:                         node.setType(rt);
226:                         return rt;
227:                 }
228:                 else
229:                 {
230:                         TypeCheckerErrors.report(3223, "Expecting sequence type after 'in'", node.getLocation(), node);
231:                         node.setType(AstFactory.newAUnknownType(node.getLocation()));
232:                         return node.getType();
233:                 }
234:         }
235:
236:         @Override
237:         public PType defaultSSimpleBlockStm(SSimpleBlockStm node,
238:                         TypeCheckInfo question) throws AnalysisException
239:         {
240:                 boolean notreached = false;
241:                 PTypeSet rtypes = new PTypeSet(question.assistantFactory);
242:                 PType last = null;
243:                 Iterator<PStm> iter = node.getStatements().iterator();
244:
245:•                while (iter.hasNext())
246:                 {
247:                         PStm stmt = iter.next();
248:•                        PType stype = stmt.apply(THIS, question.newMandatory(question.mandatory && !iter.hasNext()));
249:
250:•                        if (notreached)
251:                         {
252:                                 TypeCheckerErrors.warning(5006, "Statement will not be reached", stmt.getLocation(), stmt);
253:                         } else
254:                         {
255:                                 last = stype;
256:                                 notreached = true;
257:
258:•                                if (stype instanceof AUnionType)
259:                                 {
260:                                         AUnionType ust = (AUnionType) stype;
261:
262:•                                        for (PType t : ust.getTypes())
263:                                         {
264:                                                 addOneType(rtypes, t);
265:
266:•                                                if (t instanceof AVoidType || t instanceof AUnknownType)
267:                                                 {
268:                                                         notreached = false;
269:                                                 }
270:                                         }
271:                                 } else
272:                                 {
273:                                         addOneType(rtypes, stype);
274:
275:•                                        if (stype instanceof AVoidType
276:                                                         || stype instanceof AUnknownType)
277:                                         {
278:                                                 notreached = false;
279:                                         }
280:                                 }
281:                         }
282:                 }
283:
284:                 // If the last statement reached has a void component, add this to the
285:                 // overall
286:                 // return type, as the block may return nothing.
287:
288:•                if (last != null
289:•                                && (question.assistantFactory.createPTypeAssistant().isType(last, AVoidType.class) || question.assistantFactory.createPTypeAssistant().isUnknown(last)))
290:                 {
291:                         rtypes.add(AstFactory.newAVoidType(node.getLocation()));
292:                 }
293:
294:•                node.setType(rtypes.isEmpty() ? AstFactory.newAVoidType(node.getLocation())
295:                                 : rtypes.getType(node.getLocation()));
296:
297:                 return node.getType();
298:         }
299:
300:         @Override
301:         public PType caseABlockSimpleBlockStm(ABlockSimpleBlockStm node,
302:                         TypeCheckInfo question) throws AnalysisException
303:         {
304:                 // Each dcl definition is in scope for later definitions...
305:
306:                 Environment local = question.env;
307:
308:•                for (PDefinition d : node.getAssignmentDefs())
309:                 {
310:                         local = new FlatCheckedEnvironment(question.assistantFactory, d, local, question.scope); // cumulative
311:                         question.assistantFactory.createPDefinitionAssistant().implicitDefinitions(d, local);
312:                         d.setType(question.assistantFactory.createPTypeAssistant().typeResolve(d.getType(), null, THIS, question));
313:                         d.apply(THIS, new TypeCheckInfo(question.assistantFactory, local, question.scope, question.qualifiers, d.getType(), question.returnType, question.fromModule, question.mandatory));
314:                 }
315:
316:                 // For type checking purposes, the definitions are treated as
317:                 // local variables. At runtime (below) they have to be treated
318:                 // more like (updatable) state.
319:
320:                 PType r = defaultSSimpleBlockStm(node, new TypeCheckInfo(question.assistantFactory, local, question.scope, null, null, question.returnType, question.fromModule, question.mandatory));
321:                 local.unusedCheck(question.env);
322:                 node.setType(r);
323:                 return r;
324:         }
325:
326:         @Override
327:         public PType caseACallObjectStm(ACallObjectStm node, TypeCheckInfo question)
328:                         throws AnalysisException
329:         {
330:                 PType dtype = node.getDesignator().apply(THIS, question);
331:
332:•                if (!question.assistantFactory.createPTypeAssistant().isClass(dtype, question.env, question.fromModule))
333:                 {
334:                         TypeCheckerErrors.report(3207, "Object designator is not an object type", node.getLocation(), node);
335:                         node.setType(AstFactory.newAUnknownType(node.getLocation()));
336:                         return node.getType();
337:                 }
338:
339:                 AClassType ctype = question.assistantFactory.createPTypeAssistant().getClassType(dtype, question.env, question.fromModule);
340:
341:                 SClassDefinition classdef = ctype.getClassdef();
342:                 SClassDefinition self = question.env.findClassDefinition();
343:                 Environment classenv = null;
344:
345:•                if (self == classdef
346:•                                || question.assistantFactory.createPDefinitionAssistant().hasSupertype(self, question.assistantFactory.createPDefinitionAssistant().getType(classdef)))
347:                 {
348:                         // All fields visible. Note that protected fields are inherited
349:                         // into "locals" so they are effectively private
350:                         classenv = new PrivateClassEnvironment(question.assistantFactory, self);
351:                 } else
352:                 {
353:                         // Only public fields externally visible
354:                         classenv = new PublicClassEnvironment(question.assistantFactory, classdef);
355:                 }
356:
357:•                if (node.getClassname() == null)
358:                 {
359:                         node.setField(new LexNameToken(ctype.getName().getName(), node.getFieldname().getName(), node.getFieldname().getLocation()));
360:                 } else
361:                 {
362:                         node.setField(node.getClassname());
363:                 }
364:
365:                 node.getField().getLocation().executable(true);
366:                 List<PType> atypes = getArgTypes(node.getArgs(), THIS, question);
367:                 node.getField().setTypeQualifier(atypes);
368:                 PDefinition fdef = classenv.findName(node.getField(), question.scope);
369:                 node.setFieldDef(fdef);
370:
371:                 AClassTypeAssistantTC assist = question.assistantFactory.createAClassTypeAssistant();
372:
373:•                if (assist.isConstructor(fdef) && !assist.inConstructor(question.env))
374:                 {
375:                         TypeCheckerErrors.report(3337, "Cannot call a constructor from here", node.getLocation(), node);
376:                 node.setType(AstFactory.newAUnknownType(node.getLocation()));
377:                 return node.getType();
378:                 }
379:
380:
381:                 // Special code for the deploy method of CPU
382:
383:•                if (Settings.dialect == Dialect.VDM_RT
384:•                                && node.getField().getModule().equals("CPU")
385:•                                && node.getField().getName().equals("deploy"))
386:                 {
387:
388:•                        if (!question.assistantFactory.createPTypeAssistant().isType(atypes.get(0), AClassType.class))
389:                         {
390:                                 TypeCheckerErrors.report(3280, "Argument to deploy must be an object", node.getArgs().get(0).getLocation(), node.getArgs().get(0));
391:                         }
392:
393:                         node.setType(AstFactory.newAVoidType(node.getLocation()));
394:                         return node.getType();
395:•                } else if (Settings.dialect == Dialect.VDM_RT
396:•                                && node.getField().getModule().equals("CPU")
397:•                                && node.getField().getName().equals("setPriority"))
398:                 {
399:•                        if (!(atypes.get(0) instanceof AOperationType))
400:                         {
401:                                 TypeCheckerErrors.report(3290, "Argument to setPriority must be an operation", node.getArgs().get(0).getLocation(), node.getArgs().get(0));
402:                         } else
403:                         {
404:                                 // Convert the variable expression to a string...
405:                                 AVariableExp a1 = (AVariableExp) node.getArgs().get(0);
406:                                 node.getArgs().remove(0);
407:                                 node.getArgs().add(0, AstFactory.newAStringLiteralExp(new LexStringToken(a1.getName().getExplicit(true).getFullName(), a1.getLocation())));
408:
409:•                                if (a1.getName().getModule().equals(a1.getName().getName())) // it's a
410:                                 // constructor
411:                                 {
412:                                         TypeCheckerErrors.report(3291, "Argument to setPriority cannot be a constructor", node.getArgs().get(0).getLocation(), node.getArgs().get(0));
413:
414:                                 }
415:                         }
416:
417:                         node.setType(AstFactory.newAVoidType(node.getLocation()));
418:                         return node.getType();
419:•                } else if (fdef == null)
420:                 {
421:                         TypeCheckerErrors.report(3209, "Member " + node.getField()
422:                                         + " is not in scope", node.getLocation(), node);
423:                         node.setType(AstFactory.newAUnknownType(node.getLocation()));
424:                         return node.getType();
425:                 } else
426:                 {
427:                         question.assistantFactory.createPDefinitionAssistant();
428:•                        if (question.assistantFactory.createPDefinitionAssistant().isStatic(fdef)
429:•                                        && !question.env.isStatic())
430:                         {
431:                                 // warning(5005, "Should invoke member " + field +
432:                                 // " from a static context");
433:                         }
434:                 }
435:
436:                 PType type = question.assistantFactory.createPDefinitionAssistant().getType(fdef);
437:
438:•                if (question.assistantFactory.createPTypeAssistant().isOperation(type, question.fromModule))
439:                 {
440:                         AOperationType optype = question.assistantFactory.createPTypeAssistant().getOperation(type, question.fromModule);
441:                         PDefinition encl = question.env.getEnclosingDefinition();
442:
443:•                        if (encl != null && encl.getAccess().getPure() && !optype.getPure())
444:                         {
445:                                 TypeCheckerErrors.report(3339, "Cannot call impure operation from a pure operation", node.getLocation(), node);
446:                         }
447:
448:                         optype.apply(THIS, question);
449:                         node.getField().setTypeQualifier(optype.getParameters());
450:                         checkArgTypes(type, optype.getParameters(), atypes, question); // Not
451:                                                                                                                                                                                                                                                                         // necessary?
452:                         node.setType(optype.getResult());
453:                         return question.assistantFactory.createPTypeAssistant().checkReturnType(question.returnType, node.getType(), question.mandatory, node.getLocation());
454:•                } else if (question.assistantFactory.createPTypeAssistant().isFunction(type, question.fromModule))
455:                 {
456:                         // This is the case where a function is called as an operation
457:                         // without
458:                         // a "return" statement.
459:
460:                         AFunctionType ftype = question.assistantFactory.createPTypeAssistant().getFunction(type);
461:                         ftype.apply(THIS, question);
462:                         node.getField().setTypeQualifier(ftype.getParameters());
463:                         checkArgTypes(type, ftype.getParameters(), atypes, question); // Not
464:                                                                                                                                                                                                                                                                 // necessary?
465:                         node.setType(ftype.getResult());
466:                         return question.assistantFactory.createPTypeAssistant().checkReturnType(question.returnType, node.getType(), question.mandatory, node.getLocation());
467:                 } else
468:                 {
469:                         TypeCheckerErrors.report(3210, "Object member is neither a function nor an operation", node.getLocation(), node);
470:                         node.setType(AstFactory.newAUnknownType(node.getLocation()));
471:                         return node.getType();
472:                 }
473:         }
474:
475:         @Override
476:         public PType caseACallStm(ACallStm node, TypeCheckInfo question)
477:                         throws AnalysisException
478:         {
479:                 List<PType> atypes = getArgTypes(node.getArgs(), THIS, question);
480:
481:•                if (question.env.isVDMPP())
482:                 {
483:                         node.getName().setTypeQualifier(atypes);
484:                 }
485:
486:                 PDefinition opdef = question.env.findName(node.getName(), question.scope);
487:
488:                 node.setRootdef(opdef);
489:
490:•                if (opdef == null)
491:                 {
492:                         TypeCheckerErrors.report(3213, "Operation " + node.getName()
493:                                         + " is not in scope", node.getLocation(), node);
494:                         question.env.listAlternatives(node.getName());
495:                         node.setType(AstFactory.newAUnknownType(node.getLocation()));
496:                         return node.getType();
497:                 }
498:
499:•                if (question.env.isVDMPP() && node.getName().getExplicit())
500:                 {
501:                         // A call like X`op() is local if X is in our hierarchy
502:                         // else it's a static call of a different class.
503:
504:                         SClassDefinition self = question.env.findClassDefinition();
505:                         PType ctype = opdef.getClassDefinition().getType();
506:
507:•                        if (!question.assistantFactory.createPDefinitionAssistant().hasSupertype(self, ctype)
508:•                                        && opdef.getAccess().getStatic() == null)
509:                         {
510:                                 TypeCheckerErrors.report(3324, "Operation " + node.getName()
511:                                                 + " is not static", node.getLocation(), node);
512:                                 node.setType(AstFactory.newAUnknownType(node.getLocation()));
513:                                 return node.getType();
514:                         }
515:                 }
516:                 
517:                 AClassTypeAssistantTC assist = question.assistantFactory.createAClassTypeAssistant();
518:
519:•                if (assist.isConstructor(opdef) && !assist.inConstructor(question.env))
520:                 {
521:                         TypeCheckerErrors.report(3337, "Cannot call a constructor from here", node.getLocation(), node);
522:                 node.setType(AstFactory.newAUnknownType(node.getLocation()));
523:                 return node.getType();
524:                 }
525:
526:•                if (!question.assistantFactory.createPDefinitionAssistant().isStatic(opdef)
527:•                                && question.env.isStatic())
528:                 {
529:                         TypeCheckerErrors.report(3214, "Cannot call " + node.getName()
530:                                         + " from static context", node.getLocation(), node);
531:                         node.setType(AstFactory.newAUnknownType(node.getLocation()));
532:                         return node.getType();
533:                 }
534:
535:                 PType type = question.assistantFactory.createPDefinitionAssistant().getType(opdef);
536:
537:•                if (question.assistantFactory.createPTypeAssistant().isOperation(type, question.fromModule))
538:                 {
539:                         AOperationType optype = question.assistantFactory.createPTypeAssistant().getOperation(type, question.fromModule);
540:                         question.assistantFactory.createPTypeAssistant().typeResolve(optype, null, THIS, question);
541:                         PDefinition encl = question.env.getEnclosingDefinition();
542:
543:•                        if (encl != null && encl.getAccess().getPure() && !optype.getPure())
544:                         {
545:                                 TypeCheckerErrors.report(3339, "Cannot call impure operation from a pure operation", node.getLocation(), node);
546:                         }
547:
548:                         // Reset the name's qualifier with the actual operation type so
549:                         // that runtime search has a simple TypeComparator call.
550:
551:•                        if (question.env.isVDMPP())
552:                         {
553:                                 node.getName().setTypeQualifier(optype.getParameters());
554:                         }
555:
556:                         checkArgTypes(node, optype, optype.getParameters(), atypes, question);
557:                         node.setType(optype.getResult());
558:                         return question.assistantFactory.createPTypeAssistant().checkReturnType(question.returnType, optype.getResult(), question.mandatory, node.getLocation());
559:•                } else if (question.assistantFactory.createPTypeAssistant().isFunction(type, question.fromModule))
560:                 {
561:                         // This is the case where a function is called as an operation
562:                         // without
563:                         // a "return" statement.
564:
565:                         AFunctionType ftype = question.assistantFactory.createPTypeAssistant().getFunction(type);
566:                         question.assistantFactory.createPTypeAssistant().typeResolve(ftype, null, THIS, question);
567:
568:                         // Reset the name's qualifier with the actual function type so
569:                         // that runtime search has a simple TypeComparator call.
570:
571:•                        if (question.env.isVDMPP())
572:                         {
573:                                 node.getName().setTypeQualifier(ftype.getParameters());
574:                         }
575:
576:                         checkArgTypes(node, ftype, ftype.getParameters(), atypes, question);
577:                         node.setType(ftype.getResult());
578:                         return question.assistantFactory.createPTypeAssistant().checkReturnType(question.returnType, ftype.getResult(), question.mandatory, node.getLocation());
579:                 } else
580:                 {
581:                         TypeCheckerErrors.report(3210, "Name is neither a function nor an operation", node.getLocation(), node);
582:                         node.setType(AstFactory.newAUnknownType(node.getLocation()));
583:                         return node.getType();
584:                 }
585:         }
586:
587:         // TODO correct, possibly wrong typecheck implementation
588:         @Override
589:         public PType caseACaseAlternativeStm(ACaseAlternativeStm node,
590:                         TypeCheckInfo question) throws AnalysisException
591:         {
592:
593:•                if (node.getDefs().size() == 0)
594:                 {
595:                         node.setDefs(new LinkedList<PDefinition>());
596:                         question.assistantFactory.createPPatternAssistant(question.fromModule).typeResolve(node.getPattern(), THIS, question);
597:
598:•                        if (node.getPattern() instanceof AExpressionPattern)
599:                         {
600:                                 // Only expression patterns need type checking...
601:                                 AExpressionPattern ep = (AExpressionPattern) node.getPattern();
602:                                 PType ptype = ep.getExp().apply(THIS, question);
603:
604:•                                if (!question.assistantFactory.getTypeComparator().compatible(ptype, node.getCtype()))
605:                                 {
606:                                         TypeCheckerErrors.report(3311, "Pattern cannot match", node.getPattern().getLocation(), node.getPattern());
607:                                 }
608:                         }
609:
610:                         question.assistantFactory.createPPatternAssistant(question.fromModule).typeResolve(node.getPattern(), THIS, question);
611:
612:                         ACasesStm stm = (ACasesStm) node.parent();
613:                         node.getDefs().addAll(question.assistantFactory.createPPatternAssistant(question.fromModule).getDefinitions(node.getPattern(), stm.getExp().getType(), NameScope.LOCAL));
614:                 }
615:
616:                 question.assistantFactory.createPDefinitionListAssistant().typeCheck(node.getDefs(), THIS, question);
617:
618:•                if (!question.assistantFactory.createPPatternAssistant(question.fromModule).matches(node.getPattern(), node.getCtype()))
619:                 {
620:                         TypeCheckerErrors.report(3311, "Pattern cannot match", node.getPattern().getLocation(), node.getPattern());
621:                 }
622:
623:                 Environment local = new FlatCheckedEnvironment(question.assistantFactory, node.getDefs(), question.env, question.scope);
624:                 PType r = node.getResult().apply(THIS, new TypeCheckInfo(question.assistantFactory, local, question.scope, null, null, question.returnType, question.fromModule, question.mandatory));
625:                 local.unusedCheck();
626:
627:                 return r;
628:         }
629:
630:         @Override
631:         public PType caseACasesStm(ACasesStm node, TypeCheckInfo question)
632:                         throws AnalysisException
633:         {
634:                 PType expType = node.getExp().apply(THIS, question);
635:                 PTypeSet rtypes = new PTypeSet(question.assistantFactory);
636:                 boolean always = false;
637:
638:•                for (ACaseAlternativeStm c : node.getCases())
639:                 {
640:                         c.setCtype(expType);
641:                         rtypes.add(c.apply(THIS, question));
642:•                        always = always || question.assistantFactory.createPPatternAssistant(question.fromModule).alwaysMatches(c.getPattern(), expType);
643:                 }
644:
645:•                if (node.getOthers() != null)
646:                 {
647:                         rtypes.add(node.getOthers().apply(THIS, question));
648:                 }
649:•                else if (!always)
650:                 {
651:                         rtypes.add(AstFactory.newAVoidType(node.getLocation()));
652:                 }
653:
654:                 node.setType(rtypes.getType(node.getLocation()));
655:                 return node.getType();
656:         }
657:
658:         @Override
659:         public PType caseAClassInvariantStm(AClassInvariantStm node,
660:                         TypeCheckInfo question)
661:         {
662:                 // Definitions already checked.
663:                 node.setType(AstFactory.newABooleanBasicType(node.getLocation()));
664:                 return node.getType();
665:         }
666:
667:         @Override
668:         public PType caseACyclesStm(ACyclesStm node, TypeCheckInfo question)
669:                         throws AnalysisException
670:         {
671:                 PDefinition encl = question.env.getEnclosingDefinition();
672:                 
673:•                if (encl != null && encl.getAccess().getPure())
674:                 {
675:                         TypeCheckerErrors.report(3346, "Cannot use cycles in pure operations", node.getLocation(), node);
676:                 }
677:
678:                 Environment newEnv = new FlatEnvironment(question.assistantFactory, question.env, true, true);
679:                 TypeCheckInfo functional = question.newInfo(newEnv);
680:                 PType argType = node.getCycles().apply(THIS, functional);
681:
682:•                if (!question.assistantFactory.getTypeComparator().compatible(AstFactory.newANatNumericBasicType(node.getLocation()), argType))
683:                 {
684:                         TypeCheckerErrors.report(3282, "Arguments to cycles must be a nat", node.getLocation(), node);
685:                         TypeCheckerErrors.detail("Actual", argType);
686:                 }
687:
688:                 return node.getStatement().apply(THIS, question);
689:         }
690:
691:         @Override
692:         public PType caseALetStm(ALetStm node, TypeCheckInfo question)
693:                         throws AnalysisException
694:         {
695:•                node.setType(typeCheckLet(node, node.getLocalDefs(),node.getStatement(), question, !node.getIsDef()));
696:                 return node.getType();
697:         }
698:
699:         @Override
700:         public PType caseADurationStm(ADurationStm node, TypeCheckInfo question)
701:                         throws AnalysisException
702:         {
703:                 PDefinition encl = question.env.getEnclosingDefinition();
704:                 
705:•                if (encl != null && encl.getAccess().getPure())
706:                 {
707:                         TypeCheckerErrors.report(3346, "Cannot use duration in pure operations", node.getLocation(), node);
708:                 }
709:
710:                 Environment newEnv = new FlatEnvironment(question.assistantFactory, question.env, true, true);
711:                 TypeCheckInfo functional = question.newInfo(newEnv);
712:                 PType argType = node.getDuration().apply(THIS, functional);
713:
714:•                if (!question.assistantFactory.getTypeComparator().compatible(AstFactory.newANatNumericBasicType(node.getLocation()), argType))
715:                 {
716:                         TypeCheckerErrors.report(3281, "Arguments to duration must be a nat", node.getLocation(), node);
717:                         TypeCheckerErrors.detail("Actual", argType);
718:                 }
719:
720:                 return node.getStatement().apply(THIS, question);
721:         }
722:
723:         @Override
724:         public PType caseAElseIfStm(AElseIfStm node, TypeCheckInfo question)
725:                         throws AnalysisException
726:         {
727:                 node.setType(typeCheckAElseIf(node, node.getLocation(), node.getElseIf(), node.getThenStm(), question));
728:                 return node.getType();
729:         }
730:
731:         @Override
732:         public PType caseAErrorStm(AErrorStm node, TypeCheckInfo question)
733:         {
734:                 node.setType(AstFactory.newAUnknownType(node.getLocation()));
735:                 return node.getType(); // Because we terminate anyway
736:         }
737:
738:         @Override
739:         public PType caseAExitStm(AExitStm node, TypeCheckInfo question)
740:                         throws AnalysisException
741:         {
742:•                if (node.getExpression() != null)
743:                 {
744:                         node.setExpType(node.getExpression().apply(THIS, question));
745:                 }
746:
747:                 // This is unknown because the statement doesn't actually return a
748:                 // value - so if this is the only statement in a body, it is not a
749:                 // type error (should return the same type as the definition return
750:                 // type).
751:
752:                 node.setType(AstFactory.newAUnknownType(node.getLocation()));
753:                 return node.getType();
754:         }
755:
756:         @Override
757:         public PType caseAForAllStm(AForAllStm node, TypeCheckInfo question)
758:                         throws AnalysisException
759:         {
760:                 node.setType(node.getSet().apply(THIS, question));
761:                 question.assistantFactory.createPPatternAssistant(question.fromModule).typeResolve(node.getPattern(), THIS, question);
762:
763:•                if (question.assistantFactory.createPTypeAssistant().isSet(node.getType(), question.fromModule))
764:                 {
765:                         SSetType st = question.assistantFactory.createPTypeAssistant().getSet(node.getType(), question.fromModule);
766:                         List<PDefinition> defs = question.assistantFactory.createPPatternAssistant(question.fromModule).getDefinitions(node.getPattern(), st.getSetof(), NameScope.LOCAL);
767:
768:                         Environment local = new FlatCheckedEnvironment(question.assistantFactory, defs, question.env, question.scope);
769:                         PType rt = node.getStatement().apply(THIS, new TypeCheckInfo(question.assistantFactory, local, question.scope));
770:                         
771:•                        if (!(st instanceof ASet1SetType) &&!(rt instanceof AVoidType))
772:                         {
773:                                 // Add () to the return type, as we may not enter the loop at all
774:                                 rt = AstFactory.newAUnionType(node.getLocation(), rt, AstFactory.newAVoidType(node.getLocation()));
775:                         }
776:                         
777:                         local.unusedCheck();
778:                         node.setType(rt);
779:                         return rt;
780:                 } else
781:                 {
782:                         TypeCheckerErrors.report(3219, "For all statement does not contain a set type", node.getLocation(), node);
783:                         node.setType(AstFactory.newAUnknownType(node.getLocation()));
784:                         return node.getType();
785:                 }
786:         }
787:
788:         @Override
789:         public PType caseAForIndexStm(AForIndexStm node, TypeCheckInfo question)
790:                         throws AnalysisException
791:         {
792:                 PType ft = node.getFrom().apply(THIS, question);
793:                 PType tt = node.getTo().apply(THIS, question);
794:
795:•                if (!question.assistantFactory.createPTypeAssistant().isNumeric(ft, question.fromModule))
796:                 {
797:                         TypeCheckerErrors.report(3220, "From type is not numeric", node.getLocation(), node);
798:                 }
799:
800:•                if (!question.assistantFactory.createPTypeAssistant().isNumeric(tt, question.fromModule))
801:                 {
802:                         TypeCheckerErrors.report(3221, "To type is not numeric", node.getLocation(), node);
803:                 }
804:
805:•                if (node.getBy() != null)
806:                 {
807:                         PType bt = node.getBy().apply(THIS, question);
808:
809:•                        if (!question.assistantFactory.createPTypeAssistant().isNumeric(bt, question.fromModule))
810:                         {
811:                                 TypeCheckerErrors.report(3222, "By type is not numeric", node.getLocation(), node);
812:                         }
813:                 }
814:
815:                 PDefinition vardef = AstFactory.newALocalDefinition(node.getVar().getLocation(), node.getVar(), NameScope.LOCAL, ft);
816:                 Environment local = new FlatCheckedEnvironment(question.assistantFactory, vardef, question.env, question.scope);
817:                 PType rt = node.getStatement().apply(THIS, new TypeCheckInfo(question.assistantFactory, local, question.scope));
818:                 AUnionType rtu = AstFactory.newAUnionType(node.getLocation(), rt, AstFactory.newAVoidType(node.getLocation()));
819:                 local.unusedCheck();
820:                 node.setType(rtu);
821:                 return rtu;
822:         }
823:
824:         @Override
825:         public PType caseAIfStm(AIfStm node, TypeCheckInfo question)
826:                         throws AnalysisException
827:         {
828:                 node.setType(typeCheckIf(node.getLocation(), node.getIfExp(), node.getThenStm(), node.getElseIf(), node.getElseStm(), question));//rtypes.getType(node.getLocation()));
829:                 return node.getType();
830:         }
831:
832:         @Override
833:         public PType caseALetBeStStm(ALetBeStStm node, TypeCheckInfo question)
834:                         throws AnalysisException
835:         {
836:                 Entry<PType, AMultiBindListDefinition> res = typecheckLetBeSt(node, node.getLocation(), node.getBind(), node.getSuchThat(), node.getStatement(), question, true);
837:                 node.setDef(res.getValue());
838:                 node.setType(res.getKey());
839:                 return node.getType();
840:         }
841:
842:         @Override
843:         public PType caseANonDeterministicSimpleBlockStm(
844:                         ANonDeterministicSimpleBlockStm node, TypeCheckInfo question)
845:                         throws AnalysisException
846:         {
847:                 PDefinition encl = question.env.getEnclosingDefinition();
848:                 
849:•                if (encl != null && encl.getAccess().getPure())
850:                 {
851:                         TypeCheckerErrors.report(3346, "Cannot use non-deterministic statement in pure operations",
852:                                 node.getLocation(), node);
853:                 }
854:
855:                 PTypeSet rtypes = new PTypeSet(question.assistantFactory);
856:                 int rcount = 0;
857:
858:•                for (PStm stmt : node.getStatements())
859:                 {
860:                         PType stype = stmt.apply(THIS, question);
861:
862:•                        if (question.assistantFactory.createPTypeAssistant().isType(stype, AUnionType.class))
863:                         {
864:                                 AUnionType ust = (AUnionType) stype;
865:•                                for (PType t : ust.getTypes())
866:                                 {
867:•                                        if (addOne(rtypes, t))
868:                                         {
869:                                                 rcount++;
870:                                         }
871:                                 }
872:                         } else
873:                         {
874:•                                if (addOne(rtypes, stype))
875:                                 {
876:                                         rcount++;
877:                                 }
878:                         }
879:                 }
880:
881:•                if (rcount > 1)
882:                 {
883:                         TypeCheckerErrors.warning(5016, "Some statements will not be reached", node.getLocation(), node);
884:                 }
885:
886:•                node.setType(rtypes.isEmpty() ? AstFactory.newAVoidType(node.getLocation())
887:                                 : rtypes.getType(node.getLocation()));
888:                 return node.getType();
889:         }
890:
891:         @Override
892:         public PType caseANotYetSpecifiedStm(ANotYetSpecifiedStm node,
893:                         TypeCheckInfo question)
894:         {
895:                 node.setType(typeCheckANotYetSpecifiedExp(node,node.getLocation()));
896:                 return node.getType();
897:         }
898:
899:         @Override
900:         public PType caseAReturnStm(AReturnStm node, TypeCheckInfo question)
901:                         throws AnalysisException
902:         {
903:                 PDefinition encl = question.env.getEnclosingDefinition();
904:                 boolean inConstructor = false;
905:
906:•                if (encl instanceof AExplicitOperationDefinition)
907:                 {
908:                         AExplicitOperationDefinition op = (AExplicitOperationDefinition) encl;
909:                         inConstructor = op.getIsConstructor();
910:•                } else if (encl instanceof AImplicitOperationDefinition)
911:                 {
912:                         AImplicitOperationDefinition op = (AImplicitOperationDefinition) encl;
913:                         inConstructor = op.getIsConstructor();
914:                 }
915:
916:•                if (inConstructor && !(node.getExpression() instanceof ASelfExp))
917:                 {
918:                         TypeCheckerErrors.report(3326, "Constructor can only return 'self'", node.getLocation(), node);
919:                 }
920:
921:•                if (node.getExpression() == null)
922:                 {
923:                         node.setType(AstFactory.newAVoidReturnType(node.getLocation()));
924:                 } else
925:                 {
926:                         node.setType(node.getExpression().apply(THIS, question));
927:                 }
928:
929:                 return question.assistantFactory.createPTypeAssistant().checkReturnType(question.returnType, node.getType(), true, node.getLocation());
930:         }
931:
932:         @Override
933:         public PType caseASkipStm(ASkipStm node, TypeCheckInfo question)
934:         {
935:                 node.setType(AstFactory.newAVoidType(node.getLocation()));
936:                 return question.assistantFactory.createPTypeAssistant().checkReturnType(question.returnType, node.getType(), question.mandatory, node.getLocation());
937:         }
938:
939:         @Override
940:         public PType caseASpecificationStm(ASpecificationStm node,
941:                         TypeCheckInfo question) throws AnalysisException
942:         {
943:
944:                 List<PDefinition> defs = new LinkedList<PDefinition>();
945:
946:                 // Now we build local definitions for each of the externals, so
947:                 // that they can be added to the local environment, while the
948:                 // global state is made inaccessible.
949:
950:•                if (node.getExternals() != null)
951:                 {
952:•                        for (AExternalClause clause : node.getExternals())
953:                         {
954:•                                for (ILexNameToken name : clause.getIdentifiers())
955:                                 {
956:•                                        if (question.env.findName(name, NameScope.STATE) == null)
957:                                         {
958:                                                 TypeCheckerErrors.report(3274, "External variable is not in scope: "
959:                                                                 + name, name.getLocation(), name);
960:                                         } else
961:                                         {
962:                                                 defs.add(AstFactory.newALocalDefinition(name.getLocation(), name, NameScope.STATE, clause.getType()));
963:                                         }
964:                                 }
965:                         }
966:                 }
967:
968:•                if (node.getErrors() != null)
969:                 {
970:•                        for (AErrorCase err : node.getErrors())
971:                         {
972:                                 PType lt = err.getLeft().apply(THIS, question);
973:                                 PType rt = err.getRight().apply(THIS, question);
974:
975:•                                if (!question.assistantFactory.createPTypeAssistant().isType(lt, ABooleanBasicType.class))
976:                                 {
977:                                         TypeCheckerErrors.report(3275, "Error clause must be a boolean", err.getLeft().getLocation(), err.getLeft());
978:                                 }
979:
980:•                                if (!question.assistantFactory.createPTypeAssistant().isType(rt, ABooleanBasicType.class))
981:                                 {
982:                                         TypeCheckerErrors.report(3275, "Error clause must be a boolean", err.getRight().getLocation(), err.getRight());
983:                                 }
984:                         }
985:                 }
986:
987:                 question.assistantFactory.createPDefinitionListAssistant().typeCheck(defs, THIS, question);
988:                 Environment local = new FlatEnvironment(question.assistantFactory, defs, question.env); // NB. No
989:                 // check
990:                 // //Unused
991:
992:•                if (node.getPrecondition() != null
993:•                                && !question.assistantFactory.createPTypeAssistant().isType(node.getPrecondition().apply(THIS, new TypeCheckInfo(question.assistantFactory, local, NameScope.NAMESANDSTATE)), ABooleanBasicType.class))
994:                 {
995:                         TypeCheckerErrors.report(3233, "Precondition is not a boolean expression", node.getPrecondition().getLocation(), node.getPrecondition());
996:                 }
997:
998:•                if (node.getPostcondition() != null
999:•                                && !question.assistantFactory.createPTypeAssistant().isType(node.getPostcondition().apply(THIS, new TypeCheckInfo(question.assistantFactory, local, NameScope.NAMESANDANYSTATE)), ABooleanBasicType.class))
1000:                 {
1001:                         TypeCheckerErrors.report(3234, "Postcondition is not a boolean expression", node.getPostcondition().getLocation(), node.getPostcondition());
1002:                 }
1003:
1004:                 node.setType(AstFactory.newAVoidType(node.getLocation()));
1005:                 return node.getType();
1006:         }
1007:
1008:         @Override
1009:         public PType caseATrapStm(ATrapStm node, TypeCheckInfo question)
1010:                         throws AnalysisException
1011:         {
1012:                 PTypeSet rtypes = new PTypeSet(question.assistantFactory);
1013:
1014:                 PStm body = node.getBody();
1015:
1016:                 PType bt = body.apply(THIS, question);
1017:                 rtypes.add(bt);
1018:
1019:                 PTypeSet extype = exitCheck(body, question);
1020:                 PType ptype = null;
1021:
1022:•                if (extype.isEmpty())
1023:                 {
1024:                         TypeCheckerErrors.report(3241, "Body of trap statement does not throw exceptions", node.getLocation(), node);
1025:                         ptype = AstFactory.newAUnknownType(body.getLocation());
1026:                 }
1027:                 else
1028:                 {
1029:                         extype.add(AstFactory.newAUnknownType(body.getLocation()));
1030:                         ptype = extype.getType(body.getLocation());
1031:                 }
1032:
1033:                 node.setType(ptype);
1034:                 node.getPatternBind().apply(THIS, question);
1035:                 // TODO: PatternBind stuff
1036:                 List<PDefinition> defs = getDefinitions(node.getPatternBind());
1037:                 question.assistantFactory.createPDefinitionListAssistant().typeCheck(defs, THIS, question);
1038:                 Environment local = new FlatCheckedEnvironment(question.assistantFactory, defs, question.env, question.scope);
1039:                 rtypes.add(node.getWith().apply(THIS, new TypeCheckInfo(question.assistantFactory, local, question.scope, question.qualifiers)));
1040:
1041:                 node.setType(rtypes.getType(node.getLocation()));
1042:                 return node.getType();
1043:         }
1044:
1045:         @Override
1046:         public PType caseAWhileStm(AWhileStm node, TypeCheckInfo question)
1047:                         throws AnalysisException
1048:         {
1049:                 question.qualifiers = null;
1050:                 PType etype = node.getExp().apply(THIS, question);
1051:
1052:•                if (!question.assistantFactory.createPTypeAssistant().isType(etype, ABooleanBasicType.class))
1053:                 {
1054:                         TypeCheckerErrors.report(3218, "Expression is not boolean", node.getLocation(), node);
1055:                 }
1056:
1057:                 List<QualifiedDefinition> qualified = node.getExp().apply(question.assistantFactory.getQualificationVisitor(), question);
1058:
1059:•                for (QualifiedDefinition qdef : qualified)
1060:                 {
1061:                         qdef.qualifyType();
1062:                 }
1063:
1064:                 PType stype = node.getStatement().apply(THIS, question);
1065:
1066:•                for (QualifiedDefinition qdef : qualified)
1067:                 {
1068:                         qdef.resetType();
1069:                 }
1070:
1071:•                if (node.getExp() instanceof ABooleanConstExp
1072:                                 && stype instanceof AUnionType)
1073:                 {
1074:                         ABooleanConstExp boolLiteral = (ABooleanConstExp) node.getExp();
1075:
1076:•                        if (boolLiteral.getValue().getValue()) // while true do...
1077:                         {
1078:                                 List<PType> edited = new Vector<PType>();
1079:                                 AUnionType original = (AUnionType) stype;
1080:
1081:•                                for (PType t : original.getTypes())
1082:                                 {
1083:•                                        if (!(t instanceof AVoidType))
1084:                                         {
1085:                                                 edited.add(t);
1086:                                         }
1087:                                 }
1088:
1089:                                 stype = AstFactory.newAUnionType(node.getLocation(), edited);
1090:                         }
1091:                 }
1092:
1093:                 return stype;
1094:         }
1095:
1096:         @Override
1097:         public PType caseAPeriodicStm(APeriodicStm node, TypeCheckInfo question)
1098:                         throws AnalysisException
1099:         {
1100:                 List<PExp> args = node.getArgs();
1101:
1102:•                if (args.size() != 4)
1103:                 {
1104:                         TypeCheckerErrors.report(3287, "Periodic thread must have 4 argument(s)", node.getLocation(), node);
1105:                 } else
1106:                 {
1107:                         Environment newEnv = new FlatEnvironment(question.assistantFactory, question.env, true, true);
1108:                         TypeCheckInfo functional = question.newInfo(newEnv);
1109:
1110:•                        for (PExp arg : args)
1111:                         {
1112:                                 PType type = arg.apply(THIS, functional);
1113:
1114:•                                if (!question.assistantFactory.createPTypeAssistant().isNumeric(type, question.fromModule))
1115:                                 {
1116:                                         TypeCheckerErrors.report(3316, "Expecting number in periodic argument", arg.getLocation(), arg);
1117:                                 }
1118:                         }
1119:                 }
1120:
1121:                 ILexNameToken opname = node.getOpname();
1122:
1123:                 opname.setTypeQualifier(new LinkedList<PType>());
1124:                 opname.getLocation().hit();
1125:                 PDefinition opdef = question.env.findName(opname, NameScope.NAMES);
1126:
1127:•                if (opdef == null)
1128:                 {
1129:                         TypeCheckerErrors.report(3228, opname + " is not in scope", node.getLocation(), node);
1130:                         node.setType(AstFactory.newAUnknownType(node.getLocation()));
1131:                         return node.getType();
1132:                 }
1133:
1134:                 // Operation must be "() ==> ()"
1135:
1136:                 AOperationType expected = AstFactory.newAOperationType(node.getLocation(), new Vector<PType>(), AstFactory.newAVoidType(node.getLocation()));
1137:
1138:                 opdef = question.assistantFactory.createPDefinitionAssistant().deref(opdef);
1139:
1140:•                if (opdef instanceof AExplicitOperationDefinition)
1141:                 {
1142:                         AExplicitOperationDefinition def = (AExplicitOperationDefinition) opdef;
1143:
1144:•                        if (!question.assistantFactory.createPTypeAssistant().equals(def.getType(), expected))
1145:                         {
1146:                                 TypeCheckerErrors.report(3229, opname
1147:                                                 + " should have no parameters or return type", node.getLocation(), node);
1148:                                 TypeCheckerErrors.detail("Actual", def.getType());
1149:                         }
1150:•                        else if (def.getAccess().getPure())
1151:                         {
1152:                                 TypeCheckerErrors.report(3347, "Cannot have a pure operation as the body of a thread", node.getLocation(), node);
1153:                         }
1154:•                } else if (opdef instanceof AImplicitOperationDefinition)
1155:                 {
1156:                         AImplicitOperationDefinition def = (AImplicitOperationDefinition) opdef;
1157:
1158:•                        if (def.getBody() == null)
1159:                         {
1160:                                 TypeCheckerErrors.report(3230, opname + " is implicit", node.getLocation(), node);
1161:                         }
1162:
1163:•                        if (!question.assistantFactory.createPTypeAssistant().equals(def.getType(), expected))
1164:                         {
1165:                                 TypeCheckerErrors.report(3231, opname
1166:                                                 + " should have no parameters or return type", node.getLocation(), node);
1167:                                 TypeCheckerErrors.detail("Actual", def.getType());
1168:                         }
1169:•                        else if (def.getAccess().getPure())
1170:                         {
1171:                                 TypeCheckerErrors.report(3347, "Cannot have a pure operation as the body of a thread", node.getLocation(), node);
1172:                         }
1173:                 } else
1174:                 {
1175:                         TypeCheckerErrors.report(3232, opname + " is not an operation name", node.getLocation(), node);
1176:                 }
1177:
1178:                 node.setType(AstFactory.newAVoidType(node.getLocation()));
1179:                 return node.getType();
1180:         }
1181:
1182:         @Override
1183:         public PType caseASporadicStm(ASporadicStm node, TypeCheckInfo question)
1184:                         throws AnalysisException
1185:         {
1186:                 List<PExp> args = node.getArgs();
1187:
1188:•                if (args.size() != 3)
1189:                 {
1190:                         TypeCheckerErrors.report(3287, "Sporadic thread must have 3 arguments", node.getLocation(), node);
1191:                 } else
1192:                 {
1193:                         Environment newEnv = new FlatEnvironment(question.assistantFactory, question.env, true, true);
1194:                         TypeCheckInfo functional = question.newInfo(newEnv);
1195:
1196:•                        for (PExp arg : args)
1197:                         {
1198:                                 PType type = arg.apply(THIS, functional);
1199:
1200:•                                if (!question.assistantFactory.createPTypeAssistant().isNumeric(type, question.fromModule))
1201:                                 {
1202:                                         TypeCheckerErrors.report(3316, "Expecting number in sporadic argument", arg.getLocation(), node);
1203:                                 }
1204:                         }
1205:                 }
1206:
1207:                 ILexNameToken opname = node.getOpname();
1208:                 opname.setTypeQualifier(new LinkedList<PType>());
1209:                 opname.getLocation().hit();
1210:                 PDefinition opdef = question.env.findName(opname, NameScope.NAMES);
1211:
1212:•                if (opdef == null)
1213:                 {
1214:                         TypeCheckerErrors.report(3228, opname + " is not in scope", node.getLocation(), node);
1215:                         node.setType(AstFactory.newAUnknownType(node.getLocation()));
1216:                         return node.getType();
1217:                 }
1218:
1219:                 // Operation must be "() ==> ()"
1220:
1221:                 AOperationType expected = AstFactory.newAOperationType(node.getLocation(), new Vector<PType>(), AstFactory.newAVoidType(node.getLocation()));
1222:                 opdef = question.assistantFactory.createPDefinitionAssistant().deref(opdef);
1223:
1224:•                if (opdef instanceof AExplicitOperationDefinition)
1225:                 {
1226:                         AExplicitOperationDefinition def = (AExplicitOperationDefinition) opdef;
1227:
1228:•                        if (!question.assistantFactory.createPTypeAssistant().equals(def.getType(), expected))
1229:                         {
1230:                                 TypeCheckerErrors.report(3229, opname
1231:                                                 + " should have no parameters or return type", node.getLocation(), node);
1232:                                 TypeCheckerErrors.detail("Actual", def.getType());
1233:                         }
1234:•                        else if (def.getAccess().getPure())
1235:                         {
1236:                                 TypeCheckerErrors.report(3347, "Cannot have a pure operation as the body of a thread", node.getLocation(), node);
1237:                         }
1238:•                } else if (opdef instanceof AImplicitOperationDefinition)
1239:                 {
1240:                         AImplicitOperationDefinition def = (AImplicitOperationDefinition) opdef;
1241:
1242:•                        if (def.getBody() == null)
1243:                         {
1244:                                 TypeCheckerErrors.report(3230, opname + " is implicit", node.getLocation(), node);
1245:                         }
1246:
1247:•                        if (!question.assistantFactory.createPTypeAssistant().equals(def.getType(), expected))
1248:                         {
1249:                                 TypeCheckerErrors.report(3231, opname
1250:                                                 + " should have no parameters or return type", node.getLocation(), node);
1251:                                 TypeCheckerErrors.detail("Actual", def.getType());
1252:                         }
1253:•                        else if (def.getAccess().getPure())
1254:                         {
1255:                                 TypeCheckerErrors.report(3347, "Cannot have a pure operation as the body of a thread", node.getLocation(), node);
1256:                         }
1257:                 } else
1258:                 {
1259:                         TypeCheckerErrors.report(3232, opname + " is not an operation name", node.getLocation(), node);
1260:                 }
1261:
1262:                 node.setType(AstFactory.newAVoidType(node.getLocation()));
1263:                 return node.getType();
1264:         }
1265:
1266:         @Override
1267:         public PType caseAStartStm(AStartStm node, TypeCheckInfo question)
1268:                         throws AnalysisException
1269:         {
1270:                 PDefinition encl = question.env.getEnclosingDefinition();
1271:                 
1272:•                if (encl != null && encl.getAccess().getPure())
1273:                 {
1274:                         TypeCheckerErrors.report(3346, "Cannot use start in pure operations", node.getLocation(), node);
1275:                 }
1276:
1277:                 PType type = node.getObj().apply(THIS, question);
1278:
1279:•                if (question.assistantFactory.createPTypeAssistant().isSet(type, question.fromModule))
1280:                 {
1281:                         SSetType set = question.assistantFactory.createPTypeAssistant().getSet(type, question.fromModule);
1282:
1283:•                        if (!question.assistantFactory.createPTypeAssistant().isClass(set.getSetof(), null, question.fromModule))
1284:                         {
1285:                                 TypeCheckerErrors.report(3235, "Expression is not a set of object references", node.getObj().getLocation(), node.getObj());
1286:                         } else
1287:                         {
1288:                                 AClassType ctype = question.assistantFactory.createPTypeAssistant().getClassType(set.getSetof(), null, question.fromModule);
1289:
1290:•                                if (question.assistantFactory.createSClassDefinitionAssistant().findThread(ctype.getClassdef()) == null)
1291:                                 {
1292:                                         TypeCheckerErrors.report(3236, "Class does not define a thread", node.getObj().getLocation(), node.getObj());
1293:                                 }
1294:                         }
1295:•                } else if (question.assistantFactory.createPTypeAssistant().isClass(type, null, question.fromModule))
1296:                 {
1297:                         AClassType ctype = question.assistantFactory.createPTypeAssistant().getClassType(type, null, question.fromModule);
1298:
1299:•                        if (question.assistantFactory.createSClassDefinitionAssistant().findThread(ctype.getClassdef()) == null)
1300:                         {
1301:                                 TypeCheckerErrors.report(3237, "Class does not define a thread", node.getObj().getLocation(), node.getObj());
1302:                         }
1303:                 } else
1304:                 {
1305:                         TypeCheckerErrors.report(3238, "Expression is not an object reference or set of object references", node.getObj().getLocation(), node.getObj());
1306:                 }
1307:
1308:                 node.setType(AstFactory.newAVoidType(node.getLocation()));
1309:                 return question.assistantFactory.createPTypeAssistant().checkReturnType(question.returnType, node.getType(), question.mandatory, node.getLocation());
1310:         }
1311:
1312:         @Override
1313:         public PType caseAStopStm(AStopStm node, TypeCheckInfo question)
1314:                         throws AnalysisException
1315:         {
1316:                 PType type = node.getObj().apply(THIS, question);
1317:
1318:•                if (question.assistantFactory.createPTypeAssistant().isSet(type, question.fromModule))
1319:                 {
1320:                         SSetType set = question.assistantFactory.createPTypeAssistant().getSet(type, question.fromModule);
1321:
1322:•                        if (!question.assistantFactory.createPTypeAssistant().isClass(set.getSetof(), null, question.fromModule))
1323:                         {
1324:                                 TypeCheckerErrors.report(3235, "Expression is not a set of object references", node.getObj().getLocation(), node.getObj());
1325:                         } else
1326:                         {
1327:                                 AClassType ctype = question.assistantFactory.createPTypeAssistant().getClassType(set.getSetof(), null, question.fromModule);
1328:
1329:•                                if (question.assistantFactory.createSClassDefinitionAssistant().findThread(ctype.getClassdef()) == null)
1330:                                 {
1331:                                         TypeCheckerErrors.report(3236, "Class does not define a thread", node.getObj().getLocation(), node.getObj());
1332:                                 }
1333:                         }
1334:•                } else if (question.assistantFactory.createPTypeAssistant().isClass(type, null, question.fromModule))
1335:                 {
1336:                         AClassType ctype = question.assistantFactory.createPTypeAssistant().getClassType(type, null, question.fromModule);
1337:
1338:•                        if (question.assistantFactory.createSClassDefinitionAssistant().findThread(ctype.getClassdef()) == null)
1339:                         {
1340:                                 TypeCheckerErrors.report(3237, "Class does not define a thread", node.getObj().getLocation(), node.getObj());
1341:                         }
1342:                 } else
1343:                 {
1344:                         TypeCheckerErrors.report(3238, "Expression is not an object reference or set of object references", node.getObj().getLocation(), node.getObj());
1345:                 }
1346:
1347:                 node.setType(AstFactory.newAVoidType(node.getLocation()));
1348:                 return question.assistantFactory.createPTypeAssistant().checkReturnType(question.returnType, node.getType(), question.mandatory, node.getLocation());
1349:         }
1350:
1351:         @Override
1352:         public PType caseASubclassResponsibilityStm(
1353:                         ASubclassResponsibilityStm node, TypeCheckInfo question)
1354:         {
1355:                 node.setType(AstFactory.newAUnknownType(node.getLocation())); // Because
1356:                                                                                                                                                 // we
1357:                                                                                                                                                 // terminate
1358:                                                                                                                                                 // anyway
1359:                 return node.getType();
1360:         }
1361:
1362:         @Override
1363:         public PType caseATixeStm(ATixeStm node, TypeCheckInfo question)
1364:                         throws AnalysisException
1365:         {
1366:
1367:                 PType rt = node.getBody().apply(THIS, question);
1368:                 PTypeSet extypes = exitCheck(node.getBody(), question);
1369:
1370:•                if (!extypes.isEmpty())
1371:                 {
1372:                         PType union = extypes.getType(node.getLocation());
1373:
1374:•                        for (ATixeStmtAlternative tsa : node.getTraps())
1375:                         {
1376:                                 tsa.setExp(union);
1377:                                 tsa.apply(THIS, question);
1378:                         }
1379:                 }
1380:                 node.setType(rt);
1381:                 return rt;
1382:         }
1383:
1384:         @Override
1385:         public PType caseATixeStmtAlternative(ATixeStmtAlternative node,
1386:                         TypeCheckInfo question) throws AnalysisException
1387:         {
1388:                 // Make a union with "?" so that pattern always matches
1389:                 PType original = node.getExp();
1390:                 node.setExp(AstFactory.newAUnionType(node.getExp().getLocation(), node.getExp(), AstFactory.newAUnknownType(node.getExp().getLocation())));
1391:                 node.getPatternBind().apply(THIS, new TypeCheckInfo(question.assistantFactory, question.env, question.scope));
1392:                 List<PDefinition> defs = getDefinitions(node.getPatternBind());
1393:                 node.setExp(original);
1394:
1395:                 question.assistantFactory.createPDefinitionListAssistant().typeCheck(defs, THIS, question);
1396:                 Environment local = new FlatCheckedEnvironment(question.assistantFactory, defs, question.env, question.scope);
1397:                 node.getStatement().apply(THIS, new TypeCheckInfo(question.assistantFactory, local, question.scope, question.qualifiers));
1398:                 local.unusedCheck();
1399:
1400:                 return null;
1401:         }
1402:
1403:         @Override
1404:         public PType caseADefPatternBind(ADefPatternBind node,
1405:                         TypeCheckInfo question) throws AnalysisException
1406:         {
1407:
1408:                 node.setDefs(null);
1409:
1410:                 PBind bind = node.getBind();
1411:                 PType type = node.getType();
1412:
1413:•                if (bind != null)
1414:                 {
1415:•                        if (bind instanceof ATypeBind)
1416:                         {
1417:                                 ATypeBind typebind = (ATypeBind) bind;
1418:                                 question.assistantFactory.createATypeBindAssistant().typeResolve(typebind, THIS, question);
1419:
1420:•                                if (!question.assistantFactory.getTypeComparator().compatible(typebind.getType(), type))
1421:                                 {
1422:                                         TypeCheckerErrors.report(3198, "Type bind not compatible with expression", bind.getLocation(), bind);
1423:                                         TypeCheckerErrors.detail2("Bind", typebind.getType(), "Exp", type);
1424:                                 }
1425:                         } else
1426:                         {
1427:                                 ASetBind setbind = (ASetBind) bind;
1428:                                 SSetType settype = question.assistantFactory.createPTypeAssistant().getSet(setbind.getSet().apply(THIS, question), question.fromModule);
1429:
1430:•                                if (!question.assistantFactory.getTypeComparator().compatible(type, settype.getSetof()))
1431:                                 {
1432:                                         TypeCheckerErrors.report(3199, "Set bind not compatible with expression", bind.getLocation(), bind);
1433:                                         TypeCheckerErrors.detail2("Bind", settype.getSetof(), "Exp", type);
1434:                                 }
1435:                         }
1436:
1437:                         PDefinition def = AstFactory.newAMultiBindListDefinition(bind.getLocation(), question.assistantFactory.createPBindAssistant().getMultipleBindList(bind));
1438:
1439:                         def.apply(THIS, question);
1440:                         List<PDefinition> defs = new LinkedList<PDefinition>();
1441:                         defs.add(def);
1442:                         node.setDefs(defs);
1443:                 } else
1444:                 {
1445:•                        assert type != null : "Can't typecheck a pattern without a type";
1446:
1447:                         question.assistantFactory.createPPatternAssistant(question.fromModule).typeResolve(node.getPattern(), THIS, question);
1448:                         node.setDefs(question.assistantFactory.createPPatternAssistant(question.fromModule).getDefinitions(node.getPattern(), type, NameScope.LOCAL));
1449:                 }
1450:                 return null;
1451:         }
1452:         
1453:         public List<PDefinition> getDefinitions(ADefPatternBind patternBind)
1454:         {
1455:•                assert patternBind.getDefs() != null : "PatternBind must be type checked before getDefinitions";
1456:
1457:                 return patternBind.getDefs();
1458:         }
1459:         
1460:         public PTypeSet exitCheck(PStm statement, TypeCheckInfo question)
1461:         {
1462:                 try
1463:                 {
1464:                         return statement.apply(question.assistantFactory.getExitTypeCollector(), question.env);
1465:                 } catch (AnalysisException e)
1466:                 {
1467:                         return new PTypeSet(question.assistantFactory);
1468:                 }
1469:
1470:         }
1471:         
1472:         public List<PType> getArgTypes(List<PExp> args,
1473:                         IQuestionAnswer<TypeCheckInfo, PType> rootVisitor,
1474:                         TypeCheckInfo question) throws AnalysisException
1475:         {
1476:                 List<PType> types = new LinkedList<PType>();
1477:
1478:•                for (PExp e : args)
1479:                 {
1480:                         types.add(e.apply(rootVisitor, question));
1481:                 }
1482:
1483:                 return types;
1484:         }
1485:
1486:         public void checkArgTypes(PType type, List<PType> ptypes, List<PType> atypes, TypeCheckInfo question)
1487:         {
1488:•                if (ptypes.size() != atypes.size())
1489:                 {
1490:                         TypeCheckerErrors.report(3211, "Expecting " + ptypes.size()
1491:                                         + " arguments", type.getLocation(), type);
1492:                 } else
1493:                 {
1494:                         int i = 0;
1495:
1496:•                        for (PType atype : atypes)
1497:                         {
1498:                                 PType ptype = ptypes.get(i++);
1499:
1500:•                                if (!question.assistantFactory.getTypeComparator().compatible(ptype, atype))
1501:                                 {
1502:                                         TypeCheckerErrors.report(3212, "Unexpected type for argument "
1503:                                                         + i, atype.getLocation(), atype);
1504:                                         TypeCheckerErrors.detail2("Expected", ptype, "Actual", atype);
1505:                                 }
1506:                         }
1507:                 }
1508:         }
1509:         
1510:         public boolean addOne(PTypeSet rtypes, PType add)
1511:         {
1512:•                if (add instanceof AVoidReturnType)
1513:                 {
1514:                         rtypes.add(AstFactory.newAVoidType(add.getLocation()));
1515:                         return true;
1516:•                } else if (!(add instanceof AVoidType))
1517:                 {
1518:                         rtypes.add(add);
1519:                         return true;
1520:                 } else
1521:                 {
1522:                         rtypes.add(add);
1523:                         return false;
1524:                 }
1525:         }
1526:         
1527:         public void addOneType(Set<PType> rtypes, PType add)
1528:         {
1529:•                if (add instanceof AVoidReturnType)
1530:                 {
1531:                         rtypes.add(AstFactory.newAVoidType(add.getLocation()));
1532:•                } else if (!(add instanceof AVoidType))
1533:                 {
1534:                         rtypes.add(add);
1535:                 }
1536:         }
1537:         
1538:         public PDefinition targetDefinition(PStateDesignator pStateDesignator,
1539:                         TypeCheckInfo question)
1540:         {
1541:•                if (pStateDesignator instanceof AIdentifierStateDesignator)
1542:                 {
1543:                         AIdentifierStateDesignator stateDesignator = (AIdentifierStateDesignator) pStateDesignator;
1544:                         return question.env.findName(stateDesignator.getName(), NameScope.STATE);
1545:                 } else
1546:                 {
1547:                         return null;
1548:                 }
1549:
1550:         }
1551:         
1552:         public void checkArgTypes(ACallStm node, PType type, List<PType> ptypes,
1553:                         List<PType> atypes, TypeCheckInfo question) {
1554:•                if (ptypes.size() != atypes.size()) {
1555:                         TypeCheckerErrors.report(3216, "Expecting " + ptypes.size()
1556:                                         + " arguments", node.getLocation(), node);
1557:                 } else {
1558:                         int i = 0;
1559:
1560:•                        for (PType atype : atypes) {
1561:                                 PType ptype = ptypes.get(i++);
1562:
1563:•                                if (!question.assistantFactory.getTypeComparator().compatible(ptype, atype)) {
1564:                                         TypeCheckerErrors.report(3217,
1565:                                                         "Unexpected type for argument " + i,
1566:                                                         node.getLocation(), type);
1567:                                         TypeCheckerErrors.detail2("Expected", ptype, "Actual",
1568:                                                         atype);
1569:                                 }
1570:                         }
1571:                 }
1572:         }
1573:
1574: }