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: 65 C: 407
86%
M: 8 C: 38
83%
M: 7 C: 17
71%
M: 9 C: 65
88%
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: 49
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: 49
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: 26
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: 13
100%
M: 0 C: 0
100%
M: 0 C: 1
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: 130
54%
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: 240 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);
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:         // TODO: Missing the other DefStatement
692:
693:         @Override
694:         public PType caseALetStm(ALetStm node, TypeCheckInfo question)
695:                         throws AnalysisException
696:         {
697:                 node.setType(typeCheckLet(node, node.getLocalDefs(),node.getStatement(),question));
698:                 return node.getType();
699:         }
700:
701:         @Override
702:         public PType caseADurationStm(ADurationStm node, TypeCheckInfo question)
703:                         throws AnalysisException
704:         {
705:                 PDefinition encl = question.env.getEnclosingDefinition();
706:                 
707:•                if (encl != null && encl.getAccess().getPure())
708:                 {
709:                         TypeCheckerErrors.report(3346, "Cannot use duration in pure operations", node.getLocation(), node);
710:                 }
711:
712:                 Environment newEnv = new FlatEnvironment(question.assistantFactory, question.env, true);
713:                 TypeCheckInfo functional = question.newInfo(newEnv);
714:                 PType argType = node.getDuration().apply(THIS, functional);
715:
716:•                if (!question.assistantFactory.getTypeComparator().compatible(AstFactory.newANatNumericBasicType(node.getLocation()), argType))
717:                 {
718:                         TypeCheckerErrors.report(3281, "Arguments to duration must be a nat", node.getLocation(), node);
719:                         TypeCheckerErrors.detail("Actual", argType);
720:                 }
721:
722:                 return node.getStatement().apply(THIS, question);
723:         }
724:
725:         @Override
726:         public PType caseAElseIfStm(AElseIfStm node, TypeCheckInfo question)
727:                         throws AnalysisException
728:         {
729:                 node.setType(typeCheckAElseIf(node, node.getLocation(), node.getElseIf(), node.getThenStm(), question));
730:                 return node.getType();
731:         }
732:
733:         @Override
734:         public PType caseAErrorStm(AErrorStm node, TypeCheckInfo question)
735:         {
736:                 node.setType(AstFactory.newAUnknownType(node.getLocation()));
737:                 return node.getType(); // Because we terminate anyway
738:         }
739:
740:         @Override
741:         public PType caseAExitStm(AExitStm node, TypeCheckInfo question)
742:                         throws AnalysisException
743:         {
744:•                if (node.getExpression() != null)
745:                 {
746:                         node.setExpType(node.getExpression().apply(THIS, question));
747:                 }
748:
749:                 // This is unknown because the statement doesn't actually return a
750:                 // value - so if this is the only statement in a body, it is not a
751:                 // type error (should return the same type as the definition return
752:                 // type).
753:
754:                 node.setType(AstFactory.newAUnknownType(node.getLocation()));
755:                 return node.getType();
756:         }
757:
758:         @Override
759:         public PType caseAForAllStm(AForAllStm node, TypeCheckInfo question)
760:                         throws AnalysisException
761:         {
762:                 node.setType(node.getSet().apply(THIS, question));
763:                 question.assistantFactory.createPPatternAssistant(question.fromModule).typeResolve(node.getPattern(), THIS, question);
764:
765:•                if (question.assistantFactory.createPTypeAssistant().isSet(node.getType(), question.fromModule))
766:                 {
767:                         SSetType st = question.assistantFactory.createPTypeAssistant().getSet(node.getType(), question.fromModule);
768:                         List<PDefinition> defs = question.assistantFactory.createPPatternAssistant(question.fromModule).getDefinitions(node.getPattern(), st.getSetof(), NameScope.LOCAL);
769:
770:                         Environment local = new FlatCheckedEnvironment(question.assistantFactory, defs, question.env, question.scope);
771:                         PType rt = node.getStatement().apply(THIS, new TypeCheckInfo(question.assistantFactory, local, question.scope));
772:                         
773:•                        if (!(st instanceof ASet1SetType) &&!(rt instanceof AVoidType))
774:                         {
775:                                 // Add () to the return type, as we may not enter the loop at all
776:                                 rt = AstFactory.newAUnionType(node.getLocation(), rt, AstFactory.newAVoidType(node.getLocation()));
777:                         }
778:                         
779:                         local.unusedCheck();
780:                         node.setType(rt);
781:                         return rt;
782:                 } else
783:                 {
784:                         TypeCheckerErrors.report(3219, "For all statement does not contain a set type", node.getLocation(), node);
785:                         node.setType(AstFactory.newAUnknownType(node.getLocation()));
786:                         return node.getType();
787:                 }
788:         }
789:
790:         @Override
791:         public PType caseAForIndexStm(AForIndexStm node, TypeCheckInfo question)
792:                         throws AnalysisException
793:         {
794:                 PType ft = node.getFrom().apply(THIS, question);
795:                 PType tt = node.getTo().apply(THIS, question);
796:
797:•                if (!question.assistantFactory.createPTypeAssistant().isNumeric(ft, question.fromModule))
798:                 {
799:                         TypeCheckerErrors.report(3220, "From type is not numeric", node.getLocation(), node);
800:                 }
801:
802:•                if (!question.assistantFactory.createPTypeAssistant().isNumeric(tt, question.fromModule))
803:                 {
804:                         TypeCheckerErrors.report(3221, "To type is not numeric", node.getLocation(), node);
805:                 }
806:
807:•                if (node.getBy() != null)
808:                 {
809:                         PType bt = node.getBy().apply(THIS, question);
810:
811:•                        if (!question.assistantFactory.createPTypeAssistant().isNumeric(bt, question.fromModule))
812:                         {
813:                                 TypeCheckerErrors.report(3222, "By type is not numeric", node.getLocation(), node);
814:                         }
815:                 }
816:
817:                 PDefinition vardef = AstFactory.newALocalDefinition(node.getVar().getLocation(), node.getVar(), NameScope.LOCAL, ft);
818:                 Environment local = new FlatCheckedEnvironment(question.assistantFactory, vardef, question.env, question.scope);
819:                 PType rt = node.getStatement().apply(THIS, new TypeCheckInfo(question.assistantFactory, local, question.scope));
820:                 AUnionType rtu = AstFactory.newAUnionType(node.getLocation(), rt, AstFactory.newAVoidType(node.getLocation()));
821:                 local.unusedCheck();
822:                 node.setType(rtu);
823:                 return rtu;
824:         }
825:
826:         @Override
827:         public PType caseAIfStm(AIfStm node, TypeCheckInfo question)
828:                         throws AnalysisException
829:         {
830:                 node.setType(typeCheckIf(node.getLocation(), node.getIfExp(), node.getThenStm(), node.getElseIf(), node.getElseStm(), question));//rtypes.getType(node.getLocation()));
831:                 return node.getType();
832:         }
833:
834:         @Override
835:         public PType caseALetBeStStm(ALetBeStStm node, TypeCheckInfo question)
836:                         throws AnalysisException
837:         {
838:                 Entry<PType, AMultiBindListDefinition> res = typecheckLetBeSt(node, node.getLocation(), node.getBind(), node.getSuchThat(), node.getStatement(), question);
839:                 node.setDef(res.getValue());
840:                 node.setType(res.getKey());
841:                 return node.getType();
842:         }
843:
844:         @Override
845:         public PType caseANonDeterministicSimpleBlockStm(
846:                         ANonDeterministicSimpleBlockStm node, TypeCheckInfo question)
847:                         throws AnalysisException
848:         {
849:                 PDefinition encl = question.env.getEnclosingDefinition();
850:                 
851:•                if (encl != null && encl.getAccess().getPure())
852:                 {
853:                         TypeCheckerErrors.report(3346, "Cannot use non-deterministic statement in pure operations",
854:                                 node.getLocation(), node);
855:                 }
856:
857:                 PTypeSet rtypes = new PTypeSet(question.assistantFactory);
858:                 int rcount = 0;
859:
860:•                for (PStm stmt : node.getStatements())
861:                 {
862:                         PType stype = stmt.apply(THIS, question);
863:
864:•                        if (question.assistantFactory.createPTypeAssistant().isType(stype, AUnionType.class))
865:                         {
866:                                 AUnionType ust = (AUnionType) stype;
867:•                                for (PType t : ust.getTypes())
868:                                 {
869:•                                        if (addOne(rtypes, t))
870:                                         {
871:                                                 rcount++;
872:                                         }
873:                                 }
874:                         } else
875:                         {
876:•                                if (addOne(rtypes, stype))
877:                                 {
878:                                         rcount++;
879:                                 }
880:                         }
881:                 }
882:
883:•                if (rcount > 1)
884:                 {
885:                         TypeCheckerErrors.warning(5016, "Some statements will not be reached", node.getLocation(), node);
886:                 }
887:
888:•                node.setType(rtypes.isEmpty() ? AstFactory.newAVoidType(node.getLocation())
889:                                 : rtypes.getType(node.getLocation()));
890:                 return node.getType();
891:         }
892:
893:         @Override
894:         public PType caseANotYetSpecifiedStm(ANotYetSpecifiedStm node,
895:                         TypeCheckInfo question)
896:         {
897:                 node.setType(typeCheckANotYetSpecifiedExp(node,node.getLocation()));
898:                 return node.getType();
899:         }
900:
901:         @Override
902:         public PType caseAReturnStm(AReturnStm node, TypeCheckInfo question)
903:                         throws AnalysisException
904:         {
905:                 PDefinition encl = question.env.getEnclosingDefinition();
906:                 boolean inConstructor = false;
907:
908:•                if (encl instanceof AExplicitOperationDefinition)
909:                 {
910:                         AExplicitOperationDefinition op = (AExplicitOperationDefinition) encl;
911:                         inConstructor = op.getIsConstructor();
912:•                } else if (encl instanceof AImplicitOperationDefinition)
913:                 {
914:                         AImplicitOperationDefinition op = (AImplicitOperationDefinition) encl;
915:                         inConstructor = op.getIsConstructor();
916:                 }
917:
918:•                if (inConstructor && !(node.getExpression() instanceof ASelfExp))
919:                 {
920:                         TypeCheckerErrors.report(3326, "Constructor can only return 'self'", node.getLocation(), node);
921:                 }
922:
923:•                if (node.getExpression() == null)
924:                 {
925:                         node.setType(AstFactory.newAVoidReturnType(node.getLocation()));
926:                 } else
927:                 {
928:                         node.setType(node.getExpression().apply(THIS, question));
929:                 }
930:
931:                 return question.assistantFactory.createPTypeAssistant().checkReturnType(question.returnType, node.getType(), true, node.getLocation());
932:         }
933:
934:         @Override
935:         public PType caseASkipStm(ASkipStm node, TypeCheckInfo question)
936:         {
937:                 node.setType(AstFactory.newAVoidType(node.getLocation()));
938:                 return question.assistantFactory.createPTypeAssistant().checkReturnType(question.returnType, node.getType(), question.mandatory, node.getLocation());
939:         }
940:
941:         @Override
942:         public PType caseASpecificationStm(ASpecificationStm node,
943:                         TypeCheckInfo question) throws AnalysisException
944:         {
945:
946:                 List<PDefinition> defs = new LinkedList<PDefinition>();
947:
948:                 // Now we build local definitions for each of the externals, so
949:                 // that they can be added to the local environment, while the
950:                 // global state is made inaccessible.
951:
952:•                if (node.getExternals() != null)
953:                 {
954:•                        for (AExternalClause clause : node.getExternals())
955:                         {
956:•                                for (ILexNameToken name : clause.getIdentifiers())
957:                                 {
958:•                                        if (question.env.findName(name, NameScope.STATE) == null)
959:                                         {
960:                                                 TypeCheckerErrors.report(3274, "External variable is not in scope: "
961:                                                                 + name, name.getLocation(), name);
962:                                         } else
963:                                         {
964:                                                 defs.add(AstFactory.newALocalDefinition(name.getLocation(), name, NameScope.STATE, clause.getType()));
965:                                         }
966:                                 }
967:                         }
968:                 }
969:
970:•                if (node.getErrors() != null)
971:                 {
972:•                        for (AErrorCase err : node.getErrors())
973:                         {
974:                                 PType lt = err.getLeft().apply(THIS, question);
975:                                 PType rt = err.getRight().apply(THIS, question);
976:
977:•                                if (!question.assistantFactory.createPTypeAssistant().isType(lt, ABooleanBasicType.class))
978:                                 {
979:                                         TypeCheckerErrors.report(3275, "Error clause must be a boolean", err.getLeft().getLocation(), err.getLeft());
980:                                 }
981:
982:•                                if (!question.assistantFactory.createPTypeAssistant().isType(rt, ABooleanBasicType.class))
983:                                 {
984:                                         TypeCheckerErrors.report(3275, "Error clause must be a boolean", err.getRight().getLocation(), err.getRight());
985:                                 }
986:                         }
987:                 }
988:
989:                 question.assistantFactory.createPDefinitionListAssistant().typeCheck(defs, THIS, question);
990:                 Environment local = new FlatEnvironment(question.assistantFactory, defs, question.env); // NB. No
991:                 // check
992:                 // //Unused
993:
994:•                if (node.getPrecondition() != null
995:•                                && !question.assistantFactory.createPTypeAssistant().isType(node.getPrecondition().apply(THIS, new TypeCheckInfo(question.assistantFactory, local, NameScope.NAMESANDSTATE)), ABooleanBasicType.class))
996:                 {
997:                         TypeCheckerErrors.report(3233, "Precondition is not a boolean expression", node.getPrecondition().getLocation(), node.getPrecondition());
998:                 }
999:
1000:•                if (node.getPostcondition() != null
1001:•                                && !question.assistantFactory.createPTypeAssistant().isType(node.getPostcondition().apply(THIS, new TypeCheckInfo(question.assistantFactory, local, NameScope.NAMESANDANYSTATE)), ABooleanBasicType.class))
1002:                 {
1003:                         TypeCheckerErrors.report(3234, "Postcondition is not a boolean expression", node.getPostcondition().getLocation(), node.getPostcondition());
1004:                 }
1005:
1006:                 node.setType(AstFactory.newAVoidType(node.getLocation()));
1007:                 return node.getType();
1008:         }
1009:
1010:         @Override
1011:         public PType caseATrapStm(ATrapStm node, TypeCheckInfo question)
1012:                         throws AnalysisException
1013:         {
1014:                 PTypeSet rtypes = new PTypeSet(question.assistantFactory);
1015:
1016:                 PStm body = node.getBody();
1017:
1018:                 PType bt = body.apply(THIS, question);
1019:                 rtypes.add(bt);
1020:
1021:                 PTypeSet extype = exitCheck(body, question);
1022:                 PType ptype = null;
1023:
1024:•                if (extype.isEmpty())
1025:                 {
1026:                         TypeCheckerErrors.report(3241, "Body of trap statement does not throw exceptions", node.getLocation(), node);
1027:                         ptype = AstFactory.newAUnknownType(body.getLocation());
1028:                 }
1029:                 else
1030:                 {
1031:                         extype.add(AstFactory.newAUnknownType(body.getLocation()));
1032:                         ptype = extype.getType(body.getLocation());
1033:                 }
1034:
1035:                 node.setType(ptype);
1036:                 node.getPatternBind().apply(THIS, question);
1037:                 // TODO: PatternBind stuff
1038:                 List<PDefinition> defs = getDefinitions(node.getPatternBind());
1039:                 question.assistantFactory.createPDefinitionListAssistant().typeCheck(defs, THIS, question);
1040:                 Environment local = new FlatCheckedEnvironment(question.assistantFactory, defs, question.env, question.scope);
1041:                 rtypes.add(node.getWith().apply(THIS, new TypeCheckInfo(question.assistantFactory, local, question.scope, question.qualifiers)));
1042:
1043:                 node.setType(rtypes.getType(node.getLocation()));
1044:                 return node.getType();
1045:         }
1046:
1047:         @Override
1048:         public PType caseAWhileStm(AWhileStm node, TypeCheckInfo question)
1049:                         throws AnalysisException
1050:         {
1051:                 question.qualifiers = null;
1052:                 PType etype = node.getExp().apply(THIS, question);
1053:
1054:•                if (!question.assistantFactory.createPTypeAssistant().isType(etype, ABooleanBasicType.class))
1055:                 {
1056:                         TypeCheckerErrors.report(3218, "Expression is not boolean", node.getLocation(), node);
1057:                 }
1058:
1059:                 List<QualifiedDefinition> qualified = node.getExp().apply(question.assistantFactory.getQualificationVisitor(), question);
1060:
1061:•                for (QualifiedDefinition qdef : qualified)
1062:                 {
1063:                         qdef.qualifyType();
1064:                 }
1065:
1066:                 PType stype = node.getStatement().apply(THIS, question);
1067:
1068:•                for (QualifiedDefinition qdef : qualified)
1069:                 {
1070:                         qdef.resetType();
1071:                 }
1072:
1073:•                if (node.getExp() instanceof ABooleanConstExp
1074:                                 && stype instanceof AUnionType)
1075:                 {
1076:                         ABooleanConstExp boolLiteral = (ABooleanConstExp) node.getExp();
1077:
1078:•                        if (boolLiteral.getValue().getValue()) // while true do...
1079:                         {
1080:                                 List<PType> edited = new Vector<PType>();
1081:                                 AUnionType original = (AUnionType) stype;
1082:
1083:•                                for (PType t : original.getTypes())
1084:                                 {
1085:•                                        if (!(t instanceof AVoidType))
1086:                                         {
1087:                                                 edited.add(t);
1088:                                         }
1089:                                 }
1090:
1091:                                 stype = AstFactory.newAUnionType(node.getLocation(), edited);
1092:                         }
1093:                 }
1094:
1095:                 return stype;
1096:         }
1097:
1098:         @Override
1099:         public PType caseAPeriodicStm(APeriodicStm node, TypeCheckInfo question)
1100:                         throws AnalysisException
1101:         {
1102:                 List<PExp> args = node.getArgs();
1103:
1104:•                if (args.size() != 4)
1105:                 {
1106:                         TypeCheckerErrors.report(3287, "Periodic thread must have 4 argument(s)", node.getLocation(), node);
1107:                 } else
1108:                 {
1109:                         Environment newEnv = new FlatEnvironment(question.assistantFactory, question.env, true);
1110:                         TypeCheckInfo functional = question.newInfo(newEnv);
1111:
1112:•                        for (PExp arg : args)
1113:                         {
1114:                                 PType type = arg.apply(THIS, functional);
1115:
1116:•                                if (!question.assistantFactory.createPTypeAssistant().isNumeric(type, question.fromModule))
1117:                                 {
1118:                                         TypeCheckerErrors.report(3316, "Expecting number in periodic argument", arg.getLocation(), arg);
1119:                                 }
1120:                         }
1121:                 }
1122:
1123:                 ILexNameToken opname = node.getOpname();
1124:
1125:                 opname.setTypeQualifier(new LinkedList<PType>());
1126:                 opname.getLocation().hit();
1127:                 PDefinition opdef = question.env.findName(opname, NameScope.NAMES);
1128:
1129:•                if (opdef == null)
1130:                 {
1131:                         TypeCheckerErrors.report(3228, opname + " is not in scope", node.getLocation(), node);
1132:                         node.setType(AstFactory.newAUnknownType(node.getLocation()));
1133:                         return node.getType();
1134:                 }
1135:
1136:                 // Operation must be "() ==> ()"
1137:
1138:                 AOperationType expected = AstFactory.newAOperationType(node.getLocation(), new Vector<PType>(), AstFactory.newAVoidType(node.getLocation()));
1139:
1140:                 opdef = question.assistantFactory.createPDefinitionAssistant().deref(opdef);
1141:
1142:•                if (opdef instanceof AExplicitOperationDefinition)
1143:                 {
1144:                         AExplicitOperationDefinition def = (AExplicitOperationDefinition) opdef;
1145:
1146:•                        if (!question.assistantFactory.createPTypeAssistant().equals(def.getType(), expected))
1147:                         {
1148:                                 TypeCheckerErrors.report(3229, opname
1149:                                                 + " should have no parameters or return type", node.getLocation(), node);
1150:                                 TypeCheckerErrors.detail("Actual", def.getType());
1151:                         }
1152:•                        else if (def.getAccess().getPure())
1153:                         {
1154:                                 TypeCheckerErrors.report(3347, "Cannot have a pure operation as the body of a thread", node.getLocation(), node);
1155:                         }
1156:•                } else if (opdef instanceof AImplicitOperationDefinition)
1157:                 {
1158:                         AImplicitOperationDefinition def = (AImplicitOperationDefinition) opdef;
1159:
1160:•                        if (def.getBody() == null)
1161:                         {
1162:                                 TypeCheckerErrors.report(3230, opname + " is implicit", node.getLocation(), node);
1163:                         }
1164:
1165:•                        if (!question.assistantFactory.createPTypeAssistant().equals(def.getType(), expected))
1166:                         {
1167:                                 TypeCheckerErrors.report(3231, opname
1168:                                                 + " should have no parameters or return type", node.getLocation(), node);
1169:                                 TypeCheckerErrors.detail("Actual", def.getType());
1170:                         }
1171:•                        else if (def.getAccess().getPure())
1172:                         {
1173:                                 TypeCheckerErrors.report(3347, "Cannot have a pure operation as the body of a thread", node.getLocation(), node);
1174:                         }
1175:                 } else
1176:                 {
1177:                         TypeCheckerErrors.report(3232, opname + " is not an operation name", node.getLocation(), node);
1178:                 }
1179:
1180:                 node.setType(AstFactory.newAVoidType(node.getLocation()));
1181:                 return node.getType();
1182:         }
1183:
1184:         @Override
1185:         public PType caseASporadicStm(ASporadicStm node, TypeCheckInfo question)
1186:                         throws AnalysisException
1187:         {
1188:                 List<PExp> args = node.getArgs();
1189:
1190:•                if (args.size() != 3)
1191:                 {
1192:                         TypeCheckerErrors.report(3287, "Sporadic thread must have 3 arguments", node.getLocation(), node);
1193:                 } else
1194:                 {
1195:                         Environment newEnv = new FlatEnvironment(question.assistantFactory, question.env, true);
1196:                         TypeCheckInfo functional = question.newInfo(newEnv);
1197:
1198:•                        for (PExp arg : args)
1199:                         {
1200:                                 PType type = arg.apply(THIS, functional);
1201:
1202:•                                if (!question.assistantFactory.createPTypeAssistant().isNumeric(type, question.fromModule))
1203:                                 {
1204:                                         TypeCheckerErrors.report(3316, "Expecting number in sporadic argument", arg.getLocation(), node);
1205:                                 }
1206:                         }
1207:                 }
1208:
1209:                 ILexNameToken opname = node.getOpname();
1210:                 opname.setTypeQualifier(new LinkedList<PType>());
1211:                 opname.getLocation().hit();
1212:                 PDefinition opdef = question.env.findName(opname, NameScope.NAMES);
1213:
1214:•                if (opdef == null)
1215:                 {
1216:                         TypeCheckerErrors.report(3228, opname + " is not in scope", node.getLocation(), node);
1217:                         node.setType(AstFactory.newAUnknownType(node.getLocation()));
1218:                         return node.getType();
1219:                 }
1220:
1221:                 // Operation must be "() ==> ()"
1222:
1223:                 AOperationType expected = AstFactory.newAOperationType(node.getLocation(), new Vector<PType>(), AstFactory.newAVoidType(node.getLocation()));
1224:                 opdef = question.assistantFactory.createPDefinitionAssistant().deref(opdef);
1225:
1226:•                if (opdef instanceof AExplicitOperationDefinition)
1227:                 {
1228:                         AExplicitOperationDefinition def = (AExplicitOperationDefinition) opdef;
1229:
1230:•                        if (!question.assistantFactory.createPTypeAssistant().equals(def.getType(), expected))
1231:                         {
1232:                                 TypeCheckerErrors.report(3229, opname
1233:                                                 + " should have no parameters or return type", node.getLocation(), node);
1234:                                 TypeCheckerErrors.detail("Actual", def.getType());
1235:                         }
1236:•                        else if (def.getAccess().getPure())
1237:                         {
1238:                                 TypeCheckerErrors.report(3347, "Cannot have a pure operation as the body of a thread", node.getLocation(), node);
1239:                         }
1240:•                } else if (opdef instanceof AImplicitOperationDefinition)
1241:                 {
1242:                         AImplicitOperationDefinition def = (AImplicitOperationDefinition) opdef;
1243:
1244:•                        if (def.getBody() == null)
1245:                         {
1246:                                 TypeCheckerErrors.report(3230, opname + " is implicit", node.getLocation(), node);
1247:                         }
1248:
1249:•                        if (!question.assistantFactory.createPTypeAssistant().equals(def.getType(), expected))
1250:                         {
1251:                                 TypeCheckerErrors.report(3231, opname
1252:                                                 + " should have no parameters or return type", node.getLocation(), node);
1253:                                 TypeCheckerErrors.detail("Actual", def.getType());
1254:                         }
1255:•                        else if (def.getAccess().getPure())
1256:                         {
1257:                                 TypeCheckerErrors.report(3347, "Cannot have a pure operation as the body of a thread", node.getLocation(), node);
1258:                         }
1259:                 } else
1260:                 {
1261:                         TypeCheckerErrors.report(3232, opname + " is not an operation name", node.getLocation(), node);
1262:                 }
1263:
1264:                 node.setType(AstFactory.newAVoidType(node.getLocation()));
1265:                 return node.getType();
1266:         }
1267:
1268:         @Override
1269:         public PType caseAStartStm(AStartStm node, TypeCheckInfo question)
1270:                         throws AnalysisException
1271:         {
1272:                 PDefinition encl = question.env.getEnclosingDefinition();
1273:                 
1274:•                if (encl != null && encl.getAccess().getPure())
1275:                 {
1276:                         TypeCheckerErrors.report(3346, "Cannot use start in pure operations", node.getLocation(), node);
1277:                 }
1278:
1279:                 PType type = node.getObj().apply(THIS, question);
1280:
1281:•                if (question.assistantFactory.createPTypeAssistant().isSet(type, question.fromModule))
1282:                 {
1283:                         SSetType set = question.assistantFactory.createPTypeAssistant().getSet(type, question.fromModule);
1284:
1285:•                        if (!question.assistantFactory.createPTypeAssistant().isClass(set.getSetof(), null, question.fromModule))
1286:                         {
1287:                                 TypeCheckerErrors.report(3235, "Expression is not a set of object references", node.getObj().getLocation(), node.getObj());
1288:                         } else
1289:                         {
1290:                                 AClassType ctype = question.assistantFactory.createPTypeAssistant().getClassType(set.getSetof(), null, question.fromModule);
1291:
1292:•                                if (question.assistantFactory.createSClassDefinitionAssistant().findThread(ctype.getClassdef()) == null)
1293:                                 {
1294:                                         TypeCheckerErrors.report(3236, "Class does not define a thread", node.getObj().getLocation(), node.getObj());
1295:                                 }
1296:                         }
1297:•                } else if (question.assistantFactory.createPTypeAssistant().isClass(type, null, question.fromModule))
1298:                 {
1299:                         AClassType ctype = question.assistantFactory.createPTypeAssistant().getClassType(type, null, question.fromModule);
1300:
1301:•                        if (question.assistantFactory.createSClassDefinitionAssistant().findThread(ctype.getClassdef()) == null)
1302:                         {
1303:                                 TypeCheckerErrors.report(3237, "Class does not define a thread", node.getObj().getLocation(), node.getObj());
1304:                         }
1305:                 } else
1306:                 {
1307:                         TypeCheckerErrors.report(3238, "Expression is not an object reference or set of object references", node.getObj().getLocation(), node.getObj());
1308:                 }
1309:
1310:                 node.setType(AstFactory.newAVoidType(node.getLocation()));
1311:                 return question.assistantFactory.createPTypeAssistant().checkReturnType(question.returnType, node.getType(), question.mandatory, node.getLocation());
1312:         }
1313:
1314:         @Override
1315:         public PType caseAStopStm(AStopStm node, TypeCheckInfo question)
1316:                         throws AnalysisException
1317:         {
1318:                 PType type = node.getObj().apply(THIS, question);
1319:
1320:•                if (question.assistantFactory.createPTypeAssistant().isSet(type, question.fromModule))
1321:                 {
1322:                         SSetType set = question.assistantFactory.createPTypeAssistant().getSet(type, question.fromModule);
1323:
1324:•                        if (!question.assistantFactory.createPTypeAssistant().isClass(set.getSetof(), null, question.fromModule))
1325:                         {
1326:                                 TypeCheckerErrors.report(3235, "Expression is not a set of object references", node.getObj().getLocation(), node.getObj());
1327:                         } else
1328:                         {
1329:                                 AClassType ctype = question.assistantFactory.createPTypeAssistant().getClassType(set.getSetof(), null, question.fromModule);
1330:
1331:•                                if (question.assistantFactory.createSClassDefinitionAssistant().findThread(ctype.getClassdef()) == null)
1332:                                 {
1333:                                         TypeCheckerErrors.report(3236, "Class does not define a thread", node.getObj().getLocation(), node.getObj());
1334:                                 }
1335:                         }
1336:•                } else if (question.assistantFactory.createPTypeAssistant().isClass(type, null, question.fromModule))
1337:                 {
1338:                         AClassType ctype = question.assistantFactory.createPTypeAssistant().getClassType(type, null, question.fromModule);
1339:
1340:•                        if (question.assistantFactory.createSClassDefinitionAssistant().findThread(ctype.getClassdef()) == null)
1341:                         {
1342:                                 TypeCheckerErrors.report(3237, "Class does not define a thread", node.getObj().getLocation(), node.getObj());
1343:                         }
1344:                 } else
1345:                 {
1346:                         TypeCheckerErrors.report(3238, "Expression is not an object reference or set of object references", node.getObj().getLocation(), node.getObj());
1347:                 }
1348:
1349:                 node.setType(AstFactory.newAVoidType(node.getLocation()));
1350:                 return question.assistantFactory.createPTypeAssistant().checkReturnType(question.returnType, node.getType(), question.mandatory, node.getLocation());
1351:         }
1352:
1353:         @Override
1354:         public PType caseASubclassResponsibilityStm(
1355:                         ASubclassResponsibilityStm node, TypeCheckInfo question)
1356:         {
1357:                 node.setType(AstFactory.newAUnknownType(node.getLocation())); // Because
1358:                                                                                                                                                 // we
1359:                                                                                                                                                 // terminate
1360:                                                                                                                                                 // anyway
1361:                 return node.getType();
1362:         }
1363:
1364:         @Override
1365:         public PType caseATixeStm(ATixeStm node, TypeCheckInfo question)
1366:                         throws AnalysisException
1367:         {
1368:
1369:                 PType rt = node.getBody().apply(THIS, question);
1370:                 PTypeSet extypes = exitCheck(node.getBody(), question);
1371:
1372:•                if (!extypes.isEmpty())
1373:                 {
1374:                         PType union = extypes.getType(node.getLocation());
1375:
1376:•                        for (ATixeStmtAlternative tsa : node.getTraps())
1377:                         {
1378:                                 tsa.setExp(union);
1379:                                 tsa.apply(THIS, question);
1380:                         }
1381:                 }
1382:                 node.setType(rt);
1383:                 return rt;
1384:         }
1385:
1386:         @Override
1387:         public PType caseATixeStmtAlternative(ATixeStmtAlternative node,
1388:                         TypeCheckInfo question) throws AnalysisException
1389:         {
1390:                 // Make a union with "?" so that pattern always matches
1391:                 PType original = node.getExp();
1392:                 node.setExp(AstFactory.newAUnionType(node.getExp().getLocation(), node.getExp(), AstFactory.newAUnknownType(node.getExp().getLocation())));
1393:                 node.getPatternBind().apply(THIS, new TypeCheckInfo(question.assistantFactory, question.env, question.scope));
1394:                 List<PDefinition> defs = getDefinitions(node.getPatternBind());
1395:                 node.setExp(original);
1396:
1397:                 question.assistantFactory.createPDefinitionListAssistant().typeCheck(defs, THIS, question);
1398:                 Environment local = new FlatCheckedEnvironment(question.assistantFactory, defs, question.env, question.scope);
1399:                 node.getStatement().apply(THIS, new TypeCheckInfo(question.assistantFactory, local, question.scope, question.qualifiers));
1400:                 local.unusedCheck();
1401:
1402:                 return null;
1403:         }
1404:
1405:         @Override
1406:         public PType caseADefPatternBind(ADefPatternBind node,
1407:                         TypeCheckInfo question) throws AnalysisException
1408:         {
1409:
1410:                 node.setDefs(null);
1411:
1412:                 PBind bind = node.getBind();
1413:                 PType type = node.getType();
1414:
1415:•                if (bind != null)
1416:                 {
1417:•                        if (bind instanceof ATypeBind)
1418:                         {
1419:                                 ATypeBind typebind = (ATypeBind) bind;
1420:                                 question.assistantFactory.createATypeBindAssistant().typeResolve(typebind, THIS, question);
1421:
1422:•                                if (!question.assistantFactory.getTypeComparator().compatible(typebind.getType(), type))
1423:                                 {
1424:                                         TypeCheckerErrors.report(3198, "Type bind not compatible with expression", bind.getLocation(), bind);
1425:                                         TypeCheckerErrors.detail2("Bind", typebind.getType(), "Exp", type);
1426:                                 }
1427:                         } else
1428:                         {
1429:                                 ASetBind setbind = (ASetBind) bind;
1430:                                 SSetType settype = question.assistantFactory.createPTypeAssistant().getSet(setbind.getSet().apply(THIS, question), question.fromModule);
1431:
1432:•                                if (!question.assistantFactory.getTypeComparator().compatible(type, settype.getSetof()))
1433:                                 {
1434:                                         TypeCheckerErrors.report(3199, "Set bind not compatible with expression", bind.getLocation(), bind);
1435:                                         TypeCheckerErrors.detail2("Bind", settype.getSetof(), "Exp", type);
1436:                                 }
1437:                         }
1438:
1439:                         PDefinition def = AstFactory.newAMultiBindListDefinition(bind.getLocation(), question.assistantFactory.createPBindAssistant().getMultipleBindList(bind));
1440:
1441:                         def.apply(THIS, question);
1442:                         List<PDefinition> defs = new LinkedList<PDefinition>();
1443:                         defs.add(def);
1444:                         node.setDefs(defs);
1445:                 } else
1446:                 {
1447:•                        assert type != null : "Can't typecheck a pattern without a type";
1448:
1449:                         question.assistantFactory.createPPatternAssistant(question.fromModule).typeResolve(node.getPattern(), THIS, question);
1450:                         node.setDefs(question.assistantFactory.createPPatternAssistant(question.fromModule).getDefinitions(node.getPattern(), type, NameScope.LOCAL));
1451:                 }
1452:                 return null;
1453:         }
1454:         
1455:         public List<PDefinition> getDefinitions(ADefPatternBind patternBind)
1456:         {
1457:•                assert patternBind.getDefs() != null : "PatternBind must be type checked before getDefinitions";
1458:
1459:                 return patternBind.getDefs();
1460:         }
1461:         
1462:         public PTypeSet exitCheck(PStm statement, TypeCheckInfo question)
1463:         {
1464:                 try
1465:                 {
1466:                         return statement.apply(question.assistantFactory.getExitTypeCollector(), question.env);
1467:                 } catch (AnalysisException e)
1468:                 {
1469:                         return new PTypeSet(question.assistantFactory);
1470:                 }
1471:
1472:         }
1473:         
1474:         public List<PType> getArgTypes(List<PExp> args,
1475:                         IQuestionAnswer<TypeCheckInfo, PType> rootVisitor,
1476:                         TypeCheckInfo question) throws AnalysisException
1477:         {
1478:                 List<PType> types = new LinkedList<PType>();
1479:
1480:•                for (PExp e : args)
1481:                 {
1482:                         types.add(e.apply(rootVisitor, question));
1483:                 }
1484:
1485:                 return types;
1486:         }
1487:
1488:         public void checkArgTypes(PType type, List<PType> ptypes, List<PType> atypes, TypeCheckInfo question)
1489:         {
1490:•                if (ptypes.size() != atypes.size())
1491:                 {
1492:                         TypeCheckerErrors.report(3211, "Expecting " + ptypes.size()
1493:                                         + " arguments", type.getLocation(), type);
1494:                 } else
1495:                 {
1496:                         int i = 0;
1497:
1498:•                        for (PType atype : atypes)
1499:                         {
1500:                                 PType ptype = ptypes.get(i++);
1501:
1502:•                                if (!question.assistantFactory.getTypeComparator().compatible(ptype, atype))
1503:                                 {
1504:                                         TypeCheckerErrors.report(3212, "Unexpected type for argument "
1505:                                                         + i, atype.getLocation(), atype);
1506:                                         TypeCheckerErrors.detail2("Expected", ptype, "Actual", atype);
1507:                                 }
1508:                         }
1509:                 }
1510:         }
1511:         
1512:         public boolean addOne(PTypeSet rtypes, PType add)
1513:         {
1514:•                if (add instanceof AVoidReturnType)
1515:                 {
1516:                         rtypes.add(AstFactory.newAVoidType(add.getLocation()));
1517:                         return true;
1518:•                } else if (!(add instanceof AVoidType))
1519:                 {
1520:                         rtypes.add(add);
1521:                         return true;
1522:                 } else
1523:                 {
1524:                         rtypes.add(add);
1525:                         return false;
1526:                 }
1527:         }
1528:         
1529:         public void addOneType(Set<PType> rtypes, PType add)
1530:         {
1531:•                if (add instanceof AVoidReturnType)
1532:                 {
1533:                         rtypes.add(AstFactory.newAVoidType(add.getLocation()));
1534:•                } else if (!(add instanceof AVoidType))
1535:                 {
1536:                         rtypes.add(add);
1537:                 }
1538:         }
1539:         
1540:         public PDefinition targetDefinition(PStateDesignator pStateDesignator,
1541:                         TypeCheckInfo question)
1542:         {
1543:•                if (pStateDesignator instanceof AIdentifierStateDesignator)
1544:                 {
1545:                         AIdentifierStateDesignator stateDesignator = (AIdentifierStateDesignator) pStateDesignator;
1546:                         return question.env.findName(stateDesignator.getName(), NameScope.STATE);
1547:                 } else
1548:                 {
1549:                         return null;
1550:                 }
1551:
1552:         }
1553:         
1554:         public void checkArgTypes(ACallStm node, PType type, List<PType> ptypes,
1555:                         List<PType> atypes, TypeCheckInfo question) {
1556:•                if (ptypes.size() != atypes.size()) {
1557:                         TypeCheckerErrors.report(3216, "Expecting " + ptypes.size()
1558:                                         + " arguments", node.getLocation(), node);
1559:                 } else {
1560:                         int i = 0;
1561:
1562:•                        for (PType atype : atypes) {
1563:                                 PType ptype = ptypes.get(i++);
1564:
1565:•                                if (!question.assistantFactory.getTypeComparator().compatible(ptype, atype)) {
1566:                                         TypeCheckerErrors.report(3217,
1567:                                                         "Unexpected type for argument " + i,
1568:                                                         node.getLocation(), type);
1569:                                         TypeCheckerErrors.detail2("Expected", ptype, "Actual",
1570:                                                         atype);
1571:                                 }
1572:                         }
1573:                 }
1574:         }
1575:
1576: }