Aadl2QuickfixProvider.java
/**
* Copyright (c) 2004-2025 Carnegie Mellon University and others. (see Contributors file).
* All Rights Reserved.
*
* NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
* OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
* MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
* SPDX-License-Identifier: EPL-2.0
*
* Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
*
* This program includes and/or can make use of certain third party source code, object code, documentation and other
* files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
* configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
* conditions contained in any such Third Party Software or separate license file distributed with such Third Party
* Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party benefici-
* aries to this license with respect to the terms applicable to their Third Party Software. Third Party Software li-
* censes only apply to the Third Party Software and not any other portion of this program or this program as a whole.
*/
package org.osate.xtext.aadl2.ui.quickfix;
import com.google.inject.Inject;
import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.ui.editor.IURIEditorOpener;
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.Fix;
import org.eclipse.xtext.ui.editor.quickfix.IssueResolutionAcceptor;
import org.eclipse.xtext.util.concurrent.IUnitOfWork;
import org.eclipse.xtext.validation.Issue;
import org.eclipse.xtext.xbase.lib.Conversions;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.osate.aadl2.AbstractFeature;
import org.osate.aadl2.Access;
import org.osate.aadl2.AccessType;
import org.osate.aadl2.ArrayDimension;
import org.osate.aadl2.ArraySize;
import org.osate.aadl2.ComponentPrototype;
import org.osate.aadl2.Connection;
import org.osate.aadl2.DirectedFeature;
import org.osate.aadl2.EnumerationLiteral;
import org.osate.aadl2.EnumerationType;
import org.osate.aadl2.Feature;
import org.osate.aadl2.FeatureGroup;
import org.osate.aadl2.FeatureGroupType;
import org.osate.aadl2.FeaturePrototype;
import org.osate.aadl2.FeaturePrototypeActual;
import org.osate.aadl2.FeaturePrototypeBinding;
import org.osate.aadl2.FeaturePrototypeReference;
import org.osate.aadl2.GroupExtension;
import org.osate.aadl2.ModalElement;
import org.osate.aadl2.ModalPath;
import org.osate.aadl2.ModalPropertyValue;
import org.osate.aadl2.Mode;
import org.osate.aadl2.ModeBinding;
import org.osate.aadl2.ModelUnit;
import org.osate.aadl2.NamedElement;
import org.osate.aadl2.NumericRange;
import org.osate.aadl2.PackageSection;
import org.osate.aadl2.PortSpecification;
import org.osate.aadl2.PropertyExpression;
import org.osate.aadl2.PropertySet;
import org.osate.aadl2.Prototype;
import org.osate.aadl2.Subcomponent;
import org.osate.aadl2.UnitLiteral;
import org.osate.xtext.aadl2.properties.ui.quickfix.PropertiesQuickfixProvider;
import org.osate.xtext.aadl2.validation.Aadl2Validator;
@SuppressWarnings("all")
public class Aadl2QuickfixProvider extends PropertiesQuickfixProvider {
@Inject
private IURIEditorOpener editorOpener;
/**
* QuickFix for matching the defining and ending identifiers of classifiers, packages, and property sets.
* The issue data array is expected to have three elements:
*
* issue.getData()[0]: The defining identifier of the classifier or model unit.
* issue.getData()[1]: The ending identifier of the classifier or model unit.
* issue.getData()[2]: The offset of the ending identifier within the Xtext document.
*/
@Fix(Aadl2Validator.MISMATCHED_BEGINNING_AND_ENDING_IDENTIFIERS)
public void fixMismatchedBeginningAndEndingIdentifiers(final Issue issue, final IssueResolutionAcceptor acceptor) {
final String beginningName = issue.getData()[0];
final String endingName = issue.getData()[1];
final int endingIdentifierOffset = Integer.parseInt(issue.getData()[2]);
acceptor.accept(issue, (("Change defining identifier to \'" + endingName) + "\'"), null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
((NamedElement) element).setName(endingName);
}
});
acceptor.accept(issue, (("Change ending identifier to \'" + beginningName) + "\'"), null, null, new IModification() {
@Override
public void apply(final IModificationContext context) throws Exception {
context.getXtextDocument().replace(endingIdentifierOffset, endingName.length(), beginningName);
}
});
}
/**
* QuickFix for Non-unique ComponentType names, most likely "refined to" missing.
* The issue data array is expected to have three elements:
*
* issue.getData()[0]: The name of the element.
* issue.getData()[1]: The offset of the ":".
* issue.getData()[2]: replacement value.
*/
@Fix(Aadl2Validator.DUPLICATE_COMPONENT_TYPE_NAME)
public void fixDuplicateComponentType(final Issue issue, final IssueResolutionAcceptor acceptor) {
final String componentTypeName = issue.getData()[0];
final int offset = Integer.parseInt(issue.getData()[1]);
final String replacementVal = issue.getData()[2];
acceptor.accept(issue, (("Add \'refined to\' to \'" + componentTypeName) + "\'"), null, null, new IModification() {
@Override
public void apply(final IModificationContext context) throws Exception {
context.getXtextDocument().replace(offset, 1, replacementVal);
}
});
}
/**
* QuickFix for duplicate literal in an enumeration
* issue.getData()[0]: The name of the EnumerationLiteral.
*/
@Fix(Aadl2Validator.DUPLICATE_LITERAL_IN_ENUMERATION)
public void fixDuplicateLiteralInEnumeration(final Issue issue, final IssueResolutionAcceptor acceptor) {
final String dupeLiteralName = issue.getData()[0];
acceptor.accept(issue, (("Remove duplicate literal \'" + dupeLiteralName) + "\'"), null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final EnumerationLiteral el = ((EnumerationLiteral) element);
EObject _eContainer = el.eContainer();
final EnumerationType enumContainer = ((EnumerationType) _eContainer);
enumContainer.getOwnedLiterals().remove(el);
}
});
}
/**
* QuickFix for unit literal being out of sequence
* issue.getData(0) UnitLiteral.baseUnit.name
* issue.getData(1) ... issue.getData(n): Alternating strings of the UnitLiteral names and URI.
*/
@Fix(Aadl2Validator.UNIT_LITERAL_OUT_OF_ORDER)
public void fixUnitLiteralOutOfOrder(final Issue issue, final IssueResolutionAcceptor acceptor) {
final String baseUnitName = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(issue.getData())));
final Iterator<String> iter = ((List<String>)Conversions.doWrapArray(issue.getData())).iterator();
boolean _hasNext = iter.hasNext();
if (_hasNext) {
iter.next();
}
while (iter.hasNext()) {
{
final String ulName = iter.next();
final String nextUri = iter.next();
acceptor.accept(issue, (((("Change unit base type \'" + baseUnitName) + "\' to \'") + ulName) + "\'"), null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final ResourceSet resourceSet = element.eResource().getResourceSet();
EObject _eObject = resourceSet.getEObject(URI.createURI(nextUri), true);
final UnitLiteral newBaseUnit = ((UnitLiteral) _eObject);
((UnitLiteral) element).setBaseUnit(newBaseUnit);
}
});
}
}
}
/**
* QuickFix for mode in modal property value not being defined for the container
* issue.getData(0) mode.name
* issue.getData(1) undefinedMode URI
* issue.getData(2) containerName
* issue.getData(3) containerURI
* issue.getData(4) ModalPropertyValue
* issue.getData(5) ... issue.getData(n): Alternating strings of proposed replacement mode names and URI.
*/
@Fix(Aadl2Validator.MODE_NOT_DEFINED_IN_CONTAINER)
public void fixModeNotDefinedInContainer(final Issue issue, final IssueResolutionAcceptor acceptor) {
final String modeName = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(issue.getData())));
final String undefinedModeURI = issue.getData()[1];
final String containerName = issue.getData()[2];
final String containerURI = issue.getData()[3];
final String modalPropertyValueURI = issue.getData()[4];
acceptor.accept(issue, (((("Add \'" + modeName) + "\' to in modes of \'") + containerName) + "\'"), null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final ResourceSet resourceSet = element.eResource().getResourceSet();
EObject _eObject = resourceSet.getEObject(URI.createURI(containerURI), true);
final ModalElement container = ((ModalElement) _eObject);
EObject _eObject_1 = resourceSet.getEObject(URI.createURI(undefinedModeURI), true);
final Mode undefinedMode = ((Mode) _eObject_1);
boolean _matched = false;
if (container instanceof ModalPath) {
_matched=true;
((ModalPath)container).getInModeOrTransitions().add(undefinedMode);
}
if (!_matched) {
container.getInModes().add(undefinedMode);
}
}
});
final Iterator<String> iter = ((List<String>)Conversions.doWrapArray(issue.getData())).iterator();
for (int i = 0; (i < 5); i++) {
boolean _hasNext = iter.hasNext();
if (_hasNext) {
iter.next();
}
}
while (iter.hasNext()) {
{
final String replacementName = iter.next();
final String nextUri = iter.next();
acceptor.accept(issue, (((("Replace \'" + modeName) + "\' with \'") + replacementName) + "\'"), null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final ResourceSet resourceSet = element.eResource().getResourceSet();
EObject _eObject = resourceSet.getEObject(URI.createURI(nextUri), true);
final Mode replacementMode = ((Mode) _eObject);
EObject _eObject_1 = resourceSet.getEObject(URI.createURI(undefinedModeURI), true);
final Mode undefinedMode = ((Mode) _eObject_1);
EObject _eObject_2 = resourceSet.getEObject(URI.createURI(modalPropertyValueURI), true);
final ModalPropertyValue mpv = ((ModalPropertyValue) _eObject_2);
mpv.getInModes().remove(undefinedMode);
mpv.getInModes().add(replacementMode);
}
});
}
}
}
/**
* QuickFix for using self keyword when not allowed
* issue.getData(0) offSet
* issue.getData(1) connectionEndURI
*/
@Fix(Aadl2Validator.SELF_NOT_ALLOWED)
public void fixSelfNotAllowed(final Issue issue, final IssueResolutionAcceptor acceptor) {
final int offSet = Integer.parseInt(IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(issue.getData()))));
final String alternateConnectionEndType = issue.getData()[1];
acceptor.accept(issue, "Remove \'self\'", null, null, new IModification() {
@Override
public void apply(final IModificationContext context) throws Exception {
context.getXtextDocument().replace(offSet, 5, "");
}
});
boolean _equals = alternateConnectionEndType.equals("processor");
if (_equals) {
acceptor.accept(issue, "Replace \'self\' with \'processor\'", null, null, new IModification() {
@Override
public void apply(final IModificationContext context) throws Exception {
context.getXtextDocument().replace(offSet, 4, "processor");
}
});
}
}
/**
* QuickFix for using processor keyword when not allowed
* issue.getData(0) offSet
* issue.getData(1) connectionEndURI
*/
@Fix(Aadl2Validator.PROCESSOR_NOT_ALLOWED)
public void fixProcessorNotAllowed(final Issue issue, final IssueResolutionAcceptor acceptor) {
final int offSet = Integer.parseInt(IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(issue.getData()))));
final String alternateConnectionEndType = issue.getData()[1];
acceptor.accept(issue, "Remove \'processor\'", null, null, new IModification() {
@Override
public void apply(final IModificationContext context) throws Exception {
context.getXtextDocument().replace(offSet, 10, "");
}
});
boolean _equals = alternateConnectionEndType.equals("self");
if (_equals) {
acceptor.accept(issue, "Replace \'processor\' with \'self\'", null, null, new IModification() {
@Override
public void apply(final IModificationContext context) throws Exception {
context.getXtextDocument().replace(offSet, 9, "self");
}
});
}
}
/**
* QuickFix for flow impl kind not matching flow spec kind
* issue.getData(0) impl kind name
* issue.getData(1) flow spec name
* issue,getData(2) offSet
*/
@Fix(Aadl2Validator.INCONSISTENT_FLOW_KIND)
public void fixInconsistentFlowKind(final Issue issue, final IssueResolutionAcceptor acceptor) {
final String flowImplKindName = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(issue.getData())));
final String flowSpecKindName = issue.getData()[1];
final int offSet = Integer.parseInt(issue.getData()[2]);
acceptor.accept(issue, (((("Change \'" + flowImplKindName) + "\' to \'") + flowSpecKindName) + "\'"), null, null, new IModification() {
@Override
public void apply(final IModificationContext context) throws Exception {
context.getXtextDocument().replace(offSet, flowImplKindName.length(), flowSpecKindName);
}
});
}
/**
* QuickFix for out flow feature identifier not matching the flow specification
* issue.getData(0) outImplName
* issue.getData(1) specName
* issue,getData(2) featureOffSet
* issue,getData(3) contextOffset
*/
@Fix(Aadl2Validator.OUT_FLOW_FEATURE_IDENTIFIER_NOT_SPEC)
public void fixOutFlowIdentifierNotSpec(final Issue issue, final IssueResolutionAcceptor acceptor) {
final String outImplName = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(issue.getData())));
final String specName = issue.getData()[1];
final int featureOffSet = Integer.parseInt(issue.getData()[2]);
final int contextOffset = Integer.parseInt(issue.getData()[3]);
acceptor.accept(issue, (((("Change \'" + outImplName) + "\' to \'") + specName) + "\'"), null, null, new IModification() {
@Override
public void apply(final IModificationContext context) throws Exception {
int useOffSet = featureOffSet;
String replacement = specName;
if ((0 < contextOffset)) {
useOffSet = contextOffset;
}
context.getXtextDocument().replace(useOffSet, outImplName.length(), replacement);
}
});
}
/**
* QuickFix for in flow feature identifier not matching the flow specification
* issue.getData(0) inImplName
* issue.getData(1) specName
* issue,getData(2) featureOffSet
* issue,getData(3) contextOffset
*/
@Fix(Aadl2Validator.IN_FLOW_FEATURE_IDENTIFIER_NOT_SPEC)
public void fixInFlowIdentifierNotSpec(final Issue issue, final IssueResolutionAcceptor acceptor) {
final String inImplName = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(issue.getData())));
final String specName = issue.getData()[1];
final int featureOffSet = Integer.parseInt(issue.getData()[2]);
acceptor.accept(issue, (((("Change \'" + inImplName) + "\' to \'") + specName) + "\'"), null, null, new IModification() {
@Override
public void apply(final IModificationContext context) throws Exception {
int useOffSet = featureOffSet;
String replacement = specName;
context.getXtextDocument().replace(useOffSet, inImplName.length(), replacement);
}
});
}
/**
* QuickFix for Subcomponent not in flow modes
* issue.getData(0) flowModeName
* issue.getData(1) flowModeURI
* issue,getData(2) subcomponentName
* issue,getData(3) subcomponentURI
*/
@Fix(Aadl2Validator.SUBCOMPONENT_NOT_IN_FLOW_MODE)
public void fixSubcomponentNotInFlowMode(final Issue issue, final IssueResolutionAcceptor acceptor) {
final String flowModeName = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(issue.getData())));
final String flowModeURI = issue.getData()[1];
final String subcomponentName = issue.getData()[2];
final String subcomponentURI = issue.getData()[3];
acceptor.accept(issue, (((("Add mode \'" + flowModeName) + "\' to in modes of \'") + subcomponentName) + "\'"), null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final URI suburi = URI.createURI(subcomponentURI);
final IXtextDocument doc = context.getXtextDocument(suburi);
doc.<Object>modify(new IUnitOfWork.Void<XtextResource>() {
@Override
public void process(final XtextResource state) throws Exception {
EObject _eObject = state.getResourceSet().getEObject(URI.createURI(flowModeURI), true);
final Mode flowMode = ((Mode) _eObject);
EObject _eObject_1 = state.getResourceSet().getEObject(suburi, true);
final Subcomponent subcomponent = ((Subcomponent) _eObject_1);
final ModeBinding modeBinding = subcomponent.createOwnedModeBinding();
modeBinding.setParentMode(flowMode);
}
});
Aadl2QuickfixProvider.this.editorOpener.open(suburi, true);
}
});
}
/**
* QuickFix for Subcomponent not in flow modes
* issue.getData(0) flowModeName
* issue.getData(1) flowModeURI
* issue,getData(2) connectionName
* issue,getData(3) connectionURI
*/
@Fix(Aadl2Validator.CONNECTION_NOT_IN_FLOW_MODE)
public void fixConnectionNotInFlowMode(final Issue issue, final IssueResolutionAcceptor acceptor) {
final String flowModeName = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(issue.getData())));
final String flowModeURI = issue.getData()[1];
final String connectionName = issue.getData()[2];
final String connectionURI = issue.getData()[3];
acceptor.accept(issue, (((("Add mode \'" + flowModeName) + "\' to in modes of \'") + connectionName) + "\'"), null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final URI connuri = URI.createURI(connectionURI);
final IXtextDocument doc = context.getXtextDocument(connuri);
doc.<Object>modify(new IUnitOfWork.Void<XtextResource>() {
@Override
public void process(final XtextResource state) throws Exception {
EObject _eObject = state.getResourceSet().getEObject(URI.createURI(flowModeURI), true);
final Mode flowMode = ((Mode) _eObject);
EObject _eObject_1 = state.getResourceSet().getEObject(connuri, true);
final Connection connection = ((Connection) _eObject_1);
connection.getInModeOrTransitions().add(flowMode);
}
});
Aadl2QuickfixProvider.this.editorOpener.open(connuri, true);
}
});
}
/**
* QuickFix for Subcomponent not in flow modes
* issue.getData(0) targetName
* issue.getData(1) targetURI
* issue,getData(2) neededModeName
* issue,getData(3) neededModeURI
*/
@Fix(Aadl2Validator.END_TO_END_FLOW_SEGMENT_NOT_IN_MODE)
public void fixEndToEndFlowSegmentNotInMode(final Issue issue, final IssueResolutionAcceptor acceptor) {
final String targetName = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(issue.getData())));
final String targetURI = issue.getData()[1];
final String neededModeName = issue.getData()[2];
final String neededModeURI = issue.getData()[3];
acceptor.accept(issue, (((("Add mode \'" + neededModeName) + "\' to in modes of \'") + targetName) + "\'"), null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final URI targeturi = URI.createURI(targetURI);
final IXtextDocument doc = context.getXtextDocument(targeturi);
doc.<Object>modify(new IUnitOfWork.Void<XtextResource>() {
@Override
public void process(final XtextResource state) throws Exception {
EObject _eObject = state.getResourceSet().getEObject(URI.createURI(neededModeURI), true);
final Mode neededMode = ((Mode) _eObject);
final EObject targetObject = state.getResourceSet().getEObject(targeturi, true);
boolean _matched = false;
if (targetObject instanceof Subcomponent) {
_matched=true;
final ModeBinding modeBinding = ((Subcomponent)targetObject).createOwnedModeBinding();
modeBinding.setParentMode(neededMode);
}
if (!_matched) {
if (targetObject instanceof ModalPath) {
_matched=true;
((ModalPath)targetObject).getInModeOrTransitions().add(neededMode);
}
}
}
});
Aadl2QuickfixProvider.this.editorOpener.open(targeturi, true);
}
});
}
/**
* QuickFix for generic text replacement
* issue.getData(0) changeFrom
* issue.getData(1) changeTo
* issue,getData(2) offSet
*/
@Fix(Aadl2Validator.GENERIC_TEXT_REPLACEMENT)
public void fixByGenericTextReplacement(final Issue issue, final IssueResolutionAcceptor acceptor) {
final String changeFrom = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(issue.getData())));
final String changeTo = issue.getData()[1];
final int offSet = Integer.parseInt(issue.getData()[2]);
acceptor.accept(issue, (((("Change \'" + changeFrom) + "\' to \'") + changeTo) + "\'"), null, null, new IModification() {
@Override
public void apply(final IModificationContext context) throws Exception {
context.getXtextDocument().replace(offSet, changeFrom.length(), changeTo);
}
});
}
/**
* QuickFix for Array size not same as reference list size
* issue.getData(0) arraySize
* issue.getData(1) referenceListSize
*/
@Fix(Aadl2Validator.ARRAY_SIZE_NOT_EQUAL_REFERENCE_LIST_SIZE)
public void fixArraySizeNotEqualRefernceListSize(final Issue issue, final IssueResolutionAcceptor acceptor) {
final int arraySize = Integer.parseInt(IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(issue.getData()))));
final int referenceListSize = Integer.parseInt(issue.getData()[1]);
acceptor.accept(issue, (((("Change Array size from \'" + Integer.valueOf(arraySize)) + "\' to \'") + Integer.valueOf(referenceListSize)) + "\'"), null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final Subcomponent subcomponent = ((Subcomponent) element);
ArraySize _size = IterableExtensions.<ArrayDimension>head(subcomponent.getArrayDimensions()).getSize();
_size.setSize(referenceListSize);
}
});
}
/**
* QuickFix for Prototype must be an array because the refined prototype is an array
*/
@Fix(Aadl2Validator.PROTOTYPE_NOT_ARRAY)
public void fixPrototypeMusBeAnArray(final Issue issue, final IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, "Change prototype to an array", null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final ComponentPrototype prototype = ((ComponentPrototype) element);
prototype.setArray(true);
}
});
}
/**
* QuickFix for Prototype binding direction not consistent with formal
* issue.getData(0) = actualDirection.toString();
* issue.getData(1) = formalDirection.toString();
*/
@Fix(Aadl2Validator.PROTOTYPE_BINDING_DIRECTION_NOT_CONSISTENT_WITH_FORMAL)
public void fixPrototypeBindingDirection(final Issue issue, final IssueResolutionAcceptor acceptor) {
final String changeFrom = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(issue.getData())));
final String changeTo = issue.getData()[1];
acceptor.accept(issue, (((("Change \'" + changeFrom) + "\' to \'") + changeTo) + "\'"), null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final FeaturePrototypeBinding binding = ((FeaturePrototypeBinding) element);
Prototype _formal = binding.getFormal();
final FeaturePrototype formal = ((FeaturePrototype) _formal);
final FeaturePrototypeActual actual = binding.getActual();
boolean _matched = false;
if (actual instanceof FeaturePrototypeReference) {
_matched=true;
((FeaturePrototypeReference)actual).setIn(formal.isIn());
((FeaturePrototypeReference)actual).setOut(formal.isOut());
}
if (!_matched) {
if (actual instanceof PortSpecification) {
_matched=true;
((PortSpecification)actual).setIn(formal.isIn());
((PortSpecification)actual).setOut(formal.isOut());
}
}
}
});
}
/**
* QuickFix for incompatible direction for prototype refinement
* issue.getData(0) = changeFrom
* issue.getData(1) = changeTo;
*/
@Fix(Aadl2Validator.INCOMPATIBLE_DIRECTION_FOR_PROTOTYPE_REFINEMENT)
public void fixIncompatibleDirectionForPrototypeRefinement(final Issue issue, final IssueResolutionAcceptor acceptor) {
final String changeFrom = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(issue.getData())));
final String changeTo = issue.getData()[1];
acceptor.accept(issue, (((("Change \'" + changeFrom) + "\' to \'") + changeTo) + "\'"), null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final FeaturePrototype prototype = ((FeaturePrototype) element);
Prototype _refined = prototype.getRefined();
final FeaturePrototype refined = ((FeaturePrototype) _refined);
prototype.setIn(refined.isIn());
prototype.setOut(refined.isOut());
}
});
}
/**
* QuickFix for incompatible feature direction in refinement
* issue.getData(0) = changeFrom
* issue.getData(1) = changeTo;
*/
@Fix(Aadl2Validator.INCOMPATIBLE_FEATURE_DIRECTION_IN_REFINEMENT)
public void fixIncompatibleFeatureDirectionInRefinement(final Issue issue, final IssueResolutionAcceptor acceptor) {
final String changeFrom = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(issue.getData())));
final String changeTo = issue.getData()[1];
acceptor.accept(issue, (((("Change \'" + changeFrom) + "\' to \'") + changeTo) + "\'"), null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final DirectedFeature feature = ((DirectedFeature) element);
Feature _refined = feature.getRefined();
final DirectedFeature refined = ((DirectedFeature) _refined);
feature.setIn(refined.isIn());
feature.setOut(refined.isOut());
}
});
}
/**
* QuickFix for incompatible feature direction in refinement
* issue.getData(0) = changeFrom
* issue.getData(1) = changeTo;
*/
@Fix(Aadl2Validator.ABSTRACT_FEATURE_DIRECTION_DOES_NOT_MATCH_PROTOTYPE)
public void fixAbstractFeatureDirectionDoesNotMatchPrototype(final Issue issue, final IssueResolutionAcceptor acceptor) {
final String changeFrom = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(issue.getData())));
final String changeTo = issue.getData()[1];
acceptor.accept(issue, (((("Change \'" + changeFrom) + "\' to \'") + changeTo) + "\'"), null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final AbstractFeature feature = ((AbstractFeature) element);
final FeaturePrototype prototype = feature.getFeaturePrototype();
feature.setIn(prototype.isIn());
feature.setOut(prototype.isOut());
}
});
}
/**
* QuickFix for incompatible feature direction in refinement
* issue.getData(0) = changeFrom
*/
@Fix(Aadl2Validator.ABSTRACT_FEATURE_DIRECTION_NOT_IN_PROTOTYPE)
public void fixAbstractFeatureDirectionNotInPrototype(final Issue issue, final IssueResolutionAcceptor acceptor) {
final String changeFrom = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(issue.getData())));
acceptor.accept(issue, (("Remove \'" + changeFrom) + "\'"), null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final AbstractFeature feature = ((AbstractFeature) element);
feature.setIn(false);
feature.setOut(false);
}
});
}
/**
* QuickFix for added direction in abstract feature refinement
* issue.getData(0) = changeFrom
*/
@Fix(Aadl2Validator.ADDED_DIRECTION_IN_ABSTRACT_FEATURE_REFINEMENT)
public void fixAddedDirectionInAbstractFeatureRefinement(final Issue issue, final IssueResolutionAcceptor acceptor) {
final String changeFrom = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(issue.getData())));
acceptor.accept(issue, (("Remove \'" + changeFrom) + "\'"), null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final AbstractFeature feature = ((AbstractFeature) element);
feature.setIn(false);
feature.setOut(false);
}
});
}
/**
* QuickFix for added prototype or classifier in abstract feature refinement
* issue.getData(0) = changeFrom
*/
@Fix(Aadl2Validator.ADDED_PROTOTYPE_OR_CLASSIFIER_IN_ABSTRACT_FEATURE_REFINEMENT)
public void fixAddedPrototypeOrClassifierInAbstractFeatureRefinement(final Issue issue, final IssueResolutionAcceptor acceptor) {
final String changeFrom = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(issue.getData())));
acceptor.accept(issue, (("Remove \'" + changeFrom) + "\'"), null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final AbstractFeature feature = ((AbstractFeature) element);
feature.setFeaturePrototype(null);
}
});
}
/**
* QuickFix for chained inverse feature group types
*/
@Fix(Aadl2Validator.CHAINED_INVERSE_FEATURE_GROUP_TYPES)
public void fixChainedInverseFeatureGroupTypes(final Issue issue, final IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, "Remove inverse", null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final FeatureGroupType featureGroupType = ((FeatureGroupType) element);
featureGroupType.setInverse(null);
}
});
}
/**
* QuickFix for extending inverse feature group types
*/
@Fix(Aadl2Validator.EXTENDED_INVERSE_FEATURE_GROUP_TYPE)
public void fixExtendedInverseFeatureGroupTypes(final Issue issue, final IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, "Remove extends", null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final GroupExtension groupExtension = ((GroupExtension) element);
EObject _eContainer = groupExtension.eContainer();
final FeatureGroupType featureGroup = ((FeatureGroupType) _eContainer);
featureGroup.setOwnedExtension(null);
}
});
}
/**
* QuickFix for extending inverse feature group types
*/
@Fix(Aadl2Validator.INVERSE_IN_FEATURE_GROUP_TYPE_EXTENSION)
public void fixInverseInFeatureGroupTypeExtension(final Issue issue, final IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, "Remove extends", null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final GroupExtension groupExtension = ((GroupExtension) element);
EObject _eContainer = groupExtension.eContainer();
final FeatureGroupType featureGroup = ((FeatureGroupType) _eContainer);
featureGroup.setOwnedExtension(null);
}
});
acceptor.accept(issue, "Remove inverse", null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final GroupExtension groupExtension = ((GroupExtension) element);
EObject _eContainer = groupExtension.eContainer();
final FeatureGroupType featureGroup = ((FeatureGroupType) _eContainer);
featureGroup.setInverse(null);
}
});
}
/**
* QuickFix for inverse in feature group
*/
@Fix(Aadl2Validator.INVERSE_IN_FEATURE_GROUP)
public void fixInverseInFeatureGroup(final Issue issue, final IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, "Remove inverse", null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final FeatureGroup featureGroup = ((FeatureGroup) element);
featureGroup.setInverse(false);
}
});
}
/**
* QuickFix for extending inverse feature group types
* issue.getData(0) = valid direction if any or empty String
* issue.getData(1) = current direction
*/
@Fix(Aadl2Validator.DIRECTION_NOT_SAME_AS_FEATURE_GROUP_MEMBERS)
public void fixDirectionNotTheSameAsFeatureGroupMembers(final Issue issue, final IssueResolutionAcceptor acceptor) {
final String validDirection = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(issue.getData())));
final String currentDirection = issue.getData()[1];
acceptor.accept(issue, (("Remove \'" + currentDirection) + "\'"), null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final FeatureGroup featureGroup = ((FeatureGroup) element);
featureGroup.setIn(false);
featureGroup.setOut(false);
}
});
boolean _equals = validDirection.equals("");
boolean _not = (!_equals);
if (_not) {
acceptor.accept(issue, (((("Change direction from \'" + currentDirection) + "\' to \'") + validDirection) + "\'"), null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final FeatureGroup featureGroup = ((FeatureGroup) element);
if (validDirection != null) {
switch (validDirection) {
case "in":
featureGroup.setIn(true);
featureGroup.setOut(false);
break;
case "out":
featureGroup.setIn(false);
featureGroup.setOut(true);
break;
default:
{
featureGroup.setIn(false);
featureGroup.setOut(false);
}
break;
}
} else {
{
featureGroup.setIn(false);
featureGroup.setOut(false);
}
}
}
});
}
}
/**
* QuickFix for reverse access kind
* issue.getData.get(0) changeFrom
* issue.getData.get(1) changeTo
*/
@Fix(Aadl2Validator.REVERSE_ACCESS_KIND)
public void fixReverseAccessKind(final Issue issue, final IssueResolutionAcceptor acceptor) {
final String changeFrom = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(issue.getData())));
final String changeTo = issue.getData()[1];
acceptor.accept(issue, (((("Change access from \'" + changeFrom) + "\' to \'") + changeTo) + "\'"), null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final Access access = ((Access) element);
access.setKind(AccessType.getByName(changeTo));
}
});
}
/**
* QuickFix for swapping Upper and Lower bounds in a range value when the upper is less than the lower
* issue.getData.get(0) lowerURI
* issue.getData.get(1) upperURI
* issue.getData.get(2) keyword before the range
* issue.getData.get(3) offSet of keyword before the range
*/
@Fix(Aadl2Validator.NUMERIC_RANGE_UPPER_LESS_THAN_LOWER)
public void fixNumericRangeUpperLessThanLower(final Issue issue, final IssueResolutionAcceptor acceptor) {
final String lowerURI = IterableExtensions.<String>head(((Iterable<String>)Conversions.doWrapArray(issue.getData())));
final String upperURI = issue.getData()[1];
final String changeFrom = issue.getData()[2];
final int offSet = Integer.parseInt(issue.getData()[3]);
final String changeTo = (changeFrom + " ");
acceptor.accept(issue, "Switch upper and lower bounds of the range", null, null, new IModification() {
@Override
public void apply(final IModificationContext context) throws Exception {
IXtextDocument _xtextDocument = context.getXtextDocument();
_xtextDocument.<Object>modify(new IUnitOfWork.Void<XtextResource>() {
@Override
public void process(final XtextResource state) throws Exception {
final ResourceSet resourceSet = state.getResourceSet();
final EObject element = resourceSet.getEObject(issue.getUriToProblem(), true);
EObject _eObject = resourceSet.getEObject(URI.createURI(lowerURI), true);
final PropertyExpression oldLower = ((PropertyExpression) _eObject);
EObject _eObject_1 = resourceSet.getEObject(URI.createURI(upperURI), true);
final PropertyExpression oldUpper = ((PropertyExpression) _eObject_1);
((NumericRange) element).setUpperBound(oldLower);
((NumericRange) element).setLowerBound(oldUpper);
}
});
context.getXtextDocument().replace(offSet, changeFrom.length(), changeTo);
}
});
}
/**
* QuickFix by making a connection bidirectional
*/
@Fix(Aadl2Validator.MAKE_CONNECTION_BIDIRECTIONAL)
public void fixMakeConnectionBiderctional(final Issue issue, final IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, "Make connection bidirectional", null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final Connection connection = ((Connection) element);
connection.setBidirectional(true);
}
});
}
/**
* QuickFix for adding a removing unused propertySet in packageSection with clause
* The issue data array is expected to have two elements:
*
* issue.getData()[0]: The name of the package or property set
* issue.getData()[1]: The URI String of the referenced AadlPackage or PropertySet.
*/
@Fix(Aadl2Validator.WITH_NOT_USED)
public void fixWithNotUsed(final Issue issue, final IssueResolutionAcceptor acceptor) {
String _get = issue.getData()[0];
String _plus = ("Remove \'" + _get);
String _plus_1 = (_plus + "\' from the with clause");
acceptor.accept(issue, _plus_1, null, null,
new ISemanticModification() {
@Override
public void apply(final EObject element, final IModificationContext context) throws Exception {
final ResourceSet resourceSet = element.eResource().getResourceSet();
EObject _eObject = resourceSet.getEObject(URI.createURI(issue.getData()[1]), true);
final ModelUnit importedModelUnit = ((ModelUnit) _eObject);
boolean _matched = false;
if (element instanceof PackageSection) {
_matched=true;
((PackageSection)element).getImportedUnits().remove(importedModelUnit);
}
if (!_matched) {
if (element instanceof PropertySet) {
_matched=true;
((PropertySet)element).getImportedUnits().remove(importedModelUnit);
}
}
}
});
}
}