static List<TypedDeclaration> collectUninitializedMembers(Tree.Body body) {
   List<TypedDeclaration> uninitialized = new ArrayList<TypedDeclaration>();
   if (body != null) {
     List<Tree.Statement> statements = body.getStatements();
     for (Tree.Statement st : statements) {
       if (st instanceof Tree.AttributeDeclaration) {
         Tree.AttributeDeclaration ad = (Tree.AttributeDeclaration) st;
         if (ad.getSpecifierOrInitializerExpression() == null) {
           Value v = ad.getDeclarationModel();
           if (!v.isFormal()) {
             uninitialized.add(v);
           }
         }
       } else if (st instanceof Tree.MethodDeclaration) {
         Tree.MethodDeclaration md = (Tree.MethodDeclaration) st;
         if (md.getSpecifierExpression() == null) {
           Function m = md.getDeclarationModel();
           if (!m.isFormal()) {
             uninitialized.add(m);
           }
         }
       } else if (st instanceof Tree.SpecifierStatement) {
         Tree.SpecifierStatement ss = (Tree.SpecifierStatement) st;
         Tree.Term term = ss.getBaseMemberExpression();
         if (term instanceof Tree.BaseMemberExpression) {
           Tree.BaseMemberExpression bme = (Tree.BaseMemberExpression) term;
           uninitialized.remove(bme.getDeclaration());
         }
       }
     }
   }
   return uninitialized;
 }
 @Override
 public void visit(Tree.AttributeDeclaration that) {
   super.visit(that);
   if (hasOuterRefs(that.getDeclarationModel(), scope, statements)) {
     result = that;
   }
 }
 @Override
 public void visit(Tree.CompilationUnit that) {
   for (Tree.Declaration st : that.getDeclarations()) {
     if (st instanceof Tree.AttributeDeclaration) {
       Tree.AttributeDeclaration ad = (Tree.AttributeDeclaration) st;
       withinAttributeInitializer =
           ad.getDeclarationModel() == declaration
               && !(ad.getSpecifierOrInitializerExpression()
                   instanceof Tree.LazySpecifierExpression);
     } else {
       withinAttributeInitializer = false;
     }
     st.visit(this);
     withinAttributeInitializer = false;
   }
 }
 @Override
 public void visit(Tree.AttributeDeclaration that) {
   ProducedType ort = requiredType;
   requiredType = that.getType().getTypeModel();
   super.visit(that);
   requiredType = ort;
 }
 @Override
 public void visit(Tree.AttributeDeclaration that) {
   if (that.getDeclarationModel() == declaration) {
     Tree.SpecifierOrInitializerExpression sie = that.getSpecifierOrInitializerExpression();
     if (sie != null) {
       super.visit(that);
       specify();
     } else {
       super.visit(that);
       if (declaration.isToplevel() && !isNativeHeader(declaration) && !isLate()) {
         if (isVariable()) {
           that.addError(
               "toplevel variable value must be initialized: '" + declaration.getName() + "'");
         } else {
           that.addError("toplevel value must be specified: '" + declaration.getName() + "'");
         }
       } else if (declaration.isClassOrInterfaceMember()
           && !isNativeHeader(declaration)
           && !declaration.isFormal()
           && that.getDeclarationModel().getInitializerParameter() == null
           && !that.getDeclarationModel().isLate()
           && declarationSection) {
         that.addError(
             "forward declaration may not occur in declaration section: '"
                 + declaration.getName()
                 + "'",
             1450);
       }
     }
   } else {
     super.visit(that);
   }
 }
 public ExtractFunctionRefactoring(ITextEditor editor) {
   super(editor);
   init((ITextSelection) editor.getSelectionProvider().getSelection());
   if (result != null) {
     newName = result.getDeclarationModel().getName();
   } else {
     newName = guessName();
   }
 }
 @Override
 public void visit(Tree.Body that) {
   if (hasParameter && that.getScope() == declaration.getContainer()) {
     hasParameter = false;
   }
   for (Tree.Statement st : that.getStatements()) {
     if (st instanceof Tree.AttributeDeclaration) {
       Tree.AttributeDeclaration ad = (Tree.AttributeDeclaration) st;
       withinAttributeInitializer =
           ad.getDeclarationModel() == declaration
               && !(ad.getSpecifierOrInitializerExpression()
                   instanceof Tree.LazySpecifierExpression);
     } else {
       withinAttributeInitializer = false;
     }
     st.visit(this);
     withinAttributeInitializer = false;
   }
 }
  private void extractStatementsInFile(TextChange tfc) throws CoreException {
    tfc.setEdit(new MultiTextEdit());
    IDocument doc = tfc.getCurrentDocument(null);

    Tree.Body body = (Tree.Body) node;

    Integer start = statements.get(0).getStartIndex();
    int length = statements.get(statements.size() - 1).getStopIndex() - start + 1;
    FindContainerVisitor fsv = new FindContainerVisitor(body);
    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);
    for (Statement s : statements) {
      s.visit(flrv);
    }
    List<TypeDeclaration> localTypes = new ArrayList<TypeDeclaration>();
    List<Tree.BaseMemberExpression> localRefs = new ArrayList<Tree.BaseMemberExpression>();
    for (Tree.BaseMemberExpression bme : flrv.getLocalReferences()) {
      if (result == null || !bme.getDeclaration().equals(result.getDeclarationModel())) {
        FindOuterReferencesVisitor v = new FindOuterReferencesVisitor(bme.getDeclaration());
        for (Statement s : body.getStatements()) {
          if (!statements.contains(s)) {
            s.visit(v);
          }
        }
        if (v.refs > 0) {
          addLocalType(dec, bme.getTypeModel(), localTypes, new ArrayList<ProducedType>());
          localRefs.add(bme);
        }
      }
    }

    String params = "";
    String args = "";
    Set<Declaration> done = new HashSet<Declaration>();
    boolean nonempty = false;
    for (Tree.BaseMemberExpression bme : localRefs) {
      if (done.add(bme.getDeclaration())) {
        params +=
            bme.getTypeModel().getProducedTypeName() + " " + bme.getIdentifier().getText() + ", ";
        args += bme.getIdentifier().getText() + ", ";
        nonempty = true;
      }
    }
    if (nonempty) {
      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 content =
        result == null ? "void" : result.getDeclarationModel().getType().getProducedTypeName();
    content += " " + newName + typeParams + "(" + params + ")" + constraints + " {";
    for (Statement s : statements) {
      content += extraIndent + toString(s);
    }
    if (result != null) {
      content += extraIndent + "return " + result.getDeclarationModel().getName() + ";";
    }
    content += indent + "}" + indent + indent;

    String invocation = newName + "(" + args + ");";
    if (result != null) {
      String modifs;
      if (result.getDeclarationModel().isShared()) {
        modifs = "shared " + result.getDeclarationModel().getType().getProducedTypeName() + " ";
      } else {
        modifs = "value ";
      }
      invocation = modifs + result.getDeclarationModel().getName() + "=" + invocation;
    }

    tfc.addEdit(new InsertEdit(decNode.getStartIndex(), content));
    tfc.addEdit(new ReplaceEdit(start, length, invocation));
  }
  public static String getInitialValueDescription(
      final Declaration dec, CeylonParseController cpc) {
    if (cpc != null) {
      Node refnode = getReferencedNode(dec);
      Tree.SpecifierOrInitializerExpression sie = null;
      String arrow = null;
      if (refnode instanceof Tree.AttributeDeclaration) {
        Tree.AttributeDeclaration ad = (Tree.AttributeDeclaration) refnode;
        sie = ad.getSpecifierOrInitializerExpression();
        arrow = " = ";
      } else if (refnode instanceof Tree.MethodDeclaration) {
        Tree.MethodDeclaration md = (Tree.MethodDeclaration) refnode;
        sie = md.getSpecifierExpression();
        arrow = " => ";
      }
      Tree.CompilationUnit lcu = cpc.getLastCompilationUnit();
      if (sie == null) {
        class FindInitializerVisitor extends Visitor {
          Tree.SpecifierOrInitializerExpression result;

          @Override
          public void visit(Tree.InitializerParameter that) {
            super.visit(that);
            Declaration d = that.getParameterModel().getModel();
            if (d != null && d.equals(dec)) {
              result = that.getSpecifierExpression();
            }
          }
        }
        FindInitializerVisitor fiv = new FindInitializerVisitor();
        fiv.visit(lcu);
        sie = fiv.result;
      }
      if (sie != null) {
        Tree.Expression e = sie.getExpression();
        if (e != null) {
          Tree.Term term = e.getTerm();
          if (term instanceof Tree.Literal) {
            String text = term.getToken().getText();
            if (text.length() < 20) {
              return arrow + text;
            }
          } else if (term instanceof Tree.BaseMemberOrTypeExpression) {
            Tree.BaseMemberOrTypeExpression bme = (Tree.BaseMemberOrTypeExpression) term;
            Tree.Identifier id = bme.getIdentifier();
            if (id != null && bme.getTypeArguments() == null) {
              return arrow + id.getText();
            }
          } else if (term != null) {
            Unit unit = lcu.getUnit();
            if (term.getUnit().equals(unit)) {
              String impl = Nodes.text(term, cpc.getTokens());
              if (impl.length() < 10) {
                return arrow + impl;
              }
            }
          }
          // don't have the token stream :-/
          // TODO: figure out where to get it from!
          return arrow + "...";
        }
      }
    }
    return "";
  }
  private void writeConstantValue(Value v) throws IOException {
    Node node = tool.getDeclarationNode(v);
    PhasedUnit pu = tool.getDeclarationUnit(v);
    if (pu == null || !(node instanceof Tree.AttributeDeclaration)) {
      return;
    }

    Tree.AttributeDeclaration attribute = (Tree.AttributeDeclaration) node;
    Tree.SpecifierOrInitializerExpression specifierExpression =
        attribute.getSpecifierOrInitializerExpression();
    if (specifierExpression == null || specifierExpression.getExpression() == null) {
      return;
    }

    Token startToken = specifierExpression.getExpression().getToken();
    int startLine = startToken.getLine();
    int startLinePosition = startToken.getCharPositionInLine();

    Token endToken = attribute.getEndToken();
    int endLine = endToken.getLine();
    int endLinePosition = endToken.getCharPositionInLine();

    StringBuilder valueBuilder = new StringBuilder(" ");
    BufferedReader sourceCodeReader =
        new BufferedReader(new InputStreamReader(pu.getUnitFile().getInputStream()));
    try {
      int lineIndex = 1;
      String line = sourceCodeReader.readLine();
      while (line != null) {
        if (lineIndex == startLine && lineIndex == endLine) {
          valueBuilder.append(line.substring(startLinePosition, endLinePosition));
          break;
        } else if (lineIndex == startLine) {
          valueBuilder.append(line.substring(startLinePosition, line.length()));
        } else if (lineIndex > startLine && lineIndex < endLine) {
          valueBuilder.append("\n");
          valueBuilder.append(line);
        } else if (lineIndex == endLine) {
          valueBuilder.append("\n");
          valueBuilder.append(line.substring(0, endLinePosition));
          break;
        }

        line = sourceCodeReader.readLine();
        lineIndex++;
      }
    } finally {
      sourceCodeReader.close();
    }

    String value = valueBuilder.toString();
    int newLineIndex = value.indexOf("\n");
    String valueFirstLine = newLineIndex != -1 ? value.substring(0, newLineIndex) : value;

    around("span class='specifier-operator'", " = ");
    around("span class='specifier-start'", valueFirstLine);
    if (newLineIndex != -1) {
      around(
          "a class='specifier-ellipsis' href='#' title='Click for expand the rest of value.'",
          "...");
      open("div class='specifier-rest'");
      write(value.substring(newLineIndex + 1));
      around("span class='specifier-semicolon'", ";");
      close("div");
    } else {
      around("span class='specifier-semicolon'", ";");
    }
  }