Package: DefinitionTypeResolver$NewQuestion

DefinitionTypeResolver$NewQuestion

nameinstructionbranchcomplexitylinemethod
DefinitionTypeResolver.NewQuestion(IQuestionAnswer, TypeCheckInfo)
M: 0 C: 9
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
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.utilities;
23:
24: import java.util.List;
25:
26: import org.overture.ast.analysis.AnalysisException;
27: import org.overture.ast.analysis.QuestionAdaptor;
28: import org.overture.ast.analysis.intf.IQuestionAnswer;
29: import org.overture.ast.definitions.AExplicitFunctionDefinition;
30: import org.overture.ast.definitions.AExplicitOperationDefinition;
31: import org.overture.ast.definitions.AImplicitFunctionDefinition;
32: import org.overture.ast.definitions.AImplicitOperationDefinition;
33: import org.overture.ast.definitions.AImportedDefinition;
34: import org.overture.ast.definitions.AInstanceVariableDefinition;
35: import org.overture.ast.definitions.ALocalDefinition;
36: import org.overture.ast.definitions.ARenamedDefinition;
37: import org.overture.ast.definitions.AStateDefinition;
38: import org.overture.ast.definitions.ATypeDefinition;
39: import org.overture.ast.definitions.AValueDefinition;
40: import org.overture.ast.definitions.PDefinition;
41: import org.overture.ast.definitions.SClassDefinition;
42: import org.overture.ast.expressions.ANotYetSpecifiedExp;
43: import org.overture.ast.expressions.ASubclassResponsibilityExp;
44: import org.overture.ast.patterns.APatternListTypePair;
45: import org.overture.ast.patterns.PPattern;
46: import org.overture.ast.typechecker.NameScope;
47: import org.overture.ast.types.AFieldField;
48: import org.overture.ast.types.AFunctionType;
49: import org.overture.ast.types.AOperationType;
50: import org.overture.ast.types.ARecordInvariantType;
51: import org.overture.ast.types.PType;
52: import org.overture.ast.types.SInvariantType;
53: import org.overture.typechecker.Environment;
54: import org.overture.typechecker.FlatCheckedEnvironment;
55: import org.overture.typechecker.FlatEnvironment;
56: import org.overture.typechecker.TypeCheckException;
57: import org.overture.typechecker.TypeCheckInfo;
58: import org.overture.typechecker.TypeCheckerErrors;
59: import org.overture.typechecker.assistant.ITypeCheckerAssistantFactory;
60:
61: /**
62: * This class implements a way to resolve types from a node in the AST
63: *
64: * @author kel
65: */
66:
67: public class DefinitionTypeResolver extends
68:                 QuestionAdaptor<DefinitionTypeResolver.NewQuestion>
69: {
70:         public static class NewQuestion
71:         {
72:                 public final IQuestionAnswer<TypeCheckInfo, PType> rootVisitor;
73:                 public final TypeCheckInfo question;
74:
75:                 public NewQuestion(IQuestionAnswer<TypeCheckInfo, PType> rootVisitor,
76:                                 TypeCheckInfo question)
77:                 {
78:                         this.rootVisitor = rootVisitor;
79:                         this.question = question;
80:                 }
81:         }
82:
83:         protected ITypeCheckerAssistantFactory af;
84:
85:         public DefinitionTypeResolver(ITypeCheckerAssistantFactory af)
86:         {
87:                 this.af = af;
88:         }
89:
90:         @Override
91:         public void defaultSClassDefinition(SClassDefinition node,
92:                         NewQuestion question) throws AnalysisException
93:         {
94:                 Environment cenv = new FlatEnvironment(question.question.assistantFactory, node.getDefinitions(), question.question.env);
95:                 af.createPDefinitionListAssistant().typeResolve(node.getDefinitions(), question.rootVisitor, new TypeCheckInfo(question.question.assistantFactory, cenv));
96:         }
97:
98:         @Override
99:         public void caseAExplicitFunctionDefinition(
100:                         AExplicitFunctionDefinition node, NewQuestion question)
101:                         throws AnalysisException
102:         {
103:                 if (node.getTypeParams().size() != 0)
104:                 {
105:                         FlatCheckedEnvironment params = new FlatCheckedEnvironment(question.question.assistantFactory, af.createAExplicitFunctionDefinitionAssistant().getTypeParamDefinitions(node), question.question.env, NameScope.NAMES);
106:
107:                         TypeCheckInfo newQuestion = new TypeCheckInfo(question.question.assistantFactory, params, question.question.scope);
108:
109:                         node.setType(af.createPTypeAssistant().typeResolve(question.question.assistantFactory.createPDefinitionAssistant().getType(node), null, question.rootVisitor, newQuestion));
110:                 } else
111:                 {
112:                         node.setType(af.createPTypeAssistant().typeResolve(node.getType(), null, question.rootVisitor, question.question));
113:                 }
114:
115:                 if (question.question.env.isVDMPP())
116:                 {
117:                         AFunctionType fType = (AFunctionType) question.question.assistantFactory.createPDefinitionAssistant().getType(node);
118:                         node.getName().setTypeQualifier(fType.getParameters());
119:                 }
120:
121:                 if (node.getBody() instanceof ASubclassResponsibilityExp
122:                                 || node.getBody() instanceof ANotYetSpecifiedExp)
123:                 {
124:                         node.setIsUndefined(true);
125:                 }
126:
127:                 if (node.getPrecondition() != null)
128:                 {
129:                         // PDefinitionAssistantTC.typeResolve(node.getPredef(), rootVisitor, question);
130:                         node.getPredef().apply(this, question);
131:                 }
132:
133:                 if (node.getPostcondition() != null)
134:                 {
135:                         // PDefinitionAssistantTC.typeResolve(node.getPostdef(), rootVisitor, question);
136:                         node.getPostdef().apply(this, question);
137:                 }
138:
139:                 for (List<PPattern> pp : node.getParamPatternList())
140:                 {
141:                         af.createPPatternListAssistant().typeResolve(pp, question.rootVisitor, question.question);
142:                 }
143:
144:         }
145:
146:         @Override
147:         public void caseAExplicitOperationDefinition(
148:                         AExplicitOperationDefinition node, NewQuestion question)
149:                         throws AnalysisException
150:         {
151:                 node.setType(af.createPTypeAssistant().typeResolve(node.getType(), null, question.rootVisitor, question.question));
152:
153:                 if (question.question.env.isVDMPP())
154:                 {
155:                         node.getName().setTypeQualifier(((AOperationType) node.getType()).getParameters());
156:
157:                         if (node.getName().getName().equals(node.getClassDefinition().getName().getName()))
158:                         {
159:                                 node.setIsConstructor(true);
160:                                 node.getClassDefinition().setHasContructors(true);
161:                         }
162:                 }
163:
164:                 if (node.getPrecondition() != null)
165:                 {
166:                         node.getPredef().apply(this, question);
167:                 }
168:
169:                 if (node.getPostcondition() != null)
170:                 {
171:                         node.getPostdef().apply(this, question);
172:                 }
173:
174:                 for (PPattern p : node.getParameterPatterns())
175:                 {
176:                         af.createPPatternAssistant(node.getLocation().getModule()).typeResolve(p, question.rootVisitor, question.question);
177:                 }
178:         }
179:
180:         @Override
181:         public void caseAImplicitFunctionDefinition(
182:                         AImplicitFunctionDefinition node, NewQuestion question)
183:                         throws AnalysisException
184:         {
185:                 if (node.getTypeParams().size() > 0)
186:                 {
187:                         FlatCheckedEnvironment params = new FlatCheckedEnvironment(af, af.createAImplicitFunctionDefinitionAssistant().getTypeParamDefinitions(node), question.question.env, NameScope.NAMES);
188:                         node.setType(af.createPTypeAssistant().typeResolve(af.createPDefinitionAssistant().getType(node), null, question.rootVisitor, new TypeCheckInfo(question.question.assistantFactory, params, question.question.scope, question.question.qualifiers)));
189:                 } else
190:                 {
191:                         question.question.qualifiers = null;
192:                         node.setType(af.createPTypeAssistant().typeResolve(af.createPDefinitionAssistant().getType(node), null, question.rootVisitor, question.question));
193:                 }
194:
195:                 if (node.getResult() != null)
196:                 {
197:                         af.createAPatternTypePairAssistant(node.getLocation().getModule()).typeResolve(node.getResult(), question.rootVisitor, question.question);
198:                         
199:                 }
200:
201:                 if (question.question.env.isVDMPP())
202:                 {
203:                         AFunctionType fType = (AFunctionType) af.createPDefinitionAssistant().getType(node);
204:                         node.getName().setTypeQualifier(fType.getParameters());
205:                 }
206:
207:                 if (node.getBody() instanceof ASubclassResponsibilityExp
208:                                 || node.getBody() instanceof ANotYetSpecifiedExp)
209:                 {
210:                         node.setIsUndefined(true);
211:                 }
212:
213:                 if (node.getPrecondition() != null)
214:                 {
215:                         node.getPredef().apply(this, question);
216:                 }
217:
218:                 if (node.getPostcondition() != null)
219:                 {
220:                         node.getPostdef().apply(this, question);
221:                 }
222:
223:                 for (APatternListTypePair pltp : node.getParamPatterns())
224:                 {
225:                         pltp.apply(THIS, question);
226:                 }
227:         }
228:
229:         @Override
230:         public void caseAImplicitOperationDefinition(
231:                         AImplicitOperationDefinition node, NewQuestion question)
232:                         throws AnalysisException
233:         {
234:                 node.setType(af.createPTypeAssistant().typeResolve(node.getType(), null, question.rootVisitor, question.question));
235:
236:                 if (node.getResult() != null)
237:                 {
238:                         af.createAPatternTypePairAssistant(node.getLocation().getModule()).typeResolve(node.getResult(), question.rootVisitor, question.question);
239:                 }
240:
241:                 if (question.question.env.isVDMPP())
242:                 {
243:                         node.getName().setTypeQualifier(((AOperationType) node.getType()).getParameters());
244:
245:                         if (node.getName().getName().equals(node.getClassDefinition().getName().getName()))
246:                         {
247:                                 node.setIsConstructor(true);
248:                                 node.getClassDefinition().setHasContructors(true);
249:                         }
250:                 }
251:
252:                 if (node.getPrecondition() != null)
253:                 {
254:                         node.getPredef().apply(this, question);
255:                 }
256:
257:                 if (node.getPostcondition() != null)
258:                 {
259:                         node.getPostdef().apply(this, question);
260:                 }
261:
262:                 for (APatternListTypePair ptp : node.getParameterPatterns())
263:                 {
264:                         ptp.apply(THIS, question);
265:                 }
266:         }
267:
268:         @Override
269:         public void caseAInstanceVariableDefinition(
270:                         AInstanceVariableDefinition node, NewQuestion question)
271:                         throws AnalysisException
272:         {
273:
274:                 try
275:                 {
276:                         node.setType(af.createPTypeAssistant().typeResolve(node.getType(), null, question.rootVisitor, question.question));
277:                 } catch (TypeCheckException e)
278:                 {
279:                         af.createPTypeAssistant().unResolve(node.getType());
280:                         throw e;
281:                 }
282:         }
283:
284:         @Override
285:         public void caseALocalDefinition(ALocalDefinition node, NewQuestion question)
286:                         throws AnalysisException
287:         {
288:                 if (node.getType() != null)
289:                 {
290:                         node.setType(af.createPTypeAssistant().typeResolve(question.question.assistantFactory.createPDefinitionAssistant().getType(node), null, question.rootVisitor, question.question));
291:                 }
292:         }
293:
294:         @Override
295:         public void caseARenamedDefinition(ARenamedDefinition node,
296:                         NewQuestion question) throws AnalysisException
297:         {
298:                 NewQuestion newq = new NewQuestion(question.rootVisitor, question.question.newModule(node.getDef().getLocation().getModule()));
299:                 node.getDef().apply(this, newq);
300:         }
301:
302:         @Override
303:         public void caseAStateDefinition(AStateDefinition node, NewQuestion question)
304:                         throws AnalysisException
305:         {
306:                 for (AFieldField f : node.getFields())
307:                 {
308:                         try
309:                         {
310:                                 f.apply(THIS, new NewQuestion(question.rootVisitor, question.question));
311:                         } catch (TypeCheckException e)
312:                         {
313:                                 question.question.assistantFactory.createPTypeAssistant().unResolve(f.getType());
314:                                 throw e;
315:                         }
316:                 }
317:
318:                 node.setRecordType(af.createPTypeAssistant().typeResolve(node.getRecordType(), null, question.rootVisitor, question.question));
319:
320:                 if (node.getInvPattern() != null)
321:                 {
322:                         node.getInvdef().apply(this, question);
323:
324:                         ARecordInvariantType rtype = (ARecordInvariantType) node.getRecordType();
325:                         rtype.setInvDef(node.getInvdef());
326:                 }
327:
328:                 if (node.getInitPattern() != null)
329:                 {
330:                         node.getInitdef().apply(this, question);
331:                 }
332:
333:         }
334:
335:         @Override
336:         public void caseATypeDefinition(ATypeDefinition node, NewQuestion question)
337:                         throws AnalysisException
338:         {
339:                 try
340:                 {
341:                         node.setInfinite(false);
342:                         node.setInvType((SInvariantType) af.createPTypeAssistant().typeResolve((SInvariantType) node.getInvType(), node, question.rootVisitor, question.question));
343:
344:                         if (node.getInfinite())
345:                         {
346:                                 TypeCheckerErrors.report(3050, "Type '" + node.getName()
347:                                                 + "' is infinite", node.getLocation(), node);
348:                         }
349:
350:                         // set type before in case the invdef uses a type defined in this one
351:                         node.setType(node.getInvType());
352:
353:                         if (node.getInvdef() != null)
354:                         {
355:                                 node.getInvdef().apply(this, question);
356:                                 af.createPPatternAssistant(node.getLocation().getModule()).typeResolve(node.getInvPattern(), question.rootVisitor, question.question);
357:                         }
358:
359:                         if (node.getEqRelation() != null)
360:                         {
361:                                 node.getEqRelation().getRelDef().apply(this, question);
362:                                 af.createPPatternAssistant(node.getLocation().getModule()).typeResolve(node.getEqRelation().getLhsPattern(), question.rootVisitor, question.question);
363:                                 af.createPPatternAssistant(node.getLocation().getModule()).typeResolve(node.getEqRelation().getRhsPattern(), question.rootVisitor, question.question);
364:                         }
365:                         
366:                         if (node.getOrdRelation() != null)
367:                         {
368:                                 node.getOrdRelation().getRelDef().apply(this, question);
369:                                 af.createPPatternAssistant(node.getLocation().getModule()).typeResolve(node.getOrdRelation().getLhsPattern(), question.rootVisitor, question.question);
370:                                 af.createPPatternAssistant(node.getLocation().getModule()).typeResolve(node.getOrdRelation().getRhsPattern(), question.rootVisitor, question.question);
371:
372:                                 if (node.getOrdRelation().getMinDef() != null)
373:                                 {
374:                                         node.getOrdRelation().getMinDef().apply(this, question);
375:                                 }
376:                                 
377:                                 if (node.getOrdRelation().getMaxDef() != null)
378:                                 {
379:                                         node.getOrdRelation().getMaxDef().apply(this, question);
380:                                 }
381:                         }
382:
383:                         node.setType(node.getInvType());
384:
385:                         if (!node.getComposeDefinitions().isEmpty())
386:                         {
387:                                 for (PDefinition compose : node.getComposeDefinitions())
388:                                 {
389:                                         compose.apply(this, question);
390:                                 }
391:                         }
392:
393:                 } catch (TypeCheckException e)
394:                 {
395:                         af.createPTypeAssistant().unResolve(node.getInvType());
396:                         throw e;
397:                 }
398:         }
399:
400:         @Override
401:         public void caseAValueDefinition(AValueDefinition node, NewQuestion question)
402:                         throws AnalysisException
403:         {
404:                 if (node.getType() != null)
405:                 {
406:                         node.setType(af.createPTypeAssistant().typeResolve(node.getType(), null, question.rootVisitor, question.question));
407:                         af.createPPatternAssistant(node.getLocation().getModule()).typeResolve(node.getPattern(), question.rootVisitor, question.question);
408:                         // af.createAValueDefinitionAssistant().updateDefs(node, question.question);
409:                         updateDefs(node, question.question);
410:                 }
411:         }
412:         
413:         public void caseAImportedDefinition(AImportedDefinition node, NewQuestion question)
414:                 throws AnalysisException
415:         {
416:                  NewQuestion newq = new NewQuestion(question.rootVisitor, question.question.newModule(node.getDef().getLocation().getModule()));
417:                  node.getDef().apply(this, question);
418:         }
419:
420:         public void updateDefs(AValueDefinition node, TypeCheckInfo question)
421:         {
422:                 PType type = node.getType();
423:                 PPattern pattern = node.getPattern();
424:
425:                 List<PDefinition> newdefs = af.createPPatternAssistant(node.getLocation().getModule()).getDefinitions(pattern, type, node.getNameScope());
426:
427:                 // The untyped definitions may have had "used" markers, so we copy
428:                 // those into the new typed definitions, lest we get warnings. We
429:                 // also mark the local definitions as "ValueDefintions" (proxies),
430:                 // so that classes can be constructed correctly (values are statics).
431:
432:                 for (PDefinition d : newdefs)
433:                 {
434:                         for (PDefinition u : node.getDefs())
435:                         {
436:                                 if (u.getName().equals(d.getName()))
437:                                 {
438:                                         if (af.createPDefinitionAssistant().isUsed(u))
439:                                         {
440:                                                 af.createPDefinitionAssistant().markUsed(d);
441:                                         }
442:
443:                                         break;
444:                                 }
445:                         }
446:
447:                         ALocalDefinition ld = (ALocalDefinition) d;
448:                         ld.setValueDefinition(node.clone());
449:                 }
450:
451:                 node.setDefs(newdefs);
452:                 List<PDefinition> defs = node.getDefs();
453:                 af.createPDefinitionListAssistant().setAccessibility(defs, node.getAccess().clone());
454:                 af.createPDefinitionListAssistant().setClassDefinition(defs, node.getClassDefinition());
455:         }
456:
457:         @Override
458:         public void caseAPatternListTypePair(APatternListTypePair pltp,
459:                         NewQuestion question) throws AnalysisException
460:         {
461:                 af.createPPatternListAssistant().typeResolve(pltp.getPatterns(), question.rootVisitor, question.question);
462:                 PType type = af.createPTypeAssistant().typeResolve(pltp.getType(), null, question.rootVisitor, question.question);
463:                 pltp.setType(type);
464:         }
465:
466:         @Override
467:         public void defaultPDefinition(PDefinition node, NewQuestion question)
468:                         throws AnalysisException
469:         {
470:                 return;
471:         }
472: }