Package: DeclAssistantIR$2

DeclAssistantIR$2

nameinstructionbranchcomplexitylinemethod
getAccess(AFieldDeclIR)
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getDecls(SClassDeclIR)
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
{...}
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%

Coverage

1: /*
2: * #%~
3: * VDM Code Generator
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.codegen.assistant;
23:
24: import java.util.HashSet;
25: import java.util.LinkedList;
26: import java.util.List;
27: import java.util.Set;
28:
29: import org.overture.ast.analysis.AnalysisException;
30: import org.overture.ast.definitions.AAssignmentDefinition;
31: import org.overture.ast.definitions.AClassClassDefinition;
32: import org.overture.ast.definitions.AEqualsDefinition;
33: import org.overture.ast.definitions.AExplicitFunctionDefinition;
34: import org.overture.ast.definitions.AExplicitOperationDefinition;
35: import org.overture.ast.definitions.AImplicitOperationDefinition;
36: import org.overture.ast.definitions.AInheritedDefinition;
37: import org.overture.ast.definitions.AInstanceVariableDefinition;
38: import org.overture.ast.definitions.AStateDefinition;
39: import org.overture.ast.definitions.ATypeDefinition;
40: import org.overture.ast.definitions.AValueDefinition;
41: import org.overture.ast.definitions.PDefinition;
42: import org.overture.ast.definitions.SClassDefinition;
43: import org.overture.ast.definitions.SFunctionDefinition;
44: import org.overture.ast.definitions.SOperationDefinition;
45: import org.overture.ast.expressions.ASubclassResponsibilityExp;
46: import org.overture.ast.expressions.PExp;
47: import org.overture.ast.intf.lex.ILexNameToken;
48: import org.overture.ast.lex.Dialect;
49: import org.overture.ast.modules.AModuleModules;
50: import org.overture.ast.node.INode;
51: import org.overture.ast.patterns.APatternListTypePair;
52: import org.overture.ast.patterns.PPattern;
53: import org.overture.ast.statements.AIdentifierStateDesignator;
54: import org.overture.ast.statements.ASubclassResponsibilityStm;
55: import org.overture.ast.types.ARecordInvariantType;
56: import org.overture.ast.util.ClonableString;
57: import org.overture.codegen.ir.IRConstants;
58: import org.overture.codegen.ir.IRGenerator;
59: import org.overture.codegen.ir.IRInfo;
60: import org.overture.codegen.ir.PIR;
61: import org.overture.codegen.ir.SDeclIR;
62: import org.overture.codegen.ir.SExpIR;
63: import org.overture.codegen.ir.SPatternIR;
64: import org.overture.codegen.ir.SStmIR;
65: import org.overture.codegen.ir.STypeIR;
66: import org.overture.codegen.ir.SourceNode;
67: import org.overture.codegen.ir.declarations.ADefaultClassDeclIR;
68: import org.overture.codegen.ir.declarations.AFieldDeclIR;
69: import org.overture.codegen.ir.declarations.AFormalParamLocalParamIR;
70: import org.overture.codegen.ir.declarations.AFuncDeclIR;
71: import org.overture.codegen.ir.declarations.AMethodDeclIR;
72: import org.overture.codegen.ir.declarations.AMutexSyncDeclIR;
73: import org.overture.codegen.ir.declarations.ANamedTraceDeclIR;
74: import org.overture.codegen.ir.declarations.APersyncDeclIR;
75: import org.overture.codegen.ir.declarations.ARecordDeclIR;
76: import org.overture.codegen.ir.declarations.AThreadDeclIR;
77: import org.overture.codegen.ir.declarations.ATypeDeclIR;
78: import org.overture.codegen.ir.declarations.AVarDeclIR;
79: import org.overture.codegen.ir.declarations.SClassDeclIR;
80: import org.overture.codegen.ir.expressions.ANotImplementedExpIR;
81: import org.overture.codegen.ir.name.ATokenNameIR;
82: import org.overture.codegen.ir.name.ATypeNameIR;
83: import org.overture.codegen.ir.statements.ABlockStmIR;
84: import org.overture.codegen.ir.statements.ANotImplementedStmIR;
85: import org.overture.codegen.ir.statements.AReturnStmIR;
86: import org.overture.codegen.ir.types.ABoolBasicTypeIR;
87: import org.overture.codegen.ir.types.ACharBasicTypeIR;
88: import org.overture.codegen.ir.types.AClassTypeIR;
89: import org.overture.codegen.ir.types.AIntNumericBasicTypeIR;
90: import org.overture.codegen.ir.types.AMethodTypeIR;
91: import org.overture.codegen.ir.types.ANat1NumericBasicTypeIR;
92: import org.overture.codegen.ir.types.ANatNumericBasicTypeIR;
93: import org.overture.codegen.ir.types.ARealNumericBasicTypeIR;
94: import org.overture.codegen.ir.types.ARecordTypeIR;
95: import org.overture.codegen.ir.types.AStringTypeIR;
96: import org.overture.codegen.ir.types.ATemplateTypeIR;
97: import org.overture.codegen.utils.LexNameTokenWrapper;
98: import org.overture.config.Settings;
99:
100: public class DeclAssistantIR extends AssistantBase
101: {
102:         public DeclAssistantIR(AssistantManager assistantManager)
103:         {
104:                 super(assistantManager);
105:         }
106:
107:         public void addDependencies(SClassDeclIR clazz,
108:                         List<ClonableString> extraDeps, boolean prepend)
109:         {
110:                 NodeAssistantIR nodeAssistant = assistantManager.getNodeAssistant();
111:                 clazz.setDependencies(nodeAssistant.buildData(clazz.getDependencies(), extraDeps, prepend));
112:         }
113:
114:         public boolean isInnerClass(SClassDeclIR node)
115:         {
116:                 return node.parent() != null
117:                                 && node.parent().getAncestor(SClassDeclIR.class) != null;
118:         }
119:
120:         public boolean isTestCase(INode node)
121:         {
122:                 // Treat SL modules that end with 'Test' as test cases (just a convention)
123:                 if(node instanceof AModuleModules)
124:                 {
125:                         AModuleModules module = (AModuleModules) node;
126:                         return module.getName().getName().endsWith(IRConstants.TEST_MODULE_NAME_POSTFIX);
127:                 }
128:
129:                 if (!(node instanceof SClassDefinition))
130:                 {
131:                         return false;
132:                 }
133:
134:                 SClassDefinition clazz = (SClassDefinition) node;
135:
136:                 for (SClassDefinition d : clazz.getSuperDefs())
137:                 {
138:                         if (d.getName().getName().equals(IRConstants.TEST_CASE))
139:                         {
140:                                 return true;
141:                         }
142:
143:                         if (isTestCase(d))
144:                         {
145:                                 return true;
146:                         }
147:                 }
148:
149:                 return false;
150:         }
151:         
152:         public boolean isFullyAbstract(SClassDefinition clazz, IRInfo info)
153:         {
154:                 if(clazz == null)
155:                 {
156:                         return false;
157:                 }
158:                 
159:                 if(info.getInstantiatedClasses().contains(clazz.getName().getName()))
160:                 {
161:                         return false;
162:                 }
163:                 
164:                 LinkedList<PDefinition> allDefs = new LinkedList<PDefinition>(clazz.getAllInheritedDefinitions());
165:                 allDefs.addAll(clazz.getDefinitions());
166:
167:                 for (PDefinition def : allDefs)
168:                 {
169:                         while (def instanceof AInheritedDefinition)
170:                         {
171:                                 def = ((AInheritedDefinition) def).getSuperdef();
172:                         }
173:                         
174:                         if(def instanceof ATypeDefinition)
175:                         {
176:                                 ATypeDefinition typeDef = (ATypeDefinition) def;
177:                                 
178:                                 if(typeDef.getType() instanceof ARecordInvariantType)
179:                                 {
180:                                         return false;
181:                                 }
182:                         }
183:                         
184:                         if(!IRConstants.PUBLIC.equals(def.getAccess().getAccess().toString()))
185:                         {
186:                                 return false;
187:                         }
188:                         
189:                         if (def instanceof AInstanceVariableDefinition)
190:                         {
191:                                 return false;
192:                         }
193:                         else if(def instanceof AExplicitOperationDefinition)
194:                         {
195:                                 AExplicitOperationDefinition op = (AExplicitOperationDefinition) def;
196:                                 
197:                                 boolean isAbstract = op.getBody() == null || op.getBody() instanceof ASubclassResponsibilityStm;
198:                                 
199:                                 if(!isAbstract)
200:                                 {
201:                                         return false;
202:                                 }
203:                         }
204:                         else if(def instanceof AExplicitFunctionDefinition)
205:                         {
206:                                 AExplicitFunctionDefinition fun = (AExplicitFunctionDefinition) def;
207:                                 
208:                                 boolean isAbstract = fun.getBody() == null || fun.getBody() instanceof ASubclassResponsibilityExp;
209:                                 
210:                                 if(!isAbstract)
211:                                 {
212:                                         return false;
213:                                 }
214:                         }
215:                 }
216:                 
217:                 return true;
218:         }
219:
220:         public boolean parentIsTest(ADefaultClassDeclIR node)
221:         {
222:                 if (node != null && node.getSuperNames().isEmpty())
223:                 {
224:                         return false;
225:                 }
226:
227:                 for(ATokenNameIR t : node.getSuperNames())
228:                 {
229:                         if(t.getName().equals(IRConstants.TEST_CASE))
230:                         {
231:                                 return true;
232:                         }
233:                 }
234:
235:                 return false;
236:         }
237:
238:         public boolean isTest(ADefaultClassDeclIR node, List<SClassDeclIR> classes)
239:         {
240:                 if(node == null || node.getSuperNames().isEmpty())
241:                 {
242:                         return false;
243:                 }
244:
245:                 for(ATokenNameIR n : node.getSuperNames())
246:                 {
247:                         if(n.getName().equals(IRConstants.TEST_CASE))
248:                         {
249:                                 return true;
250:                         }
251:
252:                         SClassDeclIR clazz = findClass(classes, n.getName());
253:
254:                         if(clazz instanceof ADefaultClassDeclIR && isTest((ADefaultClassDeclIR) clazz, classes))
255:                         {
256:                                 return true;
257:                         }
258:                 }
259:
260:                 return false;
261:         }
262:
263:         public <T extends SClassDeclIR> T buildClass(SClassDefinition node,
264:                         IRInfo question, T classCg) throws AnalysisException
265:         {
266:                 String name = node.getName().getName();
267:                 String access = node.getAccess().getAccess().toString();
268:                 boolean isAbstract = node.getIsAbstract();
269:                 boolean isStatic = false;
270:                 LinkedList<ILexNameToken> superNames = node.getSupernames();
271:
272:                 classCg.setPackage(null);
273:                 classCg.setName(name);
274:                 classCg.setAccess(access);
275:                 classCg.setAbstract(isAbstract);
276:                 classCg.setStatic(isStatic);
277:                 classCg.setStatic(false);
278:
279:                 for (ILexNameToken s : superNames)
280:                 {
281:                         ATokenNameIR superName = new ATokenNameIR();
282:                         superName.setName(s.getName());
283:
284:                         classCg.getSuperNames().add(superName);
285:                 }
286:
287:                 LinkedList<PDefinition> defs = node.getDefinitions();
288:
289:                 for (PDefinition def : defs)
290:                 {
291:                         SDeclIR decl = def.apply(question.getDeclVisitor(), question);
292:
293:                         if (decl == null)
294:                         {
295:                                 continue;// Unspported stuff returns null by default
296:                         }
297:                         if (decl instanceof AFieldDeclIR)
298:                         {
299:                                 classCg.getFields().add((AFieldDeclIR) decl);
300:                         } else if (decl instanceof AMethodDeclIR)
301:                         {
302:                                 classCg.getMethods().add((AMethodDeclIR) decl);
303:                         } else if (decl instanceof ATypeDeclIR)
304:                         {
305:                                 classCg.getTypeDecls().add((ATypeDeclIR) decl);
306:                         } else if (decl instanceof AFuncDeclIR)
307:                         {
308:                                 classCg.getFunctions().add((AFuncDeclIR) decl);
309:                         } else if (decl instanceof AThreadDeclIR)
310:                         {
311:                                 if (question.getSettings().generateConc())
312:                                 {
313:                                         classCg.setThread((AThreadDeclIR) decl);
314:                                 }
315:                         } else if (decl instanceof APersyncDeclIR)
316:                         {
317:                                 classCg.getPerSyncs().add((APersyncDeclIR) decl);
318:                         } else if (decl instanceof AMutexSyncDeclIR)
319:                         {
320:                                 classCg.getMutexSyncs().add((AMutexSyncDeclIR) decl);
321:                         } else if (decl instanceof ANamedTraceDeclIR)
322:                         {
323:                                 classCg.getTraces().add((ANamedTraceDeclIR) decl);
324:                         } else
325:                         {
326:                                 log.error("Unexpected definition in class: " + name + ": "
327:                                                 + def.getName().getName() + " at " + def.getLocation());
328:                         }
329:                 }
330:
331:                 if (node.getInvariant() != null
332:                                 && question.getSettings().generateInvariants())
333:                 {
334:                         SDeclIR invCg = node.getInvariant().apply(question.getDeclVisitor(), question);
335:                         classCg.setInvariant(invCg);
336:                 }
337:
338:                 boolean defaultConstructorExplicit = false;
339:                 for (AMethodDeclIR method : classCg.getMethods())
340:                 {
341:                         if (method.getIsConstructor() && method.getFormalParams().isEmpty())
342:                         {
343:                                 defaultConstructorExplicit = true;
344:                                 break;
345:                         }
346:                 }
347:
348:                 if (!defaultConstructorExplicit)
349:                 {
350:                         AMethodDeclIR defaultContructor = question.getDeclAssistant().consDefaultContructor(name);
351:                         defaultContructor.setSourceNode(new SourceNode(node));
352:                         classCg.getMethods().add(defaultContructor);
353:                 }
354:
355:                 question.addClass(classCg);
356:
357:                 return classCg;
358:         }
359:
360:         public AMethodDeclIR funcToMethod(AFuncDeclIR node)
361:         {
362:                 SDeclIR preCond = node.getPreCond();
363:                 SDeclIR postCond = node.getPostCond();
364:                 String access = node.getAccess();
365:                 Boolean isAbstract = node.getAbstract();
366:                 LinkedList<ATemplateTypeIR> templateTypes = node.getTemplateTypes();
367:                 AMethodTypeIR methodType = node.getMethodType();
368:                 LinkedList<AFormalParamLocalParamIR> formalParams = node.getFormalParams();
369:                 String name = node.getName();
370:                 SExpIR body = node.getBody();
371:                 SourceNode sourceNode = node.getSourceNode();
372:
373:                 AMethodDeclIR method = new AMethodDeclIR();
374:                 method.setSourceNode(sourceNode);
375:
376:                 if (preCond != null)
377:                 {
378:                         method.setPreCond(preCond.clone());
379:                 }
380:                 if (postCond != null)
381:                 {
382:                         method.setPostCond(postCond.clone());
383:                 }
384:
385:                 method.setAccess(access);
386:                 method.setAbstract(isAbstract);
387:                 method.setTemplateTypes(cloneNodes(templateTypes, ATemplateTypeIR.class));
388:                 method.setMethodType(methodType.clone());
389:                 method.setFormalParams(cloneNodes(formalParams, AFormalParamLocalParamIR.class));
390:                 method.setName(name);
391:                 method.setStatic(true);
392:                 method.setIsConstructor(false);
393:                 method.setImplicit(node.getImplicit());
394:
395:                 if (!(body instanceof ANotImplementedExpIR))
396:                 {
397:                         AReturnStmIR returnStm = new AReturnStmIR();
398:                         // Approximate return statement source node as the function body
399:                         returnStm.setSourceNode(body.getSourceNode());
400:                         returnStm.setExp(body.clone());
401:                         method.setBody(returnStm);
402:                 } else
403:                 {
404:                         method.setBody(new ANotImplementedStmIR());
405:                 }
406:                 return method;
407:         }
408:
409:         public String getNodeName(INode node)
410:         {
411:                 if (node instanceof SClassDefinition)
412:                 {
413:                         return ((SClassDefinition) node).getName().getName();
414:                 } else if (node instanceof AModuleModules)
415:                 {
416:                         return ((AModuleModules) node).getName().getName();
417:                 }
418:
419:                 // Fall back
420:                 return node.toString();
421:         }
422:
423:         public boolean isLibrary(INode node)
424:         {
425:                 if (node instanceof SClassDefinition)
426:                 {
427:                         return isLibraryName(((SClassDefinition) node).getName().getName());
428:                 } else if (node instanceof AModuleModules)
429:                 {
430:                         return isLibraryName(((AModuleModules) node).getName().getName());
431:                 }
432:
433:                 return false;
434:         }
435:
436:         public boolean isLibraryName(String className)
437:         {
438:                 String[] classNames;
439:
440:                 if(Settings.dialect == Dialect.VDM_SL)
441:                 {
442:                         classNames = IRConstants.CLASS_NAMES_USED_IN_SL;
443:                 }
444:                 else
445:                 {
446:                         classNames = IRConstants.CLASS_NAMES_USED_IN_VDM_PP_RT;
447:                 }
448:
449:                 for (int i = 0; i < classNames.length; i++)
450:                 {
451:                         if (classNames[i].equals(className))
452:                         {
453:                                 return true;
454:                         }
455:                 }
456:
457:                 return false;
458:         }
459:
460:         public <T extends SDeclIR> List<T> getAllDecls(SClassDeclIR classDecl,
461:                         List<SClassDeclIR> classes, DeclStrategy<T> strategy)
462:         {
463:                 List<T> allDecls = new LinkedList<T>();
464:
465:                 allDecls.addAll(strategy.getDecls(classDecl));
466:
467:                 Set<String> allSuperNames = getSuperClasses(classDecl, classes);
468:
469:                 for (String s : allSuperNames)
470:                 {
471:                         SClassDeclIR superClassDecl = findClass(classes, s);
472:
473:                         if (superClassDecl != null)
474:                         {
475:                                 for (T superDecl : strategy.getDecls(superClassDecl))
476:                                 {
477:                                         if (isInherited(strategy.getAccess(superDecl)))
478:                                         {
479:                                                 allDecls.add(superDecl);
480:                                         }
481:                                 }
482:                         }
483:                 }
484:
485:                 return allDecls;
486:         }
487:
488:         public Set<String> getSuperClasses(SClassDeclIR classDecl,
489:                         List<SClassDeclIR> classes)
490:         {
491:                 if (classDecl.getSuperNames().isEmpty())
492:                 {
493:                         return new HashSet<>();
494:                 } else
495:                 {
496:                         Set<String> superClasses = new HashSet<>();
497:
498:                         for (ATokenNameIR s : classDecl.getSuperNames())
499:                         {
500:                                 superClasses.add(s.getName());
501:
502:                                 SClassDeclIR clazz = findClass(classes, s.getName());
503:
504:                                 if (clazz != null)
505:                                 {
506:                                         superClasses.addAll(getSuperClasses(clazz, classes));
507:                                 }
508:                         }
509:
510:                         return superClasses;
511:                 }
512:         }
513:
514:         public List<AMethodDeclIR> getAllMethods(SClassDeclIR classDecl,
515:                         List<SClassDeclIR> classes)
516:         {
517:                 DeclStrategy<AMethodDeclIR> methodDeclStrategy = new DeclStrategy<AMethodDeclIR>()
518:                 {
519:                         @Override
520:                         public String getAccess(AMethodDeclIR decl)
521:                         {
522:                                 return decl.getAccess();
523:                         }
524:
525:                         @Override
526:                         public List<AMethodDeclIR> getDecls(SClassDeclIR classDecl)
527:                         {
528:                                 return classDecl.getMethods();
529:                         }
530:                 };
531:
532:                 return getAllDecls(classDecl, classes, methodDeclStrategy);
533:         }
534:
535:         public List<AFieldDeclIR> getAllFields(SClassDeclIR classDecl,
536:                         List<SClassDeclIR> classes)
537:         {
538:                 DeclStrategy<AFieldDeclIR> fieldDeclStrategy = new DeclStrategy<AFieldDeclIR>()
539:                 {
540:                         @Override
541:                         public String getAccess(AFieldDeclIR decl)
542:                         {
543:                                 return decl.getAccess();
544:                         }
545:
546:                         @Override
547:                         public List<AFieldDeclIR> getDecls(SClassDeclIR classDecl)
548:                         {
549:                                 return classDecl.getFields();
550:                         }
551:                 };
552:
553:                 return getAllDecls(classDecl, classes, fieldDeclStrategy);
554:         }
555:
556:         public boolean isInherited(String access)
557:         {
558:                 return access.equals(IRConstants.PROTECTED)
559:                                 || access.equals(IRConstants.PUBLIC);
560:         }
561:
562:         public void setFinalLocalDefs(List<PDefinition> localDefs,
563:                         List<AVarDeclIR> localDecls, IRInfo question)
564:                         throws AnalysisException
565:         {
566:                 for (PDefinition def : localDefs)
567:                 {
568:                         AVarDeclIR varDecl = null;
569:
570:                         if (def instanceof AValueDefinition)
571:                         {
572:                                 varDecl = consLocalVarDecl((AValueDefinition) def, question);
573:                         } else if (def instanceof AEqualsDefinition)
574:                         {
575:                                 varDecl = consLocalVarDecl((AEqualsDefinition) def, question);
576:                         }
577:
578:                         if (varDecl != null)
579:                         {
580:                                 varDecl.setFinal(true);
581:                                 localDecls.add(varDecl);
582:                         } else
583:                         {
584:                                 log.error("Problems encountered when trying to construct local variable");
585:                         }
586:                 }
587:         }
588:
589:         public SClassDeclIR findClass(List<SClassDeclIR> classes, String moduleName)
590:         {
591:                 for (SClassDeclIR classDecl : classes)
592:                 {
593:                         if (classDecl.getName().equals(moduleName))
594:                         {
595:                                 return classDecl;
596:                         }
597:                 }
598:
599:                 return null;
600:         }
601:
602:         // This method assumes that the record is defined in definingClass and not a super class
603:         public ARecordDeclIR findRecord(SClassDeclIR definingClass,
604:                         String recordName)
605:         {
606:                 for (ATypeDeclIR typeDecl : definingClass.getTypeDecls())
607:                 {
608:                         SDeclIR decl = typeDecl.getDecl();
609:
610:                         if (!(decl instanceof ARecordDeclIR))
611:                         {
612:                                 continue;
613:                         }
614:
615:                         ARecordDeclIR recordDecl = (ARecordDeclIR) decl;
616:
617:                         if (recordDecl.getName().equals(recordName))
618:                         {
619:                                 return recordDecl;
620:                         }
621:                 }
622:
623:                 return null;
624:         }
625:
626:         // This method assumes that the record is defined in definingClass and not a super class
627:         public List<ARecordDeclIR> getRecords(SClassDeclIR definingClass)
628:         {
629:                 List<ARecordDeclIR> records = new LinkedList<ARecordDeclIR>();
630:
631:                 for (ATypeDeclIR typeDecl : definingClass.getTypeDecls())
632:                 {
633:                         SDeclIR decl = typeDecl.getDecl();
634:
635:                         if (!(decl instanceof ARecordDeclIR))
636:                         {
637:                                 continue;
638:                         }
639:
640:                         ARecordDeclIR recordDecl = (ARecordDeclIR) decl;
641:
642:                         records.add(recordDecl);
643:                 }
644:
645:                 return records;
646:         }
647:
648:         public ARecordDeclIR findRecord(List<SClassDeclIR> classes,
649:                         ARecordTypeIR recordType)
650:         {
651:                 SClassDeclIR definingClass = findClass(classes, recordType.getName().getDefiningClass());
652:                 ARecordDeclIR record = findRecord(definingClass, recordType.getName().getName());
653:
654:                 return record;
655:         }
656:
657:         private AVarDeclIR consLocalVarDecl(AValueDefinition valueDef,
658:                         IRInfo question) throws AnalysisException
659:         {
660:                 STypeIR type = valueDef.getType().apply(question.getTypeVisitor(), question);
661:                 SPatternIR pattern = valueDef.getPattern().apply(question.getPatternVisitor(), question);
662:                 SExpIR exp = valueDef.getExpression().apply(question.getExpVisitor(), question);
663:
664:                 return consLocalVarDecl(valueDef, type, pattern, exp);
665:
666:         }
667:
668:         private AVarDeclIR consLocalVarDecl(AEqualsDefinition equalsDef,
669:                         IRInfo question) throws AnalysisException
670:         {
671:                 STypeIR type = equalsDef.getExpType().apply(question.getTypeVisitor(), question);
672:                 SPatternIR pattern = equalsDef.getPattern().apply(question.getPatternVisitor(), question);
673:                 SExpIR exp = equalsDef.getTest().apply(question.getExpVisitor(), question);
674:
675:                 return consLocalVarDecl(equalsDef, type, pattern, exp);
676:
677:         }
678:
679:         public AVarDeclIR consLocalVarDecl(STypeIR type, SPatternIR pattern,
680:                         SExpIR exp)
681:         {
682:                 return consLocalVarDecl(exp.getSourceNode() != null
683:                                 ? exp.getSourceNode().getVdmNode() : null, type, pattern, exp);
684:         }
685:
686:         public AVarDeclIR consLocalVarDecl(INode node, STypeIR type,
687:                         SPatternIR pattern, SExpIR exp)
688:         {
689:                 AVarDeclIR localVarDecl = new AVarDeclIR();
690:                 localVarDecl.setType(type);
691:                 localVarDecl.setFinal(false);
692:                 localVarDecl.setSourceNode(node != null ? new SourceNode(node) : null);
693:                 localVarDecl.setPattern(pattern);
694:                 localVarDecl.setExp(exp);
695:
696:                 return localVarDecl;
697:         }
698:
699:         public AFieldDeclIR constructField(String access, String name,
700:                         boolean isStatic, boolean isFinal, STypeIR type, SExpIR exp)
701:         {
702:
703:                 AFieldDeclIR field = new AFieldDeclIR();
704:                 field.setAccess(access);
705:                 field.setName(name);
706:                 field.setVolatile(false);
707:                 field.setStatic(isStatic);
708:                 field.setFinal(isFinal);
709:                 field.setType(type);
710:                 field.setInitial(exp);
711:
712:                 return field;
713:         }
714:
715:         public Set<ILexNameToken> getOverloadedMethodNames(
716:                         AClassClassDefinition classDef)
717:         {
718:                 List<LexNameTokenWrapper> methodNames = getMethodNames(classDef);
719:                 Set<LexNameTokenWrapper> duplicates = findDuplicates(methodNames);
720:
721:                 Set<ILexNameToken> overloadedMethodNames = new HashSet<ILexNameToken>();
722:
723:                 for (LexNameTokenWrapper wrapper : methodNames)
724:                 {
725:                         if (duplicates.contains(wrapper))
726:                         {
727:                                 overloadedMethodNames.add(wrapper.getName());
728:                         }
729:                 }
730:
731:                 return overloadedMethodNames;
732:         }
733:
734:         private Set<LexNameTokenWrapper> findDuplicates(
735:                         List<LexNameTokenWrapper> nameWrappers)
736:         {
737:                 Set<LexNameTokenWrapper> duplicates = new HashSet<LexNameTokenWrapper>();
738:                 Set<LexNameTokenWrapper> temp = new HashSet<LexNameTokenWrapper>();
739:
740:                 for (LexNameTokenWrapper wrapper : nameWrappers)
741:                 {
742:                         if (!temp.add(wrapper))
743:                         {
744:                                 duplicates.add(wrapper);
745:                         }
746:                 }
747:
748:                 return duplicates;
749:         }
750:
751:         private List<LexNameTokenWrapper> getMethodNames(
752:                         AClassClassDefinition classDef)
753:         {
754:                 List<LexNameTokenWrapper> methodNames = new LinkedList<LexNameTokenWrapper>();
755:
756:                 List<PDefinition> allDefs = new LinkedList<PDefinition>();
757:
758:                 LinkedList<PDefinition> defs = classDef.getDefinitions();
759:                 LinkedList<PDefinition> inheritedDefs = classDef.getAllInheritedDefinitions();
760:
761:                 allDefs.addAll(defs);
762:                 allDefs.addAll(inheritedDefs);
763:
764:                 for (PDefinition def : allDefs)
765:                 {
766:                         if (def instanceof SOperationDefinition
767:                                         || def instanceof SFunctionDefinition)
768:                         {
769:                                 methodNames.add(new LexNameTokenWrapper(def.getName()));
770:                         }
771:                 }
772:
773:                 return methodNames;
774:         }
775:
776:         public void setDefaultValue(AVarDeclIR localDecl, STypeIR typeCg)
777:         {
778:                 ExpAssistantIR expAssistant = assistantManager.getExpAssistant();
779:
780:                 if (typeCg instanceof AStringTypeIR)
781:                 {
782:                         localDecl.setExp(expAssistant.getDefaultStringlValue());
783:                 } else if (typeCg instanceof ACharBasicTypeIR)
784:                 {
785:                         localDecl.setExp(expAssistant.getDefaultCharlValue());
786:                 } else if (typeCg instanceof AIntNumericBasicTypeIR)
787:                 {
788:                         localDecl.setExp(expAssistant.getDefaultIntValue());
789:                 } else if (typeCg instanceof ANat1NumericBasicTypeIR)
790:                 {
791:                         localDecl.setExp(expAssistant.getDefaultNat1Value());
792:                 } else if (typeCg instanceof ANatNumericBasicTypeIR)
793:                 {
794:                         localDecl.setExp(expAssistant.getDefaultNatValue());
795:                 } else if (typeCg instanceof ARealNumericBasicTypeIR)
796:                 {
797:                         localDecl.setExp(expAssistant.getDefaultRealValue());
798:                 } else if (typeCg instanceof ABoolBasicTypeIR)
799:                 {
800:                         localDecl.setExp(expAssistant.getDefaultBoolValue());
801:                 } else
802:                 {
803:                         localDecl.setExp(assistantManager.getExpAssistant().consUndefinedExp());
804:                 }
805:         }
806:
807:         public AFieldDeclIR getFieldDecl(List<SClassDeclIR> classes,
808:                         ARecordTypeIR recordType, int number)
809:         {
810:                 ARecordDeclIR record = findRecord(classes, recordType);
811:
812:                 return record.getFields().get(number);
813:         }
814:
815:         public AFieldDeclIR getFieldDecl(SClassDeclIR clazz, String fieldName)
816:         {
817:                 for (AFieldDeclIR field : clazz.getFields())
818:                 {
819:                         if (field.getName().equals(fieldName))
820:                         {
821:                                 return field;
822:                         }
823:                 }
824:
825:                 return null;
826:         }
827:
828:         public AFieldDeclIR getFieldDecl(List<SClassDeclIR> classes,
829:                         ARecordTypeIR recordType, String memberName)
830:         {
831:                 ATypeNameIR name = recordType.getName();
832:
833:                 if (name == null)
834:                 {
835:                         throw new IllegalArgumentException("Could not find type name for record type: "
836:                                         + recordType);
837:                 }
838:
839:                 String definingClassName = name.getDefiningClass();
840:
841:                 if (definingClassName == null)
842:                 {
843:                         throw new IllegalArgumentException("Could not find defining class for record type: "
844:                                         + recordType);
845:                 }
846:
847:                 String recName = name.getName();
848:
849:                 if (recName == null)
850:                 {
851:                         throw new IllegalArgumentException("Could not find record name for record type: "
852:                                         + recordType);
853:                 }
854:
855:                 SClassDeclIR definingClass = null;
856:                 for (SClassDeclIR currentClass : classes)
857:                 {
858:                         if (currentClass.getName().equals(definingClassName))
859:                         {
860:                                 definingClass = currentClass;
861:                                 break;
862:                         }
863:                 }
864:
865:                 if (definingClass == null)
866:                 {
867:                         throw new IllegalArgumentException("Could not find defining class with name: "
868:                                         + definingClassName);
869:                 }
870:
871:                 List<ARecordDeclIR> records = getRecords(definingClass);
872:
873:                 ARecordDeclIR recordDecl = null;
874:                 for (ARecordDeclIR currentRec : records)
875:                 {
876:                         if (currentRec.getName().equals(recName))
877:                         {
878:                                 recordDecl = currentRec;
879:                                 break;
880:                         }
881:                 }
882:
883:                 if (recordDecl == null)
884:                 {
885:                         throw new IllegalArgumentException("Could not find record with name '"
886:                                         + recName + "' in class '" + definingClassName + "'");
887:                 }
888:
889:                 List<AFieldDeclIR> fields = recordDecl.getFields();
890:
891:                 AFieldDeclIR field = null;
892:                 for (AFieldDeclIR currentField : fields)
893:                 {
894:                         if (currentField.getName().equals(memberName))
895:                         {
896:                                 field = currentField;
897:                         }
898:                 }
899:
900:                 return field;
901:         }
902:
903:         public AMethodDeclIR initMethod(SOperationDefinition node, IRInfo question)
904:                         throws AnalysisException
905:         {
906:                 String access = node.getAccess().getAccess().toString();
907:                 boolean isStatic = question.getTcFactory().createPDefinitionAssistant().isStatic(node);
908:                 boolean isAsync = question.getTcFactory().createPAccessSpecifierAssistant().isAsync(node.getAccess());
909:                 String operationName = node.getName().getName();
910:                 STypeIR type = node.getType().apply(question.getTypeVisitor(), question);
911:
912:                 if (!(type instanceof AMethodTypeIR))
913:                 {
914:                         return null;
915:                 }
916:
917:                 AMethodTypeIR methodType = (AMethodTypeIR) type;
918:
919:                 SStmIR bodyCg = null;
920:                 if (node.getBody() != null)
921:                 {
922:                         bodyCg = node.getBody().apply(question.getStmVisitor(), question);
923:                 }
924:
925:                 boolean isConstructor = node.getIsConstructor();
926:                 boolean isAbstract = node.getBody() instanceof ASubclassResponsibilityStm;
927:
928:                 AMethodDeclIR method = new AMethodDeclIR();
929:
930:                 method.setImplicit(false);
931:                 method.setAccess(access);
932:                 method.setStatic(isStatic);
933:                 method.setAsync(isAsync);
934:                 method.setMethodType(methodType);
935:                 method.setName(operationName);
936:                 method.setBody(bodyCg);
937:                 method.setIsConstructor(isConstructor);
938:                 method.setAbstract(isAbstract);
939:                 method.setImplicit(node instanceof AImplicitOperationDefinition);
940:
941:                 AExplicitFunctionDefinition preCond = node.getPredef();
942:                 SDeclIR preCondCg = preCond != null
943:                                 ? preCond.apply(question.getDeclVisitor(), question) : null;
944:                 method.setPreCond(preCondCg);
945:
946:                 AExplicitFunctionDefinition postCond = node.getPostdef();
947:                 SDeclIR postCondCg = postCond != null
948:                                 ? postCond.apply(question.getDeclVisitor(), question) : null;
949:                 method.setPostCond(postCondCg);
950:
951:                 return method;
952:         }
953:
954:         public List<AFormalParamLocalParamIR> consFormalParams(
955:                         List<APatternListTypePair> params, IRInfo question)
956:                         throws AnalysisException
957:         {
958:                 List<AFormalParamLocalParamIR> paramsCg = new LinkedList<>();
959:                 for (APatternListTypePair patternListPair : params)
960:                 {
961:                         STypeIR pairTypeCg = patternListPair.getType().apply(question.getTypeVisitor(), question);
962:
963:                         for (PPattern p : patternListPair.getPatterns())
964:                         {
965:                                 SPatternIR patternCg = p.apply(question.getPatternVisitor(), question);
966:
967:                                 AFormalParamLocalParamIR paramCg = new AFormalParamLocalParamIR();
968:                                 paramCg.setPattern(patternCg);
969:                                 paramCg.setType(pairTypeCg.clone());
970:
971:                                 paramsCg.add(paramCg);
972:                         }
973:                 }
974:                 return paramsCg;
975:         }
976:
977:         /**
978:          * Based on the definition table computed by {@link IRGenerator#computeDefTable(List)} this method determines
979:          * whether a identifier state designator is local or not.
980:          *
981:          * @param id
982:          * The identifier state designator
983:          * @param info
984:          * The IR info
985:          * @return True if <code>id</code> is local - false otherwise
986:          */
987:         public boolean isLocal(AIdentifierStateDesignator id, IRInfo info)
988:         {
989:                 PDefinition idDef = info.getIdStateDesignatorDefs().get(id);
990:
991:                 if (idDef == null)
992:                 {
993:                         log.error("Could not find definition for identifier state designator ");
994:                         return false;
995:                 } else
996:                 {
997:                         return idDef instanceof AAssignmentDefinition;
998:                 }
999:         }
1000:
1001:         public boolean inFunc(INode node)
1002:         {
1003:                 if (node.getAncestor(SFunctionDefinition.class) != null)
1004:                 {
1005:                         return true;
1006:                 }
1007:
1008:                 // If a node appears in a pre or post condition of an operation then the pre/post
1009:                 // expression might be directly linked to the operation. Therefore the above ancestor
1010:                 // check will not work.
1011:
1012:                 return appearsInPreOrPosOfEnclosingOp(node) || appearsInInvariant(node);
1013:         }
1014:
1015:         private boolean appearsInInvariant(INode node) {
1016:                 
1017:                 return node.getAncestor(AStateDefinition.class) != null;
1018:         }
1019:
1020:         public boolean appearsInPreOrPosOfEnclosingFunc(INode node)
1021:         {
1022:                 SFunctionDefinition encFunc = node.getAncestor(SFunctionDefinition.class);
1023:
1024:                 if (encFunc == null)
1025:                 {
1026:                         return false;
1027:                 }
1028:
1029:                 PExp preCond = encFunc.getPrecondition();
1030:                 PExp postCond = encFunc.getPostcondition();
1031:
1032:                 return appearsInPreOrPostExp(node, preCond, postCond);
1033:         }
1034:
1035:         public boolean appearsInPreOrPosOfEnclosingOp(INode node)
1036:         {
1037:                 SOperationDefinition encOp = node.getAncestor(SOperationDefinition.class);
1038:
1039:                 if (encOp == null)
1040:                 {
1041:                         return false;
1042:                 }
1043:
1044:                 PExp preCond = encOp.getPrecondition();
1045:                 PExp postCond = encOp.getPostcondition();
1046:
1047:                 return appearsInPreOrPostExp(node, preCond, postCond);
1048:         }
1049:
1050:         private boolean appearsInPreOrPostExp(INode node, PExp preCond,
1051:                         PExp postCond)
1052:         {
1053:                 INode next = node;
1054:                 Set<INode> visited = new HashSet<INode>();
1055:
1056:                 while (next.parent() != null
1057:                                 && !(next.parent() instanceof SOperationDefinition)
1058:                                 && !visited.contains(next))
1059:                 {
1060:                         visited.add(next);
1061:                         next = next.parent();
1062:                 }
1063:
1064:                 // If we are in a pre or post condition then 'next' should point to the
1065:                 // pre or post expression of the operation
1066:
1067:                 return preCond == next || postCond == next;
1068:         }
1069:
1070:         public AMethodDeclIR consDefaultContructor(String name)
1071:         {
1072:                 AMethodDeclIR constructor = new AMethodDeclIR();
1073:
1074:                 AClassTypeIR classType = new AClassTypeIR();
1075:                 classType.setName(name);
1076:
1077:                 AMethodTypeIR methodType = new AMethodTypeIR();
1078:                 methodType.setResult(classType);
1079:
1080:                 constructor.setMethodType(methodType);
1081:                 constructor.setAccess(IRConstants.PUBLIC);
1082:                 constructor.setAbstract(false);
1083:                 constructor.setIsConstructor(true);
1084:                 constructor.setName(name);
1085:                 constructor.setImplicit(false);
1086:                 constructor.setBody(new ABlockStmIR());
1087:
1088:                 return constructor;
1089:         }
1090:         
1091:         public SClassDefinition getSourceClass(PIR node) {
1092:
1093:                 SClassDeclIR enclosingClass = node.getAncestor(SClassDeclIR.class);
1094:
1095:                 if (enclosingClass != null) {
1096:
1097:                         INode sourceNode = AssistantBase.getVdmNode(node);
1098:
1099:                         if (sourceNode instanceof SClassDefinition) {
1100:                                 return (SClassDefinition) sourceNode;
1101:                         }
1102:                 }
1103:
1104:                 return null;
1105:         }
1106: }