Fixed: [Issue 167] Package scope resolution fails with nested types
diff --git a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/bugs/Issue167_PackageScopingWithNestedTypes_Test.java b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/bugs/Issue167_PackageScopingWithNestedTypes_Test.java
new file mode 100644
index 0000000..9fbaf66
--- /dev/null
+++ b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/bugs/Issue167_PackageScopingWithNestedTypes_Test.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2011 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.bugs;
+
+import static com.google.eclipse.protobuf.junit.IEObjectDescriptions.descriptionsIn;
+import static com.google.eclipse.protobuf.junit.core.Setups.integrationTestSetup;
+import static com.google.eclipse.protobuf.junit.core.XtextRule.createWith;
+import static com.google.eclipse.protobuf.junit.matchers.ContainNames.contain;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
+
+import com.google.eclipse.protobuf.junit.core.XtextRule;
+import com.google.eclipse.protobuf.protobuf.*;
+import com.google.eclipse.protobuf.scoping.ProtobufScopeProvider;
+
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.xtext.scoping.IScope;
+import org.junit.*;
+
+/**
+ * Tests fix for <a href="http://code.google.com/p/protobuf-dt/issues/detail?id=167">Issue 167</a>.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class Issue167_PackageScopingWithNestedTypes_Test {
+
+ private static EReference reference;
+
+ @BeforeClass public static void setUpOnce() {
+ reference = mock(EReference.class);
+ }
+
+ @Rule public XtextRule xtext = createWith(integrationTestSetup());
+
+ private ProtobufScopeProvider provider;
+
+ @Before public void setUp() {
+ provider = xtext.getInstanceOf(ProtobufScopeProvider.class);
+ }
+
+ // // Create file types.proto
+ //
+ // syntax = 'proto2';
+ // package com.google.proto.base.shared;
+ //
+ // message Outer {
+ // enum Type {
+ // ONE = 1;
+ // TWO = 2;
+ // }
+ // }
+
+ // syntax = "proto2";
+ // package com.google.proto.project.shared;
+ //
+ // import "types.proto";
+ //
+ // message Summary {
+ // repeated base.shared.Outer.Type type = 1;
+ // }
+ @Test public void should_include_package_intersection() {
+ MessageField field = xtext.find("type", " =", MessageField.class);
+ IScope scope = provider.scope_ComplexTypeLink_target((ComplexTypeLink) field.getType(), reference);
+ assertThat(descriptionsIn(scope), contain("base.shared.Outer.Type", "proto.base.shared.Outer.Type",
+ "google.proto.base.shared.Outer.Type",
+ "com.google.proto.base.shared.Outer.Type"));
+ }
+}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/PackageIntersectionDescriptions.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/PackageIntersectionDescriptions.java
index 42c174a..49a36fd 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/PackageIntersectionDescriptions.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/PackageIntersectionDescriptions.java
@@ -1,9 +1,10 @@
/*
* Copyright (c) 2011 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
- *
+ *
+ * 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.scoping;
@@ -12,12 +13,11 @@
import static org.eclipse.xtext.resource.EObjectDescription.create;
import com.google.eclipse.protobuf.model.util.*;
-import com.google.eclipse.protobuf.naming.NameResolver;
import com.google.eclipse.protobuf.protobuf.Package;
import com.google.inject.Inject;
import org.eclipse.emf.ecore.EObject;
-import org.eclipse.xtext.naming.QualifiedName;
+import org.eclipse.xtext.naming.*;
import org.eclipse.xtext.resource.IEObjectDescription;
import java.util.*;
@@ -29,19 +29,19 @@
@Inject private Packages packages;
@Inject private QualifiedNames qualifiedNames;
- @Inject private NameResolver nameResolver;
+ @Inject private IQualifiedNameProvider nameProvider;
// See issue 161
Collection<IEObjectDescription> intersection(Package fromImporter, Package fromImported, EObject e) {
if (fromImporter == null || fromImported == null) return emptySet();
- return intersection(segmentNames(fromImporter), segmentNames(fromImported), e);
+ return intersection2(segmentNames(fromImporter), segmentNames(fromImported), e);
}
-
+
private List<String> segmentNames(Package aPackage) {
return packages.segmentsOf(aPackage);
}
-
- private Collection<IEObjectDescription> intersection(List<String> packageInImporter, List<String> packageInImported,
+
+ private Collection<IEObjectDescription> intersection2(List<String> packageInImporter, List<String> packageInImported,
EObject e) {
int n1Count = packageInImporter.size();
int n2Count = packageInImported.size();
@@ -53,23 +53,16 @@
}
}
if (start == 0) return emptySet(); // no intersection found.
- List<String> intersection = new ArrayList<String>();
- intersection.add(nameResolver.nameOf(e));
Set<IEObjectDescription> descriptions = new HashSet<IEObjectDescription>();
- for (int i = n2Count - 1; i >= 0; i--) {
- if (i >= start) {
- intersection.add(0, packageInImported.get(i));
- continue;
- }
- if (i == start - 1) {
- descriptions.add(create(fqn(intersection), e));
- }
- intersection.add(0, packageInImported.get(i));
- descriptions.add(create(fqn(intersection), e));
+ QualifiedName fqn = nameProvider.getFullyQualifiedName(e);
+ List<String> segments = new ArrayList<String>(fqn.getSegments());
+ for (int i = 0; i < start; i++) {
+ segments.remove(0);
+ descriptions.add(create(fqn(segments), e));
}
return descriptions;
}
-
+
private QualifiedName fqn(List<String> segments) {
return qualifiedNames.createFqn(segments);
}