@Override public void visit(Tree.AssignOp that) { Tree.Term lt = that.getLeftTerm(); if (isEffectivelyBaseMemberExpression(lt)) { Tree.StaticMemberOrTypeExpression m = (Tree.StaticMemberOrTypeExpression) lt; // Declaration member = getTypedDeclaration(m.getScope(), // name(m.getIdentifier()), null, false, m.getUnit()); Declaration member = m.getDeclaration(); if (member == declaration) { if (that.getRightTerm() != null) { that.getRightTerm().visit(this); } checkVariable(lt, that); specify(); lt.visit(this); } else { super.visit(that); } } }
@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 extractExpressionInFile(TextChange tfc) throws CoreException { tfc.setEdit(new MultiTextEdit()); IDocument doc = tfc.getCurrentDocument(null); Tree.Term term = (Tree.Term) node; Integer start = term.getStartIndex(); int length = term.getStopIndex() - start + 1; String exp = toString(term); FindContainerVisitor fsv = new FindContainerVisitor(term); rootNode.visit(fsv); Tree.Declaration decNode = fsv.getDeclaration(); /*if (decNode instanceof Tree.Declaration) { Tree.AnnotationList anns = ((Tree.Declaration) decNode).getAnnotationList(); if (anns!=null && !anns.getAnnotations().isEmpty()) { decNode = anns.getAnnotations().get(0); } }*/ Declaration dec = decNode.getDeclarationModel(); FindLocalReferencesVisitor flrv = new FindLocalReferencesVisitor(dec); term.visit(flrv); List<TypeDeclaration> localTypes = new ArrayList<TypeDeclaration>(); for (Tree.BaseMemberExpression bme : flrv.getLocalReferences()) { addLocalType(dec, bme.getTypeModel(), localTypes, new ArrayList<ProducedType>()); } String params = ""; String args = ""; if (!flrv.getLocalReferences().isEmpty()) { for (Tree.BaseMemberExpression bme : flrv.getLocalReferences()) { params += bme.getTypeModel().getProducedTypeName() + " " + bme.getIdentifier().getText() + ", "; args += bme.getIdentifier().getText() + ", "; } params = params.substring(0, params.length() - 2); args = args.substring(0, args.length() - 2); } String indent = "\n" + getIndent(decNode, doc); String extraIndent = indent + getDefaultIndent(); String typeParams = ""; String constraints = ""; if (!localTypes.isEmpty()) { for (TypeDeclaration t : localTypes) { typeParams += t.getName() + ", "; if (!t.getSatisfiedTypes().isEmpty()) { constraints += extraIndent + getDefaultIndent() + "given " + t.getName() + " satisfies "; for (ProducedType pt : t.getSatisfiedTypes()) { constraints += pt.getProducedTypeName() + "&"; } constraints = constraints.substring(0, constraints.length() - 1); } } typeParams = "<" + typeParams.substring(0, typeParams.length() - 2) + ">"; } String type; String ending; if ("Void".equals(term.getTypeModel().getProducedTypeName())) { type = "void"; ending = ""; } else { type = explicitType || dec.isToplevel() ? term.getTypeModel().getProducedTypeName() : "function"; ending = "return "; } tfc.addEdit( new InsertEdit( decNode.getStartIndex(), type + " " + newName + typeParams + "(" + params + ")" + constraints + " {" + extraIndent + ending + exp + ";" + indent + "}" + indent + indent)); tfc.addEdit(new ReplaceEdit(start, length, newName + "(" + args + ")")); }