private static ClassOrInterface findClassContainer(Tree.CompilationUnit cu, Node node) { FindContainerVisitor fcv = new FindContainerVisitor(node); fcv.visit(cu); Tree.Declaration declaration = fcv.getDeclaration(); if (declaration == null || declaration == node) return null; if (declaration instanceof Tree.ClassOrInterface) return (ClassOrInterface) declaration.getDeclarationModel(); if (declaration instanceof Tree.MethodDefinition) return findClassContainer(declaration.getDeclarationModel()); if (declaration instanceof Tree.ObjectDefinition) return findClassContainer(declaration.getDeclarationModel()); return null; }
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)); }
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 + ")")); }