package de.ugoe.cs.swe.bnftools.ui.quickfix.processors; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.jface.text.BadLocationException; import org.eclipse.ltk.core.refactoring.Change; import org.eclipse.ltk.core.refactoring.CompositeChange; import org.eclipse.ltk.core.refactoring.RefactoringStatus; import org.eclipse.ltk.core.refactoring.TextFileChange; import org.eclipse.ltk.core.refactoring.participants.CheckConditionsContext; import org.eclipse.ltk.core.refactoring.participants.RefactoringParticipant; import org.eclipse.ltk.core.refactoring.participants.RefactoringProcessor; import org.eclipse.ltk.core.refactoring.participants.SharableParticipants; import org.eclipse.text.edits.DeleteEdit; import org.eclipse.text.edits.MultiTextEdit; import org.eclipse.text.edits.ReplaceEdit; import org.eclipse.text.edits.TextEditGroup; import org.eclipse.xtext.parsetree.CompositeNode; import org.eclipse.xtext.ui.editor.XtextEditor; import org.eclipse.xtext.ui.editor.model.XtextDocument; import de.ugoe.cs.swe.bnftools.utils.DeclarationReferencesPair; import de.ugoe.cs.swe.bnftools.utils.Utils; public class InlineRulesProcessor extends RefactoringProcessor { private IFile file; private CompositeNode rootNode; private XtextDocument document; private List nodePairs; private boolean isRemoveLine; // ---------------------------------------------------------------------------------------------------- public InlineRulesProcessor(XtextEditor editor, CompositeNode root, XtextDocument doc, List nodePairs, boolean removal) { file = (IFile) editor.getEditorInput().getAdapter(IFile.class); this.rootNode = root; this.document = doc; this.nodePairs = nodePairs; this.isRemoveLine = removal; } // ---------------------------------------------------------------------------------------------------- @Override public Object[] getElements() { return null; } // ---------------------------------------------------------------------------------------------------- @Override public String getIdentifier() { return "Inline Rules Processor"; } // ---------------------------------------------------------------------------------------------------- @Override public String getProcessorName() { return "Inline Rules Processor"; } // ---------------------------------------------------------------------------------------------------- @Override public boolean isApplicable() throws CoreException { return (rootNode != null); } // ---------------------------------------------------------------------------------------------------- @Override public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException { RefactoringStatus status = new RefactoringStatus(); if (rootNode == null) status.addFatalError("Root node is null!"); return status; } // ---------------------------------------------------------------------------------------------------- @Override public RefactoringStatus checkFinalConditions(IProgressMonitor pm, CheckConditionsContext context) throws CoreException, OperationCanceledException { return checkInitialConditions(pm); } // ---------------------------------------------------------------------------------------------------- @Override public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { CompositeChange compositeChange = new CompositeChange("Inline Rule"); pm.beginTask("Inline Rules Refactoring", 2); //initialising the edit MultiTextEdit multiEdit = new MultiTextEdit(); TextFileChange fileChange = new TextFileChange("Inline Rules", file); fileChange.setEdit(multiEdit); fileChange.setTextType("bnf"); compositeChange.add(fileChange); // inline Rules for (int i=0; i < nodePairs.size(); i++) { CompositeNode declarationRule = nodePairs.get(i).getDeclarationNode(); List ruleReferences = nodePairs.get(i).getReferenceNodes(); try { String ruleText = document.get(declarationRule.getOffset(), declarationRule.getLength()); String ruleRightHandSide = ruleText.substring(ruleText.indexOf("::=")+3).trim(); if (ruleRightHandSide.length() == 0) return compositeChange; ruleRightHandSide = "(" + ruleRightHandSide + ")"; //TODO: handle the parentheses more intelligently! // replace references with passthrough rule name for (int j=0; j < ruleReferences.size(); j++) { CompositeNode ruleReference = ruleReferences.get(j); ReplaceEdit replaceEdit2 = new ReplaceEdit(ruleReference.getOffset(), ruleReference.getLength(), ruleRightHandSide); multiEdit.addChild(replaceEdit2); TextEditGroup editGroup2 = new TextEditGroup("reference renaming", replaceEdit2); fileChange.addTextEditGroup(editGroup2); pm.worked(1); } // remove old line if (isRemoveLine) { int amount = Utils.stepBackNewlines(document, declarationRule.getOffset()); DeleteEdit deleteEdit = new DeleteEdit(declarationRule.getOffset() - amount, declarationRule.getLength() + amount); multiEdit.addChild(deleteEdit); TextEditGroup editGroup3 = new TextEditGroup("remove old line", deleteEdit); fileChange.addTextEditGroup(editGroup3); pm.worked(1); } } catch (BadLocationException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return compositeChange; } // ---------------------------------------------------------------------------------------------------- @Override public RefactoringParticipant[] loadParticipants(RefactoringStatus status, SharableParticipants sharedParticipants) throws CoreException { return null; } }