/** * Test whether a definition is a class constructor. */ public boolean isConstructor(PDefinition def) { if (def instanceof AExplicitOperationDefinition) { AExplicitOperationDefinition op = (AExplicitOperationDefinition)def; return op.getIsConstructor(); } else if (def instanceof AImplicitOperationDefinition) { AImplicitOperationDefinition op = (AImplicitOperationDefinition)def; return op.getIsConstructor(); } else if (def instanceof AInheritedDefinition) { AInheritedDefinition op = (AInheritedDefinition)def; return isConstructor(op.getSuperdef()); } return false; }
private String getInitName(APlainCallStmIR node) { if (node.getSourceNode() != null && node.getSourceNode().getVdmNode() != null) { INode vdmNode = node.getSourceNode().getVdmNode(); if (vdmNode instanceof ACallStm) { ACallStm c = (ACallStm) vdmNode; PDefinition rootDef = c.getRootdef(); while (rootDef instanceof AInheritedDefinition) { rootDef = ((AInheritedDefinition) rootDef).getSuperdef(); } if (rootDef instanceof AExplicitOperationDefinition) { AExplicitOperationDefinition op = (AExplicitOperationDefinition) rootDef; if (op.getIsConstructor()) { return getObjectInitializerCall(op); } } } } return null; }
@Override public SStmIR 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 AReturnStmIR(); } else { question.addUnsupportedNode(operation, "Unexpected expression returned by constructor: Values expliclty returned by constructors must be 'self'."); return null; } } AReturnStmIR returnStm = new AReturnStmIR(); if (exp != null) { SExpIR expCg = exp.apply(question.getExpVisitor(), question); returnStm.setExp(expCg); } return returnStm; }
@Override public PType caseAReturnStm(AReturnStm node, TypeCheckInfo question) throws AnalysisException { PDefinition encl = question.env.getEnclosingDefinition(); boolean inConstructor = false; if (encl instanceof AExplicitOperationDefinition) { AExplicitOperationDefinition op = (AExplicitOperationDefinition) encl; inConstructor = op.getIsConstructor(); } else if (encl instanceof AImplicitOperationDefinition) { AImplicitOperationDefinition op = (AImplicitOperationDefinition) encl; inConstructor = op.getIsConstructor(); } if (inConstructor && !(node.getExpression() instanceof ASelfExp)) { TypeCheckerErrors.report(3326, "Constructor can only return 'self'", node.getLocation(), node); } if (node.getExpression() == null) { node.setType(AstFactory.newAVoidReturnType(node.getLocation())); } else { node.setType(node.getExpression().apply(THIS, question)); } return question.assistantFactory.createPTypeAssistant().checkReturnType(question.returnType, node.getType(), node.getLocation()); }
&& ((AExplicitOperationDefinition) rootdef).getIsConstructor();
if (node.getIsConstructor() && node.getClassDefinition() != null && node.getClassDefinition().getInvariant() != null) if (!node.getIsConstructor() && !assistantFactory.getTypeComparator().isSubType(node.getActualResult(), ((AOperationType) node.getType()).getResult()))
@Override public NameValuePairList caseAExplicitOperationDefinition( AExplicitOperationDefinition def, Context initialContext) throws AnalysisException { NameValuePairList nvl = new NameValuePairList(); FunctionValue prefunc = def.getPredef() == null ? null : new FunctionValue(def.getPredef(), null, null, null); FunctionValue postfunc = def.getPostdef() == null ? null : new FunctionValue(def.getPostdef(), null, null, null); OperationValue op = new OperationValue(def, prefunc, postfunc, def.getState(), af); op.isConstructor = def.getIsConstructor(); op.isStatic = af.createPAccessSpecifierAssistant().isStatic(def.getAccess()); nvl.add(new NameValuePair(def.getName(), op)); if (def.getPredef() != null) { prefunc.isStatic = af.createPAccessSpecifierAssistant().isStatic(def.getAccess()); nvl.add(new NameValuePair(def.getPredef().getName(), prefunc)); } if (def.getPostdef() != null) { postfunc.isStatic = af.createPAccessSpecifierAssistant().isStatic(def.getAccess()); nvl.add(new NameValuePair(def.getPostdef().getName(), postfunc)); } return nvl; }
if (node.getIsConstructor()) if (node.getIsConstructor() && !question.assistantFactory.createPTypeAssistant().isType(node.getActualResult(), AVoidType.class) && !compatible || !node.getIsConstructor() && !compatible) } else if (!node.getIsConstructor() && !question.assistantFactory.createPTypeAssistant().isUnknown(actualResult))