Search in sources :

Example 1 with Edit

use of org.eclipse.titanium.refactoring.scope.nodes.Edit in project titan.EclipsePlug-ins by eclipse.

the class ChangeCreator method createTextEdit.

private TextEdit[] createTextEdit(final IFile toVisit, final String fileContent, final Edit e, final Map<Edit, InsertEdit> editsDone) {
    // check for multi-declaration statement
    if (e.declSt.isMultiDeclaration()) {
        final Location cutLoc = calculateMultiDeclarationCutLoc(fileContent, e.declSt);
        final String moveContent = calculateMultiDeclarationMoveContent(fileContent, e.declSt);
        // remove stmt from multi-declaration
        e.declSt.removeFromMultiDeclaration();
        // create remove edit
        final int cutLen = cutLoc.getEndOffset() - cutLoc.getOffset();
        final TextEdit cut = new DeleteEdit(cutLoc.getOffset(), cutLen);
        // create insert edit
        InsertEdit insert = null;
        if (!e.isRemoveEdit()) {
            // update insert location if the insertionPoint stmt was moved
            int insertOffset = ((ILocateableNode) e.insertionPoint.getAstNode()).getLocation().getOffset();
            for (Map.Entry<Edit, InsertEdit> ed : editsDone.entrySet()) {
                if (ed.getKey().declSt.equals(e.insertionPoint)) {
                    insertOffset = ed.getValue().getOffset();
                    break;
                }
            }
            // 
            insertOffset = findLineBeginningOffset(fileContent, insertOffset);
            insert = new InsertEdit(insertOffset, moveContent);
            editsDone.put(e, insert);
        }
        if (insert != null) {
            return new TextEdit[] { insert, cut };
        }
        return new TextEdit[] { cut };
    } else {
        // 
        final Location cutLoc = findStatementLocation(fileContent, ((ILocateableNode) e.declSt.getAstNode()).getLocation(), true);
        InsertEdit insert = null;
        if (!e.isRemoveEdit()) {
            final Location copyLoc = findStatementLocation(fileContent, ((ILocateableNode) e.declSt.getAstNode()).getLocation(), false);
            // update insert location if the insertionPoint stmt was moved
            final Location insPLoc = ((ILocateableNode) e.insertionPoint.getAstNode()).getLocation();
            int insertOffset = insPLoc.getOffset();
            for (Map.Entry<Edit, InsertEdit> ed : editsDone.entrySet()) {
                if (ed.getKey().declSt.equals(e.insertionPoint)) {
                    insertOffset = ed.getValue().getOffset();
                    break;
                }
            }
            // 
            final int prefixStartOffset = findLineBeginningOffset(fileContent, insertOffset);
            final String insertText = fileContent.substring(copyLoc.getOffset(), copyLoc.getEndOffset()) + "\n";
            String insertPrefix = fileContent.substring(prefixStartOffset, insertOffset);
            // if prefix is not whitespace only, do not use the prefix
            if (!insertPrefix.trim().equals("")) {
                insertPrefix = "";
            }
            insert = new InsertEdit(prefixStartOffset, insertPrefix + insertText);
            editsDone.put(e, insert);
        }
        final int cutLen = cutLoc.getEndOffset() - cutLoc.getOffset();
        final TextEdit cut = new DeleteEdit(cutLoc.getOffset(), cutLen);
        // System.err.println("DeleteEdit: " + fileContent.substring(cutLoc.getOffset(), cutLoc.getEndOffset()));
        if (insert != null) {
            return new TextEdit[] { insert, cut };
        }
        return new TextEdit[] { cut };
    }
}
Also used : InsertEdit(org.eclipse.text.edits.InsertEdit) MultiTextEdit(org.eclipse.text.edits.MultiTextEdit) TextEdit(org.eclipse.text.edits.TextEdit) ILocateableNode(org.eclipse.titan.designer.AST.ILocateableNode) Edit(org.eclipse.titanium.refactoring.scope.nodes.Edit) InsertEdit(org.eclipse.text.edits.InsertEdit) MultiTextEdit(org.eclipse.text.edits.MultiTextEdit) TextEdit(org.eclipse.text.edits.TextEdit) DeleteEdit(org.eclipse.text.edits.DeleteEdit) DeleteEdit(org.eclipse.text.edits.DeleteEdit) Map(java.util.Map) HashMap(java.util.HashMap) Location(org.eclipse.titan.designer.AST.Location)

