summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkwannheden2009-08-21 08:09:05 (EDT)
committer sefftinge2009-08-21 08:09:05 (EDT)
commita923e59705d156d0709e7f4d06599e6113df7e59 (patch)
tree91ecf569fa182431203dbddb20666fd764d55dea
parent3a690efefcd739c1fbff5b8562f17c4c4e2d2601 (diff)
downloadorg.eclipse.xtext-a923e59705d156d0709e7f4d06599e6113df7e59.zip
org.eclipse.xtext-a923e59705d156d0709e7f4d06599e6113df7e59.tar.gz
org.eclipse.xtext-a923e59705d156d0709e7f4d06599e6113df7e59.tar.bz2
Feature: declarative quickfix support - https://bugs.eclipse.org/bugs/show_bug.cgi?id=263793
-rw-r--r--examples/org.eclipse.xtext.example.domainmodel.ui/META-INF/MANIFEST.MF3
-rw-r--r--examples/org.eclipse.xtext.example.domainmodel.ui/plugin.xml18
-rw-r--r--examples/org.eclipse.xtext.example.domainmodel.ui/plugin.xml_gen7
-rw-r--r--examples/org.eclipse.xtext.example.domainmodel.ui/src/org/eclipse/xtext/example/quickfix/DomainmodelQuickfixProvider.java24
-rw-r--r--examples/org.eclipse.xtext.example.domainmodel/src/org/eclipse/xtext/example/GenerateDomainmodelLanguage.mwe1
-rw-r--r--examples/org.eclipse.xtext.example.domainmodel/src/org/eclipse/xtext/example/validation/DomainmodelJavaValidator.java18
-rw-r--r--plugins/org.eclipse.xtext.ui.core/META-INF/MANIFEST.MF1
-rw-r--r--plugins/org.eclipse.xtext.ui.core/plugin.xml3
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/DefaultDiagnosticConverter.java29
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/IXtextResourceChecker.java3
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextQuickAssistAssistant.java176
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewerConfiguration.java14
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/model/XtextDocumentUtil.java11
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/quickfix/AbstractDeclarativeQuickfixProvider.java198
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/quickfix/Fix.java29
-rwxr-xr-xtests/org.eclipse.xtext.generator.tests/src/org/eclipse/xtext/validation/AbstractDeclarativeValidatorTest.java36
-rw-r--r--tests/org.eclipse.xtext.generator.tests/src/org/eclipse/xtext/xtext/XtextInspectorTest.java4
-rw-r--r--tests/org.eclipse.xtext.generator.tests/src/org/eclipse/xtext/xtext/XtextValidationTest.java6
-rw-r--r--tests/org.eclipse.xtext.ui.core.tests/src/org/eclipse/xtext/ui/core/quickfix/AbstractDeclarativeQuickfixProviderTest.java77
-rw-r--r--tests/org.eclipse.xtext.ui.core.tests/src/org/eclipse/xtext/ui/core/quickfix/MockMarker.java134
20 files changed, 764 insertions, 28 deletions
diff --git a/examples/org.eclipse.xtext.example.domainmodel.ui/META-INF/MANIFEST.MF b/examples/org.eclipse.xtext.example.domainmodel.ui/META-INF/MANIFEST.MF
index faf3330..fb9eb40 100644
--- a/examples/org.eclipse.xtext.example.domainmodel.ui/META-INF/MANIFEST.MF
+++ b/examples/org.eclipse.xtext.example.domainmodel.ui/META-INF/MANIFEST.MF
@@ -14,7 +14,8 @@ Require-Bundle: org.eclipse.xtext.example.domainmodel,
org.eclipse.ui,
org.eclipse.emf.index;bundle-version="0.7.0",
org.eclipse.emf.index.ui;bundle-version="0.7.0",
- org.eclipse.xtext.xtext.ui;bundle-version="0.8.0"
+ org.eclipse.xtext.xtext.ui;bundle-version="0.8.0",
+ org.eclipse.ui.ide
Export-Package: org.eclipse.xtext.example,
org.eclipse.xtext.example.contentassist
Bundle-Activator: org.eclipse.xtext.example.ui.internal.DomainmodelActivator
diff --git a/examples/org.eclipse.xtext.example.domainmodel.ui/plugin.xml b/examples/org.eclipse.xtext.example.domainmodel.ui/plugin.xml
index e82ea83..4f91046 100644
--- a/examples/org.eclipse.xtext.example.domainmodel.ui/plugin.xml
+++ b/examples/org.eclipse.xtext.example.domainmodel.ui/plugin.xml
@@ -112,7 +112,7 @@
</command>
</extension>
<extension point="org.eclipse.ui.menus">
- <menuContribution
+ <menuContribution
locationURI="popup:#TextEditorContext?after=group.open">
<command
commandId="org.eclipse.xtext.example.Domainmodel.validate"
@@ -120,12 +120,20 @@
tooltip="Trigger expensive validation">
<visibleWhen
checkEnabled="false">
- <reference
- definitionId="org.eclipse.xtext.example.Domainmodel.Editor.opened">
- </reference>
+ <reference
+ definitionId="org.eclipse.xtext.example.Domainmodel.Editor.opened">
+ </reference>
</visibleWhen>
</command>
</menuContribution>
- </extension>
+ </extension>
+
+ <!-- quickfix marker resolution generator -->
+ <extension
+ point="org.eclipse.ui.ide.markerResolution">
+ <markerResolutionGenerator
+ class="org.eclipse.xtext.example.DomainmodelExecutableExtensionFactory:org.eclipse.xtext.example.quickfix.DomainmodelQuickfixProvider">
+ </markerResolutionGenerator>
+ </extension>
</plugin>
diff --git a/examples/org.eclipse.xtext.example.domainmodel.ui/plugin.xml_gen b/examples/org.eclipse.xtext.example.domainmodel.ui/plugin.xml_gen
index 3cb7488..1392bbe 100644
--- a/examples/org.eclipse.xtext.example.domainmodel.ui/plugin.xml_gen
+++ b/examples/org.eclipse.xtext.example.domainmodel.ui/plugin.xml_gen
@@ -112,5 +112,12 @@
</extension>
+ <!-- quickfix marker resolution generator -->
+ <extension
+ point="org.eclipse.ui.ide.markerResolution">
+ <markerResolutionGenerator
+ class="org.eclipse.xtext.example.DomainmodelExecutableExtensionFactory:org.eclipse.xtext.example.quickfix.DomainmodelQuickfixProvider">
+ </markerResolutionGenerator>
+ </extension>
</plugin>
diff --git a/examples/org.eclipse.xtext.example.domainmodel.ui/src/org/eclipse/xtext/example/quickfix/DomainmodelQuickfixProvider.java b/examples/org.eclipse.xtext.example.domainmodel.ui/src/org/eclipse/xtext/example/quickfix/DomainmodelQuickfixProvider.java
new file mode 100644
index 0000000..03e62db
--- /dev/null
+++ b/examples/org.eclipse.xtext.example.domainmodel.ui/src/org/eclipse/xtext/example/quickfix/DomainmodelQuickfixProvider.java
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2009 itemis AG (http://www.itemis.eu) 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
+ *
+ *******************************************************************************/
+package org.eclipse.xtext.example.quickfix;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.xtext.example.domainmodel.Type;
+import org.eclipse.xtext.example.validation.DomainmodelJavaValidator;
+import org.eclipse.xtext.ui.core.quickfix.AbstractDeclarativeQuickfixProvider;
+import org.eclipse.xtext.ui.core.quickfix.Fix;
+
+public class DomainmodelQuickfixProvider extends AbstractDeclarativeQuickfixProvider {
+
+ @Fix(code = DomainmodelJavaValidator.CAPITAL_TYPE_NAME, label = "Capitalize name", description = "Capitalize name of type")
+ public void fixName(Type type, IMarker marker) {
+ type.setName(type.getName().toUpperCase());
+ }
+
+}
diff --git a/examples/org.eclipse.xtext.example.domainmodel/src/org/eclipse/xtext/example/GenerateDomainmodelLanguage.mwe b/examples/org.eclipse.xtext.example.domainmodel/src/org/eclipse/xtext/example/GenerateDomainmodelLanguage.mwe
index a21b197..13971dc 100644
--- a/examples/org.eclipse.xtext.example.domainmodel/src/org/eclipse/xtext/example/GenerateDomainmodelLanguage.mwe
+++ b/examples/org.eclipse.xtext.example.domainmodel/src/org/eclipse/xtext/example/GenerateDomainmodelLanguage.mwe
@@ -28,6 +28,7 @@
</fragment>
<fragment class="org.eclipse.xtext.generator.scoping.JavaScopingFragment"/>
<fragment class="org.eclipse.xtext.generator.validation.JavaValidatorFragment"/>
+ <fragment class="org.eclipse.xtext.generator.quickfix.QuickfixProviderFragment"/>
<fragment class="org.eclipse.xtext.generator.formatting.FormatterFragment"/>
<fragment class="org.eclipse.xtext.ui.generator.contentAssist.JavaBasedContentAssistFragment"/>
diff --git a/examples/org.eclipse.xtext.example.domainmodel/src/org/eclipse/xtext/example/validation/DomainmodelJavaValidator.java b/examples/org.eclipse.xtext.example.domainmodel/src/org/eclipse/xtext/example/validation/DomainmodelJavaValidator.java
index f691ea7..1f92afc 100644
--- a/examples/org.eclipse.xtext.example.domainmodel/src/org/eclipse/xtext/example/validation/DomainmodelJavaValidator.java
+++ b/examples/org.eclipse.xtext.example.domainmodel/src/org/eclipse/xtext/example/validation/DomainmodelJavaValidator.java
@@ -1,14 +1,18 @@
package org.eclipse.xtext.example.validation;
-
+import org.eclipse.xtext.example.domainmodel.DomainmodelPackage;
+import org.eclipse.xtext.example.domainmodel.Type;
+import org.eclipse.xtext.validation.Check;
public class DomainmodelJavaValidator extends AbstractDomainmodelJavaValidator {
-// @Check
-// public void checkTypeNameStartsWithCapital(Type type) {
-// if (!Character.isUpperCase(type.getName().charAt(0))) {
-// warning("Name should start with a capital", MyDslPackage.TYPE__NAME);
-// }
-// }
+ public static final int CAPITAL_TYPE_NAME = 1;
+
+ @Check
+ public void checkTypeNameStartsWithCapital(Type type) {
+ if (!Character.isUpperCase(type.getName().charAt(0))) {
+ warning("Name should start with a capital", DomainmodelPackage.TYPE__NAME, CAPITAL_TYPE_NAME);
+ }
+ }
}
diff --git a/plugins/org.eclipse.xtext.ui.core/META-INF/MANIFEST.MF b/plugins/org.eclipse.xtext.ui.core/META-INF/MANIFEST.MF
index 70ad1e3..0399904 100644
--- a/plugins/org.eclipse.xtext.ui.core/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.xtext.ui.core/META-INF/MANIFEST.MF
@@ -34,6 +34,7 @@ Export-Package: org.eclipse.xtext.ui.core,
org.eclipse.xtext.ui.core.editor.toggleComments,
org.eclipse.xtext.ui.core.editor.utils,
org.eclipse.xtext.ui.core.internal,
+ org.eclipse.xtext.ui.core.quickfix,
org.eclipse.xtext.ui.core.util,
org.eclipse.xtext.ui.core.wizard
Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/plugins/org.eclipse.xtext.ui.core/plugin.xml b/plugins/org.eclipse.xtext.ui.core/plugin.xml
index 52f4f60..cad2157 100644
--- a/plugins/org.eclipse.xtext.ui.core/plugin.xml
+++ b/plugins/org.eclipse.xtext.ui.core/plugin.xml
@@ -147,6 +147,9 @@
point="org.eclipse.core.resources.markers">
<super type="org.eclipse.emf.ecore.diagnostic"/>
<persistent value="true"/>
+ <attribute
+ name="code">
+ </attribute>
</extension>
<extension
id="org.eclipse.xtext.ui.core.check.fast"
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/DefaultDiagnosticConverter.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/DefaultDiagnosticConverter.java
index e67d66a..06368b0 100644
--- a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/DefaultDiagnosticConverter.java
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/DefaultDiagnosticConverter.java
@@ -8,14 +8,15 @@
package org.eclipse.xtext.ui.core.editor;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.eclipse.core.resources.IMarker;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.EValidator;
import org.eclipse.emf.ecore.resource.Resource.Diagnostic;
+import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.parsetree.AbstractNode;
import org.eclipse.xtext.parsetree.NodeAdapter;
import org.eclipse.xtext.parsetree.NodeUtil;
@@ -64,12 +65,24 @@ public class DefaultDiagnosticConverter implements IDiagnosticConverter {
marker.put(IMarker.CHAR_START, locationData.getSecond());
marker.put(IMarker.CHAR_END, locationData.getThird());
}
+ final EObject causer = getCauser(diagnostic);
+ if (causer != null)
+ marker.put(EValidator.URI_ATTRIBUTE, EcoreUtil.getURI(causer).toString());
+ final Integer code = diagnostic.getCode();
+ if (code != null)
+ marker.put(IXtextResourceChecker.CODE_KEY, code);
marker.put(IXtextResourceChecker.DIAGNOSTIC_KEY, diagnostic);
marker.put(IMarker.MESSAGE, diagnostic.getMessage());
marker.put(IMarker.PRIORITY, Integer.valueOf(IMarker.PRIORITY_LOW));
acceptor.accept(marker);
}
+ protected EObject getCauser(org.eclipse.emf.common.util.Diagnostic diagnostic) {
+ // causer is the first element see Diagnostician.getData
+ Object causer = diagnostic.getData().get(0);
+ return causer instanceof EObject ? (EObject) causer : null;
+ }
+
/**
* @return the location data for the given diagnostic.
* <ol>
@@ -79,15 +92,13 @@ public class DefaultDiagnosticConverter implements IDiagnosticConverter {
* </ol>
*/
protected Triple<Integer, Integer, Integer> getLocationData(org.eclipse.emf.common.util.Diagnostic diagnostic) {
- Iterator<?> data = diagnostic.getData().iterator();
- // causer is the first element see Diagnostician.getData
- Object causer = data.next();
- if (causer instanceof EObject) {
- EObject ele = (EObject) causer;
+ EObject causer = getCauser(diagnostic);
+ if (causer != null) {
// feature is the second element see Diagnostician.getData
- Object feature = data.hasNext() ? data.next() : null;
- EStructuralFeature structuralFeature = resolveStructuralFeature(ele, feature);
- return getLocationData(ele, structuralFeature);
+ List<?> data = diagnostic.getData();
+ Object feature = data.size() > 1 ? data.get(1) : null;
+ EStructuralFeature structuralFeature = resolveStructuralFeature(causer, feature);
+ return getLocationData(causer, structuralFeature);
}
return null;
}
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/IXtextResourceChecker.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/IXtextResourceChecker.java
index 53d8481..f55ff9d 100644
--- a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/IXtextResourceChecker.java
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/IXtextResourceChecker.java
@@ -7,7 +7,8 @@ import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.ecore.resource.Resource;
public interface IXtextResourceChecker {
-
+
+ static final String CODE_KEY = "code";
static final String DIAGNOSTIC_KEY = "EmfDiagnostic";
List<Map<String, Object>> check(final Resource resource, Map<?, ?> context, IProgressMonitor monitor);
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextQuickAssistAssistant.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextQuickAssistAssistant.java
new file mode 100644
index 0000000..a9a93d0
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextQuickAssistAssistant.java
@@ -0,0 +1,176 @@
+package org.eclipse.xtext.ui.core.editor;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.jface.text.AbstractReusableInformationControlCreator;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.DefaultInformationControl;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IInformationControl;
+import org.eclipse.jface.text.IInformationControlCreator;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.DefaultInformationControl.IInformationPresenter;
+import org.eclipse.jface.text.contentassist.ICompletionProposal;
+import org.eclipse.jface.text.contentassist.ICompletionProposalExtension3;
+import org.eclipse.jface.text.contentassist.IContextInformation;
+import org.eclipse.jface.text.quickassist.IQuickAssistInvocationContext;
+import org.eclipse.jface.text.quickassist.IQuickAssistProcessor;
+import org.eclipse.jface.text.quickassist.QuickAssistAssistant;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IMarkerResolution;
+import org.eclipse.ui.IMarkerResolution2;
+import org.eclipse.ui.ide.IDE;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
+
+/**
+ * @author Knut Wannheden - Initial contribution and API
+ */
+public class XtextQuickAssistAssistant extends QuickAssistAssistant {
+
+ private static class XtextCompletionProposal implements ICompletionProposal, ICompletionProposalExtension3 {
+
+ private Position pos;
+ private IMarker marker;
+ private IMarkerResolution resolution;
+
+ public XtextCompletionProposal(Position pos, IMarker marker, IMarkerResolution resolution) {
+ this.pos = pos;
+ this.marker = marker;
+ this.resolution = resolution;
+ }
+
+ public void apply(IDocument document) {
+ resolution.run(marker);
+ }
+
+ public Point getSelection(IDocument document) {
+ return new Point(pos.offset, 0);
+ }
+
+ public String getAdditionalProposalInfo() {
+ if (resolution instanceof IMarkerResolution2)
+ return ((IMarkerResolution2) resolution).getDescription();
+ return null;
+ }
+
+ public String getDisplayString() {
+ return resolution.getLabel();
+ }
+
+ public Image getImage() {
+ if (resolution instanceof IMarkerResolution2) {
+ return ((IMarkerResolution2) resolution).getImage();
+ }
+ return null;
+ }
+
+ public IContextInformation getContextInformation() {
+ return null;
+ }
+
+ public IInformationControlCreator getInformationControlCreator() {
+ return null;
+ }
+
+ public int getPrefixCompletionStart(IDocument document, int completionOffset) {
+ return 0;
+ }
+
+ public CharSequence getPrefixCompletionText(IDocument document, int completionOffset) {
+ return null;
+ }
+
+ }
+
+ private static class XtextQuickAssistProcessor implements IQuickAssistProcessor {
+
+ private String errorMessage;
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
+ public boolean canFix(Annotation annotation) {
+ if (annotation.isMarkedDeleted() || !(annotation instanceof MarkerAnnotation))
+ return false;
+
+ final MarkerAnnotation markerAnnotation = (MarkerAnnotation) annotation;
+ if (markerAnnotation.isQuickFixableStateSet())
+ return markerAnnotation.isQuickFixable();
+
+ final IMarker marker = markerAnnotation.getMarker();
+ boolean canFix = IDE.getMarkerHelpRegistry().hasResolutions(marker);
+
+ if (canFix) {
+ final IMarkerResolution[] contributedResolutions = IDE.getMarkerHelpRegistry().getResolutions(marker);
+ canFix = contributedResolutions.length > 0;
+ }
+
+ if (!markerAnnotation.isQuickFixableStateSet())
+ markerAnnotation.setQuickFixable(canFix);
+
+ return canFix;
+ }
+
+ public boolean canAssist(IQuickAssistInvocationContext invocationContext) {
+ return false;
+ }
+
+ public ICompletionProposal[] computeQuickAssistProposals(IQuickAssistInvocationContext invocationContext) {
+ final IAnnotationModel amodel = invocationContext.getSourceViewer().getAnnotationModel();
+ final IDocument doc = invocationContext.getSourceViewer().getDocument();
+
+ final int offset = invocationContext.getOffset();
+ final List<ICompletionProposal> list = new ArrayList<ICompletionProposal>();
+
+ for (Iterator<?> it = amodel.getAnnotationIterator(); it.hasNext();) {
+ Object key = it.next();
+ if (!(key instanceof MarkerAnnotation) || !((MarkerAnnotation) key).isQuickFixable())
+ continue;
+
+ MarkerAnnotation annotation = (MarkerAnnotation) key;
+ IMarker marker = annotation.getMarker();
+
+ IMarkerResolution[] resolutions = IDE.getMarkerHelpRegistry().getResolutions(marker);
+ if (resolutions != null) {
+ Position pos = amodel.getPosition(annotation);
+ try {
+ int line = doc.getLineOfOffset(pos.getOffset());
+ int start = pos.getOffset();
+ String delim = doc.getLineDelimiter(line);
+ int delimLength = delim != null ? delim.length() : 0;
+ int end = doc.getLineLength(line) + start - delimLength;
+ if (offset >= start && offset <= end) {
+ for (int i = 0; i < resolutions.length; i++) {
+ list.add(new XtextCompletionProposal(pos, marker, resolutions[i]));
+ }
+ }
+ }
+ catch (BadLocationException e) {
+ errorMessage = e.getMessage();
+ }
+
+ }
+ }
+ return list.toArray(new ICompletionProposal[list.size()]);
+ }
+ }
+
+ public XtextQuickAssistAssistant() {
+ setQuickAssistProcessor(new XtextQuickAssistProcessor());
+ setInformationControlCreator(new AbstractReusableInformationControlCreator() {
+ @Override
+ public IInformationControl doCreateInformationControl(Shell parent) {
+ return new DefaultInformationControl(parent, (IInformationPresenter) null);
+ }
+ });
+ }
+
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewerConfiguration.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewerConfiguration.java
index 548a99c..125a316 100644
--- a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewerConfiguration.java
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewerConfiguration.java
@@ -18,6 +18,7 @@ import org.eclipse.jface.text.formatter.IContentFormatter;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
+import org.eclipse.jface.text.quickassist.IQuickAssistAssistant;
import org.eclipse.jface.text.reconciler.IReconciler;
import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.ISourceViewer;
@@ -64,6 +65,9 @@ public class XtextSourceViewerConfiguration extends TextSourceViewerConfiguratio
return new ProblemHover(sourceViewer);
}
+ @Inject(optional = true)
+ private IQuickAssistAssistant quickAssistant;
+
@Override
public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
return contentAssistantFactory.createConfiguredAssistant(this, sourceViewer);
@@ -114,6 +118,16 @@ public class XtextSourceViewerConfiguration extends TextSourceViewerConfiguratio
return detectors.toArray(new IHyperlinkDetector[detectors.size()]);
}
+ @Override
+ public IQuickAssistAssistant getQuickAssistAssistant(ISourceViewer sourceViewer) {
+ if (sourceViewer.isEditable()) {
+ if (quickAssistant == null)
+ quickAssistant = new XtextQuickAssistAssistant();
+ return quickAssistant;
+ }
+ return null;
+ }
+
@Override
public IContentFormatter getContentFormatter(ISourceViewer sourceViewer) {
if (contentFormatterFactory != null)
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/model/XtextDocumentUtil.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/model/XtextDocumentUtil.java
index 68e9a9a..33b2d43 100644
--- a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/model/XtextDocumentUtil.java
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/model/XtextDocumentUtil.java
@@ -1,7 +1,12 @@
package org.eclipse.xtext.ui.core.editor.model;
+import org.eclipse.core.resources.IFile;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.projection.ProjectionDocument;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.xtext.ui.core.editor.XtextEditor;
public class XtextDocumentUtil {
@@ -12,6 +17,12 @@ public class XtextDocumentUtil {
return get(((ProjectionDocument) ctx).getMasterDocument());
if (ctx instanceof ITextViewer)
return get(((ITextViewer) ctx).getDocument());
+ if (ctx instanceof XtextEditor)
+ return ((XtextEditor) ctx).getDocument();
+ if (ctx instanceof IFile) {
+ IWorkbenchPage activePage = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ return get(activePage.findEditor(new FileEditorInput((IFile) ctx)));
+ }
return null;
}
}
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/quickfix/AbstractDeclarativeQuickfixProvider.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/quickfix/AbstractDeclarativeQuickfixProvider.java
new file mode 100644
index 0000000..aab2b5a
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/quickfix/AbstractDeclarativeQuickfixProvider.java
@@ -0,0 +1,198 @@
+/*******************************************************************************
+ * Copyright (c) 2009 itemis AG (http://www.itemis.eu) 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
+ *******************************************************************************/
+package org.eclipse.xtext.ui.core.quickfix;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EValidator;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.IMarkerResolution;
+import org.eclipse.ui.IMarkerResolution2;
+import org.eclipse.ui.IMarkerResolutionGenerator2;
+import org.eclipse.xtext.concurrent.IUnitOfWork;
+import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.ui.core.IImageHelper;
+import org.eclipse.xtext.ui.core.editor.IXtextResourceChecker;
+import org.eclipse.xtext.ui.core.editor.MarkerUtil;
+import org.eclipse.xtext.ui.core.editor.model.IXtextDocument;
+import org.eclipse.xtext.ui.core.editor.model.XtextDocumentUtil;
+import org.eclipse.xtext.ui.core.editor.model.edit.IDocumentEditor;
+import org.eclipse.xtext.util.SimpleCache;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import com.google.inject.Inject;
+
+/**
+ * @author Knut Wannheden - Initial contribution and API
+ */
+public class AbstractDeclarativeQuickfixProvider implements IMarkerResolutionGenerator2 {
+
+ @Inject
+ private IDocumentEditor documentEditor;
+
+ public IDocumentEditor getDocumentEditor() {
+ return documentEditor;
+ }
+
+ @Inject
+ private IImageHelper imageHelper;
+
+ public IImageHelper getImageHelper() {
+ return imageHelper;
+ }
+
+ protected IXtextDocument getDocument(IMarker marker) {
+ return XtextDocumentUtil.get(marker.getResource());
+ }
+
+ protected URI getURI(final IMarker marker) {
+ String uri = marker.getAttribute(EValidator.URI_ATTRIBUTE, null);
+ return uri == null ? null : URI.createURI(uri);
+ }
+
+ protected Integer getCode(final IMarker marker) {
+ Integer code = marker.getAttribute(IXtextResourceChecker.CODE_KEY, -1);
+ return code;
+ }
+
+ protected EObject getContext(final IMarker marker) {
+ final IXtextDocument document = getDocument(marker);
+ if (document == null)
+ return null;
+
+ final EObject context = document.readOnly(new IUnitOfWork<EObject, XtextResource>() {
+ public EObject exec(XtextResource state) throws Exception {
+ URI uri = getURI(marker);
+ return uri != null ? state.getEObject(uri.fragment()) : null;
+ }
+ });
+ return context;
+ }
+
+ protected Predicate<Method> getFixMethodPredicate(final IMarker marker) {
+ return new Predicate<Method>() {
+ public boolean apply(Method input) {
+ Fix annotation = input.getAnnotation(Fix.class);
+ return input.getParameterTypes().length == 2 && Void.TYPE == input.getReturnType()
+ && annotation != null && annotation.code() == getCode(marker);
+ }
+ };
+ }
+
+ private volatile Set<Method> fixMethods = null;
+
+ private final SimpleCache<Class<?>, List<Method>> methodsForType = new SimpleCache<Class<?>, List<Method>>(
+ new Function<Class<?>, List<Method>>() {
+ public List<Method> apply(Class<?> param) {
+ List<Method> result = Lists.newArrayList();
+ for (Method m : fixMethods) {
+ if (methodMatched(m, param))
+ result.add(m);
+ }
+ return result;
+ }
+
+ private boolean methodMatched(Method method, Class<?> param) {
+ return method.getParameterTypes()[0].isAssignableFrom(param);
+ }
+ });
+
+ protected IMarkerResolution[] getMarkerResolutions(final IMarker marker, List<Method> fixMethods) {
+ return Lists.transform(fixMethods, new Function<Method, IMarkerResolution>() {
+ public IMarkerResolution apply(final Method from) {
+ return new IMarkerResolution2() {
+ private final Fix annotation = from.getAnnotation(Fix.class);
+
+ public void run(IMarker marker) {
+ executeFixMethod(from, marker);
+ }
+
+ public String getLabel() {
+ return annotation.label();
+ }
+
+ public Image getImage() {
+ String image = annotation.image();
+ return image != null ? getImageHelper().getImage(image) : null;
+ }
+
+ public String getDescription() {
+ return annotation.description();
+ }
+ };
+ }
+ }).toArray(new IMarkerResolution[fixMethods.size()]);
+ }
+
+ protected void executeFixMethod(final Method method, final IMarker marker) {
+ IXtextDocument document = getDocument(marker);
+ documentEditor.process(new IUnitOfWork<Void, XtextResource>() {
+ public java.lang.Void exec(XtextResource state) throws Exception {
+ URI uri = getURI(marker);
+ EObject context = state.getEObject(uri.fragment());
+ method.invoke(AbstractDeclarativeQuickfixProvider.this, new Object[] { context, marker });
+ return null;
+ }
+ }, document);
+ }
+
+ private Iterable<Method> collectMethods(Class<? extends AbstractDeclarativeQuickfixProvider> clazz, IMarker marker) {
+ List<Method> methods = Lists.newArrayList(clazz.getMethods());
+ return Iterables.filter(methods, getFixMethodPredicate(marker));
+ }
+
+ protected List<Method> getFixMethods(final IMarker marker) {
+ final EObject context = getContext(marker);
+ if (context == null)
+ return Collections.emptyList();
+
+ if (fixMethods == null) {
+ synchronized (this) {
+ if (fixMethods == null) {
+ Set<Method> methods = Sets.newLinkedHashSet(collectMethods(getClass(), marker));
+ this.fixMethods = methods;
+ }
+ }
+ }
+
+ final List<Method> fixMethods = methodsForType.get(context.getClass());
+ return fixMethods;
+ }
+
+ public boolean hasResolutions(final IMarker marker) {
+ try {
+ if (!marker.isSubtypeOf(MarkerUtil.CHECK_MARKER_ID))
+ return false;
+ }
+ catch (CoreException e) {
+ return false;
+ }
+ if (getURI(marker) == null || getCode(marker) == null)
+ return false;
+
+ List<Method> fixMethods = getFixMethods(marker);
+ return !fixMethods.isEmpty();
+ }
+
+ public IMarkerResolution[] getResolutions(IMarker marker) {
+ List<Method> fixMethods = getFixMethods(marker);
+ return getMarkerResolutions(marker, fixMethods);
+ }
+
+}
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/quickfix/Fix.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/quickfix/Fix.java
new file mode 100644
index 0000000..c522623
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/quickfix/Fix.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2009 itemis AG (http://www.itemis.eu) 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
+ *******************************************************************************/
+package org.eclipse.xtext.ui.core.quickfix;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @author Knut Wannheden - Initial contribution and API
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD})
+public @interface Fix {
+
+ int code();
+
+ String label() default "";
+
+ String description() default "";
+
+ String image() default "";
+}
diff --git a/tests/org.eclipse.xtext.generator.tests/src/org/eclipse/xtext/validation/AbstractDeclarativeValidatorTest.java b/tests/org.eclipse.xtext.generator.tests/src/org/eclipse/xtext/validation/AbstractDeclarativeValidatorTest.java
index 18ca9d7..5101098 100755
--- a/tests/org.eclipse.xtext.generator.tests/src/org/eclipse/xtext/validation/AbstractDeclarativeValidatorTest.java
+++ b/tests/org.eclipse.xtext.generator.tests/src/org/eclipse/xtext/validation/AbstractDeclarativeValidatorTest.java
@@ -218,6 +218,24 @@ public class AbstractDeclarativeValidatorTest extends TestCase {
assertEquals(Diagnostic.ERROR, diag.getSeverity());
}
+ public void testErrorWithCode() {
+ AbstractDeclarativeValidator test = new AbstractDeclarativeValidator() {
+ @Check
+ @SuppressWarnings("unused")
+ public void foo(Object x) {
+ error("Error Message", 1, 42);
+ }
+ };
+ BasicDiagnostic chain = new BasicDiagnostic();
+ test.validate(EcorePackage.eINSTANCE.getEClass(), chain, Collections.emptyMap());
+ assertEquals(1, chain.getChildren().size());
+
+ Diagnostic diag = chain.getChildren().get(0);
+ assertEquals("Error Message", diag.getMessage());
+ assertEquals(42, diag.getCode());
+ assertEquals(Diagnostic.ERROR, diag.getSeverity());
+ }
+
public void testWarning() {
AbstractDeclarativeValidator test = new AbstractDeclarativeValidator() {
@Check
@@ -254,6 +272,24 @@ public class AbstractDeclarativeValidatorTest extends TestCase {
assertEquals(Diagnostic.WARNING, diag.getSeverity());
}
+ public void testWarningWithCode() {
+ AbstractDeclarativeValidator test = new AbstractDeclarativeValidator() {
+ @Check
+ @SuppressWarnings("unused")
+ public void foo(Object x) {
+ warning("Error Message", 1, 42);
+ }
+ };
+ BasicDiagnostic chain = new BasicDiagnostic();
+ test.validate(EcorePackage.eINSTANCE.getEClass(), chain, Collections.emptyMap());
+ assertEquals(1, chain.getChildren().size());
+
+ Diagnostic diag = chain.getChildren().get(0);
+ assertEquals("Error Message", diag.getMessage());
+ assertEquals(42, diag.getCode());
+ assertEquals(Diagnostic.WARNING, diag.getSeverity());
+ }
+
public void testAssertTrue1() {
AbstractDeclarativeValidator test = new AbstractDeclarativeValidator() {
@Check
diff --git a/tests/org.eclipse.xtext.generator.tests/src/org/eclipse/xtext/xtext/XtextInspectorTest.java b/tests/org.eclipse.xtext.generator.tests/src/org/eclipse/xtext/xtext/XtextInspectorTest.java
index 7d7fd58..0dca433 100644
--- a/tests/org.eclipse.xtext.generator.tests/src/org/eclipse/xtext/xtext/XtextInspectorTest.java
+++ b/tests/org.eclipse.xtext.generator.tests/src/org/eclipse/xtext/xtext/XtextInspectorTest.java
@@ -47,14 +47,14 @@ public abstract class XtextInspectorTest extends AbstractXtextTests implements V
protected abstract boolean isExpectingWarnings();
- public void acceptError(String message, EObject object, Integer feature) {
+ public void acceptError(String message, EObject object, Integer feature, Integer code) {
if (!isExpectingErrors())
fail("unexpected call to acceptError");
Triple<String,EObject,Integer> error = Tuples.create(message, object, feature);
errors.add(error);
}
- public void acceptWarning(String message, EObject object, Integer feature) {
+ public void acceptWarning(String message, EObject object, Integer feature, Integer code) {
if (!isExpectingWarnings())
fail("unexpected call to acceptWarning");
Triple<String,EObject,Integer> warning = Tuples.create(message, object, feature);
diff --git a/tests/org.eclipse.xtext.generator.tests/src/org/eclipse/xtext/xtext/XtextValidationTest.java b/tests/org.eclipse.xtext.generator.tests/src/org/eclipse/xtext/xtext/XtextValidationTest.java
index 3ac1db5..822ce8d 100644
--- a/tests/org.eclipse.xtext.generator.tests/src/org/eclipse/xtext/xtext/XtextValidationTest.java
+++ b/tests/org.eclipse.xtext.generator.tests/src/org/eclipse/xtext/xtext/XtextValidationTest.java
@@ -596,7 +596,7 @@ public class XtextValidationTest extends AbstractGeneratorTest implements Valida
assertEquals(diag.getSeverity(), Diagnostic.OK);
assertTrue(diag.getChildren().toString(), diag.getChildren().isEmpty());
}
-
+
public void testBug_286683() throws Exception {
XtextResource resource = getResourceFromString("grammar org.xtext.example.MyDsl with org.xtext.example.MyDsl\n"+
"generate myDsl 'http://www.xtext.org/example/MyDsl'\n"+
@@ -610,12 +610,12 @@ public class XtextValidationTest extends AbstractGeneratorTest implements Valida
assertEquals(diag.getChildren().toString(), 1, diag.getChildren().size());
}
- public void acceptError(String message, EObject object, Integer feature) {
+ public void acceptError(String message, EObject object, Integer feature, Integer code) {
assertNull(lastMessage);
lastMessage = message;
}
- public void acceptWarning(String message, EObject object, Integer feature) {
+ public void acceptWarning(String message, EObject object, Integer feature, Integer code) {
fail("Unexpected call to acceptWarning(..)");
}
}
diff --git a/tests/org.eclipse.xtext.ui.core.tests/src/org/eclipse/xtext/ui/core/quickfix/AbstractDeclarativeQuickfixProviderTest.java b/tests/org.eclipse.xtext.ui.core.tests/src/org/eclipse/xtext/ui/core/quickfix/AbstractDeclarativeQuickfixProviderTest.java
new file mode 100644
index 0000000..b9710a1
--- /dev/null
+++ b/tests/org.eclipse.xtext.ui.core.tests/src/org/eclipse/xtext/ui/core/quickfix/AbstractDeclarativeQuickfixProviderTest.java
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2009 itemis AG (http://www.itemis.eu) 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
+ *******************************************************************************/
+package org.eclipse.xtext.ui.core.quickfix;
+
+import junit.framework.TestCase;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.ui.IMarkerResolution;
+
+/**
+ * @author Knut Wannheden - Initial contribution and API
+ */
+public class AbstractDeclarativeQuickfixProviderTest extends TestCase {
+
+ private static final int DUMMY_CODE = 42;
+
+ public void testHasResolutions() throws Exception {
+ AbstractDeclarativeQuickfixProvider generator = new AbstractDeclarativeQuickfixProvider() {
+ @Override
+ protected EObject getContext(IMarker marker) {
+ return ((MockMarker) marker).getContext();
+ }
+
+ @Fix(code = DUMMY_CODE)
+ @SuppressWarnings("unused")
+ public void fixError(EObject obj, IMarker marker) {
+ }
+ };
+ IMarker marker = MockMarker.newFastErrorMarker(null, null, null);
+ assertFalse(generator.hasResolutions(marker));
+ marker = MockMarker.newFastErrorMarker(null, EcorePackage.eINSTANCE.getEClass(), DUMMY_CODE);
+ assertTrue(generator.hasResolutions(marker));
+ assertEquals(1, generator.getResolutions(marker).length);
+ }
+
+ public void testGetResolutions() throws Exception {
+ AbstractDeclarativeQuickfixProvider generator = new AbstractDeclarativeQuickfixProvider() {
+ @Override
+ protected EObject getContext(IMarker marker) {
+ return ((MockMarker) marker).getContext();
+ }
+
+ @Fix(code = DUMMY_CODE, label = "fixError1")
+ @SuppressWarnings("unused")
+ public void fixError1(EObject obj, IMarker marker) {
+ }
+
+ @Fix(code = DUMMY_CODE, label = "fixError2")
+ @SuppressWarnings("unused")
+ public void fixError2(EPackage obj, IMarker marker) {
+ }
+
+ @Fix(code = DUMMY_CODE, label = "fixError3")
+ @SuppressWarnings("unused")
+ public void fixError3(EClass obj, IMarker marker) {
+ }
+ };
+ IMarker marker = MockMarker.newFastErrorMarker(null, null, null);
+ IMarkerResolution[] resolutions = generator.getResolutions(marker);
+ assertEquals(0, resolutions.length);
+ marker = MockMarker.newFastErrorMarker(null, EcorePackage.eINSTANCE.getEClass(), DUMMY_CODE);
+ resolutions = generator.getResolutions(marker);
+ assertEquals(2, resolutions.length);
+ assertEquals("fixError1", resolutions[0].getLabel());
+ assertEquals("fixError3", resolutions[1].getLabel());
+ }
+
+}
diff --git a/tests/org.eclipse.xtext.ui.core.tests/src/org/eclipse/xtext/ui/core/quickfix/MockMarker.java b/tests/org.eclipse.xtext.ui.core.tests/src/org/eclipse/xtext/ui/core/quickfix/MockMarker.java
new file mode 100644
index 0000000..84f8f2c
--- /dev/null
+++ b/tests/org.eclipse.xtext.ui.core.tests/src/org/eclipse/xtext/ui/core/quickfix/MockMarker.java
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2009 itemis AG (http://www.itemis.eu) 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
+ *******************************************************************************/
+package org.eclipse.xtext.ui.core.quickfix;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EValidator;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.xtext.ui.core.editor.IXtextResourceChecker;
+import org.eclipse.xtext.ui.core.editor.MarkerUtil;
+
+/**
+ * @author knut - Initial contribution and API
+ */
+final class MockMarker implements IMarker {
+
+ private String type;
+ private IResource resource;
+ private EObject context;
+ private Map<String, ?> attributes;
+
+ public static MockMarker newFastErrorMarker(IResource resource, EObject context, Integer code) {
+ Map<String, Object> attributes = new HashMap<String, Object>();
+ attributes.put(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
+ if (context != null)
+ attributes.put(EValidator.URI_ATTRIBUTE, EcoreUtil.getURI(context).toString());
+ attributes.put(IXtextResourceChecker.CODE_KEY, code);
+ return new MockMarker(MarkerUtil.FAST_CHECK_MARKER_ID, resource, context, attributes);
+ }
+
+ public MockMarker(String type, IResource resource, EObject context, Map<String, ?> attributes) {
+ this.type = type;
+ this.resource = resource;
+ this.context = context;
+ this.attributes = attributes;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Object getAdapter(Class adapter) {
+ return null;
+ }
+
+ public void setAttributes(String[] attributeNames, Object[] values) throws CoreException {
+ throw new UnsupportedOperationException();
+ }
+
+ @SuppressWarnings("unchecked")
+ public void setAttributes(Map attributes) throws CoreException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setAttribute(String attributeName, boolean value) throws CoreException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setAttribute(String attributeName, Object value) throws CoreException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setAttribute(String attributeName, int value) throws CoreException {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isSubtypeOf(String superType) throws CoreException {
+ return true;
+ }
+
+ public String getType() throws CoreException {
+ return type;
+ }
+
+ public IResource getResource() {
+ return resource;
+ }
+
+ public EObject getContext() {
+ return context;
+ }
+
+ public long getId() {
+ return 0;
+ }
+
+ public long getCreationTime() throws CoreException {
+ return 0;
+ }
+
+ public Object[] getAttributes(String[] attributeNames) throws CoreException {
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Map getAttributes() throws CoreException {
+ return attributes;
+ }
+
+ public boolean getAttribute(String attributeName, boolean defaultValue) {
+ Object result = attributes.get(attributeName);
+ return result == null ? defaultValue : (Boolean) result;
+ }
+
+ public String getAttribute(String attributeName, String defaultValue) {
+ Object result = attributes.get(attributeName);
+ return result == null ? defaultValue : (String) result;
+ }
+
+ public int getAttribute(String attributeName, int defaultValue) {
+ Object result = attributes.get(attributeName);
+ return result == null ? defaultValue : (Integer) result;
+ }
+
+ public Object getAttribute(String attributeName) throws CoreException {
+ return attributes.get(attributeName);
+ }
+
+ public boolean exists() {
+ return true;
+ }
+
+ public void delete() throws CoreException {
+ throw new UnsupportedOperationException();
+ }
+
+} \ No newline at end of file