Package: TypeCheckerOthersVisitor

TypeCheckerOthersVisitor

nameinstructionbranchcomplexitylinemethod
TypeCheckerOthersVisitor(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%
caseAApplyObjectDesignator(AApplyObjectDesignator, TypeCheckInfo)
M: 52 C: 184
78%
M: 3 C: 11
79%
M: 3 C: 5
63%
M: 6 C: 20
77%
M: 0 C: 1
100%
caseADefPatternBind(ADefPatternBind, TypeCheckInfo)
M: 101 C: 188
65%
M: 12 C: 16
57%
M: 10 C: 5
33%
M: 13 C: 34
72%
M: 0 C: 1
100%
caseAFieldObjectDesignator(AFieldObjectDesignator, TypeCheckInfo)
M: 66 C: 180
73%
M: 5 C: 13
72%
M: 5 C: 5
50%
M: 9 C: 26
74%
M: 0 C: 1
100%
caseAFieldStateDesignator(AFieldStateDesignator, TypeCheckInfo)
M: 66 C: 159
71%
M: 3 C: 11
79%
M: 3 C: 5
63%
M: 10 C: 23
70%
M: 0 C: 1
100%
caseAIdentifierObjectDesignator(AIdentifierObjectDesignator, TypeCheckInfo)
M: 0 C: 17
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
caseAIdentifierStateDesignator(AIdentifierStateDesignator, TypeCheckInfo)
M: 115 C: 274
70%
M: 14 C: 32
70%
M: 11 C: 13
54%
M: 22 C: 54
71%
M: 0 C: 1
100%
caseAMapSeqStateDesignator(AMapSeqStateDesignator, TypeCheckInfo)
M: 62 C: 126
67%
M: 5 C: 9
64%
M: 5 C: 3
38%
M: 11 C: 16
59%
M: 0 C: 1
100%
caseANewObjectDesignator(ANewObjectDesignator, TypeCheckInfo)
M: 0 C: 17
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
caseASelfObjectDesignator(ASelfObjectDesignator, TypeCheckInfo)
M: 13 C: 15
54%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 2 C: 3
60%
M: 0 C: 1
100%
functionApply(AApplyObjectDesignator, AFunctionType, Environment, NameScope, boolean, IQuestionAnswer)
M: 111 C: 0
0%
M: 8 C: 0
0%
M: 5 C: 0
0%
M: 19 C: 0
0%
M: 1 C: 0
0%
mapApply(AApplyObjectDesignator, SMapType, Environment, NameScope, boolean, IQuestionAnswer)
M: 25 C: 32
56%
M: 2 C: 2
50%
M: 2 C: 1
33%
M: 4 C: 4
50%
M: 0 C: 1
100%
operationApply(AApplyObjectDesignator, AOperationType, Environment, NameScope, boolean, IQuestionAnswer)
M: 54 C: 57
51%
M: 3 C: 5
63%
M: 3 C: 2
40%
M: 9 C: 10
53%
M: 0 C: 1
100%
seqApply(AApplyObjectDesignator, SSeqType, Environment, NameScope, boolean, IQuestionAnswer, TypeCheckInfo)
M: 22 C: 32
59%
M: 2 C: 2
50%
M: 2 C: 1
33%
M: 4 C: 4
50%
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%

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.LinkedList;
25: import java.util.Set;
26:
27: import org.overture.ast.analysis.AnalysisException;
28: import org.overture.ast.analysis.intf.IQuestionAnswer;
29: import org.overture.ast.definitions.AAssignmentDefinition;
30: import org.overture.ast.definitions.AExternalDefinition;
31: import org.overture.ast.definitions.PDefinition;
32: import org.overture.ast.expressions.PExp;
33: import org.overture.ast.factory.AstFactory;
34: import org.overture.ast.intf.lex.ILexIdentifierToken;
35: import org.overture.ast.intf.lex.ILexNameToken;
36: import org.overture.ast.lex.LexNameToken;
37: import org.overture.ast.node.Node;
38: import org.overture.ast.patterns.ADefPatternBind;
39: import org.overture.ast.patterns.ASeqBind;
40: import org.overture.ast.patterns.ASetBind;
41: import org.overture.ast.patterns.ATypeBind;
42: import org.overture.ast.statements.AApplyObjectDesignator;
43: import org.overture.ast.statements.AFieldObjectDesignator;
44: import org.overture.ast.statements.AFieldStateDesignator;
45: import org.overture.ast.statements.AForPatternBindStm;
46: import org.overture.ast.statements.AIdentifierObjectDesignator;
47: import org.overture.ast.statements.AIdentifierStateDesignator;
48: import org.overture.ast.statements.AMapSeqStateDesignator;
49: import org.overture.ast.statements.ANewObjectDesignator;
50: import org.overture.ast.statements.ASelfObjectDesignator;
51: import org.overture.ast.statements.ATixeStmtAlternative;
52: import org.overture.ast.statements.ATrapStm;
53: import org.overture.ast.typechecker.NameScope;
54: import org.overture.ast.types.AClassType;
55: import org.overture.ast.types.AFieldField;
56: import org.overture.ast.types.AFunctionType;
57: import org.overture.ast.types.AOperationType;
58: import org.overture.ast.types.ARecordInvariantType;
59: import org.overture.ast.types.SSetType;
60: import org.overture.ast.types.PType;
61: import org.overture.ast.types.SMapType;
62: import org.overture.ast.types.SSeqType;
63: import org.overture.ast.util.PTypeSet;
64: import org.overture.typechecker.Environment;
65: import org.overture.typechecker.TypeCheckInfo;
66: import org.overture.typechecker.TypeCheckerErrors;
67:
68:•public class TypeCheckerOthersVisitor extends AbstractTypeCheckVisitor
69: {
70:
71:         public TypeCheckerOthersVisitor(
72:                         IQuestionAnswer<TypeCheckInfo, PType> typeCheckVisitor)
73:         {
74:                 super(typeCheckVisitor);
75:         }
76:
77:         @Override
78:         public PType caseADefPatternBind(ADefPatternBind node,
79:                         TypeCheckInfo question) throws AnalysisException
80:         {
81:                 node.setDefs(null);
82:
83:                 PType type = null;
84:
85:                 Node parent = node.getAncestor(AForPatternBindStm.class);
86:•                if (parent != null)
87:                 {
88:                         type = ((AForPatternBindStm) parent).getSeqType().getSeqof();
89:•                } else if ((parent = node.getAncestor(ATrapStm.class)) != null)
90:                 {
91:                         type = ((ATrapStm) parent).getType();
92:•                } else if ((parent = node.getAncestor(ATixeStmtAlternative.class)) != null)
93:                 {
94:                         type = ((ATixeStmtAlternative) parent).getExp();
95:                 }
96:
97:•                if (node.getBind() != null)
98:                 {
99:•                        if (node.getBind() instanceof ATypeBind)
100:                         {
101:                                 ATypeBind typebind = (ATypeBind) node.getBind();
102:                                 typebind.setType(question.assistantFactory.createPTypeAssistant().typeResolve(typebind.getType(), null, THIS, question));
103:
104:                                 // resolve pattern such that it is resolved before it is cloned later in newAMultiBindListDefinition
105:•                                if (node.getBind().getPattern() != null)
106:                                 {
107:                                         question.assistantFactory.createPPatternAssistant(question.fromModule).typeResolve(node.getBind().getPattern(), THIS, question);
108:                                 }
109:
110:•                                if (!question.assistantFactory.getTypeComparator().compatible(typebind.getType(), type))
111:                                 {
112:                                         TypeCheckerErrors.report(3198, "Type bind not compatible with expression", node.getBind().getLocation(), node.getBind());
113:                                         TypeCheckerErrors.detail2("Bind", typebind.getType(), "Exp", type);
114:                                 }
115:                         }
116:•                        else if (node.getBind() instanceof ASetBind)
117:                         {
118:                                 ASetBind setbind = (ASetBind) node.getBind();
119:                                 PType bindtype = setbind.getSet().apply(THIS, question);
120:                                 
121:•                                if (!question.assistantFactory.createPTypeAssistant().isSet(bindtype, question.fromModule))
122:                                 {
123:                                         TypeCheckerErrors.report(3199, "Set bind not compatible with expression", node.getBind().getLocation(), node.getBind());
124:                                 }
125:                                 else
126:                                 {
127:                                 SSetType settype = question.assistantFactory.createPTypeAssistant().getSet(bindtype, question.fromModule);
128:                                 
129:•                                 if (!question.assistantFactory.getTypeComparator().compatible(type, settype.getSetof()))
130:                                 {
131:                                         TypeCheckerErrors.report(3199, "Set bind not compatible with expression", node.getBind().getLocation(), node.getBind());
132:                                         TypeCheckerErrors.detail2("Bind", settype.getSetof(), "Exp", type);
133:                                 }
134:                                 }
135:                         }
136:                         else
137:                         {
138:                                 ASeqBind seqbind = (ASeqBind) node.getBind();
139:                                 PType bindtype = seqbind.getSeq().apply(THIS, question);
140:                                 
141:•                                if (!question.assistantFactory.createPTypeAssistant().isSeq(bindtype, question.fromModule))
142:                                 {
143:                                         TypeCheckerErrors.report(3199, "Seq bind not compatible with expression", node.getBind().getLocation(), node.getBind());
144:                                 }
145:                                 else
146:                                 {
147:                                 SSeqType seqtype = question.assistantFactory.createPTypeAssistant().getSeq(bindtype, question.fromModule);
148:                                 
149:•                                 if (!question.assistantFactory.getTypeComparator().compatible(type, seqtype.getSeqof()))
150:                                 {
151:                                         TypeCheckerErrors.report(3199, "Seq bind not compatible with expression", node.getBind().getLocation(), node.getBind());
152:                                         TypeCheckerErrors.detail2("Bind", seqtype.getSeqof(), "Exp", type);
153:                                 }
154:                                 }
155:                         }
156:
157:                         PDefinition def = AstFactory.newAMultiBindListDefinition(node.getBind().getLocation(), question.assistantFactory.createPBindAssistant().getMultipleBindList(node.getBind()));
158:
159:                         def.apply(THIS, question);
160:                         LinkedList<PDefinition> defs = new LinkedList<PDefinition>();
161:                         defs.add(def);
162:                         node.setDefs(defs);
163:                 } else
164:                 {
165:•                        assert type != null : "Can't typecheck a pattern without a type";
166:
167:                         question.assistantFactory.createPPatternAssistant(question.fromModule).typeResolve(node.getPattern(), THIS, question);
168:                         node.setDefs(question.assistantFactory.createPPatternAssistant(question.fromModule).getDefinitions(node.getPattern(), type, NameScope.LOCAL));
169:                 }
170:
171:                 return null;
172:         }
173:
174:         @Override
175:         public PType caseAFieldStateDesignator(AFieldStateDesignator node,
176:                         TypeCheckInfo question) throws AnalysisException
177:         {
178:
179:                 PType type = node.getObject().apply(THIS, question);
180:                 PTypeSet result = new PTypeSet(question.assistantFactory);
181:•                boolean unique = !question.assistantFactory.createPTypeAssistant().isUnion(type, question.fromModule);
182:                 ILexIdentifierToken field = node.getField();
183:
184:•                if (question.assistantFactory.createPTypeAssistant().isRecord(type, question.fromModule))
185:                 {
186:
187:                         ARecordInvariantType rec = question.assistantFactory.createPTypeAssistant().getRecord(type, question.fromModule);
188:                         AFieldField rf = question.assistantFactory.createARecordInvariantTypeAssistant().findField(rec, field.getName());
189:
190:•                        if (rf == null)
191:                         {
192:                                 TypeCheckerErrors.concern(unique, 3246, "Unknown field name, '"
193:                                                 + field + "'", node.getLocation(), field);
194:                                 result.add(AstFactory.newAUnknownType(field.getLocation()));
195:                         } else
196:                         {
197:                                 result.add(rf.getType());
198:                         }
199:                 }
200:
201:•                if (question.assistantFactory.createPTypeAssistant().isClass(type, question.env, question.fromModule))
202:                 {
203:                         AClassType ctype = question.assistantFactory.createPTypeAssistant().getClassType(type, question.env, question.fromModule);
204:                         String cname = ctype.getName().getName();
205:
206:                         node.setObjectfield(new LexNameToken(cname, field.getName(), node.getObject().getLocation()));
207:                         PDefinition fdef = question.assistantFactory.createPDefinitionAssistant().findName(ctype.getClassdef(), node.getObjectfield(), NameScope.STATE);
208:                         // SClassDefinitionAssistantTC.findName(ctype.getClassdef(), node.getObjectfield(), NameScope.STATE);
209:
210:•                        if (fdef == null)
211:                         {
212:                                 TypeCheckerErrors.concern(unique, 3260, "Unknown class field name, '"
213:                                                 + field + "'", field.getLocation(), field);
214:                                 result.add(AstFactory.newAUnknownType(node.getLocation()));
215:
216:•                        } else if (question.assistantFactory.createSClassDefinitionAssistant().isAccessible(question.env, fdef, false))
217:                         {
218:
219:                                 result.add(fdef.getType());
220:
221:                         } else
222:                         {
223:
224:                                 TypeCheckerErrors.concern(unique, 3092, "Inaccessible member "
225:                                                 + field.getName() + " of class " + cname, field.getLocation(), field);
226:                                 result.add(AstFactory.newAUnknownType(node.getLocation()));
227:                         }
228:                 }
229:
230:•                if (result.isEmpty())
231:                 {
232:                         TypeCheckerErrors.report(3245, "Field assignment is not of a record or object type", node.getLocation(), node);
233:                         TypeCheckerErrors.detail2("Expression", node.getObject(), "Type", type);
234:                         node.setType(AstFactory.newAUnknownType(field.getLocation()));
235:                         return node.getType();
236:                 }
237:
238:                 node.setType(result.getType(node.getLocation()));
239:                 return node.getType();
240:         }
241:
242:         @Override
243:         public PType caseAIdentifierStateDesignator(
244:                         AIdentifierStateDesignator node, TypeCheckInfo question)
245:         {
246:                 Environment env = question.env;
247:                 PDefinition encl = env.getEnclosingDefinition();
248:
249:•                if (env.isVDMPP())
250:                 {
251:                         // We generate an explicit name because accessing a variable
252:                         // by name in VDM++ does not "inherit" values from a superclass.
253:
254:                         ILexNameToken name = node.getName();
255:                         ILexNameToken exname = name.getExplicit(true);
256:                         PDefinition def = env.findName(exname, NameScope.STATE);
257:
258:•                        if (def == null)
259:                         {
260:
261:                                 Set<PDefinition> matches = env.findMatches(exname);
262:
263:•                                if (!matches.isEmpty())
264:                                 {
265:                                         PDefinition match = matches.iterator().next(); // Just take first
266:
267:•                                        if (question.assistantFactory.createPDefinitionAssistant().isFunction(match))
268:                                         {
269:                                                 TypeCheckerErrors.report(3247, "Function apply not allowed in state designator", name.getLocation(), name);
270:                                         } else
271:                                         {
272:                                                 TypeCheckerErrors.report(3247, "Operation call not allowed in state designator", name.getLocation(), name);
273:                                         }
274:
275:                                         node.setType(match.getType());
276:                                         return node.getType();
277:                                 } else
278:                                 {
279:                                         TypeCheckerErrors.report(3247, "Symbol '" + name
280:                                                         + "' is not an updatable variable", name.getLocation(), name);
281:                                 }
282:
283:                                 node.setType(AstFactory.newAUnknownType(name.getLocation()));
284:                                 return node.getType();
285:•                        } else if (!question.assistantFactory.createPDefinitionAssistant().isUpdatable(def))
286:                         {
287:                                 TypeCheckerErrors.report(3301, "Variable '" + name
288:                                                 + "' in scope is not updatable", name.getLocation(), name);
289:                                 node.setType(AstFactory.newAUnknownType(name.getLocation()));
290:                                 return node.getType();
291:•                        } else if (encl != null &&
292:•                                encl.getAccess().getPure() &&
293:•                                question.assistantFactory.createPDefinitionAssistant().isInstanceVariable(def))
294:                         {
295:                                         TypeCheckerErrors.report(3338, "Cannot update state in a pure operation", name.getLocation(), name);
296:                         }
297:•                        else if (def.getClassDefinition() != null)
298:                         {
299:•                                if (!question.assistantFactory.createSClassDefinitionAssistant().isAccessible(env, def, true))
300:                                 {
301:                                         TypeCheckerErrors.report(3180, "Inaccessible member '"
302:                                                         + name + "' of class "
303:                                                         + def.getClassDefinition().getName().getName(), name.getLocation(), name);
304:                                         node.setType(AstFactory.newAUnknownType(name.getLocation()));
305:                                         return node.getType();
306:•                                } else if (!question.assistantFactory.createPDefinitionAssistant().isStatic(def)
307:•                                                && env.isStatic())
308:                                 {
309:                                         TypeCheckerErrors.report(3181, "Cannot access " + name
310:                                                         + " from a static context", name.getLocation(), name);
311:                                         node.setType(AstFactory.newAUnknownType(name.getLocation()));
312:                                         return node.getType();
313:                                 }
314:•                        } else if (def instanceof AExternalDefinition)
315:                         {
316:                                 AExternalDefinition d = (AExternalDefinition) def;
317:
318:•                                if (d.getReadOnly())
319:                                 {
320:                                         TypeCheckerErrors.report(3248, "Cannot assign to 'ext rd' state "
321:                                                         + name, name.getLocation(), name);
322:                                 }
323:                         }
324:                         // else just state access in (say) an explicit operation
325:
326:                         node.setType(question.assistantFactory.createPDefinitionAssistant().getType(def));
327:                         return node.getType();
328:                 } else
329:                 {
330:                         ILexNameToken name = node.getName();
331:                         PDefinition def = env.findName(name, NameScope.STATE);
332:
333:•                        if (def == null)
334:                         {
335:                                 TypeCheckerErrors.report(3247, "Unknown state variable '"
336:                                                 + name + "' in assignment", name.getLocation(), name);
337:                                 node.setType(AstFactory.newAUnknownType(name.getLocation()));
338:                                 return node.getType();
339:•                        } else if (question.assistantFactory.createPDefinitionAssistant().isFunction(def))
340:                         {
341:                                 TypeCheckerErrors.report(3247, "Function apply not allowed in state designator", name.getLocation(), name);
342:                                 node.setType(AstFactory.newAUnknownType(name.getLocation()));
343:                                 return node.getType();
344:•                        } else if (question.assistantFactory.createPDefinitionAssistant().isOperation(def))
345:                         {
346:                                 TypeCheckerErrors.report(3247, "Operation call not allowed in state designator", name.getLocation(), name);
347:                                 node.setType(AstFactory.newAUnknownType(name.getLocation()));
348:                                 return node.getType();
349:•                        } else if (!question.assistantFactory.createPDefinitionAssistant().isUpdatable(def))
350:                         {
351:                                 TypeCheckerErrors.report(3301, "Variable '" + name
352:                                                 + "' in scope is not updatable", name.getLocation(), name);
353:                                 node.setType(AstFactory.newAUnknownType(name.getLocation()));
354:                                 return node.getType();
355:                         }
356:•                        else if (encl != null && encl.getAccess().getPure() && !(def instanceof AAssignmentDefinition))
357:                         {
358:                                 TypeCheckerErrors.report(3338, "Cannot update state in a pure operation", name.getLocation(), name);
359:                         }
360:•                        else if (def instanceof AExternalDefinition)
361:                         {
362:                                 AExternalDefinition d = (AExternalDefinition) def;
363:
364:•                                if (d.getReadOnly())
365:                                 {
366:                                         TypeCheckerErrors.report(3248, "Cannot assign to 'ext rd' state "
367:                                                         + name, name.getLocation(), name);
368:                                 }
369:                         }
370:                         // else just state access in (say) an explicit operation
371:
372:                         node.setType(question.assistantFactory.createPDefinitionAssistant().getType(def));
373:                         return node.getType();
374:                 }
375:         }
376:
377:         @Override
378:         public PType caseAMapSeqStateDesignator(AMapSeqStateDesignator node,
379:                         TypeCheckInfo question) throws AnalysisException
380:         {
381:                 PType etype = node.getExp().apply(THIS, new TypeCheckInfo(question.assistantFactory, question.env, NameScope.NAMESANDSTATE));
382:                 PType rtype = node.getMapseq().apply(THIS, new TypeCheckInfo(question.assistantFactory, question.env));
383:                 PTypeSet result = new PTypeSet(question.assistantFactory);
384:
385:•                if (question.assistantFactory.createPTypeAssistant().isMap(rtype, question.fromModule))
386:                 {
387:                         node.setMapType(question.assistantFactory.createPTypeAssistant().getMap(rtype, question.fromModule));
388:
389:•                        if (!question.assistantFactory.getTypeComparator().compatible(node.getMapType().getFrom(), etype))
390:                         {
391:                                 TypeCheckerErrors.report(3242, "Map element assignment of wrong type", node.getLocation(), node);
392:                                 TypeCheckerErrors.detail2("Expect", node.getMapType().getFrom(), "Actual", etype);
393:                         } else
394:                         {
395:                                 result.add(node.getMapType().getTo());
396:                         }
397:                 }
398:
399:•                if (question.assistantFactory.createPTypeAssistant().isSeq(rtype, question.fromModule))
400:                 {
401:                         node.setSeqType(question.assistantFactory.createPTypeAssistant().getSeq(rtype, question.fromModule));
402:
403:•                        if (!question.assistantFactory.createPTypeAssistant().isNumeric(etype, question.fromModule))
404:                         {
405:                                 TypeCheckerErrors.report(3243, "Seq index is not numeric", node.getLocation(), node);
406:                                 TypeCheckerErrors.detail("Actual", etype);
407:                         } else
408:                         {
409:                                 result.add(node.getSeqType().getSeqof());
410:                         }
411:                 }
412:
413:•                if (question.assistantFactory.createPTypeAssistant().isFunction(rtype, question.fromModule))
414:                 {
415:                         // Error case, but improves errors if we work out the return type
416:                         AFunctionType ftype = question.assistantFactory.createPTypeAssistant().getFunction(rtype);
417:                         result.add(ftype.getResult());
418:                 }
419:
420:•                if (question.assistantFactory.createPTypeAssistant().isOperation(rtype, question.fromModule))
421:                 {
422:                         // Error case, but improves errors if we work out the return type
423:                         AOperationType otype = question.assistantFactory.createPTypeAssistant().getOperation(rtype, question.fromModule);
424:                         result.add(otype.getResult());
425:                 }
426:
427:•                if (result.isEmpty())
428:                 {
429:                         TypeCheckerErrors.report(3244, "Expecting a map or a sequence", node.getLocation(), node);
430:                         node.setType(AstFactory.newAUnknownType(node.getLocation()));
431:                         return node.getType();
432:                 }
433:
434:                 node.setType(result.getType(node.getLocation()));
435:                 return node.getType();
436:         }
437:
438:         @Override
439:         public PType caseASelfObjectDesignator(ASelfObjectDesignator node,
440:                         TypeCheckInfo question)
441:         {
442:                 PDefinition def = question.env.findName(node.getSelf(), NameScope.NAMES);
443:
444:•                if (def == null)
445:                 {
446:                         TypeCheckerErrors.report(3263, "Cannot reference 'self' from here", node.getSelf().getLocation(), node.getSelf());
447:                         return AstFactory.newAUnknownType(node.getSelf().getLocation());
448:                 }
449:
450:                 return question.assistantFactory.createPDefinitionAssistant().getType(def);
451:         }
452:
453:         @Override
454:         public PType caseAApplyObjectDesignator(AApplyObjectDesignator node,
455:                         TypeCheckInfo question) throws AnalysisException
456:         {
457:                 LinkedList<PType> argtypes = new LinkedList<PType>();
458:
459:•                for (PExp a : node.getArgs())
460:                 {
461:                         argtypes.add(a.apply(THIS, new TypeCheckInfo(question.assistantFactory, question.env, NameScope.NAMESANDSTATE)));
462:                 }
463:
464:                 PType type = node.getObject().apply(THIS, new TypeCheckInfo(question.assistantFactory, question.env, null, argtypes));
465:•                boolean unique = !question.assistantFactory.createPTypeAssistant().isUnion(type, question.fromModule);
466:                 PTypeSet result = new PTypeSet(question.assistantFactory);
467:
468:•                if (question.assistantFactory.createPTypeAssistant().isMap(type, question.fromModule))
469:                 {
470:                         SMapType map = question.assistantFactory.createPTypeAssistant().getMap(type, question.fromModule);
471:                         result.add(mapApply(node, map, question.env, NameScope.NAMESANDSTATE, unique, THIS));
472:                 }
473:
474:•                if (question.assistantFactory.createPTypeAssistant().isSeq(type, question.fromModule))
475:                 {
476:                         SSeqType seq = question.assistantFactory.createPTypeAssistant().getSeq(type, question.fromModule);
477:                         result.add(seqApply(node, seq, question.env, NameScope.NAMESANDSTATE, unique, THIS, question));
478:                 }
479:
480:•                if (question.assistantFactory.createPTypeAssistant().isFunction(type, question.fromModule))
481:                 {
482:                         AFunctionType ft = question.assistantFactory.createPTypeAssistant().getFunction(type);
483:                         question.assistantFactory.createPTypeAssistant().typeResolve(ft, null, THIS, new TypeCheckInfo(question.assistantFactory, question.env));
484:                         result.add(functionApply(node, ft, question.env, NameScope.NAMESANDSTATE, unique, THIS));
485:                 }
486:
487:•                if (question.assistantFactory.createPTypeAssistant().isOperation(type, question.fromModule))
488:                 {
489:                         AOperationType ot = question.assistantFactory.createPTypeAssistant().getOperation(type, question.fromModule);
490:                         question.assistantFactory.createPTypeAssistant().typeResolve(ot, null, THIS, new TypeCheckInfo(question.assistantFactory, question.env));
491:                         result.add(operationApply(node, ot, question.env, NameScope.NAMESANDSTATE, unique, THIS));
492:                 }
493:
494:•                if (result.isEmpty())
495:                 {
496:                         TypeCheckerErrors.report(3249, "Object designator is not a map, sequence, function or operation", node.getLocation(), node);
497:                         TypeCheckerErrors.detail2("Designator", node.getObject(), "Type", type);
498:                         return AstFactory.newAUnknownType(node.getLocation());
499:                 }
500:
501:                 return result.getType(node.getLocation());
502:         }
503:
504:         @Override
505:         public PType caseANewObjectDesignator(ANewObjectDesignator node,
506:                         TypeCheckInfo question) throws AnalysisException
507:         {
508:                 return node.getExpression().apply(THIS, new TypeCheckInfo(question.assistantFactory, question.env, NameScope.NAMESANDSTATE, question.qualifiers));
509:         }
510:
511:         @Override
512:         public PType caseAIdentifierObjectDesignator(
513:                         AIdentifierObjectDesignator node, TypeCheckInfo question)
514:                         throws AnalysisException
515:         {
516:                 return node.getExpression().apply(THIS, new TypeCheckInfo(question.assistantFactory, question.env, NameScope.NAMESANDSTATE, question.qualifiers));
517:         }
518:
519:         @Override
520:         public PType caseAFieldObjectDesignator(AFieldObjectDesignator node,
521:                         TypeCheckInfo question) throws AnalysisException
522:         {
523:
524:                 PType type = node.getObject().apply(THIS, new TypeCheckInfo(question.assistantFactory, question.env, null, question.qualifiers));
525:                 PTypeSet result = new PTypeSet(question.assistantFactory);
526:•                boolean unique = !question.assistantFactory.createPTypeAssistant().isUnion(type, question.fromModule);
527:
528:•                if (question.assistantFactory.createPTypeAssistant().isClass(type, question.env, question.fromModule))
529:                 {
530:                         AClassType ctype = question.assistantFactory.createPTypeAssistant().getClassType(type, question.env, question.fromModule);
531:
532:•                        if (node.getClassName() == null)
533:                         {
534:                                 node.setField(new LexNameToken(ctype.getName().getName(), node.getFieldName().getName(), node.getFieldName().getLocation()));
535:                         } else
536:                         {
537:                                 node.setField(node.getClassName());
538:                         }
539:
540:                         ILexNameToken field = node.getField();
541:                         field.setTypeQualifier(question.qualifiers);
542:                         PDefinition fdef = question.assistantFactory.createPDefinitionAssistant().findName(ctype.getClassdef(), field, NameScope.NAMESANDSTATE);
543:
544:•                        if (fdef == null)
545:                         {
546:                                 TypeCheckerErrors.concern(unique, 3260, "Unknown class member name, '"
547:                                                 + field + "'", node.getLocation(), node);
548:                                 result.add(AstFactory.newAUnknownType(node.getLocation()));
549:                         }
550:•                        else if (!question.assistantFactory.createSClassDefinitionAssistant().isAccessible(question.env, fdef, false))
551:                         {
552:                                 TypeCheckerErrors.concern(unique, 3260, "Inaccessible class member name, '"
553:                                         + field + "'", node.getLocation(), node);
554:                                 result.add(AstFactory.newAUnknownType(node.getLocation()));
555:                         }
556:                         else
557:                         {
558:                                 result.add(question.assistantFactory.createPDefinitionAssistant().getType(fdef));
559:                         }
560:                 }
561:
562:•                if (question.assistantFactory.createPTypeAssistant().isRecord(type, question.fromModule))
563:                 {
564:•                        String sname = node.getFieldName() != null ? node.getFieldName().getName()
565:                                         : node.getClassName().toString();
566:                         ARecordInvariantType rec = question.assistantFactory.createPTypeAssistant().getRecord(type, question.fromModule);
567:                         AFieldField rf = question.assistantFactory.createARecordInvariantTypeAssistant().findField(rec, sname);
568:
569:•                        if (rf == null)
570:                         {
571:                                 TypeCheckerErrors.concern(unique, 3261, "Unknown field name, '"
572:                                                 + sname + "'", node.getLocation(), node);
573:                                 result.add(AstFactory.newAUnknownType(node.getLocation()));
574:                         } else
575:                         {
576:                                 result.add(rf.getType());
577:                         }
578:                 }
579:
580:•                if (result.isEmpty())
581:                 {
582:                         TypeCheckerErrors.report(3262, "Field assignment is not of a class or record type", node.getLocation(), node);
583:                         TypeCheckerErrors.detail2("Expression", node.getObject(), "Type", type);
584:                         return AstFactory.newAUnknownType(node.getLocation());
585:                 }
586:
587:                 return result.getType(node.getLocation());
588:
589:         }
590:         
591:         public PType mapApply(AApplyObjectDesignator node, SMapType map,
592:                         Environment env, NameScope scope, boolean unique,
593:                         IQuestionAnswer<TypeCheckInfo, PType> rootVisitor)
594:                         throws AnalysisException
595:         {
596:
597:•                if (node.getArgs().size() != 1)
598:                 {
599:                         TypeCheckerErrors.concern(unique, 3250, "Map application must have one argument", node.getLocation(), node);
600:                         return AstFactory.newAUnknownType(node.getLocation());
601:                 }
602:
603:                 PType argtype = node.getArgs().get(0).apply(rootVisitor, new TypeCheckInfo(env.af, env, scope));
604:
605:•                if (!env.af.getTypeComparator().compatible(map.getFrom(), argtype))
606:                 {
607:                         TypeCheckerErrors.concern(unique, 3251, "Map application argument is incompatible type", node.getLocation(), node);
608:                         TypeCheckerErrors.detail2(unique, "Map domain", map.getFrom(), "Argument", argtype);
609:                 }
610:
611:                 return map.getTo();
612:         }
613:
614:         public PType seqApply(AApplyObjectDesignator node, SSeqType seq,
615:                         Environment env, NameScope scope, boolean unique,
616:                         IQuestionAnswer<TypeCheckInfo, PType> rootVisitor, TypeCheckInfo question)
617:                         throws AnalysisException
618:         {
619:
620:•                if (node.getArgs().size() != 1)
621:                 {
622:                         TypeCheckerErrors.concern(unique, 3252, "Sequence application must have one argument", node.getLocation(), node);
623:                         return AstFactory.newAUnknownType(node.getLocation());
624:                 }
625:
626:                 PType argtype = node.getArgs().get(0).apply(rootVisitor, new TypeCheckInfo(question.assistantFactory, env, scope));
627:
628:•                if (!env.af.createPTypeAssistant().isNumeric(argtype, question.fromModule))
629:                 {
630:                         TypeCheckerErrors.concern(unique, 3253, "Sequence argument is not numeric", node.getLocation(), node);
631:                         TypeCheckerErrors.detail(unique, "Type", argtype);
632:                 }
633:
634:                 return seq.getSeqof();
635:         }
636:
637:         public PType functionApply(AApplyObjectDesignator node,
638:                         AFunctionType ftype, Environment env, NameScope scope,
639:                         boolean unique, IQuestionAnswer<TypeCheckInfo, PType> rootVisitor)
640:                         throws AnalysisException
641:         {
642:
643:                 LinkedList<PType> ptypes = ftype.getParameters();
644:
645:•                if (node.getArgs().size() > ptypes.size())
646:                 {
647:                         TypeCheckerErrors.concern(unique, 3254, "Too many arguments", node.getLocation(), node);
648:                         TypeCheckerErrors.detail2(unique, "Args", node.getArgs(), "Params", ptypes);
649:                         return ftype.getResult();
650:•                } else if (node.getArgs().size() < ptypes.size())
651:                 {
652:                         TypeCheckerErrors.concern(unique, 3255, "Too few arguments", node.getLocation(), node);
653:                         TypeCheckerErrors.detail2(unique, "Args", node.getArgs(), "Params", ptypes);
654:                         return ftype.getResult();
655:                 }
656:
657:                 int i = 0;
658:
659:•                for (PExp a : node.getArgs())
660:                 {
661:                         PType at = a.apply(rootVisitor, new TypeCheckInfo(env.af, env, scope));
662:                         PType pt = ptypes.get(i++);
663:
664:•                        if (!env.af.getTypeComparator().compatible(pt, at))
665:                         {
666:
667:                                 // TypeCheckerErrors.concern(unique, 3256, "Inappropriate type for argument " + i
668:                                 // +". (Expected: "+pt+" Actual: "+at+")" ,node.getLocation(),node);
669:                                 TypeCheckerErrors.concern(unique, 3256, "Inappropriate type for argument "
670:                                                 + i, node.getLocation(), node);
671:                                 TypeCheckerErrors.detail2(unique, "Expect", pt, "Actual", at);
672:                         }
673:                 }
674:
675:                 return ftype.getResult();
676:         }
677:
678:         public PType operationApply(AApplyObjectDesignator node,
679:                         AOperationType optype, Environment env, NameScope scope,
680:                         boolean unique, IQuestionAnswer<TypeCheckInfo, PType> rootVisitor)
681:                         throws AnalysisException
682:         {
683:                 LinkedList<PType> ptypes = optype.getParameters();
684:
685:•                if (node.getArgs().size() > ptypes.size())
686:                 {
687:                         TypeCheckerErrors.concern(unique, 3257, "Too many arguments", node.getLocation(), node);
688:                         TypeCheckerErrors.detail2(unique, "Args", node.getArgs(), "Params", ptypes);
689:                         return optype.getResult();
690:•                } else if (node.getArgs().size() < ptypes.size())
691:                 {
692:                         TypeCheckerErrors.concern(unique, 3258, "Too few arguments", node.getLocation(), node);
693:                         TypeCheckerErrors.detail2(unique, "Args", node.getArgs(), "Params", ptypes);
694:                         return optype.getResult();
695:                 }
696:
697:                 int i = 0;
698:
699:•                for (PExp a : node.getArgs())
700:                 {
701:                         PType at = a.apply(rootVisitor, new TypeCheckInfo(env.af, env, scope));
702:                         PType pt = ptypes.get(i++);
703:
704:•                        if (!env.af.getTypeComparator().compatible(pt, at))
705:                         { // + ". (Expected: "+pt+" Actual: "+at+")"
706:                                 TypeCheckerErrors.concern(unique, 3259, "Inappropriate type for argument "
707:                                                 + i, node.getLocation(), node);
708:                                 TypeCheckerErrors.detail2(unique, "Expect", pt, "Actual", at);
709:                         }
710:                 }
711:
712:                 return optype.getResult();
713:         }
714:
715: }