Example 2 with Edit

use of org.eclipse.titanium.refactoring.scope.nodes.Edit in project titan.EclipsePlug-ins by eclipse.

the class ChangeCreator method analyzeFunction.

/**
 * Analyze a function or testcase
 */
private List<Edit> analyzeFunction(final Definition def) {
    if (!(def instanceof Def_Function || def instanceof Def_Testcase)) {
        ErrorReporter.logError("ChangeCreator.analyzeFunction(): def must be a Def_Function or a Def_Testcase! def type: " + def.getClass());
        return null;
    }
    final FunctionAnalyzer vis = new FunctionAnalyzer();
    def.accept(vis);
    final Environment env = vis.getResult();
    final List<Edit> eds = env.refactor();
    return eds;
}
Also used : Def_Testcase(org.eclipse.titan.designer.AST.TTCN3.definitions.Def_Testcase) Environment(org.eclipse.titanium.refactoring.scope.nodes.Environment) Edit(org.eclipse.titanium.refactoring.scope.nodes.Edit) InsertEdit(org.eclipse.text.edits.InsertEdit) MultiTextEdit(org.eclipse.text.edits.MultiTextEdit) TextEdit(org.eclipse.text.edits.TextEdit) DeleteEdit(org.eclipse.text.edits.DeleteEdit) Def_Function(org.eclipse.titan.designer.AST.TTCN3.definitions.Def_Function)

Example 3 with Edit

use of org.eclipse.titanium.refactoring.scope.nodes.Edit in project titan.EclipsePlug-ins by eclipse.

the class ChangeCreator method createFileChange.

/**
 * Creates the {@link #change} object, which contains all the inserted and edited texts
 * in the selected resources.
 */
