Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuergen Haug2019-07-10 06:41:00 -0400
committerJuergen Haug2019-07-10 08:10:06 -0400
commit76b8609dc25774b804addfbe13be96065d0e15a6 (patch)
treebed63dd56f4b2e1f03ff9ed4a1ffc5b9d5818e30
parent9bd8a8bd2e2662045909ad774ee2d857a47e24a5 (diff)
downloadorg.eclipse.etrice-76b8609dc25774b804addfbe13be96065d0e15a6.tar.gz
org.eclipse.etrice-76b8609dc25774b804addfbe13be96065d0e15a6.tar.xz
org.eclipse.etrice-76b8609dc25774b804addfbe13be96065d0e15a6.zip
Bug 549132 - [room.ui] Add hyperlink to namespace imports
-rw-r--r--plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/linking/ImportAwareHyperlinkHelper.java151
-rw-r--r--plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/base/util/ImportHelpers.java66
-rw-r--r--plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/validation/BaseJavaValidator.java33
-rw-r--r--plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/highlight/RoomSemanticHighlightingCalculator.java5
-rw-r--r--plugins/org.eclipse.etrice.core.room/src/org/eclipse/etrice/core/validation/RoomJavaValidator.java9
5 files changed, 107 insertions, 157 deletions
diff --git a/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/linking/ImportAwareHyperlinkHelper.java b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/linking/ImportAwareHyperlinkHelper.java
index a96071feb..c349db409 100644
--- a/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/linking/ImportAwareHyperlinkHelper.java
+++ b/plugins/org.eclipse.etrice.core.common.ui/src/org/eclipse/etrice/core/common/ui/linking/ImportAwareHyperlinkHelper.java
@@ -16,153 +16,76 @@
package org.eclipse.etrice.core.common.ui.linking;
import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.EcoreFactory;
-import org.eclipse.emf.ecore.EcorePackage;
-import org.eclipse.etrice.core.common.base.Import;
-import org.eclipse.etrice.core.common.scoping.ModelLocatorUriResolver;
+import org.eclipse.etrice.core.common.base.util.ImportHelpers;
import org.eclipse.jface.text.Region;
import org.eclipse.xtext.AbstractRule;
import org.eclipse.xtext.RuleCall;
-import org.eclipse.xtext.naming.IQualifiedNameConverter;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.nodemodel.ILeafNode;
-import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.parser.IParseResult;
-import org.eclipse.xtext.resource.EObjectAtOffsetHelper;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.XtextResource;
-import org.eclipse.xtext.scoping.IGlobalScopeProvider;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.ui.editor.hyperlinking.HyperlinkHelper;
import org.eclipse.xtext.ui.editor.hyperlinking.IHyperlinkAcceptor;
import org.eclipse.xtext.ui.editor.hyperlinking.XtextHyperlink;
-import com.google.common.base.Predicates;
import com.google.inject.Inject;
import com.google.inject.Provider;
-/**
- * @author Henrik Rentz-Reichert (initial contribution)
- *
- */
public class ImportAwareHyperlinkHelper extends HyperlinkHelper {
- @Inject
- protected Provider<XtextHyperlink> hyperlinkProvider;
-
- @Inject
- protected ModelLocatorUriResolver uriResolver;
+ @Inject ImportHelpers importHelpers;
+ @Inject Provider<XtextHyperlink> hyperlinkProvider;
- @Inject
- protected EObjectAtOffsetHelper eObjectAtOffsetHelper;
-
- @Inject
- protected IGlobalScopeProvider globalScopeProvider;
-
- @Inject
- protected IQualifiedNameConverter nameConverter;
-
- /*
- * (non-Javadoc)
- *
- * @see org.eclipse.xtext.ui.editor.hyperlinking.HyperlinkHelper#
- * createHyperlinksByOffset(org.eclipse.xtext.resource.XtextResource, int,
- * org.eclipse.xtext.ui.editor.hyperlinking.IHyperlinkAcceptor)
- */
+ @SuppressWarnings("deprecation")
@Override
public void createHyperlinksByOffset(XtextResource resource, int offset, IHyperlinkAcceptor acceptor) {
- XtextHyperlink link = createByImportObject(resource, offset);
- if (link == null)
- link = createByImportNode(resource, offset);
- if (link != null)
- acceptor.accept(link);
-
- super.createHyperlinksByOffset(resource, offset, acceptor);
- }
-
- private XtextHyperlink createByImportObject(XtextResource resource, int offset) {
- EObject eObject = eObjectAtOffsetHelper.resolveElementAt(resource, offset);
- if (eObject == null || !(eObject instanceof Import))
- return null;
-
- Import importObj = (Import) eObject;
-
- // Create hyperlink based on the qualified name of the import using the global scope provider
- String name = importObj.getImportedNamespace();
- if(name != null) {
- QualifiedName qualifiedName = nameConverter.toQualifiedName(name);
- if(!qualifiedName.getLastSegment().equals("*")) {
- EReference reference = EcoreFactory.eINSTANCE.createEReference();
- reference.setEType(EcorePackage.eINSTANCE.getEObject());
- IScope scope = globalScopeProvider.getScope(resource, reference, Predicates.alwaysTrue());
- IEObjectDescription eod = scope.getSingleElement(qualifiedName);
- if(eod != null) {
- URI uri = eod.getEObjectURI();
- INode node = NodeModelUtils.getNode(importObj);
- XtextHyperlink result = hyperlinkProvider.get();
- result.setHyperlinkText(eod.getName().toString());
- result.setURI(uri);
- result.setHyperlinkRegion(new Region(node.getOffset(), node.getLength())); // whole import statement
- return result;
- }
- }
- }
-
- // Create hyperlink using the import uri
- if (importObj.getImportURI() == null)
- return null;
-
- String uritext = uriResolver.resolve(importObj.getImportURI(), resource);
- if (uritext == null)
- return null;
-
- XtextHyperlink result = hyperlinkProvider.get();
- result.setHyperlinkText(uritext); // ?
- try {
- result.setURI(URI.createURI(uritext));
- }
- catch (IllegalArgumentException e) {
- return null;
- }
-
- INode node = NodeModelUtils.getNode(importObj);
- result.setHyperlinkRegion(new Region(node.getOffset(), node.getLength())); // whole import statement
-
- return result;
- }
-
- private XtextHyperlink createByImportNode(XtextResource resource, int offset) {
IParseResult parseResult = resource.getParseResult();
if (parseResult != null && parseResult.getRootNode() != null) {
ILeafNode leaf = NodeModelUtils.findLeafNodeAtOffset(parseResult.getRootNode(), offset);
- EObject grammarElement = leaf.getParent().getGrammarElement();
- if (grammarElement instanceof RuleCall) {
- RuleCall rc = (RuleCall) grammarElement;
- AbstractRule rule = rc.getRule();
- if (rule.getName().equals("Import")) {
- String text = leaf.getText().substring(1, leaf.getText().length() - 1);
-
- String uritext = uriResolver.resolve(text, resource);
- if (uritext == null)
- return null;
+ Region region = new Region(leaf.getOffset(), leaf.getLength());
+
+ AbstractRule leafRule = null;
+ if(leaf.getGrammarElement() instanceof RuleCall) {
+ leafRule = ((RuleCall) leaf.getGrammarElement()).getRule();
+ }
+
+ AbstractRule parentRule = null;
+ if(leaf.getParent().getGrammarElement() instanceof RuleCall) {
+ parentRule = ((RuleCall) leaf.getParent().getGrammarElement()).getRule();
+ }
+
+ // FQN and ImportedFQN => create link on fqn
+ if (parentRule.getName().equals("FQN") || parentRule.getName().equals("ImportedFQN")) {
+ QualifiedName fqn = importHelpers.toFQN(leaf.getParent().getText().trim());
+ // query global scope, that is how elements are actually resolved
+ IScope scope = importHelpers.getVisibleScope(resource, null);
+ IEObjectDescription candidate = scope.getSingleElement(fqn); // take first
+ if(candidate != null) {
+ createHyperlinksTo(resource, region, candidate.getEObjectOrProxy(), acceptor);
+ }
+ }
+ // Import-importURI => create link on uri text
+ else if(parentRule.getName().equals("Import") && leafRule.getName().equals("STRING")) {
+ String text = leaf.getText().substring(1, leaf.getText().length() - 1);
- XtextHyperlink result = hyperlinkProvider.get();
- result.setHyperlinkText(uritext);
- result.setHyperlinkRegion(new Region(leaf.getOffset() + 1, leaf.getLength() - 2)); // omit ""
+ String uritext = importHelpers.getUriResolver().resolve(text, resource);
+ if(uritext != null) {
try {
+ XtextHyperlink result = hyperlinkProvider.get();
+ result.setHyperlinkText(uritext);
+ result.setHyperlinkRegion(region); // ignore: deprecated since Xtext 2.18
result.setURI(URI.createURI(uritext));
-
- return result;
+ acceptor.accept(result);
}
catch (IllegalArgumentException e) {
}
}
}
}
-
- return null;
+
+ super.createHyperlinksByOffset(resource, offset, acceptor);
}
}
diff --git a/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/base/util/ImportHelpers.java b/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/base/util/ImportHelpers.java
index ec3bab4e0..010ab8e4d 100644
--- a/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/base/util/ImportHelpers.java
+++ b/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/base/util/ImportHelpers.java
@@ -19,28 +19,71 @@ import java.util.List;
import java.util.Optional;
import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EcoreFactory;
+import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.etrice.core.common.base.Import;
+import org.eclipse.etrice.core.common.scoping.ModelLocatorUriResolver;
import org.eclipse.xtext.naming.IQualifiedNameConverter;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.IResourceDescription;
+import org.eclipse.xtext.resource.IResourceDescriptions;
import org.eclipse.xtext.resource.IResourceServiceProvider;
-import org.eclipse.xtext.scoping.impl.ImportUriResolver;
+import org.eclipse.xtext.scoping.IGlobalScopeProvider;
+import org.eclipse.xtext.scoping.IScope;
import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
import com.google.common.collect.Lists;
+import com.google.inject.Inject;
public class ImportHelpers {
+ private final static EClass EOBJECT = EcorePackage.eINSTANCE.getEObject();
+
+ @Inject IQualifiedNameConverter nameConverter;
+ @Inject ModelLocatorUriResolver importUriResolver;
+ @Inject IGlobalScopeProvider globalScope; // visible/imported scope
+ @Inject IResourceDescriptions resourceDescriptions; // world scope
+
+ public ModelLocatorUriResolver getUriResolver() {
+ return importUriResolver;
+ }
+
+// /**
+// * Returns elements from workspace.
+// */
+// public Iterable<IEObjectDescription> findInWorskpace(QualifiedName fqn) {
+// return resourceDescriptions.getExportedObjects(EOBJECT, fqn, false);
+// }
+
+ /**
+ * Returns current visible/imported scope of given resource.
+ */
+ public IScope getVisibleScope(Resource context) {
+ return getVisibleScope(context, null);
+ }
+
+ /**
+ * Returns current visible/imported scope of given resource.
+ */
+ public IScope getVisibleScope(Resource context, EClass type) {
+ EReference reference = EcoreFactory.eINSTANCE.createEReference();
+ reference.setEType((type != null) ? type : EOBJECT);
+
+ return globalScope.getScope(context, reference, Predicates.alwaysTrue());
+ }
+
/**
* Returns a list of imported target eObjects for an import or absent if import is not computable.
- * The list contains either a single exact match (name and quickFixCandidateMatcher) or candidates (name
- * or quickFixCandidateMatcher) or empty.
+ * The list contains either a single exact match (imported namespace && quickFixCandidateMatcher)
+ * or candidates only (imported namespace || quickFixCandidateMatcher) or is optional empty.
*/
- public static Optional<List<IEObjectDescription>> getImportedObjectsFor(Import imp, ImportUriResolver importUriResolver,
- Predicate<IEObjectDescription> quickFixCandidateMatcher) {
+ public Optional<List<IEObjectDescription>> getImportedObjectsFor(Import imp, Predicate<IEObjectDescription> quickFixCandidateMatcher) {
QualifiedName importedFQN = toFQN(imp);
if (importedFQN == null)
@@ -89,16 +132,19 @@ public class ImportHelpers {
return Optional.of(candidates);
}
-
- public static QualifiedName toFQN(Import imp) {
- IQualifiedNameConverter nameConverter = new IQualifiedNameConverter.DefaultImpl();
+
+ public QualifiedName toFQN(String fqn) {
boolean isWildcard = false;
try {
- QualifiedName orig = nameConverter.toQualifiedName(imp.getImportedNamespace());
+ QualifiedName orig = nameConverter.toQualifiedName(fqn);
isWildcard = orig.getLastSegment().equals("*");
return (isWildcard) ? orig.skipLast(1) : orig;
} catch(IllegalArgumentException e){
return null;
- }
+ }
+ }
+
+ public QualifiedName toFQN(Import imp) {
+ return toFQN(imp.getImportedNamespace());
}
}
diff --git a/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/validation/BaseJavaValidator.java b/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/validation/BaseJavaValidator.java
index 892a124c0..5a1838102 100644
--- a/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/validation/BaseJavaValidator.java
+++ b/plugins/org.eclipse.etrice.core.common/src/org/eclipse/etrice/core/common/validation/BaseJavaValidator.java
@@ -18,8 +18,6 @@ import java.util.HashSet;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.EReference;
-import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.etrice.core.common.base.Annotation;
@@ -35,17 +33,13 @@ import org.eclipse.etrice.core.common.base.KeyValue;
import org.eclipse.etrice.core.common.base.RealLiteral;
import org.eclipse.etrice.core.common.base.SimpleAnnotationAttribute;
import org.eclipse.etrice.core.common.base.StringLiteral;
-import org.eclipse.emf.ecore.EcoreFactory;
+import org.eclipse.etrice.core.common.base.util.ImportHelpers;
import org.eclipse.etrice.generator.base.io.IModelPathProvider;
-import org.eclipse.xtext.naming.IQualifiedNameConverter;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.IEObjectDescription;
-import org.eclipse.xtext.scoping.IGlobalScopeProvider;
-import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.impl.ImportUriResolver;
import org.eclipse.xtext.validation.Check;
-import com.google.common.base.Predicates;
import com.google.inject.Inject;
/**
@@ -65,8 +59,7 @@ public class BaseJavaValidator extends org.eclipse.etrice.core.common.validation
public static final String IMPORTED_NAMESPACE_MISSING = "BaseJavaValidator.ImportedNamespaceMissing";
@Inject ImportUriResolver importUriResolver;
- @Inject IGlobalScopeProvider globalScopeProvider;
- @Inject IQualifiedNameConverter nameConverter;
+ @Inject ImportHelpers importHelpers;
@Inject IModelPathProvider modelPathProvider;
@Check
@@ -246,30 +239,20 @@ public class BaseJavaValidator extends org.eclipse.etrice.core.common.validation
*/
@Check
public void checkImportedNamespace(Import imp) {
- if(imp.getImportURI() != null) {
+ if(imp.getImportURI() != null || imp.getImportedNamespace() == null) {
return;
}
- String name = imp.getImportedNamespace();
- if(name == null) {
- return;
- }
+ QualifiedName fqn = importHelpers.toFQN(imp);
+
Resource resource = imp.eResource();
if(modelPathProvider.get(resource).isEmpty()) {
error("no modelpath definition present", BasePackage.Literals.IMPORT__IMPORTED_NAMESPACE, MODELPATH_DESCRIPTION_MISSING);
return;
- }
- QualifiedName importedNamespace = nameConverter.toQualifiedName(name);
- if(importedNamespace.getLastSegment().equals("*")) {
- return;
- }
-
- EReference reference = EcoreFactory.eINSTANCE.createEReference();
- reference.setEType(EcorePackage.eINSTANCE.getEObject());
- IScope scope = globalScopeProvider.getScope(resource, reference, Predicates.alwaysTrue());
- IEObjectDescription eod = scope.getSingleElement(importedNamespace);
+ }
+ IEObjectDescription eod = importHelpers.getVisibleScope(resource).getSingleElement(fqn);
if(eod == null) {
- error("could not find imported namespace " + importedNamespace, BasePackage.Literals.IMPORT__IMPORTED_NAMESPACE, IMPORTED_NAMESPACE_MISSING);
+ error("could not find imported namespace " + fqn, BasePackage.Literals.IMPORT__IMPORTED_NAMESPACE, IMPORTED_NAMESPACE_MISSING);
}
}
}
diff --git a/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/highlight/RoomSemanticHighlightingCalculator.java b/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/highlight/RoomSemanticHighlightingCalculator.java
index 75bf907b7..b3a885c4d 100644
--- a/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/highlight/RoomSemanticHighlightingCalculator.java
+++ b/plugins/org.eclipse.etrice.core.room.ui/src/org/eclipse/etrice/core/ui/highlight/RoomSemanticHighlightingCalculator.java
@@ -52,7 +52,6 @@ import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.XtextResource;
-import org.eclipse.xtext.scoping.impl.ImportUriResolver;
import org.eclipse.xtext.util.CancelIndicator;
import com.google.common.base.Predicate;
@@ -69,7 +68,7 @@ public class RoomSemanticHighlightingCalculator extends BaseSemanticHighlighter
@Inject RoomGrammarAccess grammar;
@Inject RoomValueConverterService converterService;
@Inject RoomHelpers roomHelpers;
- @Inject ImportUriResolver importUriResolver;
+ @Inject ImportHelpers importHelpers;
@Override
public void provideHighlightingFor(XtextResource resource, IHighlightedPositionAcceptor acceptor, CancelIndicator cancelIndicator) {
@@ -139,7 +138,7 @@ public class RoomSemanticHighlightingCalculator extends BaseSemanticHighlighter
Predicate<IEObjectDescription> nameMatcher = (input) -> {
return importElement.getImportedNamespace().equals(input.getQualifiedName().toString());
};
- Optional<List<IEObjectDescription>> matches = ImportHelpers.getImportedObjectsFor(importElement, importUriResolver, nameMatcher);
+ Optional<List<IEObjectDescription>> matches = importHelpers.getImportedObjectsFor(importElement, nameMatcher);
if(matches.isPresent() && matches.get().size() == 1) {
EObject annotatedElement = matches.get().get(0).getEObjectOrProxy();
if(annotatedElement instanceof RoomElement) {
diff --git a/plugins/org.eclipse.etrice.core.room/src/org/eclipse/etrice/core/validation/RoomJavaValidator.java b/plugins/org.eclipse.etrice.core.room/src/org/eclipse/etrice/core/validation/RoomJavaValidator.java
index 3542a62b1..2f9f12545 100644
--- a/plugins/org.eclipse.etrice.core.room/src/org/eclipse/etrice/core/validation/RoomJavaValidator.java
+++ b/plugins/org.eclipse.etrice.core.room/src/org/eclipse/etrice/core/validation/RoomJavaValidator.java
@@ -86,7 +86,6 @@ import org.eclipse.xtext.naming.IQualifiedNameConverter;
import org.eclipse.xtext.naming.IQualifiedNameProvider;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.IEObjectDescription;
-import org.eclipse.xtext.scoping.impl.ImportUriResolver;
import org.eclipse.xtext.validation.Check;
import org.eclipse.xtext.validation.CheckType;
@@ -109,11 +108,11 @@ public class RoomJavaValidator extends AbstractRoomJavaValidator {
@Inject protected IQualifiedNameConverter nameConverter;
- @Inject ImportUriResolver importUriResolver;
-
@Inject private IModelPathProvider modelPathProvider;
@Inject InterfaceContractHelpers contractMonitorHelpers;
+
+ @Inject ImportHelpers importHelpers;
/* message strings */
public static final String OPTIONAL_REFS_HAVE_TO_HAVE_MULTIPLICITY_ANY = "optional refs have to have multiplicity any [*]";
@@ -153,7 +152,7 @@ public class RoomJavaValidator extends AbstractRoomJavaValidator {
@Check
public void checkRoomImportedNamespace(Import imp) {
- QualifiedName importedFQN = ImportHelpers.toFQN(imp);
+ QualifiedName importedFQN = importHelpers.toFQN(imp);
if(importedFQN == null)
return;
@@ -182,7 +181,7 @@ public class RoomJavaValidator extends AbstractRoomJavaValidator {
}
};
- Optional<List<IEObjectDescription>> importCandidates = ImportHelpers.getImportedObjectsFor(imp, importUriResolver, candidateMatcher);
+ Optional<List<IEObjectDescription>> importCandidates = importHelpers.getImportedObjectsFor(imp, candidateMatcher);
if(!importCandidates.isPresent()) {
return;
}

Back to the top