/**
* Copyright (c) 2012 Cloudsmith Inc. and other contributors, as listed below.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cloudsmith
*
*/
package org.cloudsmith.geppetto.pp.dsl.ui.quickfix;
import org.cloudsmith.geppetto.pp.dsl.validation.IPPDiagnostics;
import org.eclipse.xtext.ui.editor.quickfix.Fix;
import org.eclipse.xtext.ui.editor.quickfix.IssueResolutionAcceptor;
import org.eclipse.xtext.validation.Issue;
/**
* A Fixer of Relationship Expressions
*
*/
public class RelationshipExpressionFixer {
// L and R can be
// RelationshipExpression
// AtExpression
// CollectExpression
// All others are illegal, and no refactoring should be made
@Fix(IPPDiagnostics.ISSUE_RIGHT_TO_LEFT_RELATIONSHIP)
public void fixRightToLeftRelationsip(final Issue issue, final IssueResolutionAcceptor acceptor) {
if(issue.getLength() > 2)
return; // can't fix it, not reported on the operator
suggestReversedOperator(issue, acceptor);
// real solution - rewrite the expression
// TODO: Implement the logic:
// R = root of N
// Sn = N.left
// N.left = Ref(right(N.left))
// Sn = N.left
// flip(R)
//
// where flip(R) is a reqursive flip (d <- e <- f, becomes f -> e -> d) by
// tranforming tree (<- (<- d e) f) to (-> (-> f e) d)
// acceptor.accept(issue, "Rewrite the expression", "Rewrite", null, new ISemanticModification() {
//
// @Override
// public void apply(EObject element, IModificationContext context) throws Exception {
// RelationshipExpression original = (RelationshipExpression) element;
// RelationshipExpression relExpr = PPFactory.eINSTANCE.createRelationshipExpression();
// relExpr.setLeftExpr(EcoreUtil.copy(original.getRightExpr()));
// relExpr.setRightExpr(EcoreUtil.copy(original.getLeftExpr()));
// relExpr.setOpName(reverseRelationshipOp(issue.getData()[0]));
// EStructuralFeature feature = original.eContainingFeature();
// Object x = original.eContainer().eGet(feature);
// if(x instanceof List) {
// List<Object> list = ((List<Object>) x);
// for(int i = 0; i < list.size(); i++) {
// if(list.get(i) == original)
//
// list.set(i, relExpr);
// }
// }
// }
// });
}
/*
private boolean isValidRelationshipExpression(EObject o) {
if(o instanceof RelationshipExpression || o instanceof AtExpression || o instanceof CollectExpression)
return true;
// Resource is trickier - must check form
return false;
}*/
private String reverseRelationshipOp(String op) {
if(op.charAt(0) == '<') {
if(op.charAt(1) == '-')
return "->";
return "~>";
}
if(op.charAt(0) == '-')
return "<-";
return "<~";
}
private void suggestReversedOperator(final Issue issue, final IssueResolutionAcceptor acceptor) {
// dirty solution; reverse the op
acceptor.accept(
issue, "Reverse the operation",
"Change the dependency to go the other direction.\nThis alters the meaning.", null,
new ReplacingModification(issue.getOffset(), issue.getLength(), reverseRelationshipOp(issue.getData()[0])));
}
}