private Change createFileChange(final IFile toVisit) {
    if (toVisit == null) {
        return null;
    }
    final ProjectSourceParser sourceParser = GlobalParser.getProjectSourceParser(toVisit.getProject());
    final Module module = sourceParser.containedModule(toVisit);
    if (module == null) {
        return null;
    }
    // 
    // collect functions
    Set<Definition> funcs;
    final FunctionCollector vis = new FunctionCollector();
    if (defSelection == null) {
        module.accept(vis);
        funcs = vis.getResult();
    } else {
        if (defSelection instanceof Def_Function || defSelection instanceof Def_Testcase) {
            // TODO any other possibilities for the type of 'defSelection'?
            funcs = new HashSet<Definition>();
            funcs.add(defSelection);
        } else {
            ErrorReporter.logError("Variable scope reduction called for " + defSelection.getIdentifier().getDisplayName() + ", but it is only supported for functions and testcases. ");
            return null;
        }
    }
    // create edits
    final List<Edit> allEdits = new ArrayList<Edit>();
    for (Definition def : funcs) {
        final List<Edit> edits = analyzeFunction(def);
        if (edits == null) {
            continue;
        }
        allEdits.addAll(edits);
    }
    if (allEdits.isEmpty()) {
        return null;
    }
    final String fileContents = loadFileContent(toVisit);
    // create text edits
    // 
    final TextFileChange tfc = new TextFileChange(toVisit.getName(), toVisit);
    final MultiTextEdit rootEdit = new MultiTextEdit();
    tfc.setEdit(rootEdit);
    // TODO this is an O(n^2) algorithm
    // merge overlapping DeleteEdits
    // used, when removing all parts of a multi-declaration statement:
    // the DeleteEdit for removing the last part covers all the DeleteEdits for the other parts
    // WARNING merging edits might make debugging more difficult, since the overlapping edit errors are avoided
    final List<TextEdit> allTes = new LinkedList<TextEdit>();
    // collect processed (insert) edits with their created insert edit
    final Map<Edit, InsertEdit> editsDone = new HashMap<Edit, InsertEdit>();
    for (Edit e : allEdits) {
        final TextEdit[] tes = createTextEdit(toVisit, fileContents, e, editsDone);
        for (TextEdit te : tes) {
            if (!(te instanceof DeleteEdit)) {
                allTes.add(te);
                // System.err.println("$ nonde added: " + te.getOffset() + "-" + te.getExclusiveEnd());
                continue;
            }
            DeleteEdit dte = (DeleteEdit) te;
            final ListIterator<TextEdit> it = allTes.listIterator();
            while (it.hasNext()) {
                final TextEdit currTe = it.next();
                if (!(currTe instanceof DeleteEdit)) {
                    continue;
                }
                final DeleteEdit currDte = (DeleteEdit) currTe;
                // if the new edit (dte) overlaps currDte, merge them
                if (doesDeleteEditsOverlap(dte, currDte)) {
                    // System.err.println("$ de removed: " + currDte.getOffset() + "-" + currDte.getExclusiveEnd());
                    it.remove();
                    dte = mergeDeleteEdits(dte, currDte);
                // System.err.println("$ merged des: " + dte.getOffset() + "-" + dte.getExclusiveEnd());
                }
            }
            // System.err.println("$ de added: " + dte.getOffset() + "-" + dte.getExclusiveEnd());
            allTes.add(dte);
        }
    }
    Collections.reverse(allTes);
    for (TextEdit te : allTes) {
        rootEdit.addChild(te);
    }
    return tfc;
}
Also used : InsertEdit(org.eclipse.text.edits.InsertEdit) Def_Testcase(org.eclipse.titan.designer.AST.TTCN3.definitions.Def_Testcase) HashMap(java.util.HashMap) Definition(org.eclipse.titan.designer.AST.TTCN3.definitions.Definition) ArrayList(java.util.ArrayList) Edit(org.eclipse.titanium.refactoring.scope.nodes.Edit) InsertEdit(org.eclipse.text.edits.InsertEdit) MultiTextEdit(org.eclipse.text.edits.MultiTextEdit) TextEdit(org.eclipse.text.edits.TextEdit) DeleteEdit(org.eclipse.text.edits.DeleteEdit) TextFileChange(org.eclipse.ltk.core.refactoring.TextFileChange) DeleteEdit(org.eclipse.text.edits.DeleteEdit) ProjectSourceParser(org.eclipse.titan.designer.parsers.ProjectSourceParser) Def_Function(org.eclipse.titan.designer.AST.TTCN3.definitions.Def_Function) LinkedList(java.util.LinkedList) MultiTextEdit(org.eclipse.text.edits.MultiTextEdit) TextEdit(org.eclipse.text.edits.TextEdit) Module(org.eclipse.titan.designer.AST.Module) MultiTextEdit(org.eclipse.text.edits.MultiTextEdit)

Aggregations

DeleteEdit (org.eclipse.text.edits.DeleteEdit)3 InsertEdit (org.eclipse.text.edits.InsertEdit)3 MultiTextEdit (org.eclipse.text.edits.MultiTextEdit)3 TextEdit (org.eclipse.text.edits.TextEdit)3 Edit (org.eclipse.titanium.refactoring.scope.nodes.Edit)3 HashMap (java.util.HashMap)2 Def_Function (org.eclipse.titan.designer.AST.TTCN3.definitions.Def_Function)2 Def_Testcase (org.eclipse.titan.designer.AST.TTCN3.definitions.Def_Testcase)2 ArrayList (java.util.ArrayList)1 LinkedList (java.util.LinkedList)1 Map (java.util.Map)1 TextFileChange (org.eclipse.ltk.core.refactoring.TextFileChange)1 ILocateableNode (org.eclipse.titan.designer.AST.ILocateableNode)1 Location (org.eclipse.titan.designer.AST.Location)1 Module (org.eclipse.titan.designer.AST.Module)1 Definition (org.eclipse.titan.designer.AST.TTCN3.definitions.Definition)1 ProjectSourceParser (org.eclipse.titan.designer.parsers.ProjectSourceParser)1 Environment (org.eclipse.titanium.refactoring.scope.nodes.Environment)1