Activates importedNamespace scoping implementation.
Switches scoping implementation for grammar types ComplexTypeLink
and ExtensibleTypeLink from ProtobufScopeProvider to
ProtobufImportedNamepaceAwareLocalScopeProvider.
Change-Id: I0b9b2d567666622ca2e548f5733de685764d8c8d
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue157_GroupsShouldBeTypes_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue157_GroupsShouldBeTypes_Test.java
index 4b7fbdf..30a3943 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue157_GroupsShouldBeTypes_Test.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue157_GroupsShouldBeTypes_Test.java
@@ -9,11 +9,14 @@
package com.google.eclipse.protobuf.bugs;
import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.when;
import static com.google.eclipse.protobuf.junit.IEObjectDescriptions.descriptionsIn;
import static com.google.eclipse.protobuf.junit.core.IntegrationTestModule.integrationTestModule;
import static com.google.eclipse.protobuf.junit.core.XtextRule.overrideRuntimeModuleWith;
import static com.google.eclipse.protobuf.junit.matchers.ContainNames.contain;
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.COMPLEX_TYPE;
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.COMPLEX_TYPE_LINK;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.xtext.scoping.IScope;
@@ -47,8 +50,10 @@
// }
// }
@Test public void should_treat_groups_as_types() {
+ when(reference.getEReferenceType()).thenReturn(COMPLEX_TYPE);
+ when(reference.getEContainingClass()).thenReturn(COMPLEX_TYPE_LINK);
MessageField field = xtext.find("mygroup", MessageField.class);
- IScope scope = scopeProvider.scope_ComplexTypeLink_target((ComplexTypeLink) field.getType(), reference);
+ IScope scope = scopeProvider.getScope((ComplexTypeLink) field.getType(), reference);
assertThat(descriptionsIn(scope), contain("Root.MyGroup", "MyGroup"));
}
}
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue161_PackageScoping_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue161_PackageScoping_Test.java
index 6966b85..35ad6a2 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue161_PackageScoping_Test.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue161_PackageScoping_Test.java
@@ -9,17 +9,19 @@
package com.google.eclipse.protobuf.bugs;
import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.when;
import static com.google.eclipse.protobuf.junit.IEObjectDescriptions.descriptionsIn;
import static com.google.eclipse.protobuf.junit.core.IntegrationTestModule.integrationTestModule;
import static com.google.eclipse.protobuf.junit.core.XtextRule.overrideRuntimeModuleWith;
import static com.google.eclipse.protobuf.junit.matchers.ContainNames.contain;
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.COMPLEX_TYPE;
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.COMPLEX_TYPE_LINK;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.xtext.scoping.IScope;
import org.junit.Rule;
import org.junit.Test;
-
import com.google.eclipse.protobuf.junit.core.XtextRule;
import com.google.eclipse.protobuf.protobuf.ComplexTypeLink;
import com.google.eclipse.protobuf.protobuf.MessageField;
@@ -56,9 +58,11 @@
// repeated base.shared.Type type = 1;
// }
@Test public void should_include_package_intersection() {
+ when(reference.getEReferenceType()).thenReturn(COMPLEX_TYPE);
+ when(reference.getEContainingClass()).thenReturn(COMPLEX_TYPE_LINK);
MessageField field = xtext.find("type", " =", MessageField.class);
- IScope scope = scopeProvider.scope_ComplexTypeLink_target((ComplexTypeLink) field.getType(), reference);
+ IScope scope = scopeProvider.getScope((ComplexTypeLink) field.getType(), reference);
assertThat(descriptionsIn(scope), contain("base.shared.Type", "proto.base.shared.Type",
- "google.proto.base.shared.Type", "com.google.proto.base.shared.Type"));
+ "google.proto.base.shared.Type", "com.google.proto.base.shared.Type"));
}
}
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue167_PackageScopingWithNestedTypes_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue167_PackageScopingWithNestedTypes_Test.java
index 079dfa5..6357a39 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue167_PackageScopingWithNestedTypes_Test.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue167_PackageScopingWithNestedTypes_Test.java
@@ -9,17 +9,19 @@
package com.google.eclipse.protobuf.bugs;
import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.when;
import static com.google.eclipse.protobuf.junit.IEObjectDescriptions.descriptionsIn;
import static com.google.eclipse.protobuf.junit.core.IntegrationTestModule.integrationTestModule;
import static com.google.eclipse.protobuf.junit.core.XtextRule.overrideRuntimeModuleWith;
import static com.google.eclipse.protobuf.junit.matchers.ContainNames.contain;
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.COMPLEX_TYPE;
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.COMPLEX_TYPE_LINK;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.xtext.scoping.IScope;
import org.junit.Rule;
import org.junit.Test;
-
import com.google.eclipse.protobuf.junit.core.XtextRule;
import com.google.eclipse.protobuf.protobuf.ComplexTypeLink;
import com.google.eclipse.protobuf.protobuf.MessageField;
@@ -58,10 +60,12 @@
// repeated base.shared.Outer.Type type = 1;
// }
@Test public void should_include_package_intersection() {
+ when(reference.getEReferenceType()).thenReturn(COMPLEX_TYPE);
+ when(reference.getEContainingClass()).thenReturn(COMPLEX_TYPE_LINK);
MessageField field = xtext.find("type", " =", MessageField.class);
- IScope scope = scopeProvider.scope_ComplexTypeLink_target((ComplexTypeLink) field.getType(), reference);
+ IScope scope = scopeProvider.getScope((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"));
+ "google.proto.base.shared.Outer.Type",
+ "com.google.proto.base.shared.Outer.Type"));
}
}
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue187_ExposeAllTypesInDescriptor_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue187_ExposeAllTypesInDescriptor_Test.java
index d151639..2769fc3 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue187_ExposeAllTypesInDescriptor_Test.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue187_ExposeAllTypesInDescriptor_Test.java
@@ -9,17 +9,19 @@
package com.google.eclipse.protobuf.bugs;
import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.when;
import static com.google.eclipse.protobuf.junit.IEObjectDescriptions.descriptionsIn;
import static com.google.eclipse.protobuf.junit.core.IntegrationTestModule.integrationTestModule;
import static com.google.eclipse.protobuf.junit.core.XtextRule.overrideRuntimeModuleWith;
import static com.google.eclipse.protobuf.junit.matchers.ContainNames.contain;
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.COMPLEX_TYPE;
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.COMPLEX_TYPE_LINK;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.xtext.scoping.IScope;
import org.junit.Rule;
import org.junit.Test;
-
import com.google.eclipse.protobuf.junit.core.XtextRule;
import com.google.eclipse.protobuf.protobuf.ComplexTypeLink;
import com.google.eclipse.protobuf.protobuf.MessageField;
@@ -46,9 +48,11 @@
// optional google.protobuf.FieldDescriptorProto.Type type = 1;
// }
@Test public void should_see_types_from_descriptor_other_than_Messages() {
+ when(reference.getEReferenceType()).thenReturn(COMPLEX_TYPE);
+ when(reference.getEContainingClass()).thenReturn(COMPLEX_TYPE_LINK);
MessageField field = xtext.find("type", MessageField.class);
TypeLink type = field.getType();
- IScope scope = scopeProvider.scope_ComplexTypeLink_target((ComplexTypeLink) type, reference);
+ IScope scope = scopeProvider.getScope((ComplexTypeLink) type, reference);
assertThat(descriptionsIn(scope), contain("google.protobuf.FieldDescriptorProto.Type"));
}
}
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue189_ScopingShouldLookForClosestType.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue189_ScopingShouldLookForClosestType.java
index 8202370..2f413f6 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue189_ScopingShouldLookForClosestType.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/bugs/Issue189_ScopingShouldLookForClosestType.java
@@ -9,17 +9,19 @@
package com.google.eclipse.protobuf.bugs;
import static org.junit.Assert.assertSame;
+import static org.mockito.Mockito.when;
import static com.google.eclipse.protobuf.junit.IEObjectDescriptions.descriptionsIn;
import static com.google.eclipse.protobuf.junit.core.IntegrationTestModule.integrationTestModule;
import static com.google.eclipse.protobuf.junit.core.XtextRule.overrideRuntimeModuleWith;
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.COMPLEX_TYPE;
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.COMPLEX_TYPE_LINK;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.xtext.scoping.IScope;
import org.junit.Rule;
import org.junit.Test;
-
import com.google.eclipse.protobuf.junit.core.XtextRule;
import com.google.eclipse.protobuf.protobuf.ComplexTypeLink;
import com.google.eclipse.protobuf.protobuf.Literal;
@@ -53,10 +55,12 @@
// READY = 1;
// }
@Test public void should_find_closest_type_possible() {
+ when(reference.getEReferenceType()).thenReturn(COMPLEX_TYPE);
+ when(reference.getEContainingClass()).thenReturn(COMPLEX_TYPE_LINK);
Literal active = xtext.find("ACTIVE", " = 0", Literal.class);
MessageField field = xtext.find("status", MessageField.class);
ComplexTypeLink link = (ComplexTypeLink) field.getType();
- IScope scope = scopeProvider.scope_ComplexTypeLink_target(link, reference);
+ IScope scope = scopeProvider.getScope(link, reference);
EObject status = descriptionsIn(scope).objectDescribedAs("Status");
assertSame(active.eContainer(), status);
}
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_ComplexTypeLink_target_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_ComplexTypeLink_target_Test.java
index dccb549..47e5fb1 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_ComplexTypeLink_target_Test.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_ComplexTypeLink_target_Test.java
@@ -9,14 +9,18 @@
package com.google.eclipse.protobuf.scoping;
import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.when;
import static com.google.eclipse.protobuf.junit.IEObjectDescriptions.descriptionsIn;
import static com.google.eclipse.protobuf.junit.core.IntegrationTestModule.integrationTestModule;
import static com.google.eclipse.protobuf.junit.core.XtextRule.overrideRuntimeModuleWith;
import static com.google.eclipse.protobuf.junit.matchers.ContainAllNames.containAll;
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.COMPLEX_TYPE;
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.COMPLEX_TYPE_LINK;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.xtext.scoping.IScope;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -26,7 +30,7 @@
import com.google.inject.Inject;
/**
- * Tests for <code>{@link ProtobufScopeProvider#scope_ComplexTypeLink_target(ComplexTypeLink, EReference)}</code>
+ * Tests for <code>{@link ProtobufScopeProvider#getScope(ComplexTypeLink, EReference)}</code>
*
* @author alruiz@google.com (Alex Ruiz)
*/
@@ -36,6 +40,12 @@
@Inject private EReference reference;
@Inject private ProtobufScopeProvider scopeProvider;
+ @Before
+ public void setup() {
+ when(reference.getEReferenceType()).thenReturn(COMPLEX_TYPE);
+ when(reference.getEContainingClass()).thenReturn(COMPLEX_TYPE_LINK);
+ }
+
// syntax = "proto2";
// package com.google.proto;
//
@@ -56,7 +66,7 @@
// }
@Test public void should_provide_Types() {
MessageField field = xtext.find("type", MessageField.class);
- IScope scope = scopeProvider.scope_ComplexTypeLink_target(typeOf(field), reference);
+ IScope scope = scopeProvider.getScope(typeOf(field), reference);
assertThat(descriptionsIn(scope), containAll("Type", "proto.Type", "google.proto.Type", "com.google.proto.Type",
".com.google.proto.Type",
"Address", "proto.Address", "google.proto.Address",
@@ -92,7 +102,7 @@
// }
@Test public void should_provide_imported_Types() {
MessageField field = xtext.find("type", " =", MessageField.class);
- IScope scope = scopeProvider.scope_ComplexTypeLink_target(typeOf(field), reference);
+ IScope scope = scopeProvider.getScope(typeOf(field), reference);
assertThat(descriptionsIn(scope), containAll("test.proto.Type", ".test.proto.Type",
"test.proto.Address", ".test.proto.Address",
"Contact", "proto.Contact", "google.proto.Contact",
@@ -126,7 +136,7 @@
// }
@Test public void should_provide_imported_Types_with_equal_package() {
MessageField field = xtext.find("type", " =", MessageField.class);
- IScope scope = scopeProvider.scope_ComplexTypeLink_target(typeOf(field), reference);
+ IScope scope = scopeProvider.getScope(typeOf(field), reference);
assertThat(descriptionsIn(scope), containAll("Type", "proto.Type", "google.proto.Type", "com.google.proto.Type",
".com.google.proto.Type",
"Address", "proto.Address", "google.proto.Address",
@@ -162,7 +172,7 @@
// }
@Test public void should_provide_public_imported_Types() {
MessageField field = xtext.find("type", " =", MessageField.class);
- IScope scope = scopeProvider.scope_ComplexTypeLink_target(typeOf(field), reference);
+ IScope scope = scopeProvider.getScope(typeOf(field), reference);
assertThat(descriptionsIn(scope), containAll("test.proto.Type", ".test.proto.Type",
"test.proto.Address", ".test.proto.Address",
"Contact", "proto.Contact", "google.proto.Contact",
@@ -203,7 +213,7 @@
// }
@Test public void should_provide_public_imported_Types_with_more_than_one_level() {
MessageField field = xtext.find("type", " =", MessageField.class);
- IScope scope = scopeProvider.scope_ComplexTypeLink_target(typeOf(field), reference);
+ IScope scope = scopeProvider.getScope(typeOf(field), reference);
assertThat(descriptionsIn(scope), containAll("test.proto.Type", ".test.proto.Type",
"test.proto.Address", ".test.proto.Address",
"Contact", "proto.Contact", "google.proto.Contact",
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufImportScope.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufImportScope.java
new file mode 100644
index 0000000..fcc0476
--- /dev/null
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufImportScope.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016 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.scoping;
+
+import static java.util.Collections.emptyList;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.xtext.naming.QualifiedName;
+import org.eclipse.xtext.resource.IEObjectDescription;
+import org.eclipse.xtext.resource.ISelectable;
+import org.eclipse.xtext.resource.impl.AliasedEObjectDescription;
+import org.eclipse.xtext.scoping.IScope;
+import org.eclipse.xtext.scoping.impl.ImportNormalizer;
+import org.eclipse.xtext.scoping.impl.ImportScope;
+
+import com.google.common.collect.Lists;
+
+public class ProtobufImportScope extends ImportScope {
+ private final EClass type;
+
+ public ProtobufImportScope(
+ List<ImportNormalizer> namespaceResolvers,
+ IScope parent,
+ ISelectable importFrom,
+ EClass type,
+ boolean ignoreCase) {
+ super(namespaceResolvers, parent, importFrom, type, ignoreCase);
+ this.type = type;
+ }
+
+ @Override
+ protected Iterable<IEObjectDescription> getAliasedElements(
+ Iterable<IEObjectDescription> candidates) {
+ ArrayList<IEObjectDescription> descriptions =
+ Lists.newArrayList(super.getAliasedElements(candidates));
+ for (IEObjectDescription imported : candidates) {
+ descriptions.add(new AliasedEObjectDescription(addLeadingDot(imported.getName()), imported));
+ }
+ return descriptions;
+ }
+
+ @Override
+ protected Iterable<IEObjectDescription> getLocalElementsByName(QualifiedName name) {
+ List<IEObjectDescription> result =
+ (List<IEObjectDescription>) super.getLocalElementsByName(name);
+ QualifiedName resolvedQualifiedName = null;
+ final QualifiedName resolvedName = name.skipFirst(1);
+ ISelectable importFrom = getImportFrom();
+ if (resolvedName != null) {
+ Iterable<IEObjectDescription> resolvedElements =
+ importFrom.getExportedObjects(type, resolvedName, isIgnoreCase());
+ for (IEObjectDescription resolvedElement : resolvedElements) {
+ if (resolvedQualifiedName == null) resolvedQualifiedName = resolvedName;
+ else if (!resolvedQualifiedName.equals(resolvedName)) {
+ if (result.get(0).getEObjectOrProxy() != resolvedElement.getEObjectOrProxy()) {
+ return emptyList();
+ }
+ }
+ QualifiedName alias = addLeadingDot(resolvedElement.getName());
+ final AliasedEObjectDescription aliasedEObjectDescription =
+ new AliasedEObjectDescription(alias, resolvedElement);
+ result.add(aliasedEObjectDescription);
+ }
+ }
+ return result;
+ }
+
+ private QualifiedName addLeadingDot(QualifiedName qualifiedName) {
+ return QualifiedName.create("").append(qualifiedName);
+ }
+}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufImportUriGlobalScopeProvider.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufImportUriGlobalScopeProvider.java
index 2e88e89..df27228 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufImportUriGlobalScopeProvider.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufImportUriGlobalScopeProvider.java
@@ -13,9 +13,11 @@
import com.google.eclipse.protobuf.model.util.Resources;
import com.google.eclipse.protobuf.protobuf.Import;
import com.google.eclipse.protobuf.protobuf.Protobuf;
+import com.google.eclipse.protobuf.util.EResources;
import com.google.inject.Inject;
import com.google.inject.Provider;
+import org.eclipse.core.resources.IProject;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtext.scoping.impl.ImportUriGlobalScopeProvider;
@@ -32,6 +34,7 @@
@Inject private Resources resources;
@Inject private Imports imports;
@Inject private IResourceScopeCache cache;
+ @Inject private ProtoDescriptorProvider descriptorProvider;
@Override
protected LinkedHashSet<URI> getImportedUris(final Resource resource) {
@@ -65,6 +68,10 @@
if (root != null) {
addPublicImportedUris(root, importedUris);
}
+ } else if (imports.hasUnresolvedDescriptorUri(singleImport)) {
+ IProject project = EResources.getProjectOf(singleImport.eResource());
+ importedUris.add(
+ descriptorProvider.descriptorLocation(project, imports.getPath(singleImport)));
}
}
});
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufImportedNamespaceAwareLocalScopeProvider.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufImportedNamespaceAwareLocalScopeProvider.java
index 3d93bf9..76cd4ab 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufImportedNamespaceAwareLocalScopeProvider.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufImportedNamespaceAwareLocalScopeProvider.java
@@ -8,10 +8,21 @@
*/
package com.google.eclipse.protobuf.scoping;
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.naming.QualifiedName;
+import org.eclipse.xtext.resource.ISelectable;
+import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.impl.ImportNormalizer;
+import org.eclipse.xtext.scoping.impl.ImportScope;
import org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider;
import org.eclipse.xtext.util.Strings;
+
import com.google.eclipse.protobuf.naming.ProtobufQualifiedNameConverter;
import com.google.inject.Inject;
@@ -19,17 +30,74 @@
extends ImportedNamespaceAwareLocalScopeProvider {
@Inject private ProtobufQualifiedNameConverter qualifiedNameConverter;
+ @Override
+ protected ImportScope createImportScope(
+ IScope parent,
+ List<ImportNormalizer> namespaceResolvers,
+ ISelectable importFrom,
+ EClass type,
+ boolean ignoreCase) {
+ return new ProtobufImportScope(namespaceResolvers, parent, importFrom, type, ignoreCase);
+ }
+
+ @Override
+ protected List<ImportNormalizer> internalGetImportedNamespaceResolvers(
+ final EObject context, boolean ignoreCase) {
+ List<ImportNormalizer> importedNamespaceResolvers = new ArrayList<>();
+ EList<EObject> eContents = context.eContents();
+ for (EObject child : eContents) {
+ String namespace = getImportedNamespace(child);
+ if (namespace != null) {
+ ImportNormalizer resolver = createImportedNamespaceResolver(namespace, ignoreCase);
+ if (resolver != null) {
+ importedNamespaceResolvers.add(resolver);
+ }
+ importedNamespaceResolvers.addAll(createResolversForInnerNamespaces(namespace, ignoreCase));
+ }
+ }
+ return importedNamespaceResolvers;
+ }
+
+ /**
+ * Creates resolvers required for scoping to handle intersecting packages. The
+ * imported namespace {@code com.google.proto.foo} requires the following
+ * resolvers:
+ * <ul>
+ * <li>{@code com.*}
+ * <li>{@code com.google.*}
+ * <li>{@code com.google.proto.*}
+ * </ul>
+ *
+ * @param namespace the namespace.
+ * @param ignoreCase {@code true} if the resolver should be case insensitive.
+ * @return a list of the resolvers for an imported namespace
+ */
+ private List<ImportNormalizer> createResolversForInnerNamespaces(
+ String namespace, boolean ignoreCase) {
+ String[] splitValue = namespace.split("\\.");
+ List<ImportNormalizer> importedNamespaceResolvers = new ArrayList<>();
+ String currentNamespaceResolver = "";
+ for (int i = 0; i < Array.getLength(splitValue) - 1; i++) {
+ currentNamespaceResolver += splitValue[i] + ".";
+ ImportNormalizer resolver =
+ createImportedNamespaceResolver(currentNamespaceResolver, ignoreCase);
+ if (resolver != null) {
+ importedNamespaceResolvers.add(resolver);
+ }
+ }
+ return importedNamespaceResolvers;
+ }
+
/**
* Creates a new {@link ImportNormalizer} for the given namespace.
*
* @param namespace the namespace.
- * @param ignoreCase <code>true</code> if the resolver should be case insensitive.
- * @return a new {@link ImportNormalizer} or {@code null} if the namespace cannot be
- * converted to a valid qualified name.
+ * @param ignoreCase {@code true} if the resolver should be case insensitive.
+ * @return a new {@link ImportNormalizer} or {@code null} if the namespace
+ * cannot be converted to a valid qualified name.
*/
@Override
- protected ImportNormalizer createImportedNamespaceResolver(String namespace,
- boolean ignoreCase) {
+ protected ImportNormalizer createImportedNamespaceResolver(String namespace, boolean ignoreCase) {
if (Strings.isEmpty(namespace)) {
return null;
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider.java
index 3b82c45..f34a85a 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider.java
@@ -19,19 +19,15 @@
import com.google.eclipse.protobuf.protobuf.AbstractCustomOption;
import com.google.eclipse.protobuf.protobuf.AbstractOption;
import com.google.eclipse.protobuf.protobuf.ComplexType;
-import com.google.eclipse.protobuf.protobuf.ComplexTypeLink;
import com.google.eclipse.protobuf.protobuf.ComplexValue;
import com.google.eclipse.protobuf.protobuf.DefaultValueFieldOption;
import com.google.eclipse.protobuf.protobuf.Enum;
import com.google.eclipse.protobuf.protobuf.ExtensibleType;
-import com.google.eclipse.protobuf.protobuf.ExtensibleTypeLink;
import com.google.eclipse.protobuf.protobuf.FieldName;
import com.google.eclipse.protobuf.protobuf.Group;
import com.google.eclipse.protobuf.protobuf.GroupElement;
import com.google.eclipse.protobuf.protobuf.IndexedElement;
import com.google.eclipse.protobuf.protobuf.LiteralLink;
-import com.google.eclipse.protobuf.protobuf.MapType;
-import com.google.eclipse.protobuf.protobuf.MapTypeLink;
import com.google.eclipse.protobuf.protobuf.Message;
import com.google.eclipse.protobuf.protobuf.MessageField;
import com.google.eclipse.protobuf.protobuf.MessageLink;
@@ -99,36 +95,11 @@
return scope;
}
- @SuppressWarnings("unused")
- public IScope scope_ComplexTypeLink_target(ComplexTypeLink link, EReference r) {
- EObject c = link.eContainer();
- if (c instanceof MapType) {
- c = c.eContainer();
- }
- if (c instanceof MapTypeLink) {
- c = c.eContainer();
- }
- if (c instanceof MessageField) {
- MessageField field = (MessageField) c;
- Collection<IEObjectDescription> complexTypes = potentialComplexTypesFor(field);
- return createScope(complexTypes);
- }
- return createEmptyScope();
- }
-
@Override
public Collection<IEObjectDescription> potentialComplexTypesFor(MessageField field) {
return modelElementFinder.find(field, complexTypeFinderDelegate, ComplexType.class);
}
- @SuppressWarnings("unused")
- public IScope scope_ExtensibleTypeLink_target(ExtensibleTypeLink link, EReference r) {
- EObject c = link.eContainer();
- Collection<IEObjectDescription> extensibleTypes =
- modelElementFinder.find(c, complexTypeFinderDelegate, ExtensibleType.class);
- return createScope(extensibleTypes);
- }
-
@Override
public Collection<IEObjectDescription> potentialExtensibleTypesFor(TypeExtension extension) {
Protobuf root = modelObjects.rootOf(extension);
@@ -295,11 +266,6 @@
value, extensionFieldNameFinderDelegate);
}
- private static IScope createEmptyScope() {
- Set<IEObjectDescription> descriptions = emptySet();
- return createScope(descriptions);
- }
-
private static IScope createScope(Iterable<IEObjectDescription> descriptions) {
return new SimpleScope(descriptions, DO_NOT_IGNORE_CASE);
}