diff options
author | Jayant Gupta | 2013-09-18 08:15:57 +0000 |
---|---|---|
committer | Jayant Gupta | 2013-09-18 08:15:57 +0000 |
commit | 3f64e53873ed85db637dcf97488b78b44585b657 (patch) | |
tree | dd2a9c59e21f164591269ee615bd0cef51dd0d1a | |
parent | 29d00871da4c6d2e18af6a81d2822f78ba7279b1 (diff) | |
download | org.eclipse.etrice-3f64e53873ed85db637dcf97488b78b44585b657.tar.gz org.eclipse.etrice-3f64e53873ed85db637dcf97488b78b44585b657.tar.xz org.eclipse.etrice-3f64e53873ed85db637dcf97488b78b44585b657.zip |
Adds QuickFixDialog and QuickFixFeature to manage it.
Change-Id: I854ad6256586db44885a8dc424c054818a139407
Signed-off-by: Jayant Gupta <gsocjayant@gmail.com>
20 files changed, 828 insertions, 37 deletions
diff --git a/plugins/org.eclipse.etrice.abstractexec.behavior/META-INF/MANIFEST.MF b/plugins/org.eclipse.etrice.abstractexec.behavior/META-INF/MANIFEST.MF index 531799893..c594cb4c8 100644 --- a/plugins/org.eclipse.etrice.abstractexec.behavior/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.etrice.abstractexec.behavior/META-INF/MANIFEST.MF @@ -14,4 +14,4 @@ Require-Bundle: org.eclipse.etrice.core.room;bundle-version="0.4.0", org.eclipse.xtext.ui;bundle-version="2.1.1" Bundle-Activator: org.eclipse.etrice.abstractexec.behavior.Activator Bundle-ActivationPolicy: lazy -Export-Package: org.eclipse.etrice.abstractexec.behavior;x-friends:="org.eclipse.etrice.abstractexec.behavior.tests" +Export-Package: org.eclipse.etrice.abstractexec.behavior;x-friends:="org.eclipse.etrice.abstractexec.behavior.tests,org.eclipse.etrice.ui.behavior" diff --git a/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/AbstractExecutionValidator.java b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/AbstractExecutionValidator.java index 25833f20f..781c71947 100644 --- a/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/AbstractExecutionValidator.java +++ b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/AbstractExecutionValidator.java @@ -45,10 +45,10 @@ import org.eclipse.xtext.validation.ValidationMessageAcceptor; public class AbstractExecutionValidator implements IRoomValidator { // c&p in tests - public static String DIAG_CODE_VIOLATION_TRIGGER = "etrice.violation_trigger"; - public static String DIAG_CODE_VIOLATION_MESSAGESEND = "etrice.violation_messagesend"; - public static String DIAG_CODE_MISSING_TRIGGER = "etrice.receive_message"; - public static String DIAG_CODE_MISSING_MESSAGESEND = "etrice.send_message"; + public static final String DIAG_CODE_VIOLATION_TRIGGER = "etrice.violation_trigger"; + public static final String DIAG_CODE_VIOLATION_MESSAGESEND = "etrice.violation_messagesend"; + public static final String DIAG_CODE_MISSING_TRIGGER = "etrice.receive_message"; + public static final String DIAG_CODE_MISSING_MESSAGESEND = "etrice.send_message"; private static boolean traceExec = false; private static String traceName = ""; @@ -186,17 +186,18 @@ public class AbstractExecutionValidator implements IRoomValidator { + msg.getMessage().getName() + " from port " + msg.getFrom().getName() + " ", container, orig.eContainingFeature(), idx, DIAG_CODE_MISSING_TRIGGER, - st.getName()); + st.getName(), msg.getFrom().getGeneralProtocol().getName(), + msg.getMessage().getName(), msg.getFrom().getName()); } List<MessageFromIf> outgoing = propGen.getOutgoingProposals(); for (MessageFromIf msg : outgoing) { messageAcceptor.acceptInfo("State should send the message " + msg.getMessage().getName() + " to port " - + msg.getFrom().getName() + " ", container, - orig.eContainingFeature(), idx, DIAG_CODE_MISSING_MESSAGESEND, - st.getName()); - + + msg.getFrom().getName() + " ", container, orig + .eContainingFeature(), idx, DIAG_CODE_MISSING_MESSAGESEND, + st.getName(), msg.getFrom().getGeneralProtocol().getName(), + msg.getMessage().getName(), msg.getFrom().getName()); } } @@ -233,8 +234,15 @@ public class AbstractExecutionValidator implements IRoomValidator { mif.eContainingFeature(), trig.getMsgFromIfPairs() .indexOf(trig), - DIAG_CODE_VIOLATION_TRIGGER, trigger - .getMsg().getName()); + DIAG_CODE_VIOLATION_TRIGGER, + trigger.getMsg().getName(), + mif.getFrom() + .getGeneralProtocol() + .getName(), mif + .getMessage() + .getName(), mif + .getFrom() + .getName()); } } } diff --git a/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ReachabilityValidator.java b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ReachabilityValidator.java index da86f29b7..6a1ea8853 100644 --- a/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ReachabilityValidator.java +++ b/plugins/org.eclipse.etrice.abstractexec.behavior/src/org/eclipse/etrice/abstractexec/behavior/ReachabilityValidator.java @@ -31,7 +31,7 @@ import org.eclipse.xtext.validation.ValidationMessageAcceptor; public class ReachabilityValidator implements IRoomValidator { - public static String DIAG_CODE_UNREACHABLE = "etrice.unreachable"; + public static final String DIAG_CODE_UNREACHABLE = "etrice.unreachable"; @Override public void validate(EObject object, ValidationMessageAcceptor messageAcceptor) { diff --git a/plugins/org.eclipse.etrice.ui.behavior/META-INF/MANIFEST.MF b/plugins/org.eclipse.etrice.ui.behavior/META-INF/MANIFEST.MF index 4447a1d9e..0338d2f03 100644 --- a/plugins/org.eclipse.etrice.ui.behavior/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.etrice.ui.behavior/META-INF/MANIFEST.MF @@ -13,7 +13,8 @@ Require-Bundle: org.eclipse.etrice.core.room.ui;bundle-version="0.4.0", org.eclipse.gef;bundle-version="3.6.1", org.eclipse.emf.transaction;bundle-version="1.4.0", org.eclipse.xtext.ui;bundle-version="2.1.1", - org.eclipse.xtext.ui.shared;bundle-version="2.1.1" + org.eclipse.xtext.ui.shared;bundle-version="2.1.1", + org.eclipse.etrice.abstractexec.behavior;bundle-version="0.4.0" Bundle-ActivationPolicy: lazy Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-Vendor: Eclipse eTrice (Incubation) diff --git a/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/add.gif b/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/add.gif Binary files differnew file mode 100644 index 000000000..d96f061a2 --- /dev/null +++ b/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/add.gif diff --git a/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/error.gif b/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/error.gif Binary files differnew file mode 100644 index 000000000..d2fc32edc --- /dev/null +++ b/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/error.gif diff --git a/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/error_tsk.gif b/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/error_tsk.gif Binary files differnew file mode 100644 index 000000000..197b295e1 --- /dev/null +++ b/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/error_tsk.gif diff --git a/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/info_tsk.gif b/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/info_tsk.gif Binary files differnew file mode 100644 index 000000000..2da001e3e --- /dev/null +++ b/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/info_tsk.gif diff --git a/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/information.gif b/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/information.gif Binary files differnew file mode 100644 index 000000000..3679f84ad --- /dev/null +++ b/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/information.gif diff --git a/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/quickassist.gif b/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/quickassist.gif Binary files differnew file mode 100644 index 000000000..94ae2a0ee --- /dev/null +++ b/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/quickassist.gif diff --git a/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/warn_tsk.gif b/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/warn_tsk.gif Binary files differnew file mode 100644 index 000000000..14009e997 --- /dev/null +++ b/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/warn_tsk.gif diff --git a/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/warning.gif b/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/warning.gif Binary files differnew file mode 100644 index 000000000..a01bb24b7 --- /dev/null +++ b/plugins/org.eclipse.etrice.ui.behavior/icons/quickfix/warning.gif diff --git a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/dialogs/QuickFixDialog.java b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/dialogs/QuickFixDialog.java new file mode 100644 index 000000000..4709eb09c --- /dev/null +++ b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/dialogs/QuickFixDialog.java @@ -0,0 +1,341 @@ +/******************************************************************************* + * Copyright (c) 2000, 2012 IBM Corporation and others. + * 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: + * IBM Corporation - initial API and implementation + * Sebastian Davids <sdavids@gmx.de> - Fix for bug 19346 - Dialog + * font should be activated and used by other components. + *******************************************************************************/ +package org.eclipse.etrice.ui.behavior.dialogs; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; + +import org.eclipse.emf.common.util.Diagnostic; +import org.eclipse.etrice.ui.behavior.Activator; +import org.eclipse.etrice.ui.common.quickfix.IssueResolution; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionChangedListener; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.IStructuredSelection; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.jface.viewers.SelectionChangedEvent; +import org.eclipse.jface.viewers.StructuredSelection; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.Viewer; +import org.eclipse.jface.viewers.ViewerComparator; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.dialogs.SelectionDialog; +import org.eclipse.xtext.validation.FeatureBasedDiagnostic; + +/** + * An abstract class to select elements out of a list of elements. + * + * @since 2.0 + */ +public class QuickFixDialog extends SelectionDialog { + + private static final String TITLE = "Quick Fix"; + private static final String MESSAGE_AREA_LABEL = "Quick Fix"; + private static final String ISSUES_LIST_LABEL = "Select a Issue:"; + private static final String RESOLUTIONS_LIST_LABEL = "Select a fix:"; + private static final String DESCRIPTION_AREA_LABEL = "Description"; + + private static final String ERROR_IMAGE = "icons/quickfix/error_tsk.gif"; + private static final String WARNING_IMAGE = "icons/quickfix/warn_tsk.gif"; + private static final String INFO_IMAGE = "icons/quickfix/info_tsk.gif"; + + private HashMap<FeatureBasedDiagnostic, List<IssueResolution>> issueResolutionsMap; + private TableViewer issueList; + private TableViewer resolutionsList; + private Label resolutionDescription; + + /** + * Constructs a list selection dialog. + * + * @param parent + * The parent for the list. + * @param renderer + * ILabelProvider for the list + */ + public QuickFixDialog( + Shell parent, + HashMap<FeatureBasedDiagnostic, List<IssueResolution>> errorResolutionsMap) { + super(parent); + this.issueResolutionsMap = errorResolutionsMap; + setTitle(TITLE); + setMessage(MESSAGE_AREA_LABEL); + } + + /* + * @see Dialog#createDialogArea(Composite) + */ + public Control createDialogArea(Composite parent) { + Composite contents = (Composite) super.createDialogArea(parent); + createMessageArea(contents); + + createLabel(contents, ISSUES_LIST_LABEL); + createIssueList(contents); + + createLabel(contents, RESOLUTIONS_LIST_LABEL); + createResolutionList(contents); + + createLabel(contents, DESCRIPTION_AREA_LABEL); + createDescritionArea(contents); + + issueList.setInput(this); + resolutionsList.setInput(this); + issueList.setSelection( + new StructuredSelection(issueList.getElementAt(0)), true); + + return contents; + } + + /** + * @param control + */ + private void createIssueList(Composite control) { + issueList = new TableViewer(control, SWT.BORDER | SWT.SINGLE + | SWT.V_SCROLL); + + issueList.setContentProvider(new IStructuredContentProvider() { + + @Override + public Object[] getElements(Object inputElement) { + return issueResolutionsMap.keySet().toArray(); + } + + @Override + public void dispose() { + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { + } + }); + + issueList.setLabelProvider(new LabelProvider() { + + @Override + public String getText(Object element) { + return ((FeatureBasedDiagnostic) element).getMessage(); + } + + @Override + public Image getImage(Object element) { + switch (((Diagnostic) element).getSeverity()) { + case Diagnostic.ERROR: + return Activator.getImage(ERROR_IMAGE); + + case Diagnostic.WARNING: + return Activator.getImage(WARNING_IMAGE); + + case Diagnostic.INFO: + return Activator.getImage(INFO_IMAGE); + } + return null; + } + }); + + issueList.setComparator(new ViewerComparator() { + @Override + public int compare(Viewer viewer, Object e1, Object e2) { + return ((FeatureBasedDiagnostic) e1).getMessage().compareTo( + ((FeatureBasedDiagnostic) e2).getMessage()); + } + }); + + issueList.addSelectionChangedListener(new ISelectionChangedListener() { + @Override + public void selectionChanged(SelectionChangedEvent event) { + resolutionsList.refresh(); + if (resolutionsList.getElementAt(0) != null) + resolutionsList.setSelection(new StructuredSelection( + resolutionsList.getElementAt(0)), true); + updateOkState(); + } + }); + } + + /** + * Create the table that shows the markers. + * + * @param control + */ + private void createResolutionList(Composite control) { + resolutionsList = new TableViewer(control, SWT.BORDER | SWT.SINGLE + | SWT.V_SCROLL); + + resolutionsList.setContentProvider(new IStructuredContentProvider() { + + @Override + public void dispose() { + } + + @Override + public Object[] getElements(Object inputElement) { + FeatureBasedDiagnostic selected = getSelectedIssue(); + if (selected == null) { + return new Object[0]; + } + return (issueResolutionsMap.get(selected)).toArray(); + } + + @Override + public void inputChanged(Viewer viewer, Object oldInput, + Object newInput) { + } + }); + + resolutionsList.setLabelProvider(new LabelProvider() { + + @Override + public String getText(Object element) { + return ((IssueResolution) element).getLabel(); + } + + @Override + public Image getImage(Object element) { + return Activator.getImage(((IssueResolution) element) + .getImage()); + } + }); + + resolutionsList + .addSelectionChangedListener(new ISelectionChangedListener() { + @Override + public void selectionChanged(SelectionChangedEvent event) { + IssueResolution resolution = getSelectedResolution(); + String description = ""; + if (resolution != null) + description = resolution.getDescription(); + resolutionDescription.setText(description); + updateOkState(); + } + }); + } + + /** + * Creates a label if name was not <code>null</code>. + * + * @param parent + * the parent composite. + * @param name + * the name of the label. + * @return returns a label if a name was given, <code>null</code> otherwise. + */ + private Label createLabel(Composite parent, String name) { + if (name == null) { + return null; + } + Label label = new Label(parent, SWT.NONE); + label.setText(name); + label.setFont(parent.getFont()); + return label; + } + + /** + * Creates the message text widget and sets layout data. + * + * @param composite + * the parent composite of the message area. + */ + protected Label createMessageArea(Composite composite) { + Label label = super.createMessageArea(composite); + + GridData data = new GridData(); + data.grabExcessVerticalSpace = false; + data.grabExcessHorizontalSpace = true; + data.horizontalAlignment = GridData.FILL; + data.verticalAlignment = GridData.BEGINNING; + label.setLayoutData(data); + + return label; + } + + private Label createDescritionArea(Composite composite) { + Label label = super.createMessageArea(composite); + + GridData data = new GridData(); + data.grabExcessVerticalSpace = true; + data.grabExcessHorizontalSpace = true; + data.horizontalAlignment = GridData.FILL; + data.verticalAlignment = GridData.BEGINNING; + label.setLayoutData(data); + + resolutionDescription = label; + + return label; + } + + /** + * Return the currently selected issue. + * + * @return {@link FeatureBasedDiagnostic} or <code>null</code> if there is + * no selection. + */ + private FeatureBasedDiagnostic getSelectedIssue() { + ISelection selection = issueList.getSelection(); + if (!(selection instanceof IStructuredSelection)) { + return null; + } + + Object first = ((IStructuredSelection) selection).getFirstElement(); + + return (FeatureBasedDiagnostic) first; + } + + /** + * Return the currently selected resolution. + * + * @return {@link IssueResolution} or <code>null</code> if there is no + * selection. + */ + private IssueResolution getSelectedResolution() { + ISelection selection = resolutionsList.getSelection(); + if (!(selection instanceof IStructuredSelection)) { + return null; + } + Object first = ((IStructuredSelection) selection).getFirstElement(); + return (IssueResolution) first; + } + + /* + * @see Dialog#cancelPressed + */ + protected void cancelPressed() { + setResult(null); + super.cancelPressed(); + } + + @Override + protected void okPressed() { + Object[] results = new Object[] { getSelectedResolution() }; + setResult(Arrays.asList(results)); + super.okPressed(); + } + + /** + * Update the enablement of the OK button based on whether or not there is a + * selection. + */ + private void updateOkState() { + Button okButton = getOkButton(); + if (okButton != null) { + okButton.setEnabled(getSelectedResolution() != null); + } + } +} diff --git a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/quickfix/BehaviorQuickfixProvider.java b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/quickfix/BehaviorQuickfixProvider.java index 9e857e0b2..a6e4b0933 100644 --- a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/quickfix/BehaviorQuickfixProvider.java +++ b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/quickfix/BehaviorQuickfixProvider.java @@ -7,35 +7,138 @@ * * CONTRIBUTORS: * Henrik Rentz-Reichert (initial contribution) + * Jayant Gupta (Added Fix methods) * *******************************************************************************/ package org.eclipse.etrice.ui.behavior.quickfix; +import org.eclipse.etrice.abstractexec.behavior.AbstractExecutionValidator; +import org.eclipse.etrice.abstractexec.behavior.ReachabilityValidator; import org.eclipse.etrice.ui.common.quickfix.AbstractQuickfixProvider; import org.eclipse.etrice.ui.common.quickfix.IDiagramModification; import org.eclipse.etrice.ui.common.quickfix.IssueResolutionAcceptor; import org.eclipse.graphiti.features.IFeatureProvider; import org.eclipse.graphiti.mm.pictograms.Diagram; import org.eclipse.xtext.ui.editor.quickfix.Fix; -import org.eclipse.xtext.validation.Issue; - +import org.eclipse.xtext.validation.FeatureBasedDiagnostic; /** * @author Henrik Rentz-Reichert - * + * @author jayant + * */ public class BehaviorQuickfixProvider extends AbstractQuickfixProvider { - @Fix("SomeIssue") - public void fixSomeIssue(final Issue issue, IssueResolutionAcceptor acceptor) { - acceptor.accept(issue, "my label", "my description", "image.gif", new IDiagramModification() { + private static final String ADD_IMG = "icons/quickfix/add.gif"; + + @Fix(AbstractExecutionValidator.DIAG_CODE_MISSING_TRIGGER) + public void fixMissingTrigger(final FeatureBasedDiagnostic issue, + IssueResolutionAcceptor acceptor) { + acceptor.accept( + issue, + "Add the missing trigger", + "Adds a new transition with trigger to handle message " + + issue.getIssueData()[2] + " from port " + + issue.getIssueData()[3], ADD_IMG, + new IDiagramModification() { + + @Override + public void apply(Diagram diagram, IFeatureProvider fp) + throws Exception { + // make a new transition & add a Trigger to handle + // message + } + }); + } + + @Fix(AbstractExecutionValidator.DIAG_CODE_MISSING_MESSAGESEND) + public void fixMissingMessageSend(final FeatureBasedDiagnostic issue, + IssueResolutionAcceptor acceptor) { + acceptor.accept( + issue, + "Send message " + issue.getIssueData()[2] + " to port " + + issue.getIssueData()[3], + "Adds a new transition with sends message " + + issue.getIssueData()[2] + " to port " + + issue.getIssueData()[3], ADD_IMG, + new IDiagramModification() { + + @Override + public void apply(Diagram diagram, IFeatureProvider fp) + throws Exception { + // make a new transition & send the message to the port + + } + + }); + } + + @Fix(AbstractExecutionValidator.DIAG_CODE_VIOLATION_TRIGGER) + public void fixViolationTrigger(final FeatureBasedDiagnostic issue, + IssueResolutionAcceptor acceptor) { + acceptor.accept(issue, "Change Trigger", "Changes the trigger", + ADD_IMG, new IDiagramModification() { + @Override + public void apply(Diagram diagram, IFeatureProvider fp) + throws Exception { + // modify diagram using features and issue data... + + } + + }); + } + + @Fix(AbstractExecutionValidator.DIAG_CODE_VIOLATION_MESSAGESEND) + public void fixViolationMessageSend(final FeatureBasedDiagnostic issue, + IssueResolutionAcceptor acceptor) { + acceptor.accept(issue, "Change Sent Message", + "Changes the sent message", ADD_IMG, + new IDiagramModification() { + + @Override + public void apply(Diagram diagram, IFeatureProvider fp) + throws Exception { + // modify diagram using features and issue data... + + } + + }); + } + + @Fix(ReachabilityValidator.DIAG_CODE_UNREACHABLE) + public void fixUnreachable(final FeatureBasedDiagnostic issue, + IssueResolutionAcceptor acceptor) { + acceptor.accept(issue, + "Add Transition from XYZ to " + issue.getIssueData()[0], + "Adds Transition from XYZ to " + issue.getIssueData()[0], + ADD_IMG, new IDiagramModification() { + + @Override + public void apply(Diagram diagram, IFeatureProvider fp) + throws Exception { + // Add the transition + + } + + }); + } + + @Fix(ReachabilityValidator.DIAG_CODE_UNREACHABLE) + public void fixUnreachable2(final FeatureBasedDiagnostic issue, + IssueResolutionAcceptor acceptor) { + acceptor.accept(issue, + "Add Transition from ABC to " + issue.getIssueData()[0], + "Adds Transition from ABC to " + issue.getIssueData()[0], + ADD_IMG, new IDiagramModification() { + + @Override + public void apply(Diagram diagram, IFeatureProvider fp) + throws Exception { + // Add the transition + + } - @Override - public void apply(Diagram diagram, IFeatureProvider fp) throws Exception { - // modify diagram using features and issue data... - } - - }); + }); } } diff --git a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/StateGraphSupport.java b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/StateGraphSupport.java index 93971f397..81a696808 100644 --- a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/StateGraphSupport.java +++ b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/StateGraphSupport.java @@ -13,6 +13,7 @@ package org.eclipse.etrice.ui.behavior.support; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import org.eclipse.emf.common.util.Diagnostic; @@ -25,8 +26,11 @@ import org.eclipse.etrice.core.room.StateGraph; import org.eclipse.etrice.core.room.TrPoint; import org.eclipse.etrice.core.room.Transition; import org.eclipse.etrice.ui.behavior.commands.StateGraphContext; +import org.eclipse.etrice.ui.behavior.dialogs.QuickFixDialog; import org.eclipse.etrice.ui.behavior.editor.BehaviorEditor; import org.eclipse.etrice.ui.behavior.markers.DecoratorUtil; +import org.eclipse.etrice.ui.behavior.quickfix.BehaviorQuickfixProvider; +import org.eclipse.etrice.ui.common.quickfix.IssueResolution; import org.eclipse.etrice.ui.common.support.DeleteWithoutConfirmFeature; import org.eclipse.graphiti.dt.IDiagramTypeProvider; import org.eclipse.graphiti.features.IAddFeature; @@ -73,6 +77,10 @@ import org.eclipse.graphiti.tb.ImageDecorator; import org.eclipse.graphiti.ui.features.DefaultFeatureProvider; import org.eclipse.graphiti.util.ColorConstant; import org.eclipse.graphiti.util.IColorConstant; +import org.eclipse.jface.window.Window; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.PlatformUI; +import org.eclipse.xtext.validation.FeatureBasedDiagnostic; public class StateGraphSupport { @@ -523,6 +531,71 @@ public class StateGraphSupport { } } + private static class QuickFixFeature extends AbstractCustomFeature { + + private boolean doneChanges = false; + + public QuickFixFeature(IFeatureProvider fp) { + super(fp); + } + + @Override + public String getName() { + return "Quick Fix"; + } + + @Override + public String getDescription() { + return "Apply Quick fixes"; + } + + @Override + public boolean canExecute(ICustomContext context) { + return true; + } + + @Override + public void execute(ICustomContext context) { + + // Get the issue Resolutions Map + Object bo = getBusinessObjectForPictogramElement(context + .getPictogramElements()[0]); + ArrayList<Diagnostic> issues = ((BehaviorEditor) getDiagramBehavior() + .getDiagramContainer()).getDiagnosingModelObserver() + .getElementDiagonsticMap().get(bo); + + HashMap<FeatureBasedDiagnostic, List<IssueResolution>> issueResolutionsMap = new HashMap<FeatureBasedDiagnostic, List<IssueResolution>>(); + BehaviorQuickfixProvider behaviorQuickfixProvider = new BehaviorQuickfixProvider(); + for (Diagnostic issue : issues) { + issueResolutionsMap + .put((FeatureBasedDiagnostic) issue, + behaviorQuickfixProvider + .getResolutions((FeatureBasedDiagnostic) issue)); + } + + // Create & Open the Quick Fix Dialog + Shell shell = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getShell(); + QuickFixDialog dlg = new QuickFixDialog(shell, issueResolutionsMap); + + if (dlg.open() != Window.OK) + return; + + Object[] result = dlg.getResult(); + if (result == null) + return; + else{ + ((IssueResolution)result[0]).apply(getDiagram()); + doneChanges = true; + } + } + + @Override + public boolean hasDoneChanges() { + return doneChanges; + } + } + private IFeatureProvider fp; public FeatureProvider(IDiagramTypeProvider dtp, IFeatureProvider fp) { @@ -563,9 +636,27 @@ public class StateGraphSupport { @Override public ICustomFeature[] getCustomFeatures(ICustomContext context) { - return new ICustomFeature[] { new GoUpFeature(fp) }; + PictogramElement pe = context.getPictogramElements()[0]; + Object bo = getBusinessObjectForPictogramElement(pe); + + ArrayList<ICustomFeature> result = new ArrayList<ICustomFeature>(); + + result.add(new GoUpFeature(fp)); + + // Provide quick fix feature only for those edit parts which have + // errors, warnings or infos. + ArrayList<Diagnostic> diagnostics = ((BehaviorEditor) getDiagramTypeProvider() + .getDiagramBehavior().getDiagramContainer()) + .getDiagnosingModelObserver().getElementDiagonsticMap() + .get(bo); + if (diagnostics != null) + result.add(new QuickFixFeature(fp)); + + ICustomFeature features[] = new ICustomFeature[result.size()]; + return result.toArray(features); } } + private class BehaviorProvider extends DefaultToolBehaviorProvider { diff --git a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/StateSupport.java b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/StateSupport.java index 28831b884..8120a8d1f 100644 --- a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/StateSupport.java +++ b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/StateSupport.java @@ -13,6 +13,8 @@ package org.eclipse.etrice.ui.behavior.support; import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.ecore.EObject; @@ -28,8 +30,11 @@ import org.eclipse.etrice.core.room.TrPoint; import org.eclipse.etrice.core.room.util.RoomHelpers; import org.eclipse.etrice.ui.behavior.ImageProvider; import org.eclipse.etrice.ui.behavior.dialogs.StatePropertyDialog; +import org.eclipse.etrice.ui.behavior.dialogs.QuickFixDialog; import org.eclipse.etrice.ui.behavior.editor.BehaviorEditor; import org.eclipse.etrice.ui.behavior.markers.DecoratorUtil; +import org.eclipse.etrice.ui.behavior.quickfix.BehaviorQuickfixProvider; +import org.eclipse.etrice.ui.common.quickfix.IssueResolution; import org.eclipse.etrice.ui.common.support.CommonSupportUtil; import org.eclipse.etrice.ui.common.support.DeleteWithoutConfirmFeature; import org.eclipse.graphiti.datatypes.IDimension; @@ -99,6 +104,7 @@ import org.eclipse.graphiti.util.IColorConstant; import org.eclipse.jface.window.Window; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.PlatformUI; +import org.eclipse.xtext.validation.FeatureBasedDiagnostic; public class StateSupport { @@ -860,6 +866,71 @@ public class StateSupport { } } + private static class QuickFixFeature extends AbstractCustomFeature { + + private boolean doneChanges = false; + + public QuickFixFeature(IFeatureProvider fp) { + super(fp); + } + + @Override + public String getName() { + return "Quick Fix"; + } + + @Override + public String getDescription() { + return "Apply Quick fixes"; + } + + @Override + public boolean canExecute(ICustomContext context) { + return true; + } + + @Override + public void execute(ICustomContext context) { + + // Get the issue Resolutions Map + Object bo = getBusinessObjectForPictogramElement(context + .getPictogramElements()[0]); + ArrayList<Diagnostic> issues = ((BehaviorEditor) getDiagramBehavior() + .getDiagramContainer()).getDiagnosingModelObserver() + .getElementDiagonsticMap().get(bo); + + HashMap<FeatureBasedDiagnostic, List<IssueResolution>> issueResolutionsMap = new HashMap<FeatureBasedDiagnostic, List<IssueResolution>>(); + BehaviorQuickfixProvider behaviorQuickfixProvider = new BehaviorQuickfixProvider(); + for (Diagnostic issue : issues) { + issueResolutionsMap + .put((FeatureBasedDiagnostic) issue, + behaviorQuickfixProvider + .getResolutions((FeatureBasedDiagnostic) issue)); + } + + // Create & Open the Quick Fix Dialog + Shell shell = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getShell(); + QuickFixDialog dlg = new QuickFixDialog(shell, issueResolutionsMap); + + if (dlg.open() != Window.OK) + return; + + Object[] result = dlg.getResult(); + if (result == null) + return; + else{ + ((IssueResolution)result[0]).apply(getDiagram()); + doneChanges = true; + } + } + + @Override + public boolean hasDoneChanges() { + return doneChanges; + } + } + private IFeatureProvider fp; public FeatureProvider(IDiagramTypeProvider dtp, IFeatureProvider fp) { @@ -946,7 +1017,16 @@ public class StateSupport { else result.add(new CreateSubGraphFeature(fp)); } - + + // Provide quick fix feature only for those edit parts which have + // errors, warnings or infos. + ArrayList<Diagnostic> diagnostics = ((BehaviorEditor) getDiagramTypeProvider() + .getDiagramBehavior().getDiagramContainer()) + .getDiagnosingModelObserver().getElementDiagonsticMap() + .get(bo); + if (diagnostics != null) + result.add(new QuickFixFeature(fp)); + ICustomFeature features[] = new ICustomFeature[result.size()]; return result.toArray(features); } diff --git a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/TrPointSupport.java b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/TrPointSupport.java index 0dbfec858..520268ec3 100644 --- a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/TrPointSupport.java +++ b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/TrPointSupport.java @@ -13,6 +13,7 @@ package org.eclipse.etrice.ui.behavior.support; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import org.eclipse.emf.common.util.Diagnostic; @@ -30,9 +31,12 @@ import org.eclipse.etrice.core.room.TransitionPoint; import org.eclipse.etrice.core.room.util.RoomHelpers; import org.eclipse.etrice.core.validation.ValidationUtil; import org.eclipse.etrice.ui.behavior.ImageProvider; +import org.eclipse.etrice.ui.behavior.dialogs.QuickFixDialog; import org.eclipse.etrice.ui.behavior.dialogs.TrPointPropertyDialog; import org.eclipse.etrice.ui.behavior.editor.BehaviorEditor; import org.eclipse.etrice.ui.behavior.markers.DecoratorUtil; +import org.eclipse.etrice.ui.behavior.quickfix.BehaviorQuickfixProvider; +import org.eclipse.etrice.ui.common.quickfix.IssueResolution; import org.eclipse.etrice.ui.common.support.CommonSupportUtil; import org.eclipse.etrice.ui.common.support.DeleteWithoutConfirmFeature; import org.eclipse.etrice.ui.common.support.NoResizeFeature; @@ -99,6 +103,7 @@ import org.eclipse.graphiti.util.IColorConstant; import org.eclipse.jface.window.Window; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.PlatformUI; +import org.eclipse.xtext.validation.FeatureBasedDiagnostic; public class TrPointSupport { @@ -711,6 +716,71 @@ public class TrPointSupport { } } + private static class QuickFixFeature extends AbstractCustomFeature { + + private boolean doneChanges = false; + + public QuickFixFeature(IFeatureProvider fp) { + super(fp); + } + + @Override + public String getName() { + return "Quick Fix"; + } + + @Override + public String getDescription() { + return "Apply Quick fixes"; + } + + @Override + public boolean canExecute(ICustomContext context) { + return true; + } + + @Override + public void execute(ICustomContext context) { + + // Get the issue Resolutions Map + Object bo = getBusinessObjectForPictogramElement(context + .getPictogramElements()[0]); + ArrayList<Diagnostic> issues = ((BehaviorEditor) getDiagramBehavior() + .getDiagramContainer()).getDiagnosingModelObserver() + .getElementDiagonsticMap().get(bo); + + HashMap<FeatureBasedDiagnostic, List<IssueResolution>> issueResolutionsMap = new HashMap<FeatureBasedDiagnostic, List<IssueResolution>>(); + BehaviorQuickfixProvider behaviorQuickfixProvider = new BehaviorQuickfixProvider(); + for (Diagnostic issue : issues) { + issueResolutionsMap + .put((FeatureBasedDiagnostic) issue, + behaviorQuickfixProvider + .getResolutions((FeatureBasedDiagnostic) issue)); + } + + // Create & Open the Quick Fix Dialog + Shell shell = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getShell(); + QuickFixDialog dlg = new QuickFixDialog(shell, issueResolutionsMap); + + if (dlg.open() != Window.OK) + return; + + Object[] result = dlg.getResult(); + if (result == null) + return; + else{ + ((IssueResolution)result[0]).apply(getDiagram()); + doneChanges = true; + } + } + + @Override + public boolean hasDoneChanges() { + return doneChanges; + } + } + protected IFeatureProvider fp; protected FeatureProvider(IDiagramTypeProvider dtp, IFeatureProvider fp) { @@ -744,7 +814,24 @@ public class TrPointSupport { @Override public ICustomFeature[] getCustomFeatures(ICustomContext context) { - return new ICustomFeature[] { new PropertyFeature(fp) }; + PictogramElement pe = context.getPictogramElements()[0]; + Object bo = getBusinessObjectForPictogramElement(pe); + + ArrayList<ICustomFeature> result = new ArrayList<ICustomFeature>(); + + result.add(new PropertyFeature(fp)); + + // Provide quick fix feature only for those edit parts which have + // errors, warnings or infos. + ArrayList<Diagnostic> diagnostics = ((BehaviorEditor) getDiagramTypeProvider() + .getDiagramBehavior().getDiagramContainer()) + .getDiagnosingModelObserver().getElementDiagonsticMap() + .get(bo); + if (diagnostics != null) + result.add(new QuickFixFeature(fp)); + + ICustomFeature features[] = new ICustomFeature[result.size()]; + return result.toArray(features); } @Override diff --git a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/TransitionSupport.java b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/TransitionSupport.java index 1d00fbf5e..50bf5d6ee 100644 --- a/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/TransitionSupport.java +++ b/plugins/org.eclipse.etrice.ui.behavior/src/org/eclipse/etrice/ui/behavior/support/TransitionSupport.java @@ -13,6 +13,8 @@ package org.eclipse.etrice.ui.behavior.support; import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; import org.eclipse.emf.common.util.Diagnostic; import org.eclipse.emf.ecore.EObject; @@ -38,9 +40,12 @@ import org.eclipse.etrice.core.room.TriggeredTransition; import org.eclipse.etrice.core.room.util.RoomHelpers; import org.eclipse.etrice.core.validation.ValidationUtil; import org.eclipse.etrice.ui.behavior.ImageProvider; +import org.eclipse.etrice.ui.behavior.dialogs.QuickFixDialog; import org.eclipse.etrice.ui.behavior.dialogs.TransitionPropertyDialog; import org.eclipse.etrice.ui.behavior.editor.BehaviorEditor; import org.eclipse.etrice.ui.behavior.markers.DecoratorUtil; +import org.eclipse.etrice.ui.behavior.quickfix.BehaviorQuickfixProvider; +import org.eclipse.etrice.ui.common.quickfix.IssueResolution; import org.eclipse.etrice.ui.common.support.DeleteWithoutConfirmFeature; import org.eclipse.graphiti.datatypes.ILocation; import org.eclipse.graphiti.dt.IDiagramTypeProvider; @@ -99,6 +104,7 @@ import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.window.Window; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.PlatformUI; +import org.eclipse.xtext.validation.FeatureBasedDiagnostic; public class TransitionSupport { @@ -765,6 +771,71 @@ public class TransitionSupport { } } + private static class QuickFixFeature extends AbstractCustomFeature { + + private boolean doneChanges = false; + + public QuickFixFeature(IFeatureProvider fp) { + super(fp); + } + + @Override + public String getName() { + return "Quick Fix"; + } + + @Override + public String getDescription() { + return "Apply Quick fixes"; + } + + @Override + public boolean canExecute(ICustomContext context) { + return true; + } + + @Override + public void execute(ICustomContext context) { + + // Get the issue Resolutions Map + Object bo = getBusinessObjectForPictogramElement(context + .getPictogramElements()[0]); + ArrayList<Diagnostic> issues = ((BehaviorEditor) getDiagramBehavior() + .getDiagramContainer()).getDiagnosingModelObserver() + .getElementDiagonsticMap().get(bo); + + HashMap<FeatureBasedDiagnostic, List<IssueResolution>> issueResolutionsMap = new HashMap<FeatureBasedDiagnostic, List<IssueResolution>>(); + BehaviorQuickfixProvider behaviorQuickfixProvider = new BehaviorQuickfixProvider(); + for (Diagnostic issue : issues) { + issueResolutionsMap + .put((FeatureBasedDiagnostic) issue, + behaviorQuickfixProvider + .getResolutions((FeatureBasedDiagnostic) issue)); + } + + // Create & Open the Quick Fix Dialog + Shell shell = PlatformUI.getWorkbench() + .getActiveWorkbenchWindow().getShell(); + QuickFixDialog dlg = new QuickFixDialog(shell, issueResolutionsMap); + + if (dlg.open() != Window.OK) + return; + + Object[] result = dlg.getResult(); + if (result == null) + return; + else{ + ((IssueResolution)result[0]).apply(getDiagram()); + doneChanges = true; + } + } + + @Override + public boolean hasDoneChanges() { + return doneChanges; + } + } + private IFeatureProvider fp; public FeatureProvider(IDiagramTypeProvider dtp, IFeatureProvider fp) { @@ -832,6 +903,15 @@ public class TransitionSupport { result.add(new RefineTransitionFeature(fp)); } + // Provide quick fix feature only for those edit parts which have + // errors, warnings or infos. + ArrayList<Diagnostic> diagnostics = ((BehaviorEditor) getDiagramTypeProvider() + .getDiagramBehavior().getDiagramContainer()) + .getDiagnosingModelObserver().getElementDiagonsticMap() + .get(bo); + if (diagnostics != null) + result.add(new QuickFixFeature(fp)); + ICustomFeature features[] = new ICustomFeature[result.size()]; return result.toArray(features); } diff --git a/plugins/org.eclipse.etrice.ui.common/src/org/eclipse/etrice/ui/common/quickfix/AbstractQuickfixProvider.java b/plugins/org.eclipse.etrice.ui.common/src/org/eclipse/etrice/ui/common/quickfix/AbstractQuickfixProvider.java index 1a223c3b5..d8232d64c 100644 --- a/plugins/org.eclipse.etrice.ui.common/src/org/eclipse/etrice/ui/common/quickfix/AbstractQuickfixProvider.java +++ b/plugins/org.eclipse.etrice.ui.common/src/org/eclipse/etrice/ui/common/quickfix/AbstractQuickfixProvider.java @@ -16,7 +16,7 @@ import java.lang.reflect.Method; import java.util.List; import org.eclipse.xtext.ui.editor.quickfix.Fix; -import org.eclipse.xtext.validation.Issue; +import org.eclipse.xtext.validation.FeatureBasedDiagnostic; import com.google.common.base.Predicate; import com.google.common.collect.Iterables; @@ -40,14 +40,14 @@ public abstract class AbstractQuickfixProvider { Fix annotation = input.getAnnotation(Fix.class); boolean result = annotation != null && issueCode.equals(annotation.value()) && input.getParameterTypes().length == 2 && Void.TYPE == input.getReturnType() - && input.getParameterTypes()[0].isAssignableFrom(Issue.class) + && input.getParameterTypes()[0].isAssignableFrom(FeatureBasedDiagnostic.class) && input.getParameterTypes()[1].isAssignableFrom(IssueResolutionAcceptor.class); return result; } }; } - protected List<IssueResolution> getResolutions(Issue issue, List<Method> fixMethods) { + protected List<IssueResolution> getResolutions(FeatureBasedDiagnostic issue, List<Method> fixMethods) { IssueResolutionAcceptor issueResolutionAcceptor = new IssueResolutionAcceptor(); for (Method fixMethod : fixMethods) { try { @@ -64,8 +64,8 @@ public abstract class AbstractQuickfixProvider { return Iterables.filter(methods, getFixMethodPredicate(issueCode)); } - protected List<Method> getFixMethods(final Issue issue) { - return Lists.newArrayList(collectMethods(getClass(), issue.getCode())); + protected List<Method> getFixMethods(final FeatureBasedDiagnostic issue) { + return Lists.newArrayList(collectMethods(getClass(), issue.getIssueCode())); } public boolean hasResolutionFor(final String issueCode) { @@ -75,7 +75,7 @@ public abstract class AbstractQuickfixProvider { return methods.iterator().hasNext(); } - public List<IssueResolution> getResolutions(final Issue issue) { + public List<IssueResolution> getResolutions(final FeatureBasedDiagnostic issue) { List<Method> fixMethods = getFixMethods(issue); return getResolutions(issue, fixMethods); } diff --git a/plugins/org.eclipse.etrice.ui.common/src/org/eclipse/etrice/ui/common/quickfix/IssueResolutionAcceptor.java b/plugins/org.eclipse.etrice.ui.common/src/org/eclipse/etrice/ui/common/quickfix/IssueResolutionAcceptor.java index e32aab7c6..1255f7c3a 100644 --- a/plugins/org.eclipse.etrice.ui.common/src/org/eclipse/etrice/ui/common/quickfix/IssueResolutionAcceptor.java +++ b/plugins/org.eclipse.etrice.ui.common/src/org/eclipse/etrice/ui/common/quickfix/IssueResolutionAcceptor.java @@ -14,7 +14,7 @@ package org.eclipse.etrice.ui.common.quickfix; import java.util.List; -import org.eclipse.xtext.validation.Issue; +import org.eclipse.xtext.validation.FeatureBasedDiagnostic; import com.google.common.collect.Lists; @@ -26,7 +26,7 @@ public class IssueResolutionAcceptor { private List<IssueResolution> issueResolutions = Lists.newArrayList(); - public void accept(Issue issue, String label, String description, String image, IDiagramModification modification) { + public void accept(FeatureBasedDiagnostic issue, String label, String description, String image, IDiagramModification modification) { issueResolutions.add(new IssueResolution(label, description, image, modification)); } |