Example #1
0
  @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;
  }
Example #4
0
  @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;
  }
  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;
  }