protected static Node getIdentifier(Node node) { if (node instanceof Tree.SpecifierStatement) { Tree.SpecifierStatement st = (Tree.SpecifierStatement) node; Tree.Term lhs = st.getBaseMemberExpression(); while (lhs instanceof Tree.ParameterizedExpression) { Tree.ParameterizedExpression pe = (Tree.ParameterizedExpression) lhs; lhs = pe.getPrimary(); } if (lhs instanceof Tree.StaticMemberOrTypeExpression) { Tree.StaticMemberOrTypeExpression mte = (Tree.StaticMemberOrTypeExpression) lhs; return mte.getIdentifier(); } else { throw new RuntimeException("impossible"); } } else { return getIdentifyingNode(node); } }
@Override public void visit(Tree.SpecifierStatement that) { Tree.Term term = that.getBaseMemberExpression(); boolean parameterized = false; while (term instanceof Tree.ParameterizedExpression) { Tree.ParameterizedExpression pe = (Tree.ParameterizedExpression) term; term = pe.getPrimary(); parameterized = true; } if (term instanceof Tree.StaticMemberOrTypeExpression) { Tree.StaticMemberOrTypeExpression bme = (Tree.StaticMemberOrTypeExpression) term; // Declaration member = getTypedDeclaration(bme.getScope(), // name(bme.getIdentifier()), null, false, bme.getUnit()); Declaration member = bme.getDeclaration(); if (member == declaration) { if ((declaration.isFormal() || declaration.isDefault()) && !isForwardReferenceable()) { // TODO: is this error correct?! look at the condition above bme.addError( "member is formal and may not be specified: '" + member.getName() + "' is declared formal"); } if (that.getRefinement()) { declare(); } Tree.SpecifierExpression se = that.getSpecifierExpression(); boolean lazy = se instanceof Tree.LazySpecifierExpression; if (declaration instanceof Value) { Value value = (Value) declaration; if (!value.isVariable() && lazy != value.isTransient()) { // check that all assignments to a non-variable, in // different paths of execution, all use the same // kind of specifier, all =>, or all = // TODO: sometimes this error appears only because // of a later line which illegally reassigns se.addError( "value must be specified using => lazy specifier: '" + member.getName() + "'"); } if (lazy) { if (value.isVariable()) { se.addError( "variable value may not be specified using => lazy specifier: '" + member.getName() + "'"); } else if (value.isLate()) { se.addError( "late reference may not be specified using => lazy specifier: '" + member.getName() + "'"); } } } if (!lazy || !parameterized) { se.visit(this); } boolean constant = !isVariable() && !isLate(); Scope scope = that.getScope(); if (constant && !declaration.isDefinedInScope(scope)) { // this error is added by ExpressionVisitor // that.addError("inherited member is not variable and may not be // specified here: '" + // member.getName() + "'"); } else if (!declared && constant) { bme.addError(shortdesc() + " is not yet declared: '" + member.getName() + "'"); } else if (inLoop && constant && !(endsInBreakReturnThrow && lastContinue == null)) { if (specified.definitely) { bme.addError( longdesc() + " is aready definitely specified: '" + member.getName() + "'", 803); } else { bme.addError( longdesc() + " is not definitely unspecified in loop: '" + member.getName() + "'", 803); } } else if (withinDeclaration && constant && !that.getRefinement()) { Declaration dec = getContainingDeclarationOfScope(scope); if (dec != null && dec.equals(member)) { bme.addError( "cannot specify " + shortdesc() + " from within its own body: '" + member.getName() + "'"); } else { bme.addError( "cannot specify " + shortdesc() + " declared in outer scope: '" + member.getName() + "'", 803); } } else if (specified.possibly && constant) { if (specified.definitely) { bme.addError( longdesc() + " is aready definitely specified: '" + member.getName() + "'", 803); } else { bme.addError( longdesc() + " is not definitely unspecified: '" + member.getName() + "'", 803); } } else { specify(); term.visit(this); } if (lazy && parameterized) { se.visit(this); } } else { super.visit(that); } } else { super.visit(that); } }