In progress: [Issue 199] Add ability to navigate to proto element from
generated C++ code.
* Changed strategy to lookup protobuf elements.
diff --git a/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/fqn/IsQualifiedNameSource.java b/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/fqn/IsQualifiedNameSource.java
deleted file mode 100644
index a5417d1..0000000
--- a/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/fqn/IsQualifiedNameSource.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2012 Google Inc.
- *
- * 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 com.google.eclipse.protobuf.cdt.fqn;
-
-import org.eclipse.xtext.naming.QualifiedName;
-import org.hamcrest.*;
-
-/**
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class IsQualifiedNameSource extends BaseMatcher<Iterable<QualifiedName>> {
-
- private final QualifiedName original;
-
- public static IsQualifiedNameSource isQualifiedNameSourceWith(String[] segments) {
- return new IsQualifiedNameSource(segments);
- }
-
- private IsQualifiedNameSource(String[] segments) {
- original = QualifiedName.create(segments);
- }
-
- @Override public boolean matches(Object item) {
- if (!(item instanceof QualifiedNameSource)) {
- return false;
- }
- QualifiedNameSource source = (QualifiedNameSource) item;
- return original.equals(source.original());
- }
-
- @Override public void describeTo(Description description) {
- description.appendValue(QualifiedNameSource.class.getSimpleName() + " with original qualified name: " + original);
- }
-}
diff --git a/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/fqn/ClassTypeQualifiedNameProviderStrategy_qualifiedNamesFrom_Test.java b/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/mapping/ClassMappingStrategy_createMappingFrom_Test.java
similarity index 70%
rename from com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/fqn/ClassTypeQualifiedNameProviderStrategy_qualifiedNamesFrom_Test.java
rename to com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/mapping/ClassMappingStrategy_createMappingFrom_Test.java
index 469f454..756bad8 100644
--- a/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/fqn/ClassTypeQualifiedNameProviderStrategy_qualifiedNamesFrom_Test.java
+++ b/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/mapping/ClassMappingStrategy_createMappingFrom_Test.java
@@ -6,11 +6,11 @@
*
* http://www.eclipse.org/legal/epl-v10.html
*/
-package com.google.eclipse.protobuf.cdt.fqn;
+package com.google.eclipse.protobuf.cdt.mapping;
-import static com.google.eclipse.protobuf.cdt.fqn.IsQualifiedNameSource.isQualifiedNameSourceWith;
import static com.google.eclipse.protobuf.junit.core.UnitTestModule.unitTestModule;
import static com.google.eclipse.protobuf.junit.core.XtextRule.overrideRuntimeModuleWith;
+import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
@@ -21,28 +21,29 @@
import org.eclipse.xtext.naming.QualifiedName;
import org.junit.*;
-import com.google.eclipse.protobuf.cdt.ProtobufCdtModule;
import com.google.eclipse.protobuf.junit.core.*;
+import com.google.eclipse.protobuf.protobuf.Message;
import com.google.inject.Inject;
/**
- * Tests for <code>{@link ClassTypeQualifiedNameProviderStrategy#qualifiedNamesFrom(IBinding)}</code>
+ * Tests for <code>{@link ClassMappingStrategy#createMappingFrom(IBinding)}</code>
*
* @author alruiz@google.com (Alex Ruiz)
*/
@SuppressWarnings("restriction")
-public class ClassTypeQualifiedNameProviderStrategy_qualifiedNamesFrom_Test {
- @Rule public XtextRule xtext = overrideRuntimeModuleWith(unitTestModule(), new ProtobufCdtModule(), new TestModule());
+public class ClassMappingStrategy_createMappingFrom_Test {
+ @Rule public XtextRule xtext = overrideRuntimeModuleWith(unitTestModule(), new TestModule());
@Inject private CPPClassType classType;
- @Inject private ClassTypeQualifiedNameProviderStrategy nameBuilder;
+ @Inject private ClassMappingStrategy mappingStrategy;
- @Test public void should_return_qualified_names_for_class_type_if_it_extends_proto_file() {
+ @Test public void should_return_qualified_name_for_class_type_if_it_extends_proto_file() {
expectClassTypeToExtendProtoMessage();
String[] segments = { "com", "google", "proto", "Test" };
when(classType.getQualifiedName()).thenReturn(segments);
- Iterable<QualifiedName> qualifiedNames = nameBuilder.qualifiedNamesFrom(classType);
- assertThat(qualifiedNames, isQualifiedNameSourceWith(segments));
+ CppToProtobufMapping mapping = mappingStrategy.createMappingFrom(classType);
+ assertThat(mapping.qualifiedName(), equalTo(QualifiedName.create(segments)));
+ assertEquals(Message.class, mapping.type());
}
private void expectClassTypeToExtendProtoMessage() {
@@ -62,8 +63,8 @@
@Test public void should_return_null_if_class_type_does_not_extend_proto_message() {
when(classType.getBases()).thenReturn(new ICPPBase[0]);
- Iterable<QualifiedName> qualifiedNames = nameBuilder.qualifiedNamesFrom(classType);
- assertNull(qualifiedNames);
+ CppToProtobufMapping mapping = mappingStrategy.createMappingFrom(classType);
+ assertNull(mapping);
}
private static class TestModule extends AbstractTestModule {
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/ProtobufCdtModule.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/ProtobufCdtModule.java
index 5a4ee54..ac97696 100644
--- a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/ProtobufCdtModule.java
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/ProtobufCdtModule.java
@@ -10,10 +10,13 @@
import static com.google.eclipse.protobuf.cdt.ProtobufObjectsProvider.getfromProtobufPlugin;
+import org.eclipse.xtext.naming.IQualifiedNameConverter;
import org.eclipse.xtext.service.AbstractGenericModule;
+import org.eclipse.xtext.ui.editor.IURIEditorOpener;
import org.eclipse.xtext.ui.editor.preferences.IPreferenceStoreAccess;
-import com.google.eclipse.protobuf.ui.editor.ModelObjectDefinitionNavigator;
+import com.google.eclipse.protobuf.model.util.*;
+import com.google.eclipse.protobuf.resource.*;
import com.google.inject.Binder;
/**
@@ -21,8 +24,13 @@
*/
public class ProtobufCdtModule extends AbstractGenericModule {
public void configureModelObjectDefinitionNavigator(Binder binder) {
+ bindToProtobufPluginObject(IndexLookup.class, binder);
bindToProtobufPluginObject(IPreferenceStoreAccess.class, binder);
- bindToProtobufPluginObject(ModelObjectDefinitionNavigator.class, binder);
+ bindToProtobufPluginObject(IQualifiedNameConverter.class, binder);
+ bindToProtobufPluginObject(IURIEditorOpener.class, binder);
+ bindToProtobufPluginObject(ModelObjects.class, binder);
+ bindToProtobufPluginObject(ResourceDescriptions.class, binder);
+ bindToProtobufPluginObject(Resources.class, binder);
}
private <T> void bindToProtobufPluginObject(Class<T> type, Binder binder) {
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/AstBasedCppToProtobufMapper.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/AstBasedCppToProtobufMapper.java
new file mode 100644
index 0000000..231fda8
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/AstBasedCppToProtobufMapper.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012 Google Inc.
+ *
+ * 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 com.google.eclipse.protobuf.cdt.actions;
+
+import static org.eclipse.cdt.internal.ui.editor.ASTProvider.WAIT_NO;
+import static org.eclipse.core.runtime.Status.*;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.eclipse.cdt.core.dom.ast.*;
+import org.eclipse.cdt.core.model.*;
+import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
+import org.eclipse.cdt.internal.ui.editor.ASTProvider;
+import org.eclipse.cdt.ui.CUIPlugin;
+import org.eclipse.core.runtime.*;
+import org.eclipse.ui.IEditorPart;
+
+import com.google.eclipse.protobuf.cdt.editor.Editors;
+import com.google.eclipse.protobuf.cdt.mapping.*;
+import com.google.inject.*;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+@SuppressWarnings("restriction")
+@Singleton class AstBasedCppToProtobufMapper {
+ @Inject private Editors editors;
+ @Inject private CppToProtobufMapper delegate;
+
+ CppToProtobufMapping createMappingFromSelectionOf(IEditorPart editor) {
+ final int offset = editors.selectionOffsetOf(editor);
+ if (offset < 0) {
+ return null;
+ }
+ IWorkingCopy workingCopy = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(editor.getEditorInput());
+ if (workingCopy == null) {
+ return null;
+ }
+ final AtomicReference<CppToProtobufMapping> mappingReference = new AtomicReference<CppToProtobufMapping>();
+ ASTProvider astProvider = ASTProvider.getASTProvider();
+ IStatus status = astProvider.runOnAST(workingCopy, WAIT_NO, null, new ASTRunnable() {
+ @Override public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) throws CoreException {
+ if (ast == null) {
+ return CANCEL_STATUS;
+ }
+ IASTNodeSelector nodeSelector= ast.getNodeSelector(null);
+ IASTName selectedName = nodeSelector.findEnclosingName(offset, 1);
+ if (selectedName == null) {
+ return CANCEL_STATUS;
+ }
+ if (selectedName.isDefinition()) {
+ IBinding binding = selectedName.resolveBinding();
+ CppToProtobufMapping info = delegate.createMappingFrom(binding);
+ mappingReference.set(info);
+ return OK_STATUS;
+ }
+ return CANCEL_STATUS;
+ }
+ });
+ if (status == CANCEL_STATUS) {
+ return null;
+ }
+ return mappingReference.get();
+ }
+}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ModelObjectLookupQueryBuilder.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ModelObjectLookupQueryBuilder.java
deleted file mode 100644
index 61e11a3..0000000
--- a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ModelObjectLookupQueryBuilder.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (c) 2012 Google Inc.
- *
- * 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 com.google.eclipse.protobuf.cdt.actions;
-
-import static org.eclipse.cdt.internal.ui.editor.ASTProvider.WAIT_NO;
-import static org.eclipse.core.runtime.Status.*;
-
-import java.util.concurrent.atomic.AtomicReference;
-
-import org.eclipse.cdt.core.dom.ast.*;
-import org.eclipse.cdt.core.model.*;
-import org.eclipse.cdt.internal.core.model.ASTCache.ASTRunnable;
-import org.eclipse.cdt.internal.ui.editor.ASTProvider;
-import org.eclipse.cdt.ui.CUIPlugin;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.runtime.*;
-import org.eclipse.jface.text.ITextSelection;
-import org.eclipse.jface.viewers.*;
-import org.eclipse.ui.IEditorPart;
-import org.eclipse.ui.texteditor.ITextEditor;
-import org.eclipse.xtext.naming.QualifiedName;
-
-import com.google.eclipse.protobuf.cdt.fqn.QualifiedNameProvider;
-import com.google.eclipse.protobuf.cdt.path.ProtoFilePathFinder;
-import com.google.eclipse.protobuf.ui.editor.ModelObjectDefinitionNavigator.Query;
-import com.google.inject.Inject;
-
-/**
- * @author alruiz@google.com (Alex Ruiz)
- */
-@SuppressWarnings("restriction")
-class ModelObjectLookupQueryBuilder {
- @Inject private QualifiedNameProvider qualifiedNameProvider;
- @Inject private ProtoFilePathFinder pathFinder;
-
- Query buildQuery(IEditorPart editor) {
- final int offset = selectionOffsetOf(editor);
- if (offset < 0) {
- return null;
- }
- IFile file = (IFile) editor.getEditorInput().getAdapter(IFile.class);
- final IPath protoFilePath = pathFinder.findProtoFilePath(file);
- if (protoFilePath == null) {
- return null;
- }
- IWorkingCopy workingCopy = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(editor.getEditorInput());
- if (workingCopy == null) {
- return null;
- }
- final AtomicReference<Query> queriesReference = new AtomicReference<Query>();
- ASTProvider astProvider = ASTProvider.getASTProvider();
- IStatus status = astProvider.runOnAST(workingCopy, WAIT_NO, null, new ASTRunnable() {
- @Override public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) throws CoreException {
- if (ast == null) {
- return CANCEL_STATUS;
- }
- IASTNodeSelector nodeSelector= ast.getNodeSelector(null);
- IASTName selectedName = nodeSelector.findEnclosingName(offset, 1);
- if (selectedName == null) {
- return CANCEL_STATUS;
- }
- if (selectedName.isDefinition()) {
- IBinding binding = selectedName.resolveBinding();
- Iterable<QualifiedName> qualifiedNames = qualifiedNameProvider.qualifiedNamesFrom(binding);
- if (qualifiedNames != null) {
- queriesReference.set(Query.newQuery(qualifiedNames, protoFilePath));
- return OK_STATUS;
- }
- }
- return CANCEL_STATUS;
- }
- });
- if (status == CANCEL_STATUS) {
- return null;
- }
- return queriesReference.get();
- }
-
- private int selectionOffsetOf(IEditorPart editor) {
- ISelectionProvider selectionProvider = ((ITextEditor) editor).getSelectionProvider();
- ISelection selection = selectionProvider.getSelection();
- if (selection instanceof ITextSelection) {
- ITextSelection textSelection = (ITextSelection) selection;
- return textSelection.getOffset();
- }
- return -1;
- }
-}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/NavigationJobs.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/NavigationJobs.java
deleted file mode 100644
index 4b9ebe3..0000000
--- a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/NavigationJobs.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2012 Google Inc.
- *
- * 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 com.google.eclipse.protobuf.cdt.actions;
-
-import static org.eclipse.core.runtime.Status.OK_STATUS;
-
-import org.eclipse.core.runtime.*;
-import org.eclipse.ui.progress.UIJob;
-
-import com.google.eclipse.protobuf.ui.editor.*;
-import com.google.eclipse.protobuf.ui.editor.ModelObjectDefinitionNavigator.Query;
-import com.google.inject.Inject;
-
-/**
- * @author alruiz@google.com (Alex Ruiz)
- */
-class NavigationJobs {
- @Inject private ModelObjectDefinitionNavigator navigator;
-
- void scheduleUsing(final Query query) {
- UIJob job = new UIJob("Navigating to .proto file") {
- @Override public IStatus runInUIThread(IProgressMonitor monitor) {
- navigator.navigateToDefinition(query);
- return OK_STATUS;
- }
- };
- job.schedule();
- }
-}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/OpenProtoDeclarationAction.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/OpenProtoDeclarationAction.java
index 0c390f6..7b96f7e 100644
--- a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/OpenProtoDeclarationAction.java
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/OpenProtoDeclarationAction.java
@@ -8,11 +8,12 @@
*/
package com.google.eclipse.protobuf.cdt.actions;
+import org.eclipse.emf.common.util.URI;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.*;
+import org.eclipse.xtext.ui.editor.IURIEditorOpener;
-import com.google.eclipse.protobuf.ui.editor.ModelObjectDefinitionNavigator.Query;
import com.google.inject.Inject;
/**
@@ -21,18 +22,18 @@
* @author alruiz@google.com (Alex Ruiz)
*/
public class OpenProtoDeclarationAction implements IEditorActionDelegate {
- private IEditorPart editor;
+ @Inject private IURIEditorOpener editorOpener;
+ @Inject private ProtobufElementUriFinder uriFinder;
- @Inject private ModelObjectLookupQueryBuilder queryBuilder;
- @Inject private NavigationJobs navigationJobs;
+ private IEditorPart editor;
@Override public void run(IAction action) {
if (editor == null) {
return;
}
- Query query = queryBuilder.buildQuery(editor);
- if (query != null) {
- navigationJobs.scheduleUsing(query);
+ URI foundUri = uriFinder.findProtobufElementUriFromSelectionOf(editor);
+ if (foundUri != null) {
+ editorOpener.open(foundUri, true);
}
}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ProtobufElementUriFinder.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ProtobufElementUriFinder.java
new file mode 100644
index 0000000..e496412
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ProtobufElementUriFinder.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2012 Google Inc.
+ *
+ * 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 com.google.eclipse.protobuf.cdt.actions;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.xtext.naming.QualifiedName;
+import org.eclipse.xtext.resource.IResourceDescription;
+
+import com.google.eclipse.protobuf.cdt.editor.Editors;
+import com.google.eclipse.protobuf.cdt.mapping.CppToProtobufMapping;
+import com.google.eclipse.protobuf.cdt.matching.ProtobufElementMatcher;
+import com.google.eclipse.protobuf.cdt.path.ProtoFilePaths;
+import com.google.eclipse.protobuf.resource.*;
+import com.google.inject.Inject;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+class ProtobufElementUriFinder {
+ @Inject private ProtobufElementMatcher matcher;
+ @Inject private ResourceDescriptions descriptions;
+ @Inject private Editors editors;
+ @Inject private IndexLookup indexLookup;
+ @Inject private AstBasedCppToProtobufMapper mapper;
+ @Inject private ProtoFilePaths paths;
+
+ URI findProtobufElementUriFromSelectionOf(IEditorPart editor) {
+ IFile file = editors.fileOpenIn(editor);
+ IPath protoFilePath = paths.protoFilePath(file);
+ if (protoFilePath != null) {
+ CppToProtobufMapping mapping = mapper.createMappingFromSelectionOf(editor);
+ if (mapping != null) {
+ IResourceDescription resource = indexLookup.resourceIn(protoFilePath);
+ return findProtobufElementUri(resource, mapping);
+ }
+ }
+ return null;
+ }
+
+ private URI findProtobufElementUri(IResourceDescription resource, CppToProtobufMapping mapping) {
+ if (resource == null) {
+ return null;
+ }
+ // try first direct lookup.
+ QualifiedName qualifiedName = mapping.qualifiedName();
+ URI foundUri = descriptions.modelObjectUri(resource, qualifiedName);
+ if (foundUri != null) {
+ return foundUri;
+ }
+ // try finding the best match.
+ return matcher.findUriOfMatchingProtobufElement(resource, mapping);
+ }
+}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/editor/Editors.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/editor/Editors.java
new file mode 100644
index 0000000..384317d
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/editor/Editors.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2012 Google Inc.
+ *
+ * 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 com.google.eclipse.protobuf.cdt.editor;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.viewers.*;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.texteditor.ITextEditor;
+
+import com.google.inject.Singleton;
+
+/**
+ * Utility methods related to editors.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+@Singleton public class Editors {
+
+ /**
+ * Returns the offset of the selected text in the given editor.
+ * @param editor the given editor.
+ * @return the offset of the selected text in the given editor, or -1 if there is no valid text information.
+ */
+ public int selectionOffsetOf(IEditorPart editor) {
+ ISelectionProvider selectionProvider = ((ITextEditor) editor).getSelectionProvider();
+ ISelection selection = selectionProvider.getSelection();
+ if (selection instanceof ITextSelection) {
+ ITextSelection textSelection = (ITextSelection) selection;
+ return textSelection.getOffset();
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the file open in the given editor.
+ * @param editor the given editor.
+ * @return the file open in the given editor.
+ */
+ public IFile fileOpenIn(IEditorPart editor) {
+ return (IFile) editor.getEditorInput().getAdapter(IFile.class);
+ }
+}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/fqn/EnumQualifiedNameProviderStrategy.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/fqn/EnumQualifiedNameProviderStrategy.java
deleted file mode 100644
index d904428..0000000
--- a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/fqn/EnumQualifiedNameProviderStrategy.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2012 Google Inc.
- *
- * 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 com.google.eclipse.protobuf.cdt.fqn;
-
-import org.eclipse.cdt.core.dom.ast.IBinding;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPEnumeration;
-import org.eclipse.xtext.naming.QualifiedName;
-
-import com.google.inject.Singleton;
-
-/**
- * @author alruiz@google.com (Alex Ruiz)
- */
-@SuppressWarnings("restriction")
-@Singleton class EnumQualifiedNameProviderStrategy implements QualifiedNameProviderStrategy<CPPEnumeration> {
- @Override public Iterable<QualifiedName> qualifiedNamesFrom(IBinding binding) {
- CPPEnumeration enumeration = supportedBindingType().cast(binding);
- String[] segments = enumeration.getQualifiedName();
- return new QualifiedNameSource(segments);
- }
-
- @Override public Class<CPPEnumeration> supportedBindingType() {
- return CPPEnumeration.class;
- }
-}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/fqn/QualifiedNameProvider.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/fqn/QualifiedNameProvider.java
deleted file mode 100644
index 03438b0..0000000
--- a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/fqn/QualifiedNameProvider.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2012 Google Inc.
- *
- * 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 com.google.eclipse.protobuf.cdt.fqn;
-
-import static com.google.common.collect.Maps.newHashMap;
-
-import java.util.Map;
-
-import org.eclipse.cdt.core.dom.ast.IBinding;
-import org.eclipse.xtext.naming.QualifiedName;
-
-import com.google.inject.Singleton;
-
-/**
- * Provides all the possible qualified names of the protocol buffer element used to generate a C++ element.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-@Singleton public class QualifiedNameProvider {
- private final Map<Class<?>, QualifiedNameProviderStrategy<?>> strategies = newHashMap();
-
- public QualifiedNameProvider() {
- add(new ClassTypeQualifiedNameProviderStrategy());
- add(new EnumQualifiedNameProviderStrategy());
- }
-
- private void add(QualifiedNameProviderStrategy<?> strategy) {
- strategies.put(strategy.supportedBindingType(), strategy);
- }
-
- /**
- * Returns a lazy-loaded <code>{@link Iterable}</code> containing all the possible qualified names of the protocol
- * buffer element used to generate a C++ element.
- * @param binding specifies the semantics of the name of the generated C++ element.
- * @return a lazy-loaded {@code Iterable} containing all the possible qualified names, or {@code null} if qualified
- * names cannot be obtained from the given {@code IBinding}.
- */
- public Iterable<QualifiedName> qualifiedNamesFrom(IBinding binding) {
- QualifiedNameProviderStrategy<? extends IBinding> strategy = strategies.get(binding.getClass());
- return (strategy != null) ? strategy.qualifiedNamesFrom(binding) : null;
- }
-}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/fqn/QualifiedNameProviderStrategy.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/fqn/QualifiedNameProviderStrategy.java
deleted file mode 100644
index 44816d0..0000000
--- a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/fqn/QualifiedNameProviderStrategy.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2012 Google Inc.
- *
- * 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 com.google.eclipse.protobuf.cdt.fqn;
-
-import org.eclipse.cdt.core.dom.ast.IBinding;
-import org.eclipse.xtext.naming.QualifiedName;
-
-/**
- * Provides all the possible qualified names of the protocol buffer element used to generate a C++ element described
- * by a specific type of <code>{@link IBinding}</code>.
- * @param <T> the type of {@code IBinding} this strategy supports.
- *
- * @author alruiz@google.com (Alex Ruiz)
- */
-interface QualifiedNameProviderStrategy<T extends IBinding> {
- Iterable<QualifiedName> qualifiedNamesFrom(IBinding binding);
-
- Class<T> supportedBindingType();
-}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/fqn/QualifiedNameSource.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/fqn/QualifiedNameSource.java
deleted file mode 100644
index 062e1ac..0000000
--- a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/fqn/QualifiedNameSource.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2012 Google Inc.
- *
- * 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 com.google.eclipse.protobuf.cdt.fqn;
-
-import static com.google.common.collect.Lists.newArrayList;
-
-import java.util.*;
-
-import org.eclipse.xtext.naming.QualifiedName;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.AbstractIterator;
-
-/**
- * @author alruiz@google.com (Alex Ruiz)
- */
-class QualifiedNameSource implements Iterable<QualifiedName> {
- private final QualifiedName original;
-
- public QualifiedNameSource(String[] segments) {
- original = QualifiedName.create(segments);
- }
-
- @VisibleForTesting QualifiedName original() {
- return original;
- }
-
- @Override public Iterator<QualifiedName> iterator() {
- return new QualifiedNameIterator();
- }
-
- private class QualifiedNameIterator extends AbstractIterator<QualifiedName> {
- private int sentCount;
-
- @Override protected QualifiedName computeNext() {
- switch (sentCount++) {
- case 0:
- return original;
- case 1:
- return nested();
- default:
- return endOfData();
- }
- }
-
- private QualifiedName nested() {
- String name = original.getLastSegment();
- if (!name.contains("_")) {
- return endOfData();
- }
- String[] nestedNames = name.split("_");
- List<String> newSegments = newArrayList(original.getSegments());
- newSegments.remove(newSegments.size() - 1);
- newSegments.addAll(newArrayList(nestedNames));
- String[] segments = newSegments.toArray(new String[newSegments.size()]);
- return QualifiedName.create(segments);
- }
- }
-}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/fqn/ClassTypeQualifiedNameProviderStrategy.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/ClassMappingStrategy.java
similarity index 71%
rename from com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/fqn/ClassTypeQualifiedNameProviderStrategy.java
rename to com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/ClassMappingStrategy.java
index 34fe592..00dacf4 100644
--- a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/fqn/ClassTypeQualifiedNameProviderStrategy.java
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/ClassMappingStrategy.java
@@ -6,7 +6,7 @@
*
* http://www.eclipse.org/legal/epl-v10.html
*/
-package com.google.eclipse.protobuf.cdt.fqn;
+package com.google.eclipse.protobuf.cdt.mapping;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.IBinding;
@@ -14,18 +14,21 @@
import org.eclipse.cdt.internal.core.dom.parser.cpp.*;
import org.eclipse.xtext.naming.QualifiedName;
+import com.google.eclipse.protobuf.protobuf.Message;
import com.google.inject.Singleton;
/**
* @author alruiz@google.com (Alex Ruiz)
*/
@SuppressWarnings("restriction")
-@Singleton class ClassTypeQualifiedNameProviderStrategy implements QualifiedNameProviderStrategy<CPPClassType> {
- @Override public Iterable<QualifiedName> qualifiedNamesFrom(IBinding binding) {
- CPPClassType classType = supportedBindingType().cast(binding);
+@Singleton class ClassMappingStrategy implements IBindingMappingStrategy<CPPClassType> {
+
+ @Override public CppToProtobufMapping createMappingFrom(IBinding binding) {
+ CPPClassType classType = typeOfSupportedBinding().cast(binding);
if (isMessage(classType)) {
String[] segments = classType.getQualifiedName();
- return new QualifiedNameSource(segments);
+ QualifiedName qualifiedName = QualifiedName.create(segments);
+ return new CppToProtobufMapping(qualifiedName, Message.class);
}
return null;
}
@@ -47,7 +50,7 @@
return "::google::protobuf::Message".equals(qualifiedNameAsText);
}
- @Override public Class<CPPClassType> supportedBindingType() {
+ @Override public Class<CPPClassType> typeOfSupportedBinding() {
return CPPClassType.class;
}
}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/CppToProtobufMapper.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/CppToProtobufMapper.java
new file mode 100644
index 0000000..8f5f919
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/CppToProtobufMapper.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012 Google Inc.
+ *
+ * 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 com.google.eclipse.protobuf.cdt.mapping;
+
+import static com.google.common.collect.Maps.newHashMap;
+
+import java.util.Map;
+
+import org.eclipse.cdt.core.dom.ast.IBinding;
+
+import com.google.inject.Singleton;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+@Singleton public class CppToProtobufMapper {
+ private final Map<Class<? extends IBinding>, IBindingMappingStrategy<?>> strategies = newHashMap();
+
+ public CppToProtobufMapper() {
+ register(new ClassMappingStrategy());
+ register(new EnumMappingStrategy());
+ }
+
+ private void register(IBindingMappingStrategy<?> strategy) {
+ strategies.put(strategy.typeOfSupportedBinding(), strategy);
+ }
+
+ /**
+ * Creates a <code>{@link CppToProtobufMapping}</code> from the C++ element whose name is described by the given
+ * {@code IBinding}.
+ * @param binding describes the name of a C++ element.
+ * @return a {@code ProtobufElementLookupInfo}, or {@code null} if the given binding does not correspond to a C++
+ * element that can be traced back to a protocol buffer element.
+ */
+ public CppToProtobufMapping createMappingFrom(IBinding binding) {
+ IBindingMappingStrategy<?> strategy = strategies.get(binding.getClass());
+ return (strategy != null) ? strategy.createMappingFrom(binding) : null;
+ }
+}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/CppToProtobufMapping.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/CppToProtobufMapping.java
new file mode 100644
index 0000000..695d380
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/CppToProtobufMapping.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012 Google Inc.
+ *
+ * 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 com.google.eclipse.protobuf.cdt.mapping;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.xtext.naming.QualifiedName;
+
+/**
+ * Information of the protocol buffer element obtained from a generated C++ element.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class CppToProtobufMapping {
+ private final QualifiedName qualifiedName;
+ private final Class<? extends EObject> type;
+
+ CppToProtobufMapping(QualifiedName qualifiedName, Class<? extends EObject> type) {
+ this.qualifiedName = qualifiedName;
+ this.type = type;
+ }
+
+ /**
+ * Returns the possible qualified name of the protocol buffer element.
+ * @return the possible qualified name of the protocol buffer element.
+ */
+ public QualifiedName qualifiedName() {
+ return qualifiedName;
+ }
+
+ /**
+ * Returns the type of the protocol buffer element.
+ * @return the type of the protocol buffer element.
+ */
+ public Class<? extends EObject> type() {
+ return type;
+ }
+}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/EnumMappingStrategy.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/EnumMappingStrategy.java
new file mode 100644
index 0000000..9c0edef
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/EnumMappingStrategy.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012 Google Inc.
+ *
+ * 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 com.google.eclipse.protobuf.cdt.mapping;
+
+import org.eclipse.cdt.core.dom.ast.IBinding;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPEnumeration;
+import org.eclipse.xtext.naming.QualifiedName;
+
+import com.google.eclipse.protobuf.protobuf.Enum;
+import com.google.inject.Singleton;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+@SuppressWarnings("restriction")
+@Singleton class EnumMappingStrategy implements IBindingMappingStrategy<CPPEnumeration> {
+
+ @Override public CppToProtobufMapping createMappingFrom(IBinding binding) {
+ CPPEnumeration enumeration = typeOfSupportedBinding().cast(binding);
+ String[] segments = enumeration.getQualifiedName();
+ QualifiedName qualifiedName = QualifiedName.create(segments);
+ return new CppToProtobufMapping(qualifiedName, Enum.class);
+ }
+
+ @Override public Class<CPPEnumeration> typeOfSupportedBinding() {
+ return CPPEnumeration.class;
+ }
+}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/IBindingMappingStrategy.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/IBindingMappingStrategy.java
new file mode 100644
index 0000000..c57b3d7
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/IBindingMappingStrategy.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2012 Google Inc.
+ *
+ * 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 com.google.eclipse.protobuf.cdt.mapping;
+
+import org.eclipse.cdt.core.dom.ast.IBinding;
+
+/**
+ * Derives a <code>{@link CppToProtobufMapping}</code> from the C++ element whose name is described by the given
+ * {@code IBinding}.
+ * @param <T> the type of {@code IBinding} supported.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+interface IBindingMappingStrategy <T extends IBinding> {
+ CppToProtobufMapping createMappingFrom(IBinding binding);
+
+ Class<T> typeOfSupportedBinding();
+}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/matching/ComplexTypeMatcherStrategy.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/matching/ComplexTypeMatcherStrategy.java
new file mode 100644
index 0000000..6302468
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/matching/ComplexTypeMatcherStrategy.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012 Google Inc.
+ *
+ * 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 com.google.eclipse.protobuf.cdt.matching;
+
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.xtext.naming.IQualifiedNameConverter;
+import org.eclipse.xtext.resource.*;
+
+import com.google.eclipse.protobuf.cdt.mapping.CppToProtobufMapping;
+import com.google.eclipse.protobuf.protobuf.*;
+import com.google.eclipse.protobuf.protobuf.Enum;
+import com.google.eclipse.protobuf.resource.ResourceDescriptions;
+import com.google.inject.Inject;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+class ComplexTypeMatcherStrategy implements ProtobufElementMatcherStrategy {
+ @Inject private IQualifiedNameConverter converter;
+ @Inject private ResourceDescriptions descriptions;
+
+ @Override public URI findUriOfMatchingProtobufElement(IResourceDescription resource, CppToProtobufMapping mapping) {
+ String qualifiedNameAsText = converter.toString(mapping.qualifiedName());
+ String regex = Pattern.quote(qualifiedNameAsText.replaceAll("_", "."));
+ Pattern pattern = Pattern.compile(regex);
+ List<IEObjectDescription> matches = descriptions.matchingQualifiedNames(resource, pattern);
+ if (matches.size() == 1) {
+ return matches.get(0).getEObjectURI();
+ }
+ return null;
+ }
+
+ @Override public boolean canHandle(Class<? extends EObject> protobufElementType) {
+ return protobufElementType.equals(Message.class) || protobufElementType.equals(Enum.class);
+ }
+}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/matching/ProtobufElementMatcher.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/matching/ProtobufElementMatcher.java
new file mode 100644
index 0000000..48e0e7c
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/matching/ProtobufElementMatcher.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012 Google Inc.
+ *
+ * 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 com.google.eclipse.protobuf.cdt.matching;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.xtext.resource.IResourceDescription;
+
+import com.google.eclipse.protobuf.cdt.mapping.CppToProtobufMapping;
+import com.google.inject.Inject;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class ProtobufElementMatcher {
+ @Inject private ComplexTypeMatcherStrategy complexTypeMatcherStrategy;
+
+ /**
+ * Returns the URI of the protocol buffer element in the given resource, whose qualified name matches the one in the
+ * given <code>{@link CppToProtobufMapping}</code>.
+ * @param resource describes the contents of a .proto file.
+ * @param mapping information of the protocol buffer element to look for.
+ * @return the found URI, or {@code null} if it was not possible to find a matching protocol buffer element.
+ */
+ public URI findUriOfMatchingProtobufElement(IResourceDescription resource, CppToProtobufMapping mapping) {
+ if (complexTypeMatcherStrategy.canHandle(mapping.type())) {
+ return complexTypeMatcherStrategy.findUriOfMatchingProtobufElement(resource, mapping);
+ }
+ return null;
+ }
+}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/matching/ProtobufElementMatcherStrategy.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/matching/ProtobufElementMatcherStrategy.java
new file mode 100644
index 0000000..95326a8
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/matching/ProtobufElementMatcherStrategy.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2012 Google Inc.
+ *
+ * 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 com.google.eclipse.protobuf.cdt.matching;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.xtext.resource.IResourceDescription;
+
+import com.google.eclipse.protobuf.cdt.mapping.CppToProtobufMapping;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+interface ProtobufElementMatcherStrategy {
+ URI findUriOfMatchingProtobufElement(IResourceDescription resource, CppToProtobufMapping mapping);
+
+ boolean canHandle(Class<? extends EObject> protobufElementType);
+}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/path/ProtoFilePathFinder.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/path/ProtoFilePaths.java
similarity index 85%
rename from com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/path/ProtoFilePathFinder.java
rename to com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/path/ProtoFilePaths.java
index fd25b97..3f69641 100644
--- a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/path/ProtoFilePathFinder.java
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/path/ProtoFilePaths.java
@@ -24,30 +24,27 @@
import com.google.inject.Inject;
/**
- * Finds the path of a .proto file, given the path of the generated C++ header file.
+ * Utility methods related to paths of .proto files.
*
* @author alruiz@google.com (Alex Ruiz)
*/
-public class ProtoFilePathFinder {
+public class ProtoFilePaths {
private static final String PATH_SEPARATOR = new String(new char[] { SEPARATOR });
@Inject private IPreferenceStoreAccess storeAccess;
/**
* Returns the path of the .proto file used as source of the generated C++ header file.
- * @param file the given file.
+ * @param cppHeaderFile the generated C++ header file.
* @return the path of the .proto file used as source of the generated C++ header file, or {@code null} if the given
* file is not a C++ header file or if C++ code generation is not enabled in the proto editor.
*/
- public IPath findProtoFilePath(IFile file) {
- IPath headerFilePath = file.getFullPath();
- if (!"h".equals(headerFilePath.getFileExtension())) {
- return null;
- }
- IPath cppOutputDirectory = cppOutputDirectory(file.getProject());
+ public IPath protoFilePath(IFile cppHeaderFile) {
+ IPath cppOutputDirectory = cppOutputDirectory(cppHeaderFile.getProject());
if (cppOutputDirectory == null) {
return null;
}
+ IPath headerFilePath = cppHeaderFile.getFullPath();
List<String> newPathSegments = newArrayList(headerFilePath.segments());
for (int i = 0; i < headerFilePath.segmentCount() - 1; i++) {
newPathSegments.remove(0);
@@ -57,7 +54,7 @@
}
int fileNameIndex = newPathSegments.size() - 1;
String fileName = newPathSegments.get(fileNameIndex);
- newPathSegments.set(fileNameIndex, fileName.replace("pb.h", "proto"));
+ newPathSegments.set(fileNameIndex, fileName.replace(".pb.h", ".proto"));
return new Path(concat(PATH_SEPARATOR, newPathSegments));
}
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/util/IPaths_areReferringToSameFile_Tests.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/util/IPaths_areReferringToSameFile_Tests.java
new file mode 100644
index 0000000..62a7d42
--- /dev/null
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/util/IPaths_areReferringToSameFile_Tests.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012 Google Inc.
+ *
+ * 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 com.google.eclipse.protobuf.util;
+
+import static org.junit.Assert.*;
+
+import org.eclipse.core.runtime.*;
+import org.eclipse.emf.common.util.URI;
+import org.junit.*;
+
+/**
+ * Tests for <code>{@link IPaths#areReferringToSameFile(IPath, URI)}</code>
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class IPaths_areReferringToSameFile_Tests {
+ private IPaths paths;
+
+ @Before public void setUp() {
+ paths = new IPaths();
+ }
+
+ @Test public void should_return_true_if_both_have_exactly_equal_segments() {
+ String pathValue = "/usr/local/google/proto";
+ IPath path = new Path(pathValue);
+ URI uri = URI.createPlatformResourceURI(pathValue, false);
+ assertTrue(paths.areReferringToSameFile(path, uri));
+ }
+
+ @Test public void should_return_true_if_path_is_subset_of_URI() {
+ IPath path = new Path("/google/proto");
+ URI uri = URI.createPlatformResourceURI("/usr/local/google/proto", false);
+ assertTrue(paths.areReferringToSameFile(path, uri));
+ }
+
+ @Test public void should_return_false_if_last_segments_in_path_and_URI_are_not_equal() {
+ IPath path = new Path("/usr/local/google/proto");
+ URI uri = URI.createPlatformResourceURI("/usr/local/google/cpp", false);
+ assertFalse(paths.areReferringToSameFile(path, uri));
+ }
+}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/ProtobufQualifiedNameConverter.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/ProtobufQualifiedNameConverter.java
index b0321cb..ecc2601 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/ProtobufQualifiedNameConverter.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/naming/ProtobufQualifiedNameConverter.java
@@ -10,19 +10,20 @@
import static org.eclipse.xtext.util.Strings.isEmpty;
-import com.google.eclipse.protobuf.util.Strings;
+import java.util.regex.Pattern;
import org.eclipse.xtext.naming.IQualifiedNameConverter.DefaultImpl;
import org.eclipse.xtext.naming.*;
-import java.util.regex.Pattern;
+import com.google.eclipse.protobuf.util.Strings;
+import com.google.inject.Singleton;
/**
* Provides support for multi-line qualified names.
*
* @author alruiz@google.com (Alex Ruiz)
*/
-public class ProtobufQualifiedNameConverter extends DefaultImpl {
+@Singleton public class ProtobufQualifiedNameConverter extends DefaultImpl {
private final Pattern delimiterPattern = Pattern.compile(delimiterPlusWhitespace());
private String delimiterPlusWhitespace() {
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/resource/ResourceDescriptions.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/resource/ResourceDescriptions.java
index 14a93f6..b0416fb 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/resource/ResourceDescriptions.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/resource/ResourceDescriptions.java
@@ -8,11 +8,17 @@
*/
package com.google.eclipse.protobuf.resource;
+import static com.google.common.collect.Lists.newArrayList;
+import static java.util.Collections.unmodifiableList;
+
+import java.util.List;
+import java.util.regex.*;
+
import org.eclipse.emf.common.util.URI;
-import org.eclipse.xtext.naming.QualifiedName;
+import org.eclipse.xtext.naming.*;
import org.eclipse.xtext.resource.*;
-import com.google.inject.Singleton;
+import com.google.inject.*;
/**
* Utility methods related to <code>{@link IResourceDescription}</code>s.
@@ -20,6 +26,8 @@
* @author alruiz@google.com (Alex Ruiz)
*/
@Singleton public class ResourceDescriptions {
+ @Inject private IQualifiedNameConverter converter;
+
/**
* Finds the URI of a model object in the given resource whose qualified name matches the given one.
* @param resource the given resource.
@@ -36,4 +44,16 @@
}
return null;
}
+
+ public List<IEObjectDescription> matchingQualifiedNames(IResourceDescription resource, Pattern pattern) {
+ List<IEObjectDescription> descriptions = newArrayList();
+ for (IEObjectDescription exported : resource.getExportedObjects()) {
+ QualifiedName qualifiedName = exported.getQualifiedName();
+ Matcher matcher = pattern.matcher(converter.toString(qualifiedName));
+ if (matcher.matches()) {
+ descriptions.add(exported);
+ }
+ }
+ return unmodifiableList(descriptions);
+ }
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/IPaths.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/IPaths.java
index 3cc88de..1b9ac5c 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/IPaths.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/util/IPaths.java
@@ -21,7 +21,6 @@
* @author alruiz@google.com (Alex Ruiz)
*/
@Singleton public class IPaths {
-
/**
* Indicates whether the given path and URI refer to the same file.
* @param p the given path.
@@ -29,13 +28,10 @@
* @return {@code true} if the given path and URI refer to the same file, {@code false} otherwise.
*/
public boolean areReferringToSameFile(IPath p, URI u) {
- // TODO test
int pIndex = p.segmentCount() - 1;
int uIndex = u.segmentCount() - 1;
while (pIndex >= 0 && uIndex >= 0) {
- String pSegment = p.segment(pIndex--);
- String uSegment = u.segment(uIndex--);
- if (!equal(pSegment, uSegment)) {
+ if (!equal(p.segment(pIndex--), u.segment(uIndex--))) {
return false;
}
}