/* * #%~ * VDM Code Generator * %% * Copyright (C) 2008 - 2014 Overture * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program. If not, see * <http://www.gnu.org/licenses/gpl-3.0.html>. * #~% */ package org.overture.codegen.assistant; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import org.overture.ast.analysis.AnalysisException; import org.overture.ast.definitions.AAssignmentDefinition; import org.overture.ast.definitions.AClassClassDefinition; import org.overture.ast.definitions.AEqualsDefinition; import org.overture.ast.definitions.AExplicitFunctionDefinition; import org.overture.ast.definitions.AExplicitOperationDefinition; import org.overture.ast.definitions.AImplicitOperationDefinition; import org.overture.ast.definitions.AInheritedDefinition; import org.overture.ast.definitions.AInstanceVariableDefinition; import org.overture.ast.definitions.ATypeDefinition; import org.overture.ast.definitions.AValueDefinition; import org.overture.ast.definitions.PDefinition; import org.overture.ast.definitions.SClassDefinition; import org.overture.ast.definitions.SFunctionDefinition; import org.overture.ast.definitions.SOperationDefinition; import org.overture.ast.expressions.ASubclassResponsibilityExp; import org.overture.ast.expressions.PExp; import org.overture.ast.intf.lex.ILexNameToken; import org.overture.ast.modules.AModuleModules; import org.overture.ast.node.INode; import org.overture.ast.patterns.APatternListTypePair; import org.overture.ast.patterns.PPattern; import org.overture.ast.statements.AIdentifierStateDesignator; import org.overture.ast.statements.ASubclassResponsibilityStm; import org.overture.ast.types.ARecordInvariantType; import org.overture.ast.util.ClonableString; import org.overture.codegen.ir.IRConstants; import org.overture.codegen.ir.IRGenerator; import org.overture.codegen.ir.IRInfo; import org.overture.codegen.ir.SDeclIR; import org.overture.codegen.ir.SExpIR; import org.overture.codegen.ir.SPatternIR; import org.overture.codegen.ir.SStmIR; import org.overture.codegen.ir.STypeIR; import org.overture.codegen.ir.SourceNode; import org.overture.codegen.ir.declarations.ADefaultClassDeclIR; import org.overture.codegen.ir.declarations.AFieldDeclIR; import org.overture.codegen.ir.declarations.AFormalParamLocalParamIR; import org.overture.codegen.ir.declarations.AFuncDeclIR; import org.overture.codegen.ir.declarations.AMethodDeclIR; import org.overture.codegen.ir.declarations.AMutexSyncDeclIR; import org.overture.codegen.ir.declarations.ANamedTraceDeclIR; import org.overture.codegen.ir.declarations.APersyncDeclIR; import org.overture.codegen.ir.declarations.ARecordDeclIR; import org.overture.codegen.ir.declarations.AThreadDeclIR; import org.overture.codegen.ir.declarations.ATypeDeclIR; import org.overture.codegen.ir.declarations.AVarDeclIR; import org.overture.codegen.ir.declarations.SClassDeclIR; import org.overture.codegen.ir.expressions.ANotImplementedExpIR; import org.overture.codegen.ir.name.ATokenNameIR; import org.overture.codegen.ir.name.ATypeNameIR; import org.overture.codegen.ir.statements.ABlockStmIR; import org.overture.codegen.ir.statements.ANotImplementedStmIR; import org.overture.codegen.ir.statements.AReturnStmIR; import org.overture.codegen.ir.types.ABoolBasicTypeIR; import org.overture.codegen.ir.types.ACharBasicTypeIR; import org.overture.codegen.ir.types.AClassTypeIR; import org.overture.codegen.ir.types.AIntNumericBasicTypeIR; import org.overture.codegen.ir.types.AMethodTypeIR; import org.overture.codegen.ir.types.ANat1NumericBasicTypeIR; import org.overture.codegen.ir.types.ANatNumericBasicTypeIR; import org.overture.codegen.ir.types.ARealNumericBasicTypeIR; import org.overture.codegen.ir.types.ARecordTypeIR; import org.overture.codegen.ir.types.AStringTypeIR; import org.overture.codegen.ir.types.ATemplateTypeIR; import org.overture.codegen.utils.LexNameTokenWrapper; public class DeclAssistantIR extends AssistantBase { public DeclAssistantIR(AssistantManager assistantManager) { super(assistantManager); } public void addDependencies(SClassDeclIR clazz, List<ClonableString> extraDeps, boolean prepend) { NodeAssistantIR nodeAssistant = assistantManager.getNodeAssistant(); clazz.setDependencies(nodeAssistant.buildData(clazz.getDependencies(), extraDeps, prepend)); } public boolean isInnerClass(SClassDeclIR node) { return node.parent() != null && node.parent().getAncestor(SClassDeclIR.class) != null; } public boolean isTestCase(INode node) { if (!(node instanceof SClassDefinition)) { return false; } SClassDefinition clazz = (SClassDefinition) node; for (SClassDefinition d : clazz.getSuperDefs()) { if (d.getName().getName().equals(IRConstants.TEST_CASE)) { return true; } if (isTestCase(d)) { return true; } } return false; } public boolean isFullyAbstract(SClassDefinition clazz, IRInfo info) { if(info.getInstantiatedClasses().contains(clazz.getName().getName())) { return false; } LinkedList<PDefinition> allDefs = new LinkedList<PDefinition>(clazz.getAllInheritedDefinitions()); allDefs.addAll(clazz.getDefinitions()); for (PDefinition def : allDefs) { while (def instanceof AInheritedDefinition) { def = ((AInheritedDefinition) def).getSuperdef(); } if(def instanceof ATypeDefinition) { ATypeDefinition typeDef = (ATypeDefinition) def; if(typeDef.getType() instanceof ARecordInvariantType) { return false; } } if(!IRConstants.PUBLIC.equals(def.getAccess().getAccess().toString())) { return false; } if (def instanceof AInstanceVariableDefinition) { return false; } else if(def instanceof AExplicitOperationDefinition) { AExplicitOperationDefinition op = (AExplicitOperationDefinition) def; boolean isAbstract = op.getBody() == null || op.getBody() instanceof ASubclassResponsibilityStm; if(!isAbstract) { return false; } } else if(def instanceof AExplicitFunctionDefinition) { AExplicitFunctionDefinition fun = (AExplicitFunctionDefinition) def; boolean isAbstract = fun.getBody() == null || fun.getBody() instanceof ASubclassResponsibilityExp; if(!isAbstract) { return false; } } } return true; } public boolean isTest(ADefaultClassDeclIR node) { return node != null && !node.getSuperNames().isEmpty() && node.getSuperNames().get(0).getName().equals(IRConstants.TEST_CASE); } public <T extends SClassDeclIR> T buildClass(SClassDefinition node, IRInfo question, T classCg) throws AnalysisException { String name = node.getName().getName(); String access = node.getAccess().getAccess().toString(); boolean isAbstract = node.getIsAbstract(); boolean isStatic = false; LinkedList<ILexNameToken> superNames = node.getSupernames(); classCg.setPackage(null); classCg.setName(name); classCg.setAccess(access); classCg.setAbstract(isAbstract); classCg.setStatic(isStatic); classCg.setStatic(false); for (ILexNameToken s : superNames) { ATokenNameIR superName = new ATokenNameIR(); superName.setName(s.getName()); classCg.getSuperNames().add(superName); } LinkedList<PDefinition> defs = node.getDefinitions(); for (PDefinition def : defs) { SDeclIR decl = def.apply(question.getDeclVisitor(), question); if (decl == null) { continue;// Unspported stuff returns null by default } if (decl instanceof AFieldDeclIR) { classCg.getFields().add((AFieldDeclIR) decl); } else if (decl instanceof AMethodDeclIR) { classCg.getMethods().add((AMethodDeclIR) decl); } else if (decl instanceof ATypeDeclIR) { classCg.getTypeDecls().add((ATypeDeclIR) decl); } else if (decl instanceof AFuncDeclIR) { classCg.getFunctions().add((AFuncDeclIR) decl); } else if (decl instanceof AThreadDeclIR) { if (question.getSettings().generateConc()) { classCg.setThread((AThreadDeclIR) decl); } } else if (decl instanceof APersyncDeclIR) { classCg.getPerSyncs().add((APersyncDeclIR) decl); } else if (decl instanceof AMutexSyncDeclIR) { classCg.getMutexSyncs().add((AMutexSyncDeclIR) decl); } else if (decl instanceof ANamedTraceDeclIR) { classCg.getTraces().add((ANamedTraceDeclIR) decl); } else { log.error("Unexpected definition in class: " + name + ": " + def.getName().getName() + " at " + def.getLocation()); } } if (node.getInvariant() != null && question.getSettings().generateInvariants()) { SDeclIR invCg = node.getInvariant().apply(question.getDeclVisitor(), question); classCg.setInvariant(invCg); } boolean defaultConstructorExplicit = false; for (AMethodDeclIR method : classCg.getMethods()) { if (method.getIsConstructor() && method.getFormalParams().isEmpty()) { defaultConstructorExplicit = true; break; } } if (!defaultConstructorExplicit) { AMethodDeclIR defaultContructor = question.getDeclAssistant().consDefaultContructor(name); defaultContructor.setSourceNode(new SourceNode(node)); classCg.getMethods().add(defaultContructor); } question.addClass(classCg); return classCg; } public AMethodDeclIR funcToMethod(AFuncDeclIR node) { SDeclIR preCond = node.getPreCond(); SDeclIR postCond = node.getPostCond(); String access = node.getAccess(); Boolean isAbstract = node.getAbstract(); LinkedList<ATemplateTypeIR> templateTypes = node.getTemplateTypes(); AMethodTypeIR methodType = node.getMethodType(); LinkedList<AFormalParamLocalParamIR> formalParams = node.getFormalParams(); String name = node.getName(); SExpIR body = node.getBody(); SourceNode sourceNode = node.getSourceNode(); AMethodDeclIR method = new AMethodDeclIR(); method.setSourceNode(sourceNode); if (preCond != null) { method.setPreCond(preCond.clone()); } if (postCond != null) { method.setPostCond(postCond.clone()); } method.setAccess(access); method.setAbstract(isAbstract); method.setTemplateTypes(cloneNodes(templateTypes, ATemplateTypeIR.class)); method.setMethodType(methodType.clone()); method.setFormalParams(cloneNodes(formalParams, AFormalParamLocalParamIR.class)); method.setName(name); method.setStatic(true); method.setIsConstructor(false); method.setImplicit(node.getImplicit()); if (!(body instanceof ANotImplementedExpIR)) { AReturnStmIR returnStm = new AReturnStmIR(); // Approximate return statement source node as the function body returnStm.setSourceNode(body.getSourceNode()); returnStm.setExp(body.clone()); method.setBody(returnStm); } else { method.setBody(new ANotImplementedStmIR()); } return method; } public String getNodeName(INode node) { if (node instanceof SClassDefinition) { return ((SClassDefinition) node).getName().getName(); } else if (node instanceof AModuleModules) { return ((AModuleModules) node).getName().getName(); } // Fall back return node.toString(); } public boolean isLibrary(INode node) { if (node instanceof SClassDefinition) { return isLibraryName(((SClassDefinition) node).getName().getName()); } else if (node instanceof AModuleModules) { return isLibraryName(((AModuleModules) node).getName().getName()); } return false; } public boolean isLibraryName(String className) { for (int i = 0; i < IRConstants.CLASS_NAMES_USED_IN_VDM.length; i++) { if (IRConstants.CLASS_NAMES_USED_IN_VDM[i].equals(className)) { return true; } } return false; } public <T extends SDeclIR> List<T> getAllDecls(SClassDeclIR classDecl, List<SClassDeclIR> classes, DeclStrategy<T> strategy) { List<T> allDecls = new LinkedList<T>(); allDecls.addAll(strategy.getDecls(classDecl)); Set<String> allSuperNames = getSuperClasses(classDecl, classes); for (String s : allSuperNames) { SClassDeclIR superClassDecl = findClass(classes, s); if (superClassDecl != null) { for (T superDecl : strategy.getDecls(superClassDecl)) { if (isInherited(strategy.getAccess(superDecl))) { allDecls.add(superDecl); } } } } return allDecls; } public Set<String> getSuperClasses(SClassDeclIR classDecl, List<SClassDeclIR> classes) { if (classDecl.getSuperNames().isEmpty()) { return new HashSet<>(); } else { Set<String> superClasses = new HashSet<>(); for (ATokenNameIR s : classDecl.getSuperNames()) { superClasses.add(s.getName()); SClassDeclIR clazz = findClass(classes, s.getName()); if (clazz != null) { superClasses.addAll(getSuperClasses(clazz, classes)); } } return superClasses; } } public List<AMethodDeclIR> getAllMethods(SClassDeclIR classDecl, List<SClassDeclIR> classes) { DeclStrategy<AMethodDeclIR> methodDeclStrategy = new DeclStrategy<AMethodDeclIR>() { @Override public String getAccess(AMethodDeclIR decl) { return decl.getAccess(); } @Override public List<AMethodDeclIR> getDecls(SClassDeclIR classDecl) { return classDecl.getMethods(); } }; return getAllDecls(classDecl, classes, methodDeclStrategy); } public List<AFieldDeclIR> getAllFields(SClassDeclIR classDecl, List<SClassDeclIR> classes) { DeclStrategy<AFieldDeclIR> fieldDeclStrategy = new DeclStrategy<AFieldDeclIR>() { @Override public String getAccess(AFieldDeclIR decl) { return decl.getAccess(); } @Override public List<AFieldDeclIR> getDecls(SClassDeclIR classDecl) { return classDecl.getFields(); } }; return getAllDecls(classDecl, classes, fieldDeclStrategy); } public boolean isInherited(String access) { return access.equals(IRConstants.PROTECTED) || access.equals(IRConstants.PUBLIC); } public void setFinalLocalDefs(List<PDefinition> localDefs, List<AVarDeclIR> localDecls, IRInfo question) throws AnalysisException { for (PDefinition def : localDefs) { AVarDeclIR varDecl = null; if (def instanceof AValueDefinition) { varDecl = consLocalVarDecl((AValueDefinition) def, question); } else if (def instanceof AEqualsDefinition) { varDecl = consLocalVarDecl((AEqualsDefinition) def, question); } if (varDecl != null) { varDecl.setFinal(true); localDecls.add(varDecl); } else { log.error("Problems encountered when trying to construct local variable"); } } } public SClassDeclIR findClass(List<SClassDeclIR> classes, String moduleName) { for (SClassDeclIR classDecl : classes) { if (classDecl.getName().equals(moduleName)) { return classDecl; } } return null; } // This method assumes that the record is defined in definingClass and not a super class public ARecordDeclIR findRecord(SClassDeclIR definingClass, String recordName) { for (ATypeDeclIR typeDecl : definingClass.getTypeDecls()) { SDeclIR decl = typeDecl.getDecl(); if (!(decl instanceof ARecordDeclIR)) { continue; } ARecordDeclIR recordDecl = (ARecordDeclIR) decl; if (recordDecl.getName().equals(recordName)) { return recordDecl; } } return null; } // This method assumes that the record is defined in definingClass and not a super class public List<ARecordDeclIR> getRecords(SClassDeclIR definingClass) { List<ARecordDeclIR> records = new LinkedList<ARecordDeclIR>(); for (ATypeDeclIR typeDecl : definingClass.getTypeDecls()) { SDeclIR decl = typeDecl.getDecl(); if (!(decl instanceof ARecordDeclIR)) { continue; } ARecordDeclIR recordDecl = (ARecordDeclIR) decl; records.add(recordDecl); } return records; } public ARecordDeclIR findRecord(List<SClassDeclIR> classes, ARecordTypeIR recordType) { SClassDeclIR definingClass = findClass(classes, recordType.getName().getDefiningClass()); ARecordDeclIR record = findRecord(definingClass, recordType.getName().getName()); return record; } private AVarDeclIR consLocalVarDecl(AValueDefinition valueDef, IRInfo question) throws AnalysisException { STypeIR type = valueDef.getType().apply(question.getTypeVisitor(), question); SPatternIR pattern = valueDef.getPattern().apply(question.getPatternVisitor(), question); SExpIR exp = valueDef.getExpression().apply(question.getExpVisitor(), question); return consLocalVarDecl(valueDef, type, pattern, exp); } private AVarDeclIR consLocalVarDecl(AEqualsDefinition equalsDef, IRInfo question) throws AnalysisException { STypeIR type = equalsDef.getExpType().apply(question.getTypeVisitor(), question); SPatternIR pattern = equalsDef.getPattern().apply(question.getPatternVisitor(), question); SExpIR exp = equalsDef.getTest().apply(question.getExpVisitor(), question); return consLocalVarDecl(equalsDef, type, pattern, exp); } public AVarDeclIR consLocalVarDecl(STypeIR type, SPatternIR pattern, SExpIR exp) { return consLocalVarDecl(exp.getSourceNode() != null ? exp.getSourceNode().getVdmNode() : null, type, pattern, exp); } public AVarDeclIR consLocalVarDecl(INode node, STypeIR type, SPatternIR pattern, SExpIR exp) { AVarDeclIR localVarDecl = new AVarDeclIR(); localVarDecl.setType(type); localVarDecl.setFinal(false); localVarDecl.setSourceNode(node != null ? new SourceNode(node) : null); localVarDecl.setPattern(pattern); localVarDecl.setExp(exp); return localVarDecl; } public AFieldDeclIR constructField(String access, String name, boolean isStatic, boolean isFinal, STypeIR type, SExpIR exp) { AFieldDeclIR field = new AFieldDeclIR(); field.setAccess(access); field.setName(name); field.setVolatile(false); field.setStatic(isStatic); field.setFinal(isFinal); field.setType(type); field.setInitial(exp); return field; } public Set<ILexNameToken> getOverloadedMethodNames( AClassClassDefinition classDef) { List<LexNameTokenWrapper> methodNames = getMethodNames(classDef); Set<LexNameTokenWrapper> duplicates = findDuplicates(methodNames); Set<ILexNameToken> overloadedMethodNames = new HashSet<ILexNameToken>(); for (LexNameTokenWrapper wrapper : methodNames) { if (duplicates.contains(wrapper)) { overloadedMethodNames.add(wrapper.getName()); } } return overloadedMethodNames; } private Set<LexNameTokenWrapper> findDuplicates( List<LexNameTokenWrapper> nameWrappers) { Set<LexNameTokenWrapper> duplicates = new HashSet<LexNameTokenWrapper>(); Set<LexNameTokenWrapper> temp = new HashSet<LexNameTokenWrapper>(); for (LexNameTokenWrapper wrapper : nameWrappers) { if (!temp.add(wrapper)) { duplicates.add(wrapper); } } return duplicates; } private List<LexNameTokenWrapper> getMethodNames( AClassClassDefinition classDef) { List<LexNameTokenWrapper> methodNames = new LinkedList<LexNameTokenWrapper>(); List<PDefinition> allDefs = new LinkedList<PDefinition>(); LinkedList<PDefinition> defs = classDef.getDefinitions(); LinkedList<PDefinition> inheritedDefs = classDef.getAllInheritedDefinitions(); allDefs.addAll(defs); allDefs.addAll(inheritedDefs); for (PDefinition def : allDefs) { if (def instanceof SOperationDefinition || def instanceof SFunctionDefinition) { methodNames.add(new LexNameTokenWrapper(def.getName())); } } return methodNames; } public void setDefaultValue(AVarDeclIR localDecl, STypeIR typeCg) { ExpAssistantIR expAssistant = assistantManager.getExpAssistant(); if (typeCg instanceof AStringTypeIR) { localDecl.setExp(expAssistant.getDefaultStringlValue()); } else if (typeCg instanceof ACharBasicTypeIR) { localDecl.setExp(expAssistant.getDefaultCharlValue()); } else if (typeCg instanceof AIntNumericBasicTypeIR) { localDecl.setExp(expAssistant.getDefaultIntValue()); } else if (typeCg instanceof ANat1NumericBasicTypeIR) { localDecl.setExp(expAssistant.getDefaultNat1Value()); } else if (typeCg instanceof ANatNumericBasicTypeIR) { localDecl.setExp(expAssistant.getDefaultNatValue()); } else if (typeCg instanceof ARealNumericBasicTypeIR) { localDecl.setExp(expAssistant.getDefaultRealValue()); } else if (typeCg instanceof ABoolBasicTypeIR) { localDecl.setExp(expAssistant.getDefaultBoolValue()); } else { localDecl.setExp(assistantManager.getExpAssistant().consUndefinedExp()); } } public AFieldDeclIR getFieldDecl(List<SClassDeclIR> classes, ARecordTypeIR recordType, int number) { ARecordDeclIR record = findRecord(classes, recordType); return record.getFields().get(number); } public AFieldDeclIR getFieldDecl(SClassDeclIR clazz, String fieldName) { for (AFieldDeclIR field : clazz.getFields()) { if (field.getName().equals(fieldName)) { return field; } } return null; } public AFieldDeclIR getFieldDecl(List<SClassDeclIR> classes, ARecordTypeIR recordType, String memberName) { ATypeNameIR name = recordType.getName(); if (name == null) { throw new IllegalArgumentException("Could not find type name for record type: " + recordType); } String definingClassName = name.getDefiningClass(); if (definingClassName == null) { throw new IllegalArgumentException("Could not find defining class for record type: " + recordType); } String recName = name.getName(); if (recName == null) { throw new IllegalArgumentException("Could not find record name for record type: " + recordType); } SClassDeclIR definingClass = null; for (SClassDeclIR currentClass : classes) { if (currentClass.getName().equals(definingClassName)) { definingClass = currentClass; break; } } if (definingClass == null) { throw new IllegalArgumentException("Could not find defining class with name: " + definingClassName); } List<ARecordDeclIR> records = getRecords(definingClass); ARecordDeclIR recordDecl = null; for (ARecordDeclIR currentRec : records) { if (currentRec.getName().equals(recName)) { recordDecl = currentRec; break; } } if (recordDecl == null) { throw new IllegalArgumentException("Could not find record with name '" + recName + "' in class '" + definingClassName + "'"); } List<AFieldDeclIR> fields = recordDecl.getFields(); AFieldDeclIR field = null; for (AFieldDeclIR currentField : fields) { if (currentField.getName().equals(memberName)) { field = currentField; } } return field; } public AMethodDeclIR initMethod(SOperationDefinition node, IRInfo question) throws AnalysisException { String access = node.getAccess().getAccess().toString(); boolean isStatic = question.getTcFactory().createPDefinitionAssistant().isStatic(node); boolean isAsync = question.getTcFactory().createPAccessSpecifierAssistant().isAsync(node.getAccess()); String operationName = node.getName().getName(); STypeIR type = node.getType().apply(question.getTypeVisitor(), question); if (!(type instanceof AMethodTypeIR)) { return null; } AMethodTypeIR methodType = (AMethodTypeIR) type; SStmIR bodyCg = null; if (node.getBody() != null) { bodyCg = node.getBody().apply(question.getStmVisitor(), question); } boolean isConstructor = node.getIsConstructor(); boolean isAbstract = node.getBody() instanceof ASubclassResponsibilityStm; AMethodDeclIR method = new AMethodDeclIR(); method.setImplicit(false); method.setAccess(access); method.setStatic(isStatic); method.setAsync(isAsync); method.setMethodType(methodType); method.setName(operationName); method.setBody(bodyCg); method.setIsConstructor(isConstructor); method.setAbstract(isAbstract); method.setImplicit(node instanceof AImplicitOperationDefinition); AExplicitFunctionDefinition preCond = node.getPredef(); SDeclIR preCondCg = preCond != null ? preCond.apply(question.getDeclVisitor(), question) : null; method.setPreCond(preCondCg); AExplicitFunctionDefinition postCond = node.getPostdef(); SDeclIR postCondCg = postCond != null ? postCond.apply(question.getDeclVisitor(), question) : null; method.setPostCond(postCondCg); return method; } public List<AFormalParamLocalParamIR> consFormalParams( List<APatternListTypePair> params, IRInfo question) throws AnalysisException { List<AFormalParamLocalParamIR> paramsCg = new LinkedList<>(); for (APatternListTypePair patternListPair : params) { STypeIR pairTypeCg = patternListPair.getType().apply(question.getTypeVisitor(), question); for (PPattern p : patternListPair.getPatterns()) { SPatternIR patternCg = p.apply(question.getPatternVisitor(), question); AFormalParamLocalParamIR paramCg = new AFormalParamLocalParamIR(); paramCg.setPattern(patternCg); paramCg.setType(pairTypeCg.clone()); paramsCg.add(paramCg); } } return paramsCg; } /** * Based on the definition table computed by {@link IRGenerator#computeDefTable(List)} this method determines * whether a identifier state designator is local or not. * * @param id * The identifier state designator * @param info * The IR info * @return True if <code>id</code> is local - false otherwise */ public boolean isLocal(AIdentifierStateDesignator id, IRInfo info) { PDefinition idDef = info.getIdStateDesignatorDefs().get(id); if (idDef == null) { log.error("Could not find definition for identifier state designator "); return false; } else { return idDef instanceof AAssignmentDefinition; } } public boolean inFunc(INode node) { if (node.getAncestor(SFunctionDefinition.class) != null) { return true; } // If a node appears in a pre or post condition of an operation then the pre/post // expression might be directly linked to the operation. Therefore the above ancestor // check will not work. return appearsInPreOrPosOfEnclosingOp(node); } public boolean appearsInPreOrPosOfEnclosingFunc(INode node) { SFunctionDefinition encFunc = node.getAncestor(SFunctionDefinition.class); if (encFunc == null) { return false; } PExp preCond = encFunc.getPrecondition(); PExp postCond = encFunc.getPostcondition(); return appearsInPreOrPostExp(node, preCond, postCond); } public boolean appearsInPreOrPosOfEnclosingOp(INode node) { SOperationDefinition encOp = node.getAncestor(SOperationDefinition.class); if (encOp == null) { return false; } PExp preCond = encOp.getPrecondition(); PExp postCond = encOp.getPostcondition(); return appearsInPreOrPostExp(node, preCond, postCond); } private boolean appearsInPreOrPostExp(INode node, PExp preCond, PExp postCond) { INode next = node; Set<INode> visited = new HashSet<INode>(); while (next.parent() != null && !(next.parent() instanceof SOperationDefinition) && !visited.contains(next)) { visited.add(next); next = next.parent(); } // If we are in a pre or post condition then 'next' should point to the // pre or post expression of the operation return preCond == next || postCond == next; } public AMethodDeclIR consDefaultContructor(String name) { AMethodDeclIR constructor = new AMethodDeclIR(); AClassTypeIR classType = new AClassTypeIR(); classType.setName(name); AMethodTypeIR methodType = new AMethodTypeIR(); methodType.setResult(classType); constructor.setMethodType(methodType); constructor.setAccess(IRConstants.PUBLIC); constructor.setAbstract(false); constructor.setIsConstructor(true); constructor.setName(name); constructor.setImplicit(false); constructor.setBody(new ABlockStmIR()); return constructor; } }