Fixed: [Issue 125] Support for custom options
diff --git a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_PropertyRef_property_Test.java b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_PropertyRef_property_Test.java
index 3d08c08..c66743d 100644
--- a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_PropertyRef_property_Test.java
+++ b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_PropertyRef_property_Test.java
@@ -90,7 +90,30 @@
// // Create file custom-options.proto
//
- // package com.google.test;
+ // package test.proto;
+ //
+ // import "google/protobuf/descriptor.proto";
+ //
+ // extend google.protobuf.FileOptions {
+ // optional int32 code = 1000;
+ // optional int32 info = 1002;
+ // }
+
+ // package com.google.proto;
+ //
+ // import 'custom-options.proto';
+ //
+ // option (test.proto.code) = 68;
+ @Test public void should_provide_imported_Property_fields_for_custom_option() {
+ Option option = xtext.find("code", ")", Option.class);
+ IScope scope = provider.scope_PropertyRef_property(option.getProperty(), reference);
+ assertThat(descriptionsIn(scope), containAll("test.proto.code", ".test.proto.code",
+ "test.proto.info", ".test.proto.info"));
+ }
+
+ // // Create file custom-options.proto
+ //
+ // package com.google.proto;
//
// import "google/protobuf/descriptor.proto";
//
@@ -104,15 +127,15 @@
// import 'custom-options.proto';
//
// option (code) = 68;
- @Test public void should_provide_imported_Property_fields_for_custom_option() {
+ @Test public void should_provide_imported_Property_fields_for_custom_option_with_equal_package() {
Option option = xtext.find("code", ")", Option.class);
IScope scope = provider.scope_PropertyRef_property(option.getProperty(), reference);
- assertThat(descriptionsIn(scope), containAll("code", "test.code", "google.test.code", "com.google.test.code",
- ".com.google.test.code",
- "info", "test.info", "google.test.info", "com.google.test.info",
- ".com.google.test.info"));
+ assertThat(descriptionsIn(scope), containAll("code", "proto.code", "google.proto.code", "com.google.proto.code",
+ ".com.google.proto.code",
+ "info", "proto.info", "google.proto.info", "com.google.proto.info",
+ ".com.google.proto.info"));
}
-
+
// package com.google.proto;
// import 'google/protobuf/descriptor.proto';
//
diff --git a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_TypeRef_type_Test.java b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_TypeRef_type_Test.java
index bbd6b84..578d94c 100644
--- a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_TypeRef_type_Test.java
+++ b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/scoping/ProtobufScopeProvider_scope_TypeRef_type_Test.java
@@ -60,7 +60,7 @@
// message Contact {
// optional Type type = 1;
// }
- @Test public void should_provide_Property_fields_for_custom_option_field() {
+ @Test public void should_provide_Types() {
Property p = xtext.find("type", Property.class);
IScope scope = provider.scope_TypeRef_type(typeOf(p), reference);
assertThat(descriptionsIn(scope), containAll("Type", "proto.Type", "google.proto.Type", "com.google.proto.Type",
@@ -71,6 +71,142 @@
"com.google.proto.Contact", ".com.google.proto.Contact"));
}
+ // // Create file types.proto
+ //
+ // package test.proto;
+ //
+ // enum Type {
+ // PERSONAL = 0;
+ // BUSINESS = 1;
+ // }
+ //
+ // message Address {
+ // optional int32 number = 1;
+ // optional string street = 2;
+ // optional string city = 3;
+ // optional int32 zipCode = 4;
+ // }
+
+ // package com.google.proto;
+ //
+ // import "types.proto";
+ //
+ // message Contact {
+ // optional com.google.test.Type type = 1;
+ // }
+ @Test public void should_provide_imported_Types() {
+ Property p = xtext.find("type", " =", Property.class);
+ IScope scope = provider.scope_TypeRef_type(typeOf(p), reference);
+ assertThat(descriptionsIn(scope), containAll("test.proto.Type", ".test.proto.Type",
+ "test.proto.Address", ".test.proto.Address",
+ "Contact", "proto.Contact", "google.proto.Contact",
+ "com.google.proto.Contact", ".com.google.proto.Contact"));
+ }
+
+ // // Create file types.proto
+ //
+ // package com.google.proto;
+ //
+ // enum Type {
+ // PERSONAL = 0;
+ // BUSINESS = 1;
+ // }
+ //
+ // message Address {
+ // optional int32 number = 1;
+ // optional string street = 2;
+ // optional string city = 3;
+ // optional int32 zipCode = 4;
+ // }
+
+ // package com.google.proto;
+ //
+ // import "types.proto";
+ //
+ // message Contact {
+ // optional com.google.test.Type type = 1;
+ // }
+ @Test public void should_provide_imported_Types_with_equal_package() {
+ Property p = xtext.find("type", " =", Property.class);
+ IScope scope = provider.scope_TypeRef_type(typeOf(p), 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",
+ "com.google.proto.Address", ".com.google.proto.Address",
+ "Contact", "proto.Contact", "google.proto.Contact",
+ "com.google.proto.Contact", ".com.google.proto.Contact"));
+ }
+
+ // // Create file types.proto
+ //
+ // package test.proto;
+ //
+ // enum Type {
+ // PERSONAL = 0;
+ // BUSINESS = 1;
+ // }
+ //
+ // message Address {
+ // optional int32 number = 1;
+ // optional string street = 2;
+ // optional string city = 3;
+ // optional int32 zipCode = 4;
+ // }
+
+ // package com.google.proto;
+ //
+ // import public "types.proto";
+ //
+ // message Contact {
+ // optional test.proto.Type type = 1;
+ // }
+ @Test public void should_provide_public_imported_Types() {
+ Property p = xtext.find("type", " =", Property.class);
+ IScope scope = provider.scope_TypeRef_type(typeOf(p), reference);
+ assertThat(descriptionsIn(scope), containAll("test.proto.Type", ".test.proto.Type",
+ "test.proto.Address", ".test.proto.Address",
+ "Contact", "proto.Contact", "google.proto.Contact",
+ "com.google.proto.Contact", ".com.google.proto.Contact"));
+ }
+
+ // // Create file public-types.proto
+ //
+ // package test.proto;
+ //
+ // enum Type {
+ // PERSONAL = 0;
+ // BUSINESS = 1;
+ // }
+ //
+ // message Address {
+ // optional int32 number = 1;
+ // optional string street = 2;
+ // optional string city = 3;
+ // optional int32 zipCode = 4;
+ // }
+
+ // // Create file types.proto
+ //
+ // package com.google.proto;
+ //
+ // import public "public-types.proto";
+
+ // package com.google.proto;
+ //
+ // import "types.proto";
+ //
+ // message Contact {
+ // optional test.proto.Type type = 1;
+ // }
+ @Test public void should_provide_public_imported_Types_with_more_than_one_level() {
+ Property p = xtext.find("type", " =", Property.class);
+ IScope scope = provider.scope_TypeRef_type(typeOf(p), reference);
+ assertThat(descriptionsIn(scope), containAll("test.proto.Type", ".test.proto.Type",
+ "test.proto.Address", ".test.proto.Address",
+ "Contact", "proto.Contact", "google.proto.Contact",
+ "com.google.proto.Contact", ".com.google.proto.Contact"));
+ }
+
private static TypeRef typeOf(Property p) {
return (TypeRef) p.getType();
}
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/CommentProcessor.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/CommentProcessor.java
index 8423fb0..acdf358 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/CommentProcessor.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/CommentProcessor.java
@@ -8,8 +8,7 @@
*/
package com.google.eclipse.protobuf.junit.core;
-import static com.google.eclipse.protobuf.junit.core.GeneratedProtoFiles.PARENT_DIRECTORY_NAME;
-import static java.io.File.separator;
+import static com.google.eclipse.protobuf.junit.core.GeneratedProtoFiles.*;
import java.io.*;
import java.util.Scanner;
@@ -36,8 +35,8 @@
}
private File createFile(String fileName, String contents) {
- verifyParentDirectoryExists();
- File file = new File(PARENT_DIRECTORY_NAME + separator + fileName);
+ ensureParentDirectoryExists();
+ File file = protoFile(fileName);
if (file.isFile()) file.delete();
Writer out = null;
try {
@@ -50,12 +49,6 @@
}
return file;
}
-
- private void verifyParentDirectoryExists() {
- File directory = new File(PARENT_DIRECTORY_NAME);
- if (directory.isDirectory()) return;
- directory.mkdir();
- }
private void closeQuietly(Writer out) {
if (out == null) return;
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/GeneratedProtoFiles.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/GeneratedProtoFiles.java
index c281b7c..bed18ac 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/GeneratedProtoFiles.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/GeneratedProtoFiles.java
@@ -8,12 +8,29 @@
*/
package com.google.eclipse.protobuf.junit.core;
+import static java.io.File.separator;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertThat;
+
+import java.io.File;
+
/**
* @author alruiz@google.com (Alex Ruiz)
*/
final class GeneratedProtoFiles {
- static final String PARENT_DIRECTORY_NAME = "test-protos";
+ private static final String PARENT_DIRECTORY_NAME = "test-protos";
+
+ static File protoFile(String fileName) {
+ return new File(PARENT_DIRECTORY_NAME + separator + fileName);
+ }
+
+ static void ensureParentDirectoryExists() {
+ File parent = new File(PARENT_DIRECTORY_NAME);
+ if (!parent.isDirectory()) {
+ assertThat(parent.mkdir(), equalTo(true));
+ }
+ }
private GeneratedProtoFiles() {}
}
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/IntegrationTestSetup.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/IntegrationTestSetup.java
index 4eae4e7..647c6cc 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/IntegrationTestSetup.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/core/IntegrationTestSetup.java
@@ -8,19 +8,18 @@
*/
package com.google.eclipse.protobuf.junit.core;
-import static com.google.eclipse.protobuf.junit.core.GeneratedProtoFiles.PARENT_DIRECTORY_NAME;
-import static java.io.File.separator;
+import static com.google.eclipse.protobuf.junit.core.GeneratedProtoFiles.protoFile;
import static org.eclipse.xtext.util.Strings.isEmpty;
-import java.io.File;
-
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.resource.Resource;
-
import com.google.eclipse.protobuf.*;
import com.google.eclipse.protobuf.scoping.IFileUriResolver;
import com.google.inject.*;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+
+import java.io.File;
+
/**
* @author alruiz@google.com (Alex Ruiz)
*/
@@ -44,7 +43,7 @@
public String resolveUri(String importUri, Resource declaringResource) {
URI uri = URI.createURI(importUri);
if (!isEmpty(uri.scheme())) return importUri; // already resolved.
- File file = new File(PARENT_DIRECTORY_NAME + separator + importUri);
+ File file = protoFile(importUri);
if (!file.exists()) throw new IllegalArgumentException("File: " + importUri + " does not exist.");
return file.toURI().toString();
}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/CustomOptionProperties.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/CustomOptionProperties.java
deleted file mode 100644
index 177d077..0000000
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/CustomOptionProperties.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * 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.ui.contentassist;
-
-import static java.util.Collections.*;
-import static org.eclipse.emf.ecore.util.EcoreUtil.getAllContents;
-
-import com.google.eclipse.protobuf.model.OptionType;
-import com.google.eclipse.protobuf.model.util.*;
-import com.google.eclipse.protobuf.protobuf.*;
-import com.google.eclipse.protobuf.protobuf.Package;
-import com.google.inject.Inject;
-
-import org.eclipse.emf.common.util.TreeIterator;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.resource.*;
-
-import java.util.*;
-
-/**
- * @author alruiz@google.com (Alex Ruiz)
- */
-class CustomOptionProperties {
-
- @Inject private Imports imports;
- @Inject private ModelFinder finder;
- @Inject private Options options;
- @Inject private Packages packages;
- @Inject private Resources resources;
-
- Collection<Property> propertiesFor(CustomOption option) {
- OptionType type = OptionType.typeOf(option);
- if (type == null) return emptyList();
- Protobuf root = finder.rootOf(option);
- if (root == null) return emptyList();
- List<Property> properties = new ArrayList<Property>();
- properties.addAll(local(root, type));
- properties.addAll(imported(root, type));
- return unmodifiableList(properties);
- }
-
- private Collection<Property> local(Protobuf root, OptionType type) {
- return local(root, type, 0);
- }
-
- private Collection<Property> local(EObject root, OptionType optionType, int level) {
- List<Property> properties = new ArrayList<Property>();
- for (EObject element : root.eContents()) {
- if (options.isExtendingOptionMessage(element, optionType)) {
- ExtendMessage extend = (ExtendMessage) element;
- for (MessageElement e : extend.getElements()) {
- if (!(e instanceof Property)) continue;
- properties.add((Property) e);
- }
- }
- if (element instanceof Message) {
- properties.addAll(local(element, optionType, level + 1));
- }
- }
- return unmodifiableList(properties);
- }
-
- private Collection<Property> imported(Protobuf root, OptionType optionType) {
- List<Import> allImports = finder.importsIn(root);
- if (allImports.isEmpty()) return emptyList();
- ResourceSet resourceSet = root.eResource().getResourceSet();
- return imported(allImports, finder.packageOf(root), resourceSet, optionType);
- }
-
- private Collection<Property> imported(List<Import> allImports, Package aPackage,
- ResourceSet resourceSet, OptionType optionType) {
- List<Property> properties = new ArrayList<Property>();
- for (Import anImport : allImports) {
- if (imports.isImportingDescriptor(anImport)) continue;
- Resource importedResource = resources.importedResource(anImport, resourceSet);
- Protobuf importedRoot = finder.rootOf(importedResource);
- if (importedRoot != null) {
- properties.addAll(publicImported(importedRoot, optionType));
- if (arePackagesRelated(aPackage, importedRoot)) {
- properties.addAll(local(importedRoot, optionType));
- continue;
- }
- }
- properties.addAll(local(importedResource, optionType));
- }
- return unmodifiableList(properties);
- }
-
- private Collection<Property> publicImported(Protobuf root, OptionType optionType) {
- List<Import> allImports = finder.publicImportsIn(root);
- if (allImports.isEmpty()) return emptyList();
- ResourceSet resourceSet = root.eResource().getResourceSet();
- return imported(allImports, finder.packageOf(root), resourceSet, optionType);
- }
-
- private boolean arePackagesRelated(Package aPackage, EObject root) {
- Package p = finder.packageOf(root);
- return packages.areRelated(aPackage, p);
- }
-
- private Collection<Property> local(Resource resource, OptionType optionType) {
- List<Property> properties = new ArrayList<Property>();
- TreeIterator<Object> contents = getAllContents(resource, true);
- while (contents.hasNext()) {
- Object next = contents.next();
- if (!options.isExtendingOptionMessage((EObject) next, optionType)) continue;
- ExtendMessage extend = (ExtendMessage) next;
- for (MessageElement e : extend.getElements()) {
- if (e instanceof Property) properties.add((Property) e);
- }
- }
- return properties;
- }
-}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java
index 25c5245..bbb4853 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/contentassist/ProtobufProposalProvider.java
@@ -25,6 +25,8 @@
import org.eclipse.swt.graphics.Image;
import org.eclipse.xtext.*;
import org.eclipse.xtext.naming.*;
+import org.eclipse.xtext.resource.IEObjectDescription;
+import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.ui.PluginImageHelper;
import org.eclipse.xtext.ui.editor.contentassist.*;
@@ -46,7 +48,7 @@
*/
public class ProtobufProposalProvider extends AbstractProtobufProposalProvider {
- @Inject private CustomOptionProperties customOptionProperties;
+ @Inject private ProtobufScopeProvider scopes;
@Inject private ProtoDescriptorProvider descriptorProvider;
@Inject private FieldOptions fieldOptions;
@Inject private ModelFinder finder;
@@ -54,7 +56,6 @@
@Inject private Images images;
@Inject private PluginImageHelper imageHelper;
@Inject private Literals literals;
- @Inject private IQualifiedNameProvider nameProvider;
@Inject private Options options;
@Inject private Properties properties;
@@ -410,27 +411,59 @@
@Override public void completeCustomOption_Property(EObject model, Assignment assignment,
ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
if (!(model instanceof CustomOption)) return;
- Image image = imageForOption();
- for (Property p : customOptionProperties.propertiesFor((CustomOption) model)) {
- QualifiedName name = nameProvider.getFullyQualifiedName(p);
- proposeAndAccept(name.toString(), image, context, acceptor);
- }
+ CustomOption option = (CustomOption) model;
+ IScope scope = scopes.scope_PropertyRef_property(option.getProperty(), null);
+ proposeAndAcceptOptions(scope, context, acceptor);
}
+ @Override public void completeCustomFieldOption_Property(EObject model, Assignment assignment,
+ ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
+ if (!(model instanceof CustomFieldOption)) return;
+ CustomFieldOption option = (CustomFieldOption) model;
+ IScope scope = scopes.scope_PropertyRef_property(option.getProperty(), null);
+ proposeAndAcceptOptions(scope, context, acceptor);
+ }
+
+ private void proposeAndAcceptOptions(IScope scope, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
+ Image image = imageForOption();
+ for (IEObjectDescription d : scope.getAllElements()) {
+ proposeAndAccept(d, image, context, acceptor);
+ }
+ }
+
private Image imageForOption() {
return imageHelper.getImage(images.imageFor(Option.class));
}
+
+ private void proposeAndAccept(IEObjectDescription d, Image image, ContentAssistContext context,
+ ICompletionProposalAcceptor acceptor) {
+ QualifiedName name = d.getName();
+ String display = name.getLastSegment() + " - " + name.toString();
+ ICompletionProposal proposal = createCompletionProposal(name.toString(), display, image, context);
+ acceptor.accept(proposal);
+ }
@Override public void completeCustomOption_PropertyField(EObject model, Assignment assignment,
ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
if (!(model instanceof CustomOption)) return;
Property property = options.propertyFrom((CustomOption) model);
- if (property == null) return;
+ proposeAndAcceptOptionFields(property, context, acceptor);
+ }
+
+ @Override public void completeCustomFieldOption_PropertyField(EObject model, Assignment assignment,
+ ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
+ if (!(model instanceof CustomFieldOption)) return;
+ Property property = fieldOptions.propertyFrom((CustomFieldOption) model);
+ proposeAndAcceptOptionFields(property, context, acceptor);
+ }
+
+ private void proposeAndAcceptOptionFields(Property property, ContentAssistContext context,
+ ICompletionProposalAcceptor acceptor) {
Message message = finder.messageTypeOf(property);
- if (message != null) {
- Image image = imageHelper.getImage("property.gif");
- for (Property p : finder.propertiesOf(message))
- proposeAndAccept(p.getName(), image, context, acceptor);
+ if (message == null) return;
+ Image image = imageHelper.getImage("property.gif");
+ for (Property p : finder.propertiesOf(message)) {
+ proposeAndAccept(p.getName(), image, context, acceptor);
}
}
@@ -440,6 +473,21 @@
CustomOption option = (CustomOption) model;
Property property = options.fieldFrom(option);
if (property == null) property = options.propertyFrom(option);
+ proposeAndAcceptOptionFieldValue(property, context, acceptor);
+ }
+
+ @Override public void completeCustomFieldOption_Value(EObject model, Assignment assignment,
+ ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
+ // TODO content assist returns "{"
+ if (!(model instanceof CustomFieldOption)) return;
+ CustomFieldOption option = (CustomFieldOption) model;
+ Property property = fieldOptions.fieldFrom(option);
+ if (property == null) property = fieldOptions.propertyFrom(option);
+ proposeAndAcceptOptionFieldValue(property, context, acceptor);
+ }
+
+ private void proposeAndAcceptOptionFieldValue(Property property, ContentAssistContext context,
+ ICompletionProposalAcceptor acceptor) {
if (property == null) return;
if (proposePrimitiveValues(property, context, acceptor)) return;
Enum enumType = finder.enumTypeOf(property);
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/OptionType.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/OptionType.java
index 339cf77..a0dec62 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/OptionType.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/OptionType.java
@@ -23,6 +23,8 @@
*/
public enum OptionType {
+ // TODO move back to package "com.google.eclipse.protobuf.scoping" and make it package-protected.
+
FILE("FileOptions"), MESSAGE("MessageOptions"), FIELD("FieldOptions"), ENUM("EnumOptions"),
LITERAL("EnumValueOptions"), SERVICE("ServiceOptions"), RPC("MethodOptions");
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/CustomOptionDescriptions.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/CustomOptionDescriptions.java
index 5963194..c459561 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/CustomOptionDescriptions.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/CustomOptionDescriptions.java
@@ -33,7 +33,6 @@
class CustomOptionDescriptions {
@Inject private ModelFinder finder;
- @Inject private ImportedNamesProvider importedNamesProvider;
@Inject private Imports imports;
@Inject private LocalNamesProvider localNamesProvider;
@Inject private Options options;
@@ -41,16 +40,16 @@
@Inject private QualifiedNameDescriptions qualifiedNamesDescriptions;
@Inject private Resources resources;
- Collection <IEObjectDescription> properties(CustomOption option) {
+ public Collection <IEObjectDescription> properties(CustomOption option) {
return allProperties(option, typeOf(option));
}
- Collection <IEObjectDescription> properties(CustomFieldOption option) {
+ public Collection <IEObjectDescription> properties(CustomFieldOption option) {
return allProperties(option, typeOf(option));
}
private Collection <IEObjectDescription> allProperties(EObject option, OptionType type) {
- Set<IEObjectDescription> descriptions = new HashSet<IEObjectDescription>();
+ Set<IEObjectDescription> descriptions = new LinkedHashSet<IEObjectDescription>();
EObject current = option.eContainer();
while (current != null) {
descriptions.addAll(local(current, type));
@@ -67,7 +66,7 @@
private Collection <IEObjectDescription> local(EObject root, OptionType optionType, int level) {
if (optionType == null) return emptyList();
- Set<IEObjectDescription> descriptions = new HashSet<IEObjectDescription>();
+ Set<IEObjectDescription> descriptions = new LinkedHashSet<IEObjectDescription>();
for (EObject element : root.eContents()) {
if (options.isExtendingOptionMessage(element, optionType)) {
ExtendMessage extend = (ExtendMessage) element;
@@ -98,7 +97,7 @@
private Collection<IEObjectDescription> imported(List<Import> allImports, Package aPackage,
ResourceSet resourceSet, OptionType optionType) {
- List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
+ Set<IEObjectDescription> descriptions = new LinkedHashSet<IEObjectDescription>();
for (Import anImport : allImports) {
if (imports.isImportingDescriptor(anImport)) continue;
Resource importedResource = resources.importedResource(anImport, resourceSet);
@@ -138,9 +137,7 @@
if (!(e instanceof Property)) continue;
Property p = (Property) e;
descriptions.addAll(qualifiedNamesDescriptions.qualifiedNames(p));
- for (QualifiedName name : importedNamesProvider.namesOf(p)) {
- descriptions.add(create(name, e));
- }
+ // TODO verify that call to 'importedNamesProvider.namesOf' is not necessary
}
}
return descriptions;
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 71c3955..1e050c7 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
@@ -43,7 +43,7 @@
@Inject private TypeDescriptions typeDescriptions;
@SuppressWarnings("unused")
- IScope scope_TypeRef_type(TypeRef typeRef, EReference reference) {
+ public IScope scope_TypeRef_type(TypeRef typeRef, EReference reference) {
EObject c = typeRef.eContainer();
if (c instanceof Property) {
Property property = (Property) c;
@@ -54,13 +54,13 @@
}
@SuppressWarnings("unused")
- IScope scope_MessageRef_type(MessageRef messageRef, EReference reference) {
+ public IScope scope_MessageRef_type(MessageRef messageRef, EReference reference) {
Protobuf root = finder.rootOf(messageRef);
return createScope(typeDescriptions.messages(root));
}
@SuppressWarnings("unused")
- IScope scope_LiteralRef_literal(LiteralRef literalRef, EReference reference) {
+ public IScope scope_LiteralRef_literal(LiteralRef literalRef, EReference reference) {
EObject c = literalRef.eContainer();
Enum anEnum = null;
if (c instanceof DefaultValueFieldOption) {
@@ -94,7 +94,7 @@
}
@SuppressWarnings("unused")
- IScope scope_PropertyRef_property(PropertyRef propertyRef, EReference reference) {
+ public IScope scope_PropertyRef_property(PropertyRef propertyRef, EReference reference) {
EObject c = propertyRef.eContainer();
if (c instanceof NativeOption) {
NativeOption option = (NativeOption) c;
@@ -117,7 +117,7 @@
}
@SuppressWarnings("unused")
- IScope scope_SimplePropertyRef_property(SimplePropertyRef propertyRef, EReference reference) {
+ public IScope scope_SimplePropertyRef_property(SimplePropertyRef propertyRef, EReference reference) {
EObject c = propertyRef.eContainer();
Property property = null;
if (c instanceof CustomOption) {
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/TypeDescriptions.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/TypeDescriptions.java
index c9b78e6..2258513 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/TypeDescriptions.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/scoping/TypeDescriptions.java
@@ -32,7 +32,6 @@
@Inject private ProtoDescriptorProvider descriptorProvider;
@Inject private ModelFinder finder;
- @Inject private ImportedNamesProvider importedNamesProvider;
@Inject private Imports imports;
@Inject private LocalNamesProvider localNamesProvider;
@Inject private Packages packages;
@@ -98,11 +97,11 @@
continue;
}
Resource importedResource = resources.importedResource(anImport, resourceSet);
- Protobuf importedRoot = finder.rootOf(importedResource);
- if (importedRoot != null) {
- descriptions.addAll(publicImported(importedRoot, targetType));
- if (arePackagesRelated(aPackage, importedRoot)) {
- descriptions.addAll(local(importedRoot, targetType));
+ Protobuf rootOfImported = finder.rootOf(importedResource);
+ if (rootOfImported != null) {
+ descriptions.addAll(publicImported(rootOfImported, targetType));
+ if (arePackagesRelated(aPackage, rootOfImported)) {
+ descriptions.addAll(local(rootOfImported, targetType));
continue;
}
}
@@ -142,9 +141,7 @@
if (!targetType.isInstance(next)) continue;
T type = targetType.cast(next);
descriptions.addAll(qualifiedNamesDescriptions.qualifiedNames(type));
- for (QualifiedName name : importedNamesProvider.namesOf(type)) {
- descriptions.add(create(name, type));
- }
+ // TODO verify that call to 'importedNamesProvider.namesOf' is not necessary
}
return descriptions;
}