mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-16 08:48:55 +00:00
Merge pull request #999 from eclipse/ak/callee_hierarchy_support
[bug 489745] Callee Hierarchy Support
This commit is contained in:
commit
5d364b058a
19 changed files with 273 additions and 104 deletions
|
@ -9,20 +9,28 @@ package org.eclipse.xtext.ide.editor.hierarchy
|
|||
|
||||
import com.google.inject.Inject
|
||||
import javax.inject.Provider
|
||||
import org.eclipse.emf.common.util.URI
|
||||
import org.eclipse.emf.ecore.EClass
|
||||
import org.eclipse.emf.ecore.EClassifier
|
||||
import org.eclipse.emf.ecore.EObject
|
||||
import org.eclipse.xtend.lib.annotations.Accessors
|
||||
import org.eclipse.xtext.findReferences.IReferenceFinder
|
||||
import org.eclipse.xtext.findReferences.IReferenceFinder.IResourceAccess
|
||||
import org.eclipse.xtext.findReferences.TargetURICollector
|
||||
import org.eclipse.xtext.findReferences.TargetURIs
|
||||
import org.eclipse.xtext.resource.IEObjectDescription
|
||||
import org.eclipse.xtext.resource.IResourceDescriptions
|
||||
import org.eclipse.xtext.resource.IResourceServiceProvider
|
||||
import org.eclipse.xtext.util.concurrent.IUnitOfWork
|
||||
|
||||
import static extension org.eclipse.xtext.EcoreUtil2.*
|
||||
|
||||
/**
|
||||
* @author kosyakov - Initial contribution and API
|
||||
* @since 2.10
|
||||
*/
|
||||
@Accessors(PUBLIC_SETTER, PROTECTED_GETTER)
|
||||
abstract class AbstractHierarchyBuilder implements HierarchyBuilder {
|
||||
abstract class AbstractHierarchyBuilder implements IHierarchyBuilder {
|
||||
|
||||
IResourceAccess resourceAccess
|
||||
|
||||
|
@ -38,9 +46,34 @@ abstract class AbstractHierarchyBuilder implements HierarchyBuilder {
|
|||
Provider<TargetURIs> targetURIProvider
|
||||
|
||||
@Inject
|
||||
HierarchyNodeLocationProvider hierarchyNodeLocationProvider
|
||||
IHierarchyNodeLocationProvider hierarchyNodeLocationProvider
|
||||
|
||||
@Inject
|
||||
IResourceServiceProvider.Registry resourceServiceProviderRegistry
|
||||
|
||||
protected def <R> R readOnly(URI objectURI, IUnitOfWork<R, EObject> work) {
|
||||
return getResourceAccess.readOnly(objectURI) [ resourceSet |
|
||||
val targetObject = resourceSet.getEObject(objectURI, true)
|
||||
return work.exec(targetObject)
|
||||
]
|
||||
}
|
||||
|
||||
protected def IEObjectDescription getDescription(URI objectURI) {
|
||||
val resourceDescription = getIndexData.getResourceDescription(objectURI.trimFragment)
|
||||
if(resourceDescription === null) return null
|
||||
|
||||
return resourceDescription.exportedObjects.findFirst[EObjectURI == objectURI]
|
||||
}
|
||||
|
||||
protected def IEObjectDescription getDescription(EObject object) {
|
||||
if(object === null) return null
|
||||
return getIndexData.getExportedObjectsByObject(object).head
|
||||
}
|
||||
|
||||
protected def isAssignable(EClass superType, EClassifier type) {
|
||||
if (type instanceof EClass)
|
||||
return superType.isAssignableFrom(type)
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,9 +7,12 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.xtext.ide.editor.hierarchy
|
||||
|
||||
import java.util.Map
|
||||
import org.eclipse.core.runtime.IProgressMonitor
|
||||
import org.eclipse.emf.common.util.URI
|
||||
import org.eclipse.emf.ecore.EObject
|
||||
import org.eclipse.emf.ecore.EReference
|
||||
import org.eclipse.xtend.lib.annotations.Accessors
|
||||
import org.eclipse.xtext.findReferences.ReferenceAcceptor
|
||||
import org.eclipse.xtext.findReferences.TargetURIs
|
||||
import org.eclipse.xtext.resource.IEObjectDescription
|
||||
|
@ -27,47 +30,80 @@ import static extension org.eclipse.xtext.nodemodel.util.NodeModelUtils.*
|
|||
* @author kosyakov - Initial contribution and API
|
||||
* @since 2.10
|
||||
*/
|
||||
class DefaultCallHierarchyBuilder extends AbstractHierarchyBuilder {
|
||||
class DefaultCallHierarchyBuilder extends AbstractHierarchyBuilder implements ICallHierarchyBuilder {
|
||||
|
||||
override buildRoots(URI rootURI, IProgressMonitor progressMonitor) {
|
||||
val rootDeclaration = rootURI.rootDeclaration
|
||||
@Accessors
|
||||
CallHierarchyType hierarchyType = CallHierarchyType.CALLER
|
||||
|
||||
override buildRoots(URI rootURI, IProgressMonitor monitor) {
|
||||
val rootDeclaration = rootURI.findDeclaration
|
||||
if(rootDeclaration === null) return emptyList
|
||||
return #[rootDeclaration.createRoot]
|
||||
}
|
||||
|
||||
override buildChildren(HierarchyNode parent, IProgressMonitor progressMonitor) {
|
||||
override buildChildren(IHierarchyNode parent, IProgressMonitor monitor) {
|
||||
if (!parent.mayHaveChildren)
|
||||
return emptyList
|
||||
|
||||
val children = newLinkedHashMap
|
||||
parent.element.EObjectURI.findDeclarations(progressMonitor) [ declaration, reference |
|
||||
var childNode = children.get(declaration.EObjectURI)
|
||||
if (childNode === null) {
|
||||
childNode = createChild(declaration, parent)
|
||||
children.put(declaration.EObjectURI, childNode)
|
||||
}
|
||||
childNode.locations += reference.createLocation
|
||||
findDeclarations(parent, monitor) [ declaration, reference |
|
||||
val childNode = children.createChild(declaration, parent)
|
||||
if (childNode !== null)
|
||||
childNode.references += reference.createNodeReference
|
||||
]
|
||||
return children.values
|
||||
}
|
||||
|
||||
protected def void findDeclarations(
|
||||
URI targetURI,
|
||||
IProgressMonitor progressMonitor,
|
||||
IHierarchyNode parent,
|
||||
IProgressMonitor monitor,
|
||||
(IEObjectDescription, IReferenceDescription)=>void acceptor
|
||||
) {
|
||||
val targetURIs = targetURI.collectTargetURIs
|
||||
switch hierarchyType {
|
||||
case CALLEE:
|
||||
findTargetDeclarations(parent.element.EObjectURI, monitor, acceptor)
|
||||
default:
|
||||
findSourceDeclarations(parent.element.EObjectURI, monitor, acceptor)
|
||||
}
|
||||
}
|
||||
|
||||
protected def void findTargetDeclarations(
|
||||
URI sourceDeclarationURI,
|
||||
IProgressMonitor monitor,
|
||||
(IEObjectDescription, IReferenceDescription)=>void acceptor
|
||||
) {
|
||||
readOnly(sourceDeclarationURI) [ sourceDeclaration |
|
||||
referenceFinder.findAllReferences(
|
||||
sourceDeclaration,
|
||||
new ReferenceAcceptor(resourceServiceProviderRegistry) [ reference |
|
||||
if (reference.filterReference) {
|
||||
val targetDeclaration = reference?.findTargetDeclaration
|
||||
acceptor.apply(targetDeclaration, reference)
|
||||
}
|
||||
],
|
||||
monitor
|
||||
)
|
||||
null
|
||||
]
|
||||
}
|
||||
|
||||
protected def void findSourceDeclarations(
|
||||
URI targetDeclarationURI,
|
||||
IProgressMonitor monitor,
|
||||
(IEObjectDescription, IReferenceDescription)=>void acceptor
|
||||
) {
|
||||
val targetURIs = targetDeclarationURI.collectTargetURIs
|
||||
referenceFinder.findAllReferences(
|
||||
targetURIs,
|
||||
resourceAccess,
|
||||
indexData,
|
||||
new ReferenceAcceptor(resourceServiceProviderRegistry) [ reference |
|
||||
val declaration = reference.declaration
|
||||
if (declaration !== null)
|
||||
acceptor.apply(declaration, reference)
|
||||
if (reference.filterReference) {
|
||||
val sourceDeclaration = reference?.findSourceDeclaration
|
||||
acceptor.apply(sourceDeclaration, reference)
|
||||
}
|
||||
],
|
||||
progressMonitor
|
||||
monitor
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -75,47 +111,33 @@ class DefaultCallHierarchyBuilder extends AbstractHierarchyBuilder {
|
|||
val targetURIs = targetURIProvider.get
|
||||
if(targetURI === null) return targetURIs
|
||||
|
||||
return resourceAccess.readOnly(targetURI) [ resourceSet |
|
||||
val targetObject = resourceSet.getEObject(targetURI, true)
|
||||
return readOnly(targetURI) [ targetObject |
|
||||
if(targetObject === null) return targetURIs
|
||||
|
||||
targetURICollector.add(targetObject, targetURIs)
|
||||
return targetURIs
|
||||
]
|
||||
}
|
||||
|
||||
protected def IEObjectDescription getRootDeclaration(URI rootURI) {
|
||||
return rootURI.declaration.rootDeclaration
|
||||
protected def boolean filterReference(IReferenceDescription reference) {
|
||||
reference !== null
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns a declaration representing a root hierarchy node for the given element; can return <code>null<code> if the hierarchy does not support such kind of declarations
|
||||
*/
|
||||
protected def IEObjectDescription getRootDeclaration(IEObjectDescription declaration) {
|
||||
return declaration
|
||||
protected def IEObjectDescription findDeclaration(URI objectURI) {
|
||||
return objectURI.description
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns a declaration representing a child node that can be reached with the given reference; can return <code>null</code> if the hierarchy does not support such kind of references
|
||||
*/
|
||||
protected def IEObjectDescription getDeclaration(IReferenceDescription reference) {
|
||||
if(reference === null) return null
|
||||
|
||||
val declarationURI = reference.containerEObjectURI ?: reference.sourceEObjectUri
|
||||
return declarationURI.declaration
|
||||
protected def IEObjectDescription findTargetDeclaration(IReferenceDescription reference) {
|
||||
return reference.targetEObjectUri.findDeclaration
|
||||
}
|
||||
|
||||
protected def IEObjectDescription getDeclaration(URI declarationURI) {
|
||||
val resourceDescription = indexData.getResourceDescription(declarationURI.trimFragment)
|
||||
if(resourceDescription === null) return null
|
||||
|
||||
return resourceDescription.exportedObjects.findFirst[EObjectURI == declarationURI]
|
||||
protected def IEObjectDescription findSourceDeclaration(IReferenceDescription reference) {
|
||||
return reference.containerEObjectURI.findDeclaration
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns a root hierarchy node for the given declaration; cannot be <code>null</code>
|
||||
*/
|
||||
protected def HierarchyNode createRoot(IEObjectDescription declaration) {
|
||||
protected def IHierarchyNode createRoot(IEObjectDescription declaration) {
|
||||
val node = new DefaultHierarchyNode
|
||||
node.element = declaration
|
||||
node.mayHaveChildren = true
|
||||
|
@ -125,7 +147,7 @@ class DefaultCallHierarchyBuilder extends AbstractHierarchyBuilder {
|
|||
/**
|
||||
* @returns a child node for the given declaration and the parent node; cannot be <code>null</code>
|
||||
*/
|
||||
protected def HierarchyNode createChild(IEObjectDescription declaration, HierarchyNode parent) {
|
||||
protected def IHierarchyNode createChild(IEObjectDescription declaration, IHierarchyNode parent) {
|
||||
val node = new DefaultHierarchyNode
|
||||
node.parent = parent
|
||||
node.element = declaration
|
||||
|
@ -133,20 +155,34 @@ class DefaultCallHierarchyBuilder extends AbstractHierarchyBuilder {
|
|||
return node
|
||||
}
|
||||
|
||||
protected def IHierarchyNode createChild(
|
||||
Map<URI, IHierarchyNode> children,
|
||||
IEObjectDescription declaration,
|
||||
IHierarchyNode parent
|
||||
) {
|
||||
if(declaration === null) return null;
|
||||
|
||||
var childNode = children.get(declaration.EObjectURI)
|
||||
if (childNode === null) {
|
||||
childNode = createChild(declaration, parent)
|
||||
children.put(declaration.EObjectURI, childNode)
|
||||
}
|
||||
return childNode
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns a location for the given reference; cannot be <code>null</code>
|
||||
* @returns a hierarchy node reference for the given reference; cannot be <code>null</code>
|
||||
*/
|
||||
protected def HierarchyNodeLocation createLocation(IReferenceDescription reference) {
|
||||
return resourceAccess.readOnly(reference.sourceEObjectUri) [ resourceSet |
|
||||
val obj = resourceSet.getEObject(reference.sourceEObjectUri, true)
|
||||
val textRegion = obj.getTextRegion(reference)
|
||||
val text = obj.getText(textRegion)
|
||||
return new DefaultHierarchyNodeLocation(text, textRegion, reference)
|
||||
protected def IHierarchyNodeReference createNodeReference(IReferenceDescription reference) {
|
||||
return readOnly(reference.sourceEObjectUri) [ sourceObject |
|
||||
val textRegion = sourceObject.getTextRegion(reference.EReference, reference.indexInList)
|
||||
val text = sourceObject.getText(textRegion)
|
||||
return new DefaultHierarchyNodeReference(text, textRegion, reference)
|
||||
]
|
||||
}
|
||||
|
||||
protected def ITextRegionWithLineInformation getTextRegion(EObject obj, IReferenceDescription reference) {
|
||||
return hierarchyNodeLocationProvider.getTextRegion(obj, reference.EReference, reference.indexInList)
|
||||
protected def ITextRegionWithLineInformation getTextRegion(EObject obj, EReference reference, int indexInList) {
|
||||
return hierarchyNodeLocationProvider.getTextRegion(obj, reference, indexInList)
|
||||
}
|
||||
|
||||
protected def String getText(EObject obj, ITextRegionWithLineInformation textRegion) {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.xtext.ide.editor.hierarchy
|
||||
|
||||
import java.util.List
|
||||
import org.eclipse.xtend.lib.annotations.Accessors
|
||||
import org.eclipse.xtext.resource.IEObjectDescription
|
||||
import org.eclipse.xtext.util.Wrapper
|
||||
|
@ -15,10 +16,10 @@ import org.eclipse.xtext.util.Wrapper
|
|||
* @author kosyakov - Initial contribution and API
|
||||
* @since 2.10
|
||||
*/
|
||||
class DefaultHierarchyNode implements HierarchyNode {
|
||||
class DefaultHierarchyNode implements IHierarchyNode {
|
||||
|
||||
@Accessors
|
||||
HierarchyNode parent
|
||||
IHierarchyNode parent
|
||||
|
||||
@Accessors(PUBLIC_SETTER)
|
||||
boolean mayHaveChildren
|
||||
|
@ -27,12 +28,12 @@ class DefaultHierarchyNode implements HierarchyNode {
|
|||
IEObjectDescription element
|
||||
|
||||
@Accessors(PUBLIC_GETTER)
|
||||
val locations = <HierarchyNodeLocation>newArrayList
|
||||
val List<IHierarchyNodeReference> references = <IHierarchyNodeReference>newArrayList
|
||||
|
||||
Wrapper<Boolean> recursive
|
||||
|
||||
override getNavigationElement() {
|
||||
return locations.head ?: element
|
||||
return references.head ?: element
|
||||
}
|
||||
|
||||
override boolean isRecursive() {
|
||||
|
|
|
@ -23,7 +23,7 @@ import static extension org.eclipse.xtext.nodemodel.util.NodeModelUtils.*
|
|||
* @since 2.10
|
||||
*/
|
||||
@Singleton
|
||||
class DefaultHierarchyNodeLocationProvider implements HierarchyNodeLocationProvider {
|
||||
class DefaultHierarchyNodeLocationProvider implements IHierarchyNodeLocationProvider {
|
||||
|
||||
@Inject
|
||||
protected ILocationInFileProvider locationInFileProvider
|
||||
|
|
|
@ -18,7 +18,7 @@ import org.eclipse.xtext.util.ITextRegionWithLineInformation
|
|||
*/
|
||||
@Accessors
|
||||
@FinalFieldsConstructor
|
||||
class DefaultHierarchyNodeLocation implements HierarchyNodeLocation {
|
||||
class DefaultHierarchyNodeReference implements IHierarchyNodeReference {
|
||||
val String text
|
||||
@Delegate
|
||||
val ITextRegionWithLineInformation textRegion
|
|
@ -7,6 +7,7 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.xtext.ide.editor.hierarchy
|
||||
|
||||
import java.util.List
|
||||
import org.eclipse.xtend.lib.annotations.Accessors
|
||||
|
||||
/**
|
||||
|
@ -14,6 +15,6 @@ import org.eclipse.xtend.lib.annotations.Accessors
|
|||
* @since 2.10
|
||||
*/
|
||||
@Accessors
|
||||
class DefaultHierarchyRoot implements HierarchyRoot {
|
||||
val roots = <HierarchyNode>newArrayList
|
||||
class DefaultHierarchyRoot implements IHierarchyRoot {
|
||||
val List<IHierarchyNode> roots = <IHierarchyNode>newArrayList
|
||||
}
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2016 TypeFox GmbH (http://www.typefox.io) 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.ide.editor.hierarchy
|
||||
|
||||
/**
|
||||
* It is used to build a call hierarchy structure.
|
||||
*
|
||||
* @author kosyakov - Initial contribution and API
|
||||
* @since 2.10
|
||||
*/
|
||||
interface ICallHierarchyBuilder extends IHierarchyBuilder {
|
||||
|
||||
static enum CallHierarchyType {
|
||||
CALLER,
|
||||
CALLEE
|
||||
}
|
||||
|
||||
def CallHierarchyType getHierarchyType();
|
||||
|
||||
def void setHierarchyType(CallHierarchyType hierarchyType);
|
||||
|
||||
}
|
|
@ -17,16 +17,16 @@ import org.eclipse.emf.common.util.URI
|
|||
* @author kosyakov - Initial contribution and API
|
||||
* @since 2.10
|
||||
*/
|
||||
interface HierarchyBuilder {
|
||||
interface IHierarchyBuilder {
|
||||
|
||||
/**
|
||||
* @returns root hierarchy nodes for the given URI; empty if the hierarchy cannot be built for the given URI
|
||||
*/
|
||||
def Collection<HierarchyNode> buildRoots(URI rootURI, IProgressMonitor monitor)
|
||||
def Collection<IHierarchyNode> buildRoots(URI rootURI, IProgressMonitor monitor)
|
||||
|
||||
/**
|
||||
* @returns child nodes for the given parent node; empty if {@link HierarchyNode#mayHaveChildren} returns <code>false</code> for the parent
|
||||
* @returns child nodes for the given parent node; empty if {@link IHierarchyNode#mayHaveChildren} returns <code>false</code> for the parent
|
||||
*/
|
||||
def Collection<HierarchyNode> buildChildren(HierarchyNode parent, IProgressMonitor monitor)
|
||||
def Collection<IHierarchyNode> buildChildren(IHierarchyNode parent, IProgressMonitor monitor)
|
||||
|
||||
}
|
|
@ -8,7 +8,7 @@
|
|||
package org.eclipse.xtext.ide.editor.hierarchy
|
||||
|
||||
import java.util.Collection
|
||||
import org.eclipse.xtext.ide.editor.navigation.Navigatable
|
||||
import org.eclipse.xtext.ide.editor.navigation.INavigatable
|
||||
import org.eclipse.xtext.resource.IEObjectDescription
|
||||
|
||||
/**
|
||||
|
@ -17,7 +17,7 @@ import org.eclipse.xtext.resource.IEObjectDescription
|
|||
* @author kosyakov - Initial contribution and API
|
||||
* @since 2.10
|
||||
*/
|
||||
interface HierarchyNode extends Navigatable {
|
||||
interface IHierarchyNode extends INavigatable {
|
||||
|
||||
/**
|
||||
* @returns an associated element that is used to build child nodes
|
||||
|
@ -27,12 +27,12 @@ interface HierarchyNode extends Navigatable {
|
|||
/**
|
||||
* @returns a parent; <code>null</code> if the node is a root
|
||||
*/
|
||||
def HierarchyNode getParent()
|
||||
def IHierarchyNode getParent()
|
||||
|
||||
/**
|
||||
* @returns locations used to reach the node from a parent; empty if the node is a root
|
||||
* @returns references used to reach the node from a parent; empty if the node is a root
|
||||
*/
|
||||
def Collection<HierarchyNodeLocation> getLocations()
|
||||
def Collection<IHierarchyNodeReference> getReferences()
|
||||
|
||||
/**
|
||||
* @returns whether there is a parent (can be transitive) containing the same element as the node
|
|
@ -13,12 +13,13 @@ import org.eclipse.emf.ecore.EStructuralFeature
|
|||
import org.eclipse.xtext.util.ITextRegionWithLineInformation
|
||||
|
||||
/**
|
||||
* This class is used to identify a region for {@link HierarchyNode} and {@link HierarchyNodeLocation}.
|
||||
* This class is used to identify a region for {@link IHierarchyNode} and {@link IHierarchyNodeReference}.
|
||||
*
|
||||
* @author kosyakov - Initial contribution and API
|
||||
* @since 2.10
|
||||
*/
|
||||
@ImplementedBy(DefaultHierarchyNodeLocationProvider)
|
||||
interface HierarchyNodeLocationProvider {
|
||||
interface IHierarchyNodeLocationProvider {
|
||||
def ITextRegionWithLineInformation getTextRegion(EObject obj)
|
||||
|
||||
def ITextRegionWithLineInformation getTextRegion(EObject owner, EStructuralFeature feature, int indexInList)
|
|
@ -7,15 +7,15 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.xtext.ide.editor.hierarchy
|
||||
|
||||
import org.eclipse.xtext.ide.editor.navigation.Navigatable
|
||||
import org.eclipse.xtext.ide.editor.navigation.INavigatable
|
||||
import org.eclipse.xtext.util.ITextRegionWithLineInformation
|
||||
|
||||
/**
|
||||
* Represents a reference between parent and child nodes. Each location is backed up with a region and a text.
|
||||
* Represents a reference between parent and child nodes. Each reference is backed up with a region and a text.
|
||||
*
|
||||
* @author kosyakov - Initial contribution and API
|
||||
* @since 2.10
|
||||
*/
|
||||
interface HierarchyNodeLocation extends Navigatable, ITextRegionWithLineInformation {
|
||||
interface IHierarchyNodeReference extends INavigatable, ITextRegionWithLineInformation {
|
||||
def String getText()
|
||||
}
|
|
@ -15,11 +15,11 @@ import java.util.Collection
|
|||
* @author kosyakov - Initial contribution and API
|
||||
* @since 2.10
|
||||
*/
|
||||
interface HierarchyRoot {
|
||||
interface IHierarchyRoot {
|
||||
|
||||
def Collection<HierarchyNode> getRoots()
|
||||
def Collection<IHierarchyNode> getRoots()
|
||||
|
||||
val EMPTY = new HierarchyRoot() {
|
||||
val EMPTY = new IHierarchyRoot() {
|
||||
|
||||
override getRoots() {
|
||||
emptyList
|
|
@ -13,7 +13,7 @@ package org.eclipse.xtext.ide.editor.navigation
|
|||
* @author kosyakov - Initial contribution and API
|
||||
* @since 2.10
|
||||
*/
|
||||
interface Navigatable {
|
||||
interface INavigatable {
|
||||
|
||||
/**
|
||||
* <p>
|
|
@ -14,9 +14,6 @@ import org.eclipse.emf.common.util.URI
|
|||
import org.eclipse.emf.ecore.resource.ResourceSet
|
||||
import org.eclipse.xtend.lib.annotations.Accessors
|
||||
import org.eclipse.xtext.ide.editor.hierarchy.AbstractHierarchyBuilder
|
||||
import org.eclipse.xtext.ide.editor.hierarchy.HierarchyBuilder
|
||||
import org.eclipse.xtext.ide.editor.hierarchy.HierarchyNode
|
||||
import org.eclipse.xtext.ide.editor.hierarchy.HierarchyNodeLocation
|
||||
import org.eclipse.xtext.junit4.validation.ValidationTestHelper
|
||||
import org.eclipse.xtext.resource.EObjectAtOffsetHelper
|
||||
import org.eclipse.xtext.resource.IResourceDescriptionsProvider
|
||||
|
@ -28,6 +25,9 @@ import org.eclipse.xtext.util.LazyStringInputStream
|
|||
import static org.junit.Assert.*
|
||||
|
||||
import static extension org.eclipse.xtext.EcoreUtil2.*
|
||||
import org.eclipse.xtext.ide.editor.hierarchy.IHierarchyBuilder
|
||||
import org.eclipse.xtext.ide.editor.hierarchy.IHierarchyNode
|
||||
import org.eclipse.xtext.ide.editor.hierarchy.IHierarchyNodeReference
|
||||
|
||||
/**
|
||||
* @author kosyakov - Initial contribution and API
|
||||
|
@ -80,20 +80,20 @@ abstract class AbstractHierarchyBuilderTest {
|
|||
return hierarchyBuilder
|
||||
}
|
||||
|
||||
protected def String toExpectation(URI rootURI, HierarchyBuilder builder) '''
|
||||
protected def String toExpectation(URI rootURI, IHierarchyBuilder builder) '''
|
||||
«FOR root : builder.buildRoots(rootURI, null)»
|
||||
«root.toExpectation(builder)»
|
||||
«ENDFOR»
|
||||
'''
|
||||
|
||||
protected def String toExpectation(HierarchyNode node, HierarchyBuilder builder) '''
|
||||
protected def String toExpectation(IHierarchyNode node, IHierarchyBuilder builder) '''
|
||||
«node.element» {
|
||||
«node.internalToExpectation(builder)»
|
||||
}
|
||||
'''
|
||||
|
||||
protected def String internalToExpectation(HierarchyNode node, HierarchyBuilder builder) '''
|
||||
«FOR location : node.locations»
|
||||
protected def String internalToExpectation(IHierarchyNode node, IHierarchyBuilder builder) '''
|
||||
«FOR location : node.references»
|
||||
«location.toExpectation»
|
||||
«ENDFOR»
|
||||
«IF node.mayHaveChildren»
|
||||
|
@ -103,13 +103,13 @@ abstract class AbstractHierarchyBuilderTest {
|
|||
«ENDIF»
|
||||
'''
|
||||
|
||||
protected def String toExpectation(HierarchyNodeLocation location) {
|
||||
protected def String toExpectation(IHierarchyNodeReference location) {
|
||||
''''«location.text»' [«location.offset», «location.length»]'''
|
||||
}
|
||||
|
||||
@Accessors
|
||||
protected static class HierarchyBuilderTestConfiguration {
|
||||
(ResourceSet)=>HierarchyBuilder hierarchyBuilderProvider
|
||||
(ResourceSet)=>IHierarchyBuilder hierarchyBuilderProvider
|
||||
Collection<Pair<String, String>> models = newArrayList
|
||||
int index
|
||||
String resourceURI
|
||||
|
|
|
@ -21,6 +21,7 @@ import org.eclipse.xtext.resource.IResourceDescriptions;
|
|||
import org.eclipse.xtext.resource.impl.DefaultResourceDescriptionStrategy;
|
||||
import org.eclipse.xtext.util.concurrent.IUnitOfWork;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
||||
/**
|
||||
|
@ -108,7 +109,7 @@ public interface IReferenceFinder {
|
|||
* Finds the references from the given source resource to the given <code>targetURIs</code>.
|
||||
*
|
||||
* @param targetURIs
|
||||
* the URIs of the target elements of the references. Should be normalized.
|
||||
* a predicate that returns true if an URI belongs to target URIs; otherwise false.
|
||||
* @param resource
|
||||
* the search scope for the resources containing the sources of the references.
|
||||
* @param acceptor
|
||||
|
@ -117,11 +118,58 @@ public interface IReferenceFinder {
|
|||
* the progress monitor. Can be null.
|
||||
*/
|
||||
void findReferences(
|
||||
TargetURIs targetURIs,
|
||||
Predicate<URI> targetURIs,
|
||||
Resource resource,
|
||||
Acceptor acceptor,
|
||||
IProgressMonitor monitor);
|
||||
|
||||
/**
|
||||
* Finds all references from the given source resource.
|
||||
*
|
||||
* @param scope
|
||||
* the search scope for the resources containing the sources of the references.
|
||||
* @param acceptor
|
||||
* accepts the matches.
|
||||
* @param monitor
|
||||
* the progress monitor. Can be null.
|
||||
*/
|
||||
void findAllReferences(
|
||||
Resource scope,
|
||||
Acceptor acceptor,
|
||||
IProgressMonitor monitor);
|
||||
|
||||
/**
|
||||
* Finds the references from the given source object to the given <code>targetURIs</code>.
|
||||
*
|
||||
* @param targetURIs
|
||||
* a predicate that returns true if an URI belongs to target URIs; otherwise false.
|
||||
* @param scope
|
||||
* the search scope for the object containing the sources of the references.
|
||||
* @param acceptor
|
||||
* accepts the matches.
|
||||
* @param monitor
|
||||
* the progress monitor. Can be null.
|
||||
*/
|
||||
void findReferences(
|
||||
Predicate<URI> targetURIs,
|
||||
EObject scope,
|
||||
Acceptor acceptor,
|
||||
IProgressMonitor monitor);
|
||||
|
||||
/**
|
||||
* Finds all references from the given source object.
|
||||
*
|
||||
* @param scope
|
||||
* the search scope for the object containing the sources of the references.
|
||||
* @param acceptor
|
||||
* accepts the matches.
|
||||
* @param monitor
|
||||
* the progress monitor. Can be null.
|
||||
*/
|
||||
void findAllReferences(
|
||||
EObject scope,
|
||||
Acceptor acceptor,
|
||||
IProgressMonitor monitor);
|
||||
|
||||
/**
|
||||
* Finds all references to the given <code>targetURIs</code>.
|
||||
|
|
|
@ -29,6 +29,8 @@ import org.eclipse.xtext.resource.IResourceDescriptions;
|
|||
import org.eclipse.xtext.resource.IResourceServiceProvider;
|
||||
import org.eclipse.xtext.util.concurrent.IUnitOfWork;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
|
||||
|
@ -114,15 +116,30 @@ public class ReferenceFinder implements IReferenceFinder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void findReferences(TargetURIs targetURIs, Resource resource, Acceptor acceptor, IProgressMonitor monitor) {
|
||||
public void findAllReferences(Resource scope, Acceptor acceptor, IProgressMonitor monitor) {
|
||||
findReferences(Predicates.<URI>alwaysTrue(), scope, acceptor, monitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findReferences(Predicate<URI> targetURIs, Resource resource, Acceptor acceptor, IProgressMonitor monitor) {
|
||||
for (EObject content : resource.getContents()) {
|
||||
if (monitor.isCanceled()) {
|
||||
throw new OperationCanceledException();
|
||||
}
|
||||
findLocalReferencesFromElement(targetURIs, content, resource, acceptor);
|
||||
findReferences(targetURIs, content, acceptor, monitor);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findAllReferences(EObject scope, Acceptor acceptor, IProgressMonitor monitor) {
|
||||
findReferences(Predicates.<URI>alwaysTrue(), scope, acceptor, monitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findReferences(Predicate<URI> targetURIs, EObject scope, Acceptor acceptor, IProgressMonitor monitor) {
|
||||
if (monitor != null && monitor.isCanceled()) {
|
||||
throw new OperationCanceledException();
|
||||
}
|
||||
findLocalReferencesFromElement(targetURIs, scope, scope.eResource(), acceptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void findReferences(final TargetURIs targetURIs, IResourceDescription resourceDescription,
|
||||
IResourceAccess resourceAccess, final Acceptor acceptor, final IProgressMonitor monitor) {
|
||||
|
@ -171,7 +188,7 @@ public class ReferenceFinder implements IReferenceFinder {
|
|||
}
|
||||
|
||||
protected void findLocalReferencesFromElement(
|
||||
TargetURIs targetURIs,
|
||||
Predicate<URI> targetURIs,
|
||||
EObject sourceCandidate,
|
||||
Resource localResource,
|
||||
Acceptor acceptor) {
|
||||
|
@ -205,7 +222,7 @@ public class ReferenceFinder implements IReferenceFinder {
|
|||
EObject instanceOrProxy = toValidInstanceOrNull(localResource, targetURIs, values.basicGet(i));
|
||||
if (instanceOrProxy != null) {
|
||||
URI refURI= EcoreUtil2.getPlatformResourceOrNormalizedURI(instanceOrProxy);
|
||||
if(targetURIs.contains(refURI)) {
|
||||
if(targetURIs.apply(refURI)) {
|
||||
sourceURI = (sourceURI == null) ? EcoreUtil2.getPlatformResourceOrNormalizedURI(sourceCandidate) : sourceURI;
|
||||
acceptor.accept(sourceCandidate, sourceURI, ref, i, instanceOrProxy, refURI);
|
||||
}
|
||||
|
@ -215,7 +232,7 @@ public class ReferenceFinder implements IReferenceFinder {
|
|||
EObject instanceOrProxy = toValidInstanceOrNull(localResource, targetURIs, (EObject) value);
|
||||
if (instanceOrProxy != null) {
|
||||
URI refURI = EcoreUtil2.getPlatformResourceOrNormalizedURI(instanceOrProxy);
|
||||
if (targetURIs.contains(refURI)) {
|
||||
if (targetURIs.apply(refURI)) {
|
||||
sourceURI = (sourceURI == null) ? EcoreUtil2
|
||||
.getPlatformResourceOrNormalizedURI(sourceCandidate) : sourceURI;
|
||||
acceptor.accept(sourceCandidate, sourceURI, ref, -1, instanceOrProxy, refURI);
|
||||
|
@ -229,7 +246,7 @@ public class ReferenceFinder implements IReferenceFinder {
|
|||
}
|
||||
}
|
||||
|
||||
protected EObject toValidInstanceOrNull(Resource resource, TargetURIs targetURIs, EObject value) {
|
||||
protected EObject toValidInstanceOrNull(Resource resource, Predicate<URI> targetURIs, EObject value) {
|
||||
EObject result = resolveInternalProxy(value, resource);
|
||||
return result;
|
||||
}
|
||||
|
@ -241,11 +258,11 @@ public class ReferenceFinder implements IReferenceFinder {
|
|||
return elementOrProxy;
|
||||
}
|
||||
|
||||
protected boolean doProcess(EObject sourceCandidate, TargetURIs targetURISet) {
|
||||
protected boolean doProcess(EObject sourceCandidate, Predicate<URI> targetURIs) {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean doProcess(EReference reference, TargetURIs targetURISet) {
|
||||
protected boolean doProcess(EReference reference, Predicate<URI> targetURIs) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@ import com.google.inject.Singleton;
|
|||
* targets.
|
||||
*
|
||||
* @author Sebastian Zarnekow - Initial contribution and API
|
||||
*
|
||||
* @since 2.10
|
||||
*/
|
||||
@Singleton
|
||||
|
|
|
@ -89,6 +89,11 @@ public class TargetURISet extends AbstractSet<URI> implements TargetURIs {
|
|||
return Collections.unmodifiableCollection(index.get(resourceURI));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(URI uri) {
|
||||
return contains(uri);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(URI uri) {
|
||||
return uris.contains(uri);
|
||||
|
|
|
@ -12,6 +12,7 @@ import java.util.Set;
|
|||
|
||||
import org.eclipse.emf.common.util.URI;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.inject.ImplementedBy;
|
||||
|
||||
/**
|
||||
|
@ -26,7 +27,7 @@ import com.google.inject.ImplementedBy;
|
|||
* @since 2.10
|
||||
*/
|
||||
@ImplementedBy(TargetURISet.class)
|
||||
public interface TargetURIs extends Iterable<URI> {
|
||||
public interface TargetURIs extends Iterable<URI>, Predicate<URI> {
|
||||
|
||||
/**
|
||||
* A user data key with equalitiy semantics on the type of the value and the
|
||||
|
|
Loading…
Reference in a new issue