blob: 92e33a7bdf667a8653bb7d552b2d05db9402e003 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 protos software gmbh (http://www.protos.de).
* 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:
* Thomas Schuetz and Henrik Rentz-Reichert (initial contribution)
*
*******************************************************************************/
package org.eclipse.etrice.core.ui.quickfix;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.etrice.core.common.base.Annotation;
import org.eclipse.etrice.core.common.base.AnnotationAttribute;
import org.eclipse.etrice.core.common.base.AnnotationType;
import org.eclipse.etrice.core.common.base.BaseFactory;
import org.eclipse.etrice.core.common.base.BooleanLiteral;
import org.eclipse.etrice.core.common.base.EnumAnnotationAttribute;
import org.eclipse.etrice.core.common.base.IntLiteral;
import org.eclipse.etrice.core.common.base.KeyValue;
import org.eclipse.etrice.core.common.base.RealLiteral;
import org.eclipse.etrice.core.common.base.SimpleAnnotationAttribute;
import org.eclipse.etrice.core.common.base.StringLiteral;
import org.eclipse.etrice.core.room.ActorRef;
import org.eclipse.etrice.core.room.ReferenceType;
import org.eclipse.etrice.core.room.StandardOperation;
import org.eclipse.etrice.core.validation.RoomJavaValidator;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.xtext.ui.editor.model.IXtextDocument;
import org.eclipse.xtext.ui.editor.model.edit.IModification;
import org.eclipse.xtext.ui.editor.model.edit.IModificationContext;
import org.eclipse.xtext.ui.editor.model.edit.ISemanticModification;
import org.eclipse.xtext.ui.editor.quickfix.DefaultQuickfixProvider;
import org.eclipse.xtext.ui.editor.quickfix.Fix;
import org.eclipse.xtext.ui.editor.quickfix.IssueResolution;
import org.eclipse.xtext.ui.editor.quickfix.IssueResolutionAcceptor;
import org.eclipse.xtext.validation.Issue;
public class RoomQuickfixProvider extends DefaultQuickfixProvider {
/**
* @author Henrik Rentz-Reichert
*
*/
private final class ChangeAnnotationAttributeModification implements ISemanticModification {
private String val;
private ChangeAnnotationAttributeModification(String val) {
this.val = val;
}
@Override
public void apply(EObject element, IModificationContext context) throws Exception {
KeyValue kv = (KeyValue) element;
StringLiteral sl = BaseFactory.eINSTANCE.createStringLiteral();
sl.setValue(val);
kv.setValue(sl);
}
}
@Override
public List<IssueResolution> getResolutions(Issue issue) {
List<IssueResolution> result = new ArrayList<IssueResolution>();
result.addAll(super.getResolutions(issue));
IssueResolutionAcceptor acceptor = getIssueResolutionAcceptorProvider().get();
QuickfixExtensionManager.getInstance().getResolutions(issue, acceptor);
result.addAll(acceptor.getIssueResolutions());
return result;
}
@Override
public boolean hasResolutionFor(String issueCode) {
return super.hasResolutionFor(issueCode) || QuickfixExtensionManager.getInstance().hasResolutionFor(issueCode);
}
@Fix(RoomJavaValidator.THREAD_MISSING)
public void fixMissingThread(final Issue issue, IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, "Add a default thread", issue.getData()[0], "add.gif", new IModification() {
public void apply(IModificationContext context) throws BadLocationException {
IXtextDocument xtextDocument = context.getXtextDocument();
int offset = issue.getOffset()+issue.getLength()-1;
String insertion = "\n\t\t"+issue.getData()[0]+"\n\t";
xtextDocument.replace(offset, 0, insertion);
}
});
}
@Fix(RoomJavaValidator.DUPLICATE_ACTOR_INSTANCE_MAPPING)
public void removeDuplicateThreadMapping(final Issue issue, IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, "Remove duplicate mapping", "remove this mapping", "remove.gif", new IModification() {
public void apply(IModificationContext context) throws BadLocationException {
IXtextDocument xtextDocument = context.getXtextDocument();
xtextDocument.replace(issue.getOffset(), issue.getLength(), "");
}
});
}
@Fix(RoomJavaValidator.WRONG_NAMESPACE)
public void fixWrongNamespace(final Issue issue, IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, "Replace with correct namespace", issue.getData()[0], "add.gif", new IModification() {
public void apply(IModificationContext context) throws BadLocationException {
IXtextDocument xtextDocument = context.getXtextDocument();
String replacement = issue.getData()[0];
xtextDocument.replace(issue.getOffset(), issue.getLength(), replacement);
}
});
}
@Fix(RoomJavaValidator.CIRCULAR_CONTAINMENT)
public void fixCircularContainment(final Issue issue, IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, "Make attribute a reference", "add 'ref' keyword", "add.gif", new IModification() {
public void apply(IModificationContext context) throws BadLocationException {
IXtextDocument xtextDocument = context.getXtextDocument();
int offset = Integer.parseInt(issue.getData()[0]);
xtextDocument.replace(issue.getOffset()+offset, 0, " ref");
}
});
}
@Fix(RoomJavaValidator.ACTOR_REF_CHANGE_REF_TYPE_TO_FIXED_OR_MULT_TO_ANY)
public void makeActorRefRefTypeFixed(final Issue issue, IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, "Make actor reference fixed", "[fixed] ActorRef...", "add.gif", new ISemanticModification() {
@Override
public void apply(EObject element, IModificationContext context) throws Exception {
ActorRef ar = (ActorRef) element;
ar.setRefType(ReferenceType.FIXED);
}
});
}
@Fix(RoomJavaValidator.ACTOR_REF_CHANGE_REF_TYPE_TO_FIXED_OR_MULT_TO_ANY)
public void makeMultiplicityAny(final Issue issue, IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, "Change multiplicity to any", "ActorRef "+issue.getData()[0]+"[*]", "add.gif", new ISemanticModification() {
@Override
public void apply(EObject element, IModificationContext context) throws Exception {
ActorRef ar = (ActorRef) element;
ar.setMultiplicity(-1);
}
});
}
@Fix(RoomJavaValidator.ACTOR_REF_CHANGE_REF_TYPE_TO_OPTIONAL)
public void makeActorRefRefTypeOptional(final Issue issue, IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, "Make actor reference fixed", "optional ActorRef...", "add.gif", new ISemanticModification() {
@Override
public void apply(EObject element, IModificationContext context) throws Exception {
ActorRef ar = (ActorRef) element;
ar.setRefType(ReferenceType.OPTIONAL);
}
});
}
@Fix(RoomJavaValidator.CHANGE_DESTRUCTOR_NAME)
public void fixDestructor(final Issue issue, IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, "Change destructor name", "~"+issue.getData()[0]+"()", "add.gif", new ISemanticModification() {
@Override
public void apply(EObject element, IModificationContext context) throws Exception {
StandardOperation op = (StandardOperation) element;
op.setName(issue.getData()[0]);
}
});
}
@Fix(RoomJavaValidator.CHANGE_CONSTRUCTOR_NAME)
public void fixConstructor(final Issue issue, IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, "Change constructor name", issue.getData()[0]+"()", "add.gif", new ISemanticModification() {
@Override
public void apply(EObject element, IModificationContext context) throws Exception {
StandardOperation op = (StandardOperation) element;
op.setName(issue.getData()[0]);
}
});
}
@Fix(RoomJavaValidator.INVALID_ANNOTATION_TARGET)
public void fixInvalidAnnotationTarget(final Issue issue, IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, "Remove this annotation", "remove @"+issue.getData()[0]+"...", "add.gif", new ISemanticModification() {
@SuppressWarnings("unchecked")
@Override
public void apply(EObject element, IModificationContext context) throws Exception {
Annotation ann = (Annotation) element;
Object getterResult = ann.eContainer().eGet(ann.eContainingFeature());
((List<? extends EObject>) getterResult).remove(ann);
}
});
acceptor.accept(issue, "Add this target to the definition", issue.getData()[1], "add.gif", new ISemanticModification() {
@Override
public void apply(EObject element, IModificationContext context) throws Exception {
Annotation ann = (Annotation) element;
ann.getType().getTargets().add(issue.getData()[2]);
}
});
}
@Fix(RoomJavaValidator.DUPLICATE_ANNOTATION_TARGETS)
public void fixDuplicateAnnotationTarget(final Issue issue, IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, "Remove the duplicate target", "remove "+issue.getData()[0], "add.gif", new ISemanticModification() {
@Override
public void apply(EObject element, IModificationContext context) throws Exception {
AnnotationType at = (AnnotationType) element;
Iterator<String> it = at.getTargets().iterator();
while (it.hasNext()) {
String tgt = it.next();
if (tgt.equals(issue.getData()[0]))
it.remove();
}
at.getTargets().add(issue.getData()[0]);
}
});
}
@Fix(RoomJavaValidator.MANDATORY_ATTRIBUTE_MISSING)
public void fixMissingAttribute(final Issue issue, IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, "Add missing attribute", "add "+issue.getData()[0], "add.gif", new ISemanticModification() {
@Override
public void apply(EObject element, IModificationContext context) throws Exception {
Annotation ann = (Annotation) element;
KeyValue kv = BaseFactory.eINSTANCE.createKeyValue();
kv.setKey(issue.getData()[0]);
for (AnnotationAttribute att : ann.getType().getAttributes()) {
if (att.getName().equals(issue.getData()[0])) {
if (att instanceof SimpleAnnotationAttribute) {
switch (((SimpleAnnotationAttribute) att).getType()) {
case BOOL: {
BooleanLiteral bl = BaseFactory.eINSTANCE.createBooleanLiteral();
kv.setValue(bl);
break;
}
case CHAR: {
StringLiteral sl = BaseFactory.eINSTANCE.createStringLiteral();
sl.setValue("");
kv.setValue(sl);
break;
}
case INT: {
IntLiteral il = BaseFactory.eINSTANCE.createIntLiteral();
il.setValue(0);
kv.setValue(il);
break;
}
case REAL: {
RealLiteral rl = BaseFactory.eINSTANCE.createRealLiteral();
rl.setValue(0);
kv.setValue(rl);
break;
}
}
}
else if (att instanceof EnumAnnotationAttribute) {
StringLiteral sl = BaseFactory.eINSTANCE.createStringLiteral();
sl.setValue(((EnumAnnotationAttribute) att).getValues().get(0));
kv.setValue(sl);
}
else {
assert(false): "unexpected sub type";
}
ann.getAttributes().add(kv);
break;
}
}
}
});
}
@Fix(RoomJavaValidator.UNDEFINED_ANNOTATION_ATTRIBUTE)
public void fixUndefinedAnnotationAttribute(final Issue issue, IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, "Remove undefined attribute", "remove "+issue.getData()[0], "add.gif", new ISemanticModification() {
@Override
public void apply(EObject element, IModificationContext context) throws Exception {
Annotation ann = (Annotation) element;
Iterator<KeyValue> it = ann.getAttributes().iterator();
while (it.hasNext()) {
KeyValue kv = it.next();
if (kv.getKey().equals(issue.getData()[0])) {
it.remove();
break;
}
}
}
});
}
@Fix(RoomJavaValidator.UNDEFINED_ANNOTATION_ATTRIBUTE_VALUE)
public void fixUndefinedAnnotationAttributeValue(final Issue issue, IssueResolutionAcceptor acceptor) {
for (int i=0; i<issue.getData().length; ++i) {
acceptor.accept(issue, "Change attribute value to "+issue.getData()[i], "... = "+issue.getData()[i], "add.gif",
new ChangeAnnotationAttributeModification(issue.getData()[i]));
}
}
@Fix(RoomJavaValidator.DUPLICATE_ANNOTATION_ATTRIBUTE)
public void fixDuplicateAnnotationAttribute(final Issue issue, IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, "Remove duplicate attribute "+issue.getData()[0], "remove "+issue.getData()[0], "add.gif", new ISemanticModification() {
@Override
public void apply(EObject element, IModificationContext context) throws Exception {
Annotation ann = (Annotation) element;
for (int i=ann.getAttributes().size()-1; i>=0; --i) {
KeyValue kv = ann.getAttributes().get(i);
if (kv.getKey().equals(issue.getData()[0])) {
ann.getAttributes().remove(i);
break;
}
}
}
});
}
@Fix(RoomJavaValidator.MULTI_LINE_DETAILCODE)
public void fixMultiLineDetailCode(final Issue issue, IssueResolutionAcceptor acceptor){
acceptor.accept(issue, "Convert to single lines", "", "correction_change.gif", new IModification() {
@Override
public void apply(IModificationContext context) throws Exception {
IXtextDocument document = context.getXtextDocument();
String editorReplace = DetailCodeIndentHelper.convertToSingleLines(document, issue);
document.replace(issue.getOffset(), issue.getLength(), editorReplace);
}
});
}
}