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); }