private void checkVariable(Tree.Term term, Node node) { if (isEffectivelyBaseMemberExpression(term)) { // Note: other cases handled in ExpressionVisitor Tree.StaticMemberOrTypeExpression mte = (Tree.StaticMemberOrTypeExpression) term; Declaration member = mte.getDeclaration(); if (member == declaration) { if ((declaration.isFormal() || declaration.isDefault()) && !isForwardReferenceable()) { term.addError( "member is formal or default and may not be assigned here: '" + member.getName() + "'"); } else if (!isVariable() && !isLate()) { if (member instanceof Value) { if (node instanceof Tree.AssignOp) { term.addError( "value is not a variable and may not be assigned here: '" + member.getName() + "'", 803); } else { term.addError("value is not a variable: '" + member.getName() + "'", 800); } } else { term.addError("not a variable value: '" + member.getName() + "'"); } } } } }
@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); } }
private void visitReference(Tree.Primary that) { Declaration member; boolean assigned; boolean metamodel; if (that instanceof Tree.MemberOrTypeExpression) { Tree.MemberOrTypeExpression mte = (Tree.MemberOrTypeExpression) that; member = mte.getDeclaration(); assigned = mte.getAssigned(); metamodel = false; } else if (that instanceof Tree.MetaLiteral) { Tree.MetaLiteral ml = (Tree.MetaLiteral) that; member = ml.getDeclaration(); assigned = false; metamodel = true; } else { return; } if (member == declaration && member.isDefinedInScope(that.getScope())) { if (!declared) { // you are allowed to refer to later // declarations in a class declaration // section or interface if (withinAttributeInitializer && member instanceof Value && !(((Value) member).isTransient())) { that.addError( "reference to value within its initializer: '" + member.getName() + "'", 1460); } else if (!metamodel && !isForwardReferenceable() && !hasParameter) { Scope container = declaration.getContainer(); if (container instanceof Class) { that.addError( "forward reference to class member in initializer: '" + member.getName() + "' is not yet declared (forward references must occur in declaration section)"); } else { that.addError( "forward reference to local declaration: '" + member.getName() + "' is not yet declared"); } } } else if (!specified.definitely || declaration.isFormal()) { // you are allowed to refer to formal // declarations in a class declaration // section or interface if (declaration.isFormal()) { if (!isForwardReferenceable()) { that.addError( "formal member may not be used in initializer: '" + member.getName() + "'"); } } else if (!metamodel && !isNativeHeader(declaration) && (!isLate() || !isForwardReferenceable())) { if (isVariable()) { that.addError("not definitely initialized: '" + member.getName() + "'"); } else { that.addError("not definitely specified: '" + member.getName() + "'"); } } } if (!assigned && member.isDefault() && !isForwardReferenceable()) { that.addError("default member may not be used in initializer: '" + member.getName() + "'"); } if (inAnonFunctionOrComprehension && specified.definitely && isVariable()) { that.addError( "variable member may not be captured by comprehension or function in extends clause: '" + member.getName() + "'"); } } }