In progress: [Issue 199] Add ability to navigate to proto element from
generated C++ code.
* Added support for nested messages.
* Code cleanup.
* Added tests.
diff --git a/com.google.eclipse.protobuf.cdt.test/.classpath b/com.google.eclipse.protobuf.cdt.test/.classpath
new file mode 100644
index 0000000..ad32c83
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt.test/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/com.google.eclipse.protobuf.cdt.test/.gitignore b/com.google.eclipse.protobuf.cdt.test/.gitignore
new file mode 100644
index 0000000..40a85ff
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt.test/.gitignore
@@ -0,0 +1 @@
+/.settings
diff --git a/com.google.eclipse.protobuf.cdt.test/.project b/com.google.eclipse.protobuf.cdt.test/.project
new file mode 100644
index 0000000..5c0fd35
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt.test/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>com.google.eclipse.protobuf.cdt.test</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/com.google.eclipse.protobuf.cdt.test/META-INF/MANIFEST.MF b/com.google.eclipse.protobuf.cdt.test/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..09d731b
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt.test/META-INF/MANIFEST.MF
@@ -0,0 +1,10 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Unit tests for com.google.eclipse.protobuf.cdt
+Bundle-SymbolicName: com.google.eclipse.protobuf.cdt.test
+Bundle-Version: 1.0.0.qualifier
+Bundle-Vendor: Google, Inc.
+Fragment-Host: com.google.eclipse.protobuf.cdt;bundle-version="1.0.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Require-Bundle: org.junit;bundle-version="4.8.2",
+ org.mockito;bundle-version="1.8.5"
diff --git a/com.google.eclipse.protobuf.cdt.test/build.properties b/com.google.eclipse.protobuf.cdt.test/build.properties
new file mode 100644
index 0000000..34d2e4d
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt.test/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/actions/ClassTypeQualifiedNameBuilder_createQualifiedNamesFrom_Test.java b/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/actions/ClassTypeQualifiedNameBuilder_createQualifiedNamesFrom_Test.java
new file mode 100644
index 0000000..1fcc16d
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/actions/ClassTypeQualifiedNameBuilder_createQualifiedNamesFrom_Test.java
@@ -0,0 +1,73 @@
+/*
+ * 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 com.google.eclipse.protobuf.junit.core.UnitTestModule.unitTestModule;
+import static com.google.eclipse.protobuf.junit.core.XtextRule.overrideRuntimeModuleWith;
+import static java.util.Collections.singletonList;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.*;
+
+import java.util.List;
+
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
+import org.eclipse.cdt.internal.core.dom.parser.c.CASTName;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.*;
+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.inject.Inject;
+
+/**
+ * Tests for <code>{@link ClassTypeQualifiedNameBuilder#createQualifiedNamesFrom(CPPClassType)}</code>
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+@SuppressWarnings("restriction")
+public class ClassTypeQualifiedNameBuilder_createQualifiedNamesFrom_Test {
+ @Rule public XtextRule xtext = overrideRuntimeModuleWith(unitTestModule(), new ProtobufCdtModule(), new TestModule());
+
+ @Inject private CPPClassType classType;
+ @Inject private QualifiedNameFactory qualifiedNameFactory;
+ @Inject private ClassTypeQualifiedNameBuilder nameBuilder;
+
+ @Test public void should_return_qualified_names_for_class_type() {
+ expectClassTypeToExtendProtoMessage();
+ String[] segments = { "com", "google", "proto", "Test" };
+ when(classType.getQualifiedName()).thenReturn(segments);
+ List<QualifiedName> expected = singletonList(QualifiedName.create(segments));
+ when(qualifiedNameFactory.createQualifiedNamesForComplexType(segments)).thenReturn(expected);
+ assertThat(nameBuilder.createQualifiedNamesFrom(classType), equalTo(expected));
+ }
+
+ private void expectClassTypeToExtendProtoMessage() {
+ ICPPBase base = mock(ICPPBase.class);
+ when(classType.getBases()).thenReturn(new ICPPBase[] { base });
+ when(base.getBaseClassSpecifierName()).thenReturn(createQualifiedName("google", "protobuf", "Message"));
+ }
+
+ private CPPASTQualifiedName createQualifiedName(String...segments) {
+ CPPASTQualifiedName qualifiedName = new CPPASTQualifiedName();
+ for (String segment : segments) {
+ qualifiedName.addName(new CASTName(segment.toCharArray()));
+ }
+ qualifiedName.setFullyQualified(true);
+ return qualifiedName;
+ }
+
+ private static class TestModule extends AbstractTestModule {
+ @Override protected void configure() {
+ mockAndBind(CPPClassType.class);
+ mockAndBind(QualifiedNameFactory.class);
+ }
+ }
+}
\ No newline at end of file
diff --git a/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/actions/QualifiedNameFactory_createQualifiedNamesForComplexType_Test.java b/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/actions/QualifiedNameFactory_createQualifiedNamesForComplexType_Test.java
new file mode 100644
index 0000000..f21019f
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/actions/QualifiedNameFactory_createQualifiedNamesForComplexType_Test.java
@@ -0,0 +1,51 @@
+/*
+ * 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 com.google.eclipse.protobuf.cdt.junit.QualifiedNamesContain.containOnly;
+import static com.google.eclipse.protobuf.junit.core.UnitTestModule.unitTestModule;
+import static com.google.eclipse.protobuf.junit.core.XtextRule.overrideRuntimeModuleWith;
+import static org.junit.Assert.assertThat;
+
+import java.util.List;
+
+import org.eclipse.xtext.naming.QualifiedName;
+import org.junit.*;
+
+import com.google.eclipse.protobuf.cdt.ProtobufCdtModule;
+import com.google.eclipse.protobuf.junit.core.XtextRule;
+import com.google.inject.Inject;
+
+/**
+ * Tests for <code>{@link QualifiedNameFactory#createQualifiedNamesForComplexType(String[])}</code>
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class QualifiedNameFactory_createQualifiedNamesForComplexType_Test {
+ @Rule public XtextRule xtext = overrideRuntimeModuleWith(unitTestModule(), new ProtobufCdtModule());
+
+ @Inject private QualifiedNameFactory qualifiedNameFactory;
+
+ @Test public void should_return_single_qualified_name_for_top_level_type() {
+ String[] segments = { "com", "google", "proto", "Test" };
+ List<QualifiedName> qualifiedNames = qualifiedNameFactory.createQualifiedNamesForComplexType(segments);
+ assertThat(qualifiedNames, containOnly("com.google.proto.Test"));
+ }
+
+ @Test public void should_split_in_underscore_for_one_level_nesting() {
+ String[] segments = { "com", "google", "proto", "Test_Inner" };
+ List<QualifiedName> qualifiedNames = qualifiedNameFactory.createQualifiedNamesForComplexType(segments);
+ assertThat(qualifiedNames, containOnly("com.google.proto.Test_Inner", "com.google.proto.Test.Inner"));
+ }
+
+ @Test public void should_split_in_underscore_for_multiple_level_nesting() {
+ String[] segments = { "com", "google", "proto", "Test_Inner_Inner" };
+ List<QualifiedName> qualifiedNames = qualifiedNameFactory.createQualifiedNamesForComplexType(segments);
+ assertThat(qualifiedNames, containOnly("com.google.proto.Test_Inner_Inner", "com.google.proto.Test.Inner.Inner"));
+ }}
diff --git a/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/junit/QualifiedNamesContain.java b/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/junit/QualifiedNamesContain.java
new file mode 100644
index 0000000..e2f213a
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/junit/QualifiedNamesContain.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.junit;
+
+import static com.google.common.collect.Lists.newArrayList;
+
+import java.util.List;
+
+import org.eclipse.xtext.naming.QualifiedName;
+import org.hamcrest.*;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class QualifiedNamesContain extends BaseMatcher<List<QualifiedName>> {
+ private final List<String> qualifiedNames;
+
+ public static QualifiedNamesContain containOnly(String...qualifiedNames) {
+ return new QualifiedNamesContain(qualifiedNames);
+ }
+
+ private QualifiedNamesContain(String[] qualifiedNames) {
+ this.qualifiedNames = newArrayList(qualifiedNames);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override public boolean matches(Object item) {
+ if (!(item instanceof List)) {
+ return false;
+ }
+ List<String> copy = newArrayList(qualifiedNames);
+ List<QualifiedName> actualNames = (List<QualifiedName>) item;
+ for (QualifiedName actual : actualNames) {
+ String expected = actual.toString();
+ copy.remove(expected);
+ }
+ return copy.isEmpty();
+ }
+
+ @Override public void describeTo(Description description) {
+ description.appendValue(qualifiedNames);
+ }
+}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ClassTypeQualifiedNameBuilder.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ClassTypeQualifiedNameBuilder.java
index b521a6a..907fa26 100644
--- a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ClassTypeQualifiedNameBuilder.java
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ClassTypeQualifiedNameBuilder.java
@@ -8,26 +8,28 @@
*/
package com.google.eclipse.protobuf.cdt.actions;
-import static java.util.Collections.*;
+import static java.util.Collections.emptyList;
-import java.util.Collection;
+import java.util.List;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.internal.core.dom.parser.cpp.*;
import org.eclipse.xtext.naming.QualifiedName;
-import com.google.inject.Singleton;
+import com.google.inject.*;
/**
* @author alruiz@google.com (Alex Ruiz)
*/
@SuppressWarnings("restriction")
@Singleton class ClassTypeQualifiedNameBuilder {
- public Collection<QualifiedName> createQualifiedNamesFrom(CPPClassType classType) {
+ @Inject QualifiedNameFactory qualifiedNameFactory;
+
+ public List<QualifiedName> createQualifiedNamesFrom(CPPClassType classType) {
if (isMessage(classType)) {
String[] segments = classType.getQualifiedName();
- return singletonList(QualifiedName.create(segments));
+ return qualifiedNameFactory.createQualifiedNamesForComplexType(segments);
}
return emptyList();
}
@@ -45,7 +47,7 @@
if (!qualifiedName.isFullyQualified()) {
return false;
}
- String rawSignature = qualifiedName.getRawSignature();
- return "::google::protobuf::Message".equals(rawSignature);
+ String qualifiedNameAsText = qualifiedName.toString();
+ return "::google::protobuf::Message".equals(qualifiedNameAsText);
}
}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ModelObjectDefinitionQueryBuilder.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ModelObjectDefinitionQueryBuilder.java
index dcb0e0e..c5f9320 100644
--- a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ModelObjectDefinitionQueryBuilder.java
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/ModelObjectDefinitionQueryBuilder.java
@@ -8,14 +8,12 @@
*/
package com.google.eclipse.protobuf.cdt.actions;
-import static com.google.common.collect.Lists.newArrayList;
import static com.google.eclipse.protobuf.ui.editor.ModelObjectDefinitionNavigator.Query.query;
import static java.lang.Math.max;
-import static java.util.Collections.emptyList;
import static org.eclipse.cdt.internal.ui.editor.ASTProvider.WAIT_NO;
import static org.eclipse.core.runtime.Status.*;
-import java.util.*;
+import java.util.Collection;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.cdt.core.dom.ast.*;
@@ -40,16 +38,16 @@
@Inject private ClassTypeQualifiedNameBuilder nameBuilder;
@Inject private ProtoFilePathFinder pathFinder;
- Collection<Query> buildQueries(final IEditorPart editor, final ITextSelection selection) {
+ Query buildQuery(final IEditorPart editor, final ITextSelection selection) {
final IPath protoFilePath = pathFinder.findProtoFilePath(editor);
if (protoFilePath == null) {
- return emptyList();
+ return null;
}
IWorkingCopy workingCopy = CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(editor.getEditorInput());
if (workingCopy == null) {
- return emptyList();
+ return null;
}
- final AtomicReference<Collection<Query>> queriesReference = new AtomicReference<Collection<Query>>();
+ 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 {
@@ -70,11 +68,7 @@
if (qualifiedNames.isEmpty()) {
return CANCEL_STATUS;
}
- List<Query> queries = newArrayList();
- for (QualifiedName qualifiedName : qualifiedNames) {
- queries.add(query(qualifiedName, protoFilePath));
- }
- queriesReference.set(queries);
+ queriesReference.set(query(qualifiedNames, protoFilePath));
return OK_STATUS;
}
}
@@ -82,7 +76,7 @@
}
});
if (status == CANCEL_STATUS) {
- return emptyList();
+ return null;
}
return queriesReference.get();
}
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
index a46878c..4b9ebe3 100644
--- 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
@@ -10,8 +10,6 @@
import static org.eclipse.core.runtime.Status.OK_STATUS;
-import java.util.Collection;
-
import org.eclipse.core.runtime.*;
import org.eclipse.ui.progress.UIJob;
@@ -25,15 +23,10 @@
class NavigationJobs {
@Inject private ModelObjectDefinitionNavigator navigator;
- void scheduleUsing(final Collection<Query> queries) {
+ void scheduleUsing(final Query query) {
UIJob job = new UIJob("Navigating to .proto file") {
@Override public IStatus runInUIThread(IProgressMonitor monitor) {
- for (Query query : queries) {
- IStatus result = navigator.navigateToDefinition(query);
- if (result.equals(OK_STATUS)) {
- break;
- }
- }
+ navigator.navigateToDefinition(query);
return OK_STATUS;
}
};
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 0dd8c35..25201bc 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,8 +8,6 @@
*/
package com.google.eclipse.protobuf.cdt.actions;
-import java.util.Collection;
-
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.ISelection;
@@ -34,9 +32,9 @@
if (editor == null || selection == null) {
return;
}
- Collection<Query> queries = queryBuilder.buildQueries(editor, selection);
- if (!queries.isEmpty()) {
- navigationJobs.scheduleUsing(queries);
+ Query query = queryBuilder.buildQuery(editor, selection);
+ if (query != null) {
+ navigationJobs.scheduleUsing(query);
}
}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/QualifiedNameBuilder.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/QualifiedNameBuilder.java
deleted file mode 100644
index 2afab3e..0000000
--- a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/QualifiedNameBuilder.java
+++ /dev/null
@@ -1,20 +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 org.eclipse.cdt.internal.core.dom.parser.ASTNode;
-import org.eclipse.xtext.naming.QualifiedName;
-
-/**
- * @author alruiz@google.com (Alex Ruiz)
- */
-@SuppressWarnings("restriction")
-interface QualifiedNameBuilder {
- QualifiedName createQualifiedNameFrom(ASTNode node);
-}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/QualifiedNameFactory.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/QualifiedNameFactory.java
new file mode 100644
index 0000000..98389a8
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/actions/QualifiedNameFactory.java
@@ -0,0 +1,41 @@
+/*
+ * 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 com.google.common.collect.Lists.newArrayList;
+import static java.util.Collections.unmodifiableList;
+
+import java.util.List;
+
+import org.eclipse.xtext.naming.QualifiedName;
+
+import com.google.eclipse.protobuf.model.util.QualifiedNames;
+import com.google.inject.*;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+@Singleton class QualifiedNameFactory {
+ @Inject private QualifiedNames qualifiedNames;
+
+ List<QualifiedName> createQualifiedNamesForComplexType(String[] segments) {
+ List<QualifiedName> names = newArrayList();
+ names.add(QualifiedName.create(segments));
+ int lastSegmentIndex = segments.length - 1;
+ String messageName = segments[lastSegmentIndex];
+ if (messageName.contains("_")) {
+ String[] hierarchicalNames = messageName.split("_");
+ List<String> newSegments = newArrayList(segments);
+ newSegments.remove(lastSegmentIndex);
+ newSegments.addAll(newArrayList(hierarchicalNames));
+ names.add(qualifiedNames.createFqn(newSegments));
+ }
+ return unmodifiableList(names);
+ }
+}
diff --git a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/resource/ModelObjectLocationLookup_findModelObjectUri_Test.java b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/resource/ModelObjectLocationLookup_findModelObjectUri_Test.java
index 51bdba7..afa5d16 100644
--- a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/resource/ModelObjectLocationLookup_findModelObjectUri_Test.java
+++ b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/resource/ModelObjectLocationLookup_findModelObjectUri_Test.java
@@ -10,6 +10,7 @@
import static com.google.eclipse.protobuf.junit.core.IntegrationTestModule.integrationTestModule;
import static com.google.eclipse.protobuf.junit.core.XtextRule.overrideRuntimeModuleWith;
+import static java.util.Collections.singletonList;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.*;
@@ -26,7 +27,7 @@
import com.google.inject.Inject;
/**
- * Tests for <code>{@link ModelObjectLocationLookup#findModelObjectUri(QualifiedName, IPath)}</code>
+ * Tests for <code>{@link ModelObjectLocationLookup#findModelObjectUri(Iterable, IPath)}</code>
*
* @author alruiz@google.com (Alex Ruiz)
*/
@@ -46,8 +47,8 @@
@Test public void should_find_URI_of_model_object_given_its_qualified_name() {
XtextResource resource = xtext.resource();
addToXtextIndex(resource);
- QualifiedName qualifiedName = fqnConverter.toQualifiedName("com.google.proto.Type");
- URI foundUri = lookup.findModelObjectUri(qualifiedName, pathOf(resource));
+ Iterable<QualifiedName> qualifiedNames = singletonList(fqnConverter.toQualifiedName("com.google.proto.Type"));
+ URI foundUri = lookup.findModelObjectUri(qualifiedNames, pathOf(resource));
Enum anEnum = xtext.find("Type", Enum.class);
String fragment = resource.getURIFragment(anEnum);
URI expectedUri = resource.getURI().appendFragment(fragment);
@@ -64,8 +65,8 @@
// message Person {}
@Test public void should_return_null_if_file_name_is_equal_but_file_path_is_not() {
addToXtextIndex(xtext.resource());
- QualifiedName qualifiedName = fqnConverter.toQualifiedName("com.google.proto.Person");
- URI foundUri = lookup.findModelObjectUri(qualifiedName, new Path("/test/src/protos/mytestmodel.proto"));
+ Iterable<QualifiedName> qualifiedNames = singletonList(fqnConverter.toQualifiedName("com.google.proto.Person"));
+ URI foundUri = lookup.findModelObjectUri(qualifiedNames, new Path("/test/src/protos/mytestmodel.proto"));
assertNull(foundUri);
}
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/editor/ModelObjectDefinitionNavigator_navigateToDefinition_Test.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/editor/ModelObjectDefinitionNavigator_navigateToDefinition_Test.java
index 1c3b020..6213098 100644
--- a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/editor/ModelObjectDefinitionNavigator_navigateToDefinition_Test.java
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/editor/ModelObjectDefinitionNavigator_navigateToDefinition_Test.java
@@ -11,6 +11,7 @@
import static com.google.eclipse.protobuf.junit.core.UnitTestModule.unitTestModule;
import static com.google.eclipse.protobuf.junit.core.XtextRule.overrideRuntimeModuleWith;
import static com.google.eclipse.protobuf.ui.editor.ModelObjectDefinitionNavigator.Query.query;
+import static java.util.Collections.singletonList;
import static org.eclipse.core.runtime.Status.*;
import static org.eclipse.emf.common.util.URI.createURI;
import static org.hamcrest.core.IsEqual.equalTo;
@@ -50,17 +51,17 @@
@Test public void should_navigate_to_model_object_if_URI_is_found() {
URI uri = createURI("file:/usr/local/project/src/protos/test.proto");
- QualifiedName qualifiedName = fqnConverter.toQualifiedName("com.google.proto.Type");
- when(locationLookup.findModelObjectUri(qualifiedName, filePath)).thenReturn(uri);
- IStatus result = navigator.navigateToDefinition(query(qualifiedName, filePath));
+ Iterable<QualifiedName> qualifiedNames = singletonList(fqnConverter.toQualifiedName("com.google.proto.Type"));
+ when(locationLookup.findModelObjectUri(qualifiedNames, filePath)).thenReturn(uri);
+ IStatus result = navigator.navigateToDefinition(query(qualifiedNames, filePath));
assertThat(result, equalTo(OK_STATUS));
verify(editorOpener).open(uri, true);
}
@Test public void should_not_navigate_to_model_object_if_URI_is_not_found() {
- QualifiedName qualifiedName = fqnConverter.toQualifiedName("com.google.proto.Person");
- when(locationLookup.findModelObjectUri(qualifiedName, filePath)).thenReturn(null);
- IStatus result = navigator.navigateToDefinition(query(qualifiedName, filePath));
+ Iterable<QualifiedName> qualifiedNames = singletonList(fqnConverter.toQualifiedName("com.google.proto.Person"));
+ when(locationLookup.findModelObjectUri(qualifiedNames, filePath)).thenReturn(null);
+ IStatus result = navigator.navigateToDefinition(query(qualifiedNames, filePath));
assertThat(result, equalTo(CANCEL_STATUS));
verifyZeroInteractions(editorOpener);
}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/ModelObjectDefinitionNavigator.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/ModelObjectDefinitionNavigator.java
index 0a1c3c2..f0393c7 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/ModelObjectDefinitionNavigator.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/editor/ModelObjectDefinitionNavigator.java
@@ -8,6 +8,7 @@
*/
package com.google.eclipse.protobuf.ui.editor;
+import static com.google.common.collect.Lists.newLinkedList;
import static org.eclipse.core.runtime.Status.*;
import org.eclipse.core.runtime.*;
@@ -28,13 +29,13 @@
@Inject private IURIEditorOpener editorOpener;
/**
- * Navigates to the definition of the model object whose qualified name matches the given one. This method will open
- * the file containing the model object definition if necessary.
+ * Navigates to the definition of the model object whose qualified name matches any of the given ones. This method
+ * will open the file containing the model object definition if necessary.
* @param query information needed to find the object model to navigate to.
* @return the result of the operation.
*/
public IStatus navigateToDefinition(Query query) {
- URI uri = locationLookup.findModelObjectUri(query.qualifiedName, query.filePath);
+ URI uri = locationLookup.findModelObjectUri(query.qualifiedNames, query.filePath);
if (uri != null) {
editorOpener.open(uri, true);
return OK_STATUS;
@@ -48,22 +49,22 @@
* @author alruiz@google.com (Alex Ruiz)
*/
public static class Query {
- final QualifiedName qualifiedName;
+ final Iterable<QualifiedName> qualifiedNames;
final IPath filePath;
/**
* Creates a new <code>{@link Query}</code>, to be used by
* <code>{@link ModelObjectDefinitionNavigator#navigateToDefinition(Query)}</code>.
- * @param qualifiedName the qualified name to match.
+ * @param qualifiedNames all the possible qualified names the model object to look for may have.
* @param filePath the path and name of the file where to perform the lookup.
* @return the created {@code Query}.
*/
- public static Query query(QualifiedName qualifiedName, IPath filePath) {
- return new Query(qualifiedName, filePath);
+ public static Query query(Iterable<QualifiedName> qualifiedNames, IPath filePath) {
+ return new Query(qualifiedNames, filePath);
}
- private Query(QualifiedName qualifiedName, IPath filePath) {
- this.qualifiedName = qualifiedName;
+ private Query(Iterable<QualifiedName> qualifiedNames, IPath filePath) {
+ this.qualifiedNames = newLinkedList(qualifiedNames);
this.filePath = filePath;
}
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/resource/ModelObjectLocationLookup.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/resource/ModelObjectLocationLookup.java
index 83e093e..4c82a51 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/resource/ModelObjectLocationLookup.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/resource/ModelObjectLocationLookup.java
@@ -27,21 +27,23 @@
@Inject private IResourceDescriptions xtextIndex;
/**
- * Finds the URI of a model object whose qualified name matches the given one.
- * @param qualifiedName the qualified name to match.
+ * Finds the URI of a model object whose qualified name matches any of the given ones.
+ * @param qualifiedNames all the possible qualified names the model object to look for may have.
* @param filePath the path and name of the file where to perform the lookup.
- * @return the URI of a model object whose qualified name matches the given one, or {@code null} if a matching model
- * object cannot be found.
+ * @return the URI of a model object whose qualified name matches any of the given ones, or {@code null} if a
+ * matching model object cannot be found.
*/
- public URI findModelObjectUri(QualifiedName qualifiedName, IPath filePath) {
+ public URI findModelObjectUri(Iterable<QualifiedName> qualifiedNames, IPath filePath) {
for (IResourceDescription resourceDescription : xtextIndex.getAllResourceDescriptions()) {
URI resourceUri = resourceDescription.getURI();
if (paths.areReferringToSameFile(filePath, resourceUri)) {
// we found the resource we are looking for.
for (IEObjectDescription exported : resourceDescription.getExportedObjects()) {
QualifiedName modelObjectQualifiedName = exported.getQualifiedName();
- if (qualifiedName.equals(modelObjectQualifiedName)) {
- return exported.getEObjectURI();
+ for (QualifiedName qualifiedName : qualifiedNames) {
+ if (qualifiedName.equals(modelObjectQualifiedName)) {
+ return exported.getEObjectURI();
+ }
}
}
break;