@Override public SStmCG caseAClassInvariantStm(AClassInvariantStm node, IRInfo question) throws AnalysisException { List<PExp> exps = new LinkedList<PExp>(); for (PDefinition d : node.getInvDefs()) { if (!(d instanceof AClassInvariantDefinition)) { Logger.getLog() .printErrorln( "Expected class invariant definition in '" + this.getClass().getName() + "'. Got: " + d); return null; } AClassInvariantDefinition invDef = (AClassInvariantDefinition) d; exps.add(invDef.getExpression()); } AReturnStmCG returnStmCg = new AReturnStmCG(); if (exps.isEmpty()) { // Should not really be necessary returnStmCg.setExp(question.getExpAssistant().consBoolLiteral(true)); } else if (exps.size() == 1) { SExpCG expCg = exps.get(0).apply(question.getExpVisitor(), question); returnStmCg.setExp(expCg); } else { // We have more than one expressions from which we will build an 'and chain' AAndBoolBinaryExpCG andExpTopCg = new AAndBoolBinaryExpCG(); andExpTopCg.setType(new ABoolBasicTypeCG()); andExpTopCg.setLeft(exps.get(0).apply(question.getExpVisitor(), question)); AAndBoolBinaryExpCG previousAndExpCg = andExpTopCg; // The remaining ones except the last for (int i = 1; i < exps.size() - 1; i++) { SExpCG nextExpCg = exps.get(i).apply(question.getExpVisitor(), question); AAndBoolBinaryExpCG nextAndExpCg = new AAndBoolBinaryExpCG(); nextAndExpCg.setType(new ABoolBasicTypeCG()); nextAndExpCg.setLeft(nextExpCg); previousAndExpCg.setRight(nextAndExpCg); previousAndExpCg = nextAndExpCg; } previousAndExpCg.setRight( exps.get(exps.size() - 1).apply(question.getExpVisitor(), question)); returnStmCg.setExp(andExpTopCg); } return returnStmCg; }
@Override public SStmCG caseAReturnStm(AReturnStm node, IRInfo question) throws AnalysisException { PExp exp = node.getExpression(); AExplicitOperationDefinition operation = node.getAncestor(AExplicitOperationDefinition.class); if (operation != null && operation.getIsConstructor()) { if (exp instanceof ASelfExp) { // The expression of the return statement points to 'null' since the OO AST // does not allow constructors to return references to explicitly // created types. Simply 'returning' in a constructor means returning // a reference for the object currently being created. return new AReturnStmCG(); } else { question.addUnsupportedNode( operation, "Unexpected expression returned by constructor: Values expliclty returned by constructors must be 'self'."); return null; } } AReturnStmCG returnStm = new AReturnStmCG(); if (exp != null) { SExpCG expCg = exp.apply(question.getExpVisitor(), question); returnStm.setExp(expCg); } return returnStm; }
private AMethodDeclCG consEqualsMethod(String name) { AIdentifierVarExpCG paramVar = transAssistant .getInfo() .getExpAssistant() .consIdVar(EQUALS_METHOD_PARAM, new AObjectTypeCG()); AClassTypeCG quoteClass = new AClassTypeCG(); quoteClass.setName(name); AInstanceofExpCG instanceCheck = new AInstanceofExpCG(); instanceCheck.setType(new ABoolBasicTypeCG()); instanceCheck.setExp(paramVar); instanceCheck.setCheckedType(quoteClass); AReturnStmCG checkReturned = new AReturnStmCG(); checkReturned.setExp(instanceCheck); AMethodDeclCG equalsMethod = consEqualMethodSignature(EQUALS_METHOD_PARAM); ABlockStmCG body = new ABlockStmCG(); body.getStatements().add(checkReturned); equalsMethod.setBody(body); return equalsMethod; }
private AMethodDeclCG consGetInstanceMethod(String name) { AClassTypeCG quoteClassType = new AClassTypeCG(); quoteClassType.setName(name); AIdentifierVarExpCG instanceVar = transAssistant.getInfo().getExpAssistant().consIdVar(INSTANCE_FIELD, quoteClassType); AEqualsBinaryExpCG nullCompare = new AEqualsBinaryExpCG(); nullCompare.setType(new ABoolBasicTypeCG()); nullCompare.setLeft(instanceVar); nullCompare.setRight(info.getExpAssistant().consNullExp()); AIdentifierVarExpCG instanceId = transAssistant .getInfo() .getExpAssistant() .consIdVar(INSTANCE_FIELD, quoteClassType.clone()); ATypeNameCG typeName = new ATypeNameCG(); typeName.setDefiningClass(null); typeName.setName(name); ANewExpCG newQuote = new ANewExpCG(); newQuote.setName(typeName); newQuote.setType(quoteClassType); AAssignToExpStmCG assignInstance = new AAssignToExpStmCG(); assignInstance.setTarget(instanceId); assignInstance.setExp(newQuote); AIfStmCG ensureInstance = new AIfStmCG(); ensureInstance.setIfExp(nullCompare); ensureInstance.setThenStm(assignInstance); AReturnStmCG returnInstance = new AReturnStmCG(); returnInstance.setExp(instanceVar.clone()); ABlockStmCG body = new ABlockStmCG(); body.getStatements().add(ensureInstance); body.getStatements().add(returnInstance); AMethodTypeCG methodType = new AMethodTypeCG(); methodType.setResult(quoteClassType.clone()); AMethodDeclCG getInstanceMethod = new AMethodDeclCG(); getInstanceMethod.setImplicit(false); getInstanceMethod.setAbstract(false); getInstanceMethod.setAccess(IJavaConstants.PUBLIC); getInstanceMethod.setIsConstructor(false); getInstanceMethod.setName(GET_INSTANCE_METHOD); getInstanceMethod.setStatic(true); getInstanceMethod.setMethodType(methodType); getInstanceMethod.setBody(body); return getInstanceMethod; }
private AMethodDeclCG consToStringMethod(String name) { SExpCG stringLit = info.getExpAssistant().consStringLiteral("<" + name + ">", false); AReturnStmCG returnStr = new AReturnStmCG(); returnStr.setExp(stringLit); AMethodDeclCG toStringMethod = consToStringSignature(); ABlockStmCG body = new ABlockStmCG(); body.getStatements().add(returnStr); toStringMethod.setBody(body); return toStringMethod; }
private AMethodDeclCG consHashcodeMethod() { AIdentifierVarExpCG hashCodeVar = transAssistant.getInfo().getExpAssistant().consIdVar(HASHCODE_FIELD, consFieldType()); AReturnStmCG returnHashCode = new AReturnStmCG(); returnHashCode.setExp(hashCodeVar); AMethodDeclCG hashCodeMethod = consHashcodeMethodSignature(); ABlockStmCG body = new ABlockStmCG(); body.getStatements().add(returnHashCode); hashCodeMethod.setBody(body); return hashCodeMethod; }