Merge branch 'master' of https://code.google.com/p/protobuf-dt/
diff --git a/com.google.eclipse.protobuf.cdt.test/META-INF/MANIFEST.MF b/com.google.eclipse.protobuf.cdt.test/META-INF/MANIFEST.MF
index 09d731b..3b08b5f 100644
--- a/com.google.eclipse.protobuf.cdt.test/META-INF/MANIFEST.MF
+++ b/com.google.eclipse.protobuf.cdt.test/META-INF/MANIFEST.MF
@@ -7,4 +7,6 @@
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"
+ org.mockito;bundle-version="1.8.5",
+ org.hamcrest;bundle-version="1.1.0",
+ org.hamcrest.library;bundle-version="1.1.0"
diff --git a/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/matching/PatternBuilder_patternToMatchFrom_Test.java b/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/matching/PatternBuilder_patternToMatchFrom_Test.java
new file mode 100644
index 0000000..ffe207e
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/matching/PatternBuilder_patternToMatchFrom_Test.java
@@ -0,0 +1,56 @@
+/*
+ * 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.matching;
+
+import static com.google.eclipse.protobuf.cdt.matching.PatternMatcher.matches;
+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.protobuf.ProtobufPackage.Literals.MESSAGE;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertThat;
+
+import java.util.regex.Pattern;
+
+import org.eclipse.xtext.naming.IQualifiedNameConverter;
+import org.junit.*;
+
+import com.google.eclipse.protobuf.cdt.mapping.CppToProtobufMapping;
+import com.google.eclipse.protobuf.junit.core.XtextRule;
+import com.google.inject.Inject;
+
+/**
+ * Tests for <code>{@link PatternBuilder#patternToMatchFrom(CppToProtobufMapping)}</code>
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class PatternBuilder_patternToMatchFrom_Test {
+ @Rule public XtextRule xtext = overrideRuntimeModuleWith(unitTestModule());
+
+ @Inject private PatternBuilder builder;
+ @Inject private IQualifiedNameConverter converter;
+
+ @Test public void should_escape_dots() {
+ CppToProtobufMapping mapping = createMessageMapping("com.google.proto.test.Person");
+ Pattern pattern = builder.patternToMatchFrom(mapping);
+ assertThat(pattern.pattern(), equalTo("com\\.google\\.proto\\.test\\.Person"));
+ assertThat("com.google.proto.test.Person", matches(pattern));
+ }
+
+ @Test public void should_escape_underscore() {
+ CppToProtobufMapping mapping = createMessageMapping("com.google.proto.test.Person_PhoneType");
+ Pattern pattern = builder.patternToMatchFrom(mapping);
+ assertThat(pattern.pattern(), equalTo("com\\.google\\.proto\\.test\\.Person(\\.|_)PhoneType"));
+ assertThat("com.google.proto.test.Person.PhoneType", matches(pattern));
+ assertThat("com.google.proto.test.Person_PhoneType", matches(pattern));
+ }
+
+ private CppToProtobufMapping createMessageMapping(String qualifiedNameAsText) {
+ return new CppToProtobufMapping(converter.toQualifiedName(qualifiedNameAsText), MESSAGE);
+ }
+}
diff --git a/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/matching/PatternMatcher.java b/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/matching/PatternMatcher.java
new file mode 100644
index 0000000..c7d4f07
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/matching/PatternMatcher.java
@@ -0,0 +1,38 @@
+/*
+ * 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.matching;
+
+import java.util.regex.Pattern;
+
+import org.hamcrest.*;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+class PatternMatcher extends TypeSafeMatcher<String> {
+ private final Pattern pattern;
+
+ static PatternMatcher matches(Pattern pattern) {
+ return new PatternMatcher(pattern);
+ }
+
+ private PatternMatcher(Pattern pattern) {
+ super(String.class);
+ this.pattern = pattern;
+ }
+
+ @Override public boolean matchesSafely(String item) {
+ return pattern.matcher(item).matches();
+ }
+
+ @Override public void describeTo(Description description) {
+ description.appendValue(pattern.pattern());
+ }
+
+}
diff --git a/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/matching/ProtobufElementMatcher_findUriOfMatchingProtobufElement_Test.java b/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/matching/ProtobufElementMatcher_findUriOfMatchingProtobufElement_Test.java
index ac4e225..15f9ec1 100644
--- a/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/matching/ProtobufElementMatcher_findUriOfMatchingProtobufElement_Test.java
+++ b/com.google.eclipse.protobuf.cdt.test/src/com/google/eclipse/protobuf/cdt/matching/ProtobufElementMatcher_findUriOfMatchingProtobufElement_Test.java
@@ -10,6 +10,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.protobuf.ProtobufPackage.Literals.MESSAGE;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.*;
@@ -105,7 +106,7 @@
private CppToProtobufMapping messageMapping(String qualifiedNameAsText) {
QualifiedName qualifiedName = fqnConverter.toQualifiedName(qualifiedNameAsText);
- return new CppToProtobufMapping(qualifiedName, Message.class);
+ return new CppToProtobufMapping(qualifiedName, MESSAGE);
}
private URI uriOfMessageWithName(String name) {
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/cpplang/CppKeywords.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/cpplang/CppKeywords.java
new file mode 100644
index 0000000..87604a6
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/cpplang/CppKeywords.java
@@ -0,0 +1,44 @@
+/*
+ * 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.cpplang;
+
+import static com.google.common.collect.Lists.newArrayList;
+
+import java.util.List;
+
+import com.google.inject.Singleton;
+
+/**
+ * C++ keywords.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+@Singleton public class CppKeywords {
+
+ private static final List<String> KEYWORDS = newArrayList("and", "and_eq", "asm", "auto", "bitand", "bitor", "bool",
+ "break", "case", "catch", "char", "class", "compl", "const", "const_cast", "continue", "default", "delete",
+ "double", "dynamic_cast", "else", "enum", "explicit", "export", "extern", "false", "float", "for", "friend",
+ "goto", "if", "inline", "int", "long", "mutable", "namespace", "new", "not", "not_eq", "operator", "or", "or_eq",
+ "private", "protected", "public", "register", "reinterpret_cast", "return", "short", "signed", "sizeof",
+ "static", "static_cast", "struct", "switch", "template", "this", "throw", "true", "try", "typedef", "typeid",
+ "typename", "union", "unsigned", "using", "virtual", "void", "volatile", "wchar_t", "while", "xor", "xor_eq");
+
+ @SuppressWarnings("unused")
+ private static final List<String> CPP11_KEYWORDS = newArrayList("alignas", "alignof", "char16_t", "char32_t",
+ "constexpr", "decltype", "noexcept", "nullptr", "static_assert", "thread_local");
+
+ /**
+ * Indicates whether the content of the given {@code String} is a C++ keyword.
+ * @param s the given {@code String}.
+ * @return {@code true} if the content of the given {@code String} is a C++ keyword, {@code false} otherwise.
+ */
+ public boolean isKeyword(String s) {
+ return KEYWORDS.contains(s);
+ }
+}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/ClassMappingStrategy.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/ClassMappingStrategy.java
index 00dacf4..2b9a1f5 100644
--- a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/ClassMappingStrategy.java
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/ClassMappingStrategy.java
@@ -8,13 +8,14 @@
*/
package com.google.eclipse.protobuf.cdt.mapping;
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.MESSAGE;
+
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.IBinding;
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.eclipse.protobuf.protobuf.Message;
import com.google.inject.Singleton;
/**
@@ -28,7 +29,7 @@
if (isMessage(classType)) {
String[] segments = classType.getQualifiedName();
QualifiedName qualifiedName = QualifiedName.create(segments);
- return new CppToProtobufMapping(qualifiedName, Message.class);
+ return new CppToProtobufMapping(qualifiedName, MESSAGE);
}
return null;
}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/CppToProtobufMapping.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/CppToProtobufMapping.java
index 35df4c4..b600a3b 100644
--- a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/CppToProtobufMapping.java
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/CppToProtobufMapping.java
@@ -8,7 +8,7 @@
*/
package com.google.eclipse.protobuf.cdt.mapping;
-import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EClass;
import org.eclipse.xtext.naming.QualifiedName;
/**
@@ -18,9 +18,9 @@
*/
public class CppToProtobufMapping {
private final QualifiedName qualifiedName;
- private final Class<? extends EObject> type;
+ private final EClass type;
- public CppToProtobufMapping(QualifiedName qualifiedName, Class<? extends EObject> type) {
+ public CppToProtobufMapping(QualifiedName qualifiedName, EClass type) {
this.qualifiedName = qualifiedName;
this.type = type;
}
@@ -37,7 +37,7 @@
* Returns the type of the protocol buffer element.
* @return the type of the protocol buffer element.
*/
- public Class<? extends EObject> type() {
+ public EClass type() {
return type;
}
}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/EnumMappingStrategy.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/EnumMappingStrategy.java
index 9c0edef..5c30caf 100644
--- a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/EnumMappingStrategy.java
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/EnumMappingStrategy.java
@@ -8,11 +8,12 @@
*/
package com.google.eclipse.protobuf.cdt.mapping;
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.ENUM;
+
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPEnumeration;
import org.eclipse.xtext.naming.QualifiedName;
-import com.google.eclipse.protobuf.protobuf.Enum;
import com.google.inject.Singleton;
/**
@@ -25,7 +26,7 @@
CPPEnumeration enumeration = typeOfSupportedBinding().cast(binding);
String[] segments = enumeration.getQualifiedName();
QualifiedName qualifiedName = QualifiedName.create(segments);
- return new CppToProtobufMapping(qualifiedName, Enum.class);
+ return new CppToProtobufMapping(qualifiedName, ENUM);
}
@Override public Class<CPPEnumeration> typeOfSupportedBinding() {
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/MethodMappingStrategy.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/MethodMappingStrategy.java
index db5150a..5dce848 100644
--- a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/MethodMappingStrategy.java
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/mapping/MethodMappingStrategy.java
@@ -8,13 +8,13 @@
*/
package com.google.eclipse.protobuf.cdt.mapping;
+import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.MESSAGE_FIELD;
+
import org.eclipse.cdt.core.dom.ast.*;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethod;
import org.eclipse.xtext.naming.QualifiedName;
-import com.google.eclipse.protobuf.protobuf.MessageField;
-
/**
* @author alruiz@google.com (Alex Ruiz)
*/
@@ -32,7 +32,7 @@
return null;
}
QualifiedName qualifiedName = QualifiedName.create(method.getQualifiedName());
- return new CppToProtobufMapping(qualifiedName, MessageField.class);
+ return new CppToProtobufMapping(qualifiedName, MESSAGE_FIELD);
}
@Override public Class<CPPMethod> typeOfSupportedBinding() {
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/matching/PatternBuilder.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/matching/PatternBuilder.java
new file mode 100644
index 0000000..f080950
--- /dev/null
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/matching/PatternBuilder.java
@@ -0,0 +1,45 @@
+/*
+ * 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.matching;
+
+import java.util.regex.Pattern;
+
+import org.eclipse.xtext.naming.IQualifiedNameConverter;
+
+import com.google.eclipse.protobuf.cdt.mapping.CppToProtobufMapping;
+import com.google.inject.Inject;
+
+/**
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+class PatternBuilder {
+ @Inject private IQualifiedNameConverter converter;
+
+ Pattern patternToMatchFrom(CppToProtobufMapping mapping) {
+ String qualifiedNameAsText = converter.toString(mapping.qualifiedName());
+ StringBuilder regex = new StringBuilder();
+ int size = qualifiedNameAsText.length();
+ // escape existing "."
+ // replace "_" with "(\.|_)"
+ for (int i = 0; i < size; i++) {
+ char c = qualifiedNameAsText.charAt(i);
+ switch (c) {
+ case '.':
+ regex.append("\\.");
+ break;
+ case '_':
+ regex.append("(\\.|_)");
+ break;
+ default:
+ regex.append(c);
+ }
+ }
+ return Pattern.compile(regex.toString());
+ }
+}
diff --git a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/matching/ProtobufElementMatcher.java b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/matching/ProtobufElementMatcher.java
index f7a254b..94655af 100644
--- a/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/matching/ProtobufElementMatcher.java
+++ b/com.google.eclipse.protobuf.cdt/src/com/google/eclipse/protobuf/cdt/matching/ProtobufElementMatcher.java
@@ -8,13 +8,15 @@
*/
package com.google.eclipse.protobuf.cdt.matching;
+import static com.google.eclipse.protobuf.resource.filter.MatchingQualifiedNameAndTypeFilter.matchingQualifiedNameAndType;
+
import java.util.List;
import java.util.regex.Pattern;
import org.eclipse.emf.common.util.URI;
-import org.eclipse.xtext.naming.*;
import org.eclipse.xtext.resource.*;
+import com.google.common.base.Predicate;
import com.google.eclipse.protobuf.cdt.mapping.CppToProtobufMapping;
import com.google.eclipse.protobuf.resource.ResourceDescriptions;
import com.google.inject.Inject;
@@ -23,7 +25,7 @@
* @author alruiz@google.com (Alex Ruiz)
*/
public class ProtobufElementMatcher {
- @Inject private IQualifiedNameConverter converter;
+ @Inject private PatternBuilder patternBuilder;
@Inject private ResourceDescriptions descriptions;
/**
@@ -34,21 +36,12 @@
* @return the found URI, or {@code null} if it was not possible to find a matching protocol buffer element.
*/
public URI findUriOfMatchingProtobufElement(IResourceDescription resource, CppToProtobufMapping mapping) {
- QualifiedName qualifiedName = mapping.qualifiedName();
- Pattern pattern = patternToMatchFrom(qualifiedName);
- List<IEObjectDescription> matches = descriptions.matchingQualifiedNames(resource, pattern, mapping.type());
+ Pattern pattern = patternBuilder.patternToMatchFrom(mapping);
+ Predicate<IEObjectDescription> filter = matchingQualifiedNameAndType(pattern, mapping.type());
+ List<IEObjectDescription> matches = descriptions.filterModelObjects(resource, filter);
if (!matches.isEmpty()) {
return matches.get(0).getEObjectURI();
}
return null;
}
-
- private Pattern patternToMatchFrom(QualifiedName qualifiedName) {
- String qualifiedNameAsText = converter.toString(qualifiedName);
- // escape existing "."
- // replace "_" with "(\.|_)"
- String regex = qualifiedNameAsText.replaceAll("\\.", "\\\\.")
- .replaceAll("_", "\\(\\\\.|_\\)");
- return Pattern.compile(regex);
- }
}
diff --git a/com.google.eclipse.protobuf.feature/feature.xml b/com.google.eclipse.protobuf.feature/feature.xml
index 1782178..e5f61f9 100644
--- a/com.google.eclipse.protobuf.feature/feature.xml
+++ b/com.google.eclipse.protobuf.feature/feature.xml
@@ -2,7 +2,7 @@
<feature
id="com.google.eclipse.protobuf"
label="%featureName"
- version="1.2.2.qualifier"
+ version="1.2.3.qualifier"
provider-name="%providerName">
<description url="https://code.google.com/p/protobuf-dt/">
@@ -22,6 +22,7 @@
</url>
<requires>
+ <import plugin="org.eclipse.xtext" version="2.2.1" match="greaterOrEqual"/>
<import plugin="org.eclipse.xtext.util"/>
<import plugin="org.eclipse.emf.ecore"/>
<import plugin="org.eclipse.emf.common"/>
@@ -42,7 +43,6 @@
<import plugin="org.eclipse.compare.core" version="3.5.200" match="greaterOrEqual"/>
<import plugin="org.eclipse.ui.console" version="3.5.100" match="greaterOrEqual"/>
<import plugin="org.eclipse.ui.workbench.texteditor"/>
- <import plugin="org.eclipse.xtext" version="2.2.1" match="greaterOrEqual"/>
</requires>
<plugin
diff --git a/com.google.eclipse.protobuf.integration.test/META-INF/MANIFEST.MF b/com.google.eclipse.protobuf.integration.test/META-INF/MANIFEST.MF
index 3136f73..5726298 100644
--- a/com.google.eclipse.protobuf.integration.test/META-INF/MANIFEST.MF
+++ b/com.google.eclipse.protobuf.integration.test/META-INF/MANIFEST.MF
@@ -9,5 +9,7 @@
org.eclipse.xtext.junit;bundle-version="2.0.0",
org.eclipse.xtext.junit4;bundle-version="2.0.0",
org.mockito;bundle-version="1.8.5",
- org.eclipse.core.resources;bundle-version="3.7.100"
+ org.eclipse.core.resources;bundle-version="3.7.100",
+ org.hamcrest;bundle-version="1.1.0",
+ org.hamcrest.library;bundle-version="1.1.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
diff --git a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/junit/matchers/ContainAllFields.java b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/junit/matchers/ContainAllFields.java
index 18b486c..83db9ee 100644
--- a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/junit/matchers/ContainAllFields.java
+++ b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/junit/matchers/ContainAllFields.java
@@ -23,7 +23,7 @@
/**
* @author alruiz@google.com (Alex Ruiz)
*/
-public class ContainAllFields extends BaseMatcher<IEObjectDescriptions> {
+public class ContainAllFields extends TypeSafeMatcher<IEObjectDescriptions> {
private final Collection<MessageField> fields = newArrayList();
public static ContainAllFields containAll(Collection<MessageField> fields) {
@@ -31,20 +31,17 @@
}
private ContainAllFields(Collection<MessageField> fields) {
+ super(IEObjectDescriptions.class);
this.fields.addAll(fields);
}
- @Override public boolean matches(Object arg) {
- if (!(arg instanceof IEObjectDescriptions)) {
- return false;
- }
- IEObjectDescriptions descriptions = (IEObjectDescriptions) arg;
- if (descriptions.size() != fields.size()) {
+ @Override public boolean matchesSafely(IEObjectDescriptions item) {
+ if (item.size() != fields.size()) {
return false;
}
for (MessageField field : fields) {
String name = field.getName();
- EObject described = descriptions.objectDescribedAs(name);
+ EObject described = item.objectDescribedAs(name);
if (described != field) {
return false;
}
diff --git a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/junit/matchers/ContainAllFieldsInMessage.java b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/junit/matchers/ContainAllFieldsInMessage.java
index a4fb223..670969c 100644
--- a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/junit/matchers/ContainAllFieldsInMessage.java
+++ b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/junit/matchers/ContainAllFieldsInMessage.java
@@ -23,7 +23,7 @@
/**
* @author alruiz@google.com (Alex Ruiz)
*/
-public class ContainAllFieldsInMessage extends BaseMatcher<IEObjectDescriptions> {
+public class ContainAllFieldsInMessage extends TypeSafeMatcher<IEObjectDescriptions> {
private final EObject container;
public static ContainAllFieldsInMessage containAllFieldsIn(Group group) {
@@ -35,21 +35,18 @@
}
private ContainAllFieldsInMessage(EObject container) {
+ super(IEObjectDescriptions.class);
this.container = container;
}
- @Override public boolean matches(Object arg) {
- if (!(arg instanceof IEObjectDescriptions)) {
- return false;
- }
- IEObjectDescriptions descriptions = (IEObjectDescriptions) arg;
+ @Override public boolean matchesSafely(IEObjectDescriptions item) {
List<IndexedElement> elements = allIndexedElements();
- if (descriptions.size() != elements.size()) {
+ if (item.size() != elements.size()) {
return false;
}
for (IndexedElement e : elements) {
String name = nameOf(e);
- EObject described = descriptions.objectDescribedAs(name);
+ EObject described = item.objectDescribedAs(name);
if (described != e) {
return false;
}
diff --git a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/junit/matchers/ContainAllLiteralsInEnum.java b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/junit/matchers/ContainAllLiteralsInEnum.java
index 40312dd..89ded43 100644
--- a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/junit/matchers/ContainAllLiteralsInEnum.java
+++ b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/junit/matchers/ContainAllLiteralsInEnum.java
@@ -24,7 +24,7 @@
/**
* @author alruiz@google.com (Alex Ruiz)
*/
-public class ContainAllLiteralsInEnum extends BaseMatcher<IEObjectDescriptions> {
+public class ContainAllLiteralsInEnum extends TypeSafeMatcher<IEObjectDescriptions> {
private final Enum anEnum;
public static ContainAllLiteralsInEnum containAllLiteralsIn(Enum anEnum) {
@@ -32,21 +32,18 @@
}
private ContainAllLiteralsInEnum(Enum anEnum) {
+ super(IEObjectDescriptions.class);
this.anEnum = anEnum;
}
- @Override public boolean matches(Object arg) {
- if (!(arg instanceof IEObjectDescriptions)) {
- return false;
- }
- IEObjectDescriptions descriptions = (IEObjectDescriptions) arg;
+ @Override public boolean matchesSafely(IEObjectDescriptions item) {
List<Literal> literals = allLiterals();
- if (descriptions.size() != literals.size()) {
+ if (item.size() != literals.size()) {
return false;
}
for (Literal literal : literals) {
String name = literal.getName();
- EObject described = descriptions.objectDescribedAs(name);
+ EObject described = item.objectDescribedAs(name);
if (described != literal) {
return false;
}
diff --git a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/junit/matchers/ContainAllNames.java b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/junit/matchers/ContainAllNames.java
index 2fb0457..b26569f 100644
--- a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/junit/matchers/ContainAllNames.java
+++ b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/junit/matchers/ContainAllNames.java
@@ -19,7 +19,7 @@
/**
* @author alruiz@google.com (Alex Ruiz)
*/
-public class ContainAllNames extends BaseMatcher<IEObjectDescriptions> {
+public class ContainAllNames extends TypeSafeMatcher<IEObjectDescriptions> {
private final String[] expectedNames;
public static ContainAllNames containAll(String... names) {
@@ -27,15 +27,12 @@
}
private ContainAllNames(String... names) {
+ super(IEObjectDescriptions.class);
expectedNames = names;
}
- @Override public boolean matches(Object arg) {
- if (!(arg instanceof IEObjectDescriptions)) {
- return false;
- }
- IEObjectDescriptions descriptions = (IEObjectDescriptions) arg;
- List<String> names = newArrayList(descriptions.names());
+ @Override public boolean matchesSafely(IEObjectDescriptions item) {
+ List<String> names = newArrayList(item.names());
if (names.size() != expectedNames.length) {
return false;
}
diff --git a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/junit/matchers/ContainNames.java b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/junit/matchers/ContainNames.java
index 456e079..3dfc2af 100644
--- a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/junit/matchers/ContainNames.java
+++ b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/junit/matchers/ContainNames.java
@@ -10,7 +10,7 @@
import static java.util.Arrays.asList;
-import java.util.List;
+import java.util.*;
import org.hamcrest.*;
@@ -19,7 +19,7 @@
/**
* @author alruiz@google.com (Alex Ruiz)
*/
-public class ContainNames extends BaseMatcher<IEObjectDescriptions> {
+public class ContainNames extends TypeSafeMatcher<IEObjectDescriptions> {
private final List<String> expectedNames;
public static ContainNames contain(String... names) {
@@ -27,15 +27,13 @@
}
private ContainNames(String... names) {
+ super(IEObjectDescriptions.class);
expectedNames = asList(names);
}
- @Override public boolean matches(Object arg) {
- if (!(arg instanceof IEObjectDescriptions)) {
- return false;
- }
- IEObjectDescriptions descriptions = (IEObjectDescriptions) arg;
- return descriptions.names().containsAll(expectedNames);
+ @Override public boolean matchesSafely(IEObjectDescriptions item) {
+ Collection<String> names = item.names();
+ return names.containsAll(expectedNames);
}
@Override public void describeTo(Description description) {
diff --git a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/validation/ImportValidator_checkNonProto2Imports_Test.java b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/validation/ImportValidator_checkNonProto2Imports_Test.java
new file mode 100644
index 0000000..5b9a99b
--- /dev/null
+++ b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/validation/ImportValidator_checkNonProto2Imports_Test.java
@@ -0,0 +1,77 @@
+/*
+ * 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.validation;
+
+import static com.google.eclipse.protobuf.junit.core.IntegrationTestModule.integrationTestModule;
+import static com.google.eclipse.protobuf.junit.core.XtextRule.overrideRuntimeModuleWith;
+import static org.mockito.Mockito.*;
+
+import org.eclipse.xtext.validation.ValidationMessageAcceptor;
+import org.junit.*;
+
+import com.google.eclipse.protobuf.junit.core.XtextRule;
+import com.google.eclipse.protobuf.protobuf.Protobuf;
+import com.google.inject.Inject;
+
+/**
+ * Tests for <code>{@link ImportValidator#checkNonProto2Imports(Protobuf)}</code>
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class ImportValidator_checkNonProto2Imports_Test {
+ @Rule public XtextRule xtext = overrideRuntimeModuleWith(integrationTestModule());
+
+ @Inject private ImportValidator validator;
+ private ValidationMessageAcceptor messageAcceptor;
+
+ @Before public void setUp() {
+ messageAcceptor = mock(ValidationMessageAcceptor.class);
+ validator.setMessageAcceptor(messageAcceptor);
+ }
+
+ // // Create file C.proto
+ //
+ // syntax = 'proto2';
+
+ // // Create file B.proto
+ //
+ // syntax = 'proto2';
+ //
+ // import "C.proto";
+
+ // syntax = "proto2";
+ //
+ // import "B.proto";
+ // import "C.proto";
+ @Test public void should_not_add_warnings_if_imported_files_are_proto2() {
+ validator.checkNonProto2Imports(xtext.root());
+ verifyNoMoreInteractions(messageAcceptor);
+ }
+
+ // // Create file C.proto
+ //
+ // syntax = 'proto2';
+ //
+ // import "B.proto";
+
+ // // Create file B.proto
+ //
+ // syntax = 'proto2';
+ //
+ // import "C.proto";
+
+ // syntax = "proto2";
+ //
+ // import "B.proto";
+ // import "C.proto";
+ @Test public void should_not_add_warnings_if_imported_files_are_proto2_even_with_circular_dependencies() {
+ validator.checkNonProto2Imports(xtext.root());
+ verifyNoMoreInteractions(messageAcceptor);
+ }
+}
diff --git a/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/validation/ImportValidator_checkNonProto2Imports_withNonProto2Imports_Tests.java b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/validation/ImportValidator_checkNonProto2Imports_withNonProto2Imports_Tests.java
new file mode 100644
index 0000000..d8f8aa9
--- /dev/null
+++ b/com.google.eclipse.protobuf.integration.test/src/com/google/eclipse/protobuf/validation/ImportValidator_checkNonProto2Imports_withNonProto2Imports_Tests.java
@@ -0,0 +1,118 @@
+/*
+ * 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.validation;
+
+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.IMPORT__IMPORT_URI;
+import static com.google.eclipse.protobuf.validation.Messages.importingNonProto2;
+import static org.eclipse.xtext.validation.ValidationMessageAcceptor.INSIGNIFICANT_INDEX;
+import static org.mockito.Mockito.*;
+
+import java.util.List;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.xtext.validation.ValidationMessageAcceptor;
+import org.junit.*;
+
+import com.google.eclipse.protobuf.junit.core.*;
+import com.google.eclipse.protobuf.model.util.Protobufs;
+import com.google.eclipse.protobuf.protobuf.*;
+import com.google.inject.*;
+
+/**
+ * Tests for <code>{@link ImportValidator#checkNonProto2Imports(Protobuf)}</code>
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class ImportValidator_checkNonProto2Imports_withNonProto2Imports_Tests {
+ @Rule public XtextRule xtext = overrideRuntimeModuleWith(integrationTestModule(), new TestModule());
+
+ @Inject private ProtobufsStub protobufs;
+ @Inject private ImportValidator validator;
+
+ private ValidationMessageAcceptor messageAcceptor;
+
+ @Before public void setUp() {
+ messageAcceptor = mock(ValidationMessageAcceptor.class);
+ validator.setMessageAcceptor(messageAcceptor);
+ }
+
+ // // Create file C.proto
+ //
+ // syntax = 'proto2';
+
+ // // Create file B.proto
+ //
+ // syntax = 'proto2';
+
+ // syntax = "proto2";
+ //
+ // import "B.proto";
+ // import "C.proto";
+ @Test public void should_add_warning_if_import_if_import_refers_directly_to_non_proto2() {
+ protobufs.nonProto2FileName = "B.proto";
+ validator.checkNonProto2Imports(xtext.root());
+ Import importWithNonProto2File = findImportReferreringToFile(protobufs.nonProto2FileName);
+ verifyThatImportingNonProto2FileCreatedWarning(importWithNonProto2File);
+ }
+
+ // // Create file C.proto
+ //
+ // syntax = 'proto2';
+
+ // // Create file B.proto
+ //
+ // syntax = 'proto2';
+ //
+ // import "C.proto";
+
+ // syntax = "proto2";
+ //
+ // import "B.proto";
+ @Test public void should_add_warning_if_import_if_import_refers_indirectly_to_non_proto2() {
+ protobufs.nonProto2FileName = "C.proto";
+ validator.checkNonProto2Imports(xtext.root());
+ Import importWithNonProto2File = findImportReferreringToFile("B.proto");
+ verifyThatImportingNonProto2FileCreatedWarning(importWithNonProto2File);
+ }
+
+ private Import findImportReferreringToFile(String fileName) {
+ List<Import> imports = protobufs.importsIn(xtext.root());
+ for (Import anImport : imports) {
+ if (anImport.getImportURI().endsWith(fileName)) {
+ return anImport;
+ }
+ }
+ return null;
+ }
+
+ private void verifyThatImportingNonProto2FileCreatedWarning(Import anImport) {
+ verify(messageAcceptor).acceptWarning(importingNonProto2, anImport, IMPORT__IMPORT_URI, INSIGNIFICANT_INDEX, null,
+ new String[0]);
+ }
+
+ private static class TestModule extends AbstractTestModule {
+ @Override protected void configure() {
+ binder().bind(Protobufs.class).to(ProtobufsStub.class);
+ }
+ }
+
+ @Singleton private static class ProtobufsStub extends Protobufs {
+ String nonProto2FileName;
+
+ @Override public boolean isProto2(Protobuf protobuf) {
+ URI resourceUri = protobuf.eResource().getURI();
+ if (resourceUri.toString().endsWith(nonProto2FileName)) {
+ return false;
+ }
+ return super.isProto2(protobuf);
+ }
+ }
+}
diff --git a/com.google.eclipse.protobuf.test/.gitignore b/com.google.eclipse.protobuf.test/.gitignore
new file mode 100644
index 0000000..42859ab
--- /dev/null
+++ b/com.google.eclipse.protobuf.test/.gitignore
@@ -0,0 +1 @@
+/test-protos
diff --git a/com.google.eclipse.protobuf.test/META-INF/MANIFEST.MF b/com.google.eclipse.protobuf.test/META-INF/MANIFEST.MF
index dbf6497..4d98f42 100644
--- a/com.google.eclipse.protobuf.test/META-INF/MANIFEST.MF
+++ b/com.google.eclipse.protobuf.test/META-INF/MANIFEST.MF
@@ -9,7 +9,9 @@
org.eclipse.xtext.junit;bundle-version="2.0.0",
org.eclipse.xtext.junit4;bundle-version="2.0.0",
org.mockito;bundle-version="1.8.5",
- org.eclipse.core.resources;bundle-version="3.7.100"
+ org.eclipse.core.resources;bundle-version="3.7.100",
+ org.hamcrest;bundle-version="1.1.0",
+ org.hamcrest.library;bundle-version="1.1.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Export-Package: com.google.eclipse.protobuf.junit.core,
com.google.eclipse.protobuf.junit.matchers,
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/matchers/EnumHasLiterals.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/matchers/EnumHasLiterals.java
index ba26024..21ef88d 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/matchers/EnumHasLiterals.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/matchers/EnumHasLiterals.java
@@ -23,7 +23,7 @@
/**
* @author alruiz@google.com (Alex Ruiz)
*/
-public class EnumHasLiterals extends BaseMatcher<Enum> {
+public class EnumHasLiterals extends TypeSafeMatcher<Enum> {
private final String[] literalNames;
public static EnumHasLiterals hasLiterals(String... literalNames) {
@@ -31,15 +31,12 @@
}
private EnumHasLiterals(String... literalNames) {
+ super(Enum.class);
this.literalNames = literalNames;
}
- @Override public boolean matches(Object item) {
- if (!(item instanceof Enum)) {
- return false;
- }
- Enum anEnum = (Enum) item;
- List<String> actualNames = newArrayList(literalNames(anEnum));
+ @Override public boolean matchesSafely(Enum item) {
+ List<String> actualNames = newArrayList(literalNames(item));
for (String name : literalNames) {
actualNames.remove(name);
}
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/matchers/FieldHasType.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/matchers/FieldHasType.java
index c02ed9f..9996ded 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/matchers/FieldHasType.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/matchers/FieldHasType.java
@@ -15,7 +15,7 @@
/**
* @author alruiz@google.com (Alex Ruiz)
*/
-public class FieldHasType extends BaseMatcher<MessageField> {
+public class FieldHasType extends TypeSafeMatcher<MessageField> {
private final String typeName;
public static FieldHasType isBool() {
@@ -31,15 +31,12 @@
}
private FieldHasType(String typeName) {
+ super(MessageField.class);
this.typeName = typeName;
}
- @Override public boolean matches(Object arg) {
- if (!(arg instanceof MessageField)) {
- return false;
- }
- MessageField field = (MessageField) arg;
- return typeName.equals(typeNameOf(field));
+ @Override public boolean matchesSafely(MessageField item) {
+ return typeName.equals(typeNameOf(item));
}
private String typeNameOf(MessageField field) {
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/stubs/resources/ResourceStub.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/stubs/resources/ResourceStub.java
deleted file mode 100644
index f69bd43..0000000
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/junit/stubs/resources/ResourceStub.java
+++ /dev/null
@@ -1,163 +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.junit.stubs.resources;
-
-import static org.eclipse.emf.common.util.URI.createURI;
-
-import java.io.*;
-import java.util.Map;
-
-import org.eclipse.emf.common.notify.*;
-import org.eclipse.emf.common.util.*;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.resource.*;
-
-/**
- * @author alruiz@google.com (Alex Ruiz)
- */
-public class ResourceStub implements Resource {
- private URI uri;
-
- public ResourceStub() {}
-
- public ResourceStub(String uri) {
- setURI(createURI(uri));
- }
-
- /** {@inheritDoc} */
- @Override public EList<Adapter> eAdapters() {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public boolean eDeliver() {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public void eSetDeliver(boolean deliver) {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public void eNotify(Notification notification) {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public ResourceSet getResourceSet() {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public URI getURI() {
- return uri;
- }
-
- /** {@inheritDoc} */
- @Override public void setURI(URI uri) {
- this.uri = uri;
- }
-
- /** {@inheritDoc} */
- @Override public long getTimeStamp() {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public void setTimeStamp(long timeStamp) {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public EList<EObject> getContents() {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public TreeIterator<EObject> getAllContents() {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public String getURIFragment(EObject eObject) {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public EObject getEObject(String uriFragment) {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public void save(Map<?, ?> options) {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public void load(Map<?, ?> options) {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public void save(OutputStream outputStream, Map<?, ?> options) {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public void load(InputStream inputStream, Map<?, ?> options) {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public boolean isTrackingModification() {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public void setTrackingModification(boolean isTrackingModification) {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public boolean isModified() {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public void setModified(boolean isModified) {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public boolean isLoaded() {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public void unload() {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public void delete(Map<?, ?> options) {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public EList<Diagnostic> getErrors() {
- throw new UnsupportedOperationException();
- }
-
- /** {@inheritDoc} */
- @Override public EList<Diagnostic> getWarnings() {
- throw new UnsupportedOperationException();
- }
-
-}
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/linking/ProtobufDiagnosticMatcher.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/linking/ProtobufDiagnosticMatcher.java
index 162a5e4..9b35c37 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/linking/ProtobufDiagnosticMatcher.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/linking/ProtobufDiagnosticMatcher.java
@@ -18,7 +18,7 @@
/**
* @author alruiz@google.com (Alex Ruiz)
*/
-class ProtobufDiagnosticMatcher extends BaseMatcher<ProtobufDiagnostic> {
+class ProtobufDiagnosticMatcher extends TypeSafeMatcher<ProtobufDiagnostic> {
private final DiagnosticMessage message;
static ProtobufDiagnosticMatcher wasCreatedFrom(DiagnosticMessage message) {
@@ -26,16 +26,14 @@
}
private ProtobufDiagnosticMatcher(DiagnosticMessage message) {
+ super(ProtobufDiagnostic.class);
this.message = message;
}
- @Override public boolean matches(Object item) {
- if (!(item instanceof ProtobufDiagnostic)) {
- return false;
- }
- ProtobufDiagnostic d = (ProtobufDiagnostic) item;
- return equal(message.getIssueCode(), d.getCode()) && Arrays.equals(message.getIssueData(), d.getData())
- && equal(message.getMessage(), d.getMessage());
+ @Override public boolean matchesSafely(ProtobufDiagnostic item) {
+ return equal(message.getIssueCode(), item.getCode()) &&
+ Arrays.equals(message.getIssueData(), item.getData()) &&
+ equal(message.getMessage(), item.getMessage());
}
@Override public void describeTo(Description description) {
diff --git a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator_checkOnlyOnePackageDefinition_Test.java b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator_checkOnlyOnePackageDefinition_Test.java
index 3d3a260..0ea1264 100644
--- a/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator_checkOnlyOnePackageDefinition_Test.java
+++ b/com.google.eclipse.protobuf.test/src/com/google/eclipse/protobuf/validation/ProtobufJavaValidator_checkOnlyOnePackageDefinition_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.protobuf.ProtobufPackage.Literals.PACKAGE__NAME;
+import static com.google.eclipse.protobuf.validation.Messages.multiplePackages;
import static com.google.eclipse.protobuf.validation.ProtobufJavaValidator.MORE_THAN_ONE_PACKAGE_ERROR;
import static org.eclipse.xtext.validation.ValidationMessageAcceptor.INSIGNIFICANT_INDEX;
import static org.mockito.Mockito.*;
@@ -45,8 +46,7 @@
@Test public void should_create_error_if_there_are_more_than_one_package_definitions() {
Package p = xtext.find("com.google.eclipse", Package.class);
validator.checkOnlyOnePackageDefinition(p);
- String message = "Multiple package definitions.";
- verify(messageAcceptor).acceptError(message, p, PACKAGE__NAME, INSIGNIFICANT_INDEX, MORE_THAN_ONE_PACKAGE_ERROR);
+ verify(messageAcceptor).acceptError(multiplePackages, p, PACKAGE__NAME, INSIGNIFICANT_INDEX, MORE_THAN_ONE_PACKAGE_ERROR);
}
// syntax = "proto2";
diff --git a/com.google.eclipse.protobuf.ui.test/META-INF/MANIFEST.MF b/com.google.eclipse.protobuf.ui.test/META-INF/MANIFEST.MF
index a90dbbd..5af6725 100644
--- a/com.google.eclipse.protobuf.ui.test/META-INF/MANIFEST.MF
+++ b/com.google.eclipse.protobuf.ui.test/META-INF/MANIFEST.MF
@@ -10,4 +10,6 @@
org.eclipse.xtext.junit;bundle-version="2.0.0",
org.eclipse.xtext.junit4;bundle-version="2.0.0",
org.eclipse.xtext.ui.junit;bundle-version="2.0.0",
- org.mockito;bundle-version="1.8.5"
+ org.mockito;bundle-version="1.8.5",
+ org.hamcrest;bundle-version="1.1.0",
+ org.hamcrest.library;bundle-version="1.1.0"
diff --git a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/contentassist/IEObjectDescriptionsHaveNames.java b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/contentassist/IEObjectDescriptionsHaveNames.java
index 392b247..7d2b688 100644
--- a/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/contentassist/IEObjectDescriptionsHaveNames.java
+++ b/com.google.eclipse.protobuf.ui.test/src/com/google/eclipse/protobuf/ui/contentassist/IEObjectDescriptionsHaveNames.java
@@ -19,7 +19,7 @@
/**
* @author alruiz@google.com (Alex Ruiz)
*/
-public class IEObjectDescriptionsHaveNames extends BaseMatcher<Collection<IEObjectDescription>> {
+public class IEObjectDescriptionsHaveNames extends TypeSafeMatcher<Collection<IEObjectDescription>> {
private final List<String> qualifiedNames;
public static IEObjectDescriptionsHaveNames containOnly(String...names) {
@@ -30,18 +30,12 @@
this.qualifiedNames = newArrayList(qualifiedNames);
}
- /** {@inheritDoc} */
- @Override @SuppressWarnings("unchecked")
- public boolean matches(Object arg) {
- if (!(arg instanceof Collection)) {
- return false;
- }
- Collection<IEObjectDescription> descriptions = (Collection<IEObjectDescription>) arg;
+ @Override public boolean matchesSafely(Collection<IEObjectDescription> item) {
List<String> copyOfNames = newArrayList(qualifiedNames);
- if (copyOfNames.size() != descriptions.size()) {
+ if (copyOfNames.size() != item.size()) {
return false;
}
- for (IEObjectDescription description : descriptions) {
+ for (IEObjectDescription description : item) {
QualifiedName qualifiedName = description.getName();
if (qualifiedName == null) {
continue;
diff --git a/com.google.eclipse.protobuf/META-INF/MANIFEST.MF b/com.google.eclipse.protobuf/META-INF/MANIFEST.MF
index caafc24..d306d0f 100644
--- a/com.google.eclipse.protobuf/META-INF/MANIFEST.MF
+++ b/com.google.eclipse.protobuf/META-INF/MANIFEST.MF
@@ -33,6 +33,7 @@
com.google.eclipse.protobuf.protobuf.impl,
com.google.eclipse.protobuf.protobuf.util,
com.google.eclipse.protobuf.resource,
+ com.google.eclipse.protobuf.resource.filter,
com.google.eclipse.protobuf.scoping,
com.google.eclipse.protobuf.serializer,
com.google.eclipse.protobuf.services,
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Imports.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Imports.java
index 43af49e..408118c 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Imports.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/model/util/Imports.java
@@ -13,10 +13,12 @@
import static org.eclipse.xtext.util.Strings.*;
import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.*;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.scoping.impl.ImportUriResolver;
import com.google.eclipse.protobuf.protobuf.Import;
+import com.google.eclipse.protobuf.resource.ResourceSets;
import com.google.eclipse.protobuf.scoping.ProtoDescriptorProvider;
import com.google.inject.Inject;
@@ -28,6 +30,7 @@
public class Imports {
@Inject private ProtoDescriptorProvider descriptorProvider;
@Inject private INodes nodes;
+ @Inject private ResourceSets resourceSets;
@Inject private ImportUriResolver uriResolver;
/**
@@ -98,6 +101,21 @@
}
/**
+ * Returns the resource referred by the URI of the given {@code Import}.
+ * @param anImport the given {@code Import}.
+ * @return the resource referred by the URI of the given {@code Import}, or {@code null} if the URI has not been
+ * resolved.
+ */
+ public Resource importedResource(Import anImport) {
+ URI resolvedUri = resolvedUriOf(anImport);
+ if (resolvedUri != null) {
+ ResourceSet resourceSet = anImport.eResource().getResourceSet();
+ return resourceSets.findResource(resourceSet, resolvedUri);
+ }
+ return null;
+ }
+
+ /**
* Returns the resolved URI of the given {@code Import}.
* @param anImport the the given {@code Import}.
* @return the resolved URI of the given {@code Import}, or {@code null} if the URI was not successfully resolved.
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/resource/ResourceDescriptions.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/resource/ResourceDescriptions.java
index ae13715..61b72a2 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/resource/ResourceDescriptions.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/resource/ResourceDescriptions.java
@@ -8,19 +8,18 @@
*/
package com.google.eclipse.protobuf.resource;
-import static com.google.common.base.Objects.equal;
+import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Lists.newArrayList;
import static java.util.Collections.unmodifiableList;
import java.util.List;
-import java.util.regex.*;
import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.*;
-import org.eclipse.xtext.naming.*;
+import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.*;
-import com.google.inject.*;
+import com.google.common.base.Predicate;
+import com.google.inject.Singleton;
/**
* Utility methods related to <code>{@link IResourceDescription}</code>s.
@@ -28,8 +27,6 @@
* @author alruiz@google.com (Alex Ruiz)
*/
@Singleton public class ResourceDescriptions {
- @Inject private IQualifiedNameConverter converter;
-
/**
* Finds the URI of a model object, in the given resource, whose qualified name matches the given one.
* @param resource the given resource.
@@ -48,30 +45,13 @@
}
/**
- * Finds the URIs of the model objects, in the given resource, that:
- * <ol>
- * <li>have a qualified name that match the given pattern, and</li>
- * <li>have an {@code EClass} whose name is equal to the simple name of the given type.
- * </ol>
- * @param resource the given resource.
- * @param pattern the pattern to match.
- * @param type the type of model object we are looking for.
- * @return the URI of the matching object models, or an empty list if matches could not be found.
+ * Returns the model objects that match the criteria specified in the given filter.
+ * @param resource the resource containing model objects.
+ * @param filter the filter to use.
+ * @return the model objects that match the criteria specified in the given filter.
*/
- public List<IEObjectDescription> matchingQualifiedNames(IResourceDescription resource, Pattern pattern,
- Class<? extends EObject> type) {
- List<IEObjectDescription> descriptions = newArrayList();
- for (IEObjectDescription exported : resource.getExportedObjects()) {
- QualifiedName qualifiedName = exported.getQualifiedName();
- Matcher matcher = pattern.matcher(converter.toString(qualifiedName));
- if (haveMatchingNames(exported.getEClass(), type) && matcher.matches()) {
- descriptions.add(exported);
- }
- }
- return unmodifiableList(descriptions);
- }
-
- private boolean haveMatchingNames(EClass eClass, Class<? extends EObject> type) {
- return equal(eClass.getName(), type.getSimpleName());
+ public List<IEObjectDescription> filterModelObjects(IResourceDescription resource, Predicate<IEObjectDescription> filter) {
+ List<IEObjectDescription> filtered = newArrayList(filter(resource.getExportedObjects(), filter));
+ return unmodifiableList(filtered);
}
}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/resource/filter/MatchingQualifiedNameAndTypeFilter.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/resource/filter/MatchingQualifiedNameAndTypeFilter.java
new file mode 100644
index 0000000..3bdac63
--- /dev/null
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/resource/filter/MatchingQualifiedNameAndTypeFilter.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.resource.filter;
+
+import java.util.regex.Pattern;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.xtext.naming.QualifiedName;
+import org.eclipse.xtext.resource.IEObjectDescription;
+
+import com.google.common.base.Predicate;
+
+/**
+ * Indicates whether the qualified name and {@code EClass} of a <code>{@link IEObjectDescription}</code> match the given
+ * pattern and type, respectively.
+ *
+ * @author alruiz@google.com (Alex Ruiz)
+ */
+public class MatchingQualifiedNameAndTypeFilter implements Predicate<IEObjectDescription> {
+ private final Pattern pattern;
+ private final EClass type;
+
+ /**
+ * Creates a new <code>{@link MatchingQualifiedNameAndTypeFilter}</code>.
+ * @param pattern the pattern that qualified names should match.
+ * @param type the type of model object to match.
+ * @return the created filter.
+ */
+ public static MatchingQualifiedNameAndTypeFilter matchingQualifiedNameAndType(Pattern pattern, EClass type) {
+ return new MatchingQualifiedNameAndTypeFilter(pattern, type);
+ }
+
+ private MatchingQualifiedNameAndTypeFilter(Pattern pattern, EClass type) {
+ this.pattern = pattern;
+ this.type = type;
+ }
+
+ @Override public boolean apply(IEObjectDescription input) {
+ if (!type.equals(input.getEClass())) {
+ return false;
+ }
+ QualifiedName qualifiedName = input.getQualifiedName();
+ return pattern.matcher(qualifiedName.toString()).matches();
+ }
+}
diff --git a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ImportValidator.java b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ImportValidator.java
index 9f978ac..d852659 100644
--- a/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ImportValidator.java
+++ b/com.google.eclipse.protobuf/src/com/google/eclipse/protobuf/validation/ImportValidator.java
@@ -8,7 +8,7 @@
*/
package com.google.eclipse.protobuf.validation;
-import static com.google.common.collect.Lists.newArrayList;
+import static com.google.common.collect.Maps.newHashMap;
import static com.google.common.collect.Sets.newHashSet;
import static com.google.eclipse.protobuf.protobuf.ProtobufPackage.Literals.IMPORT__IMPORT_URI;
import static com.google.eclipse.protobuf.validation.Messages.*;
@@ -17,15 +17,13 @@
import java.util.*;
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.resource.*;
+import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtext.scoping.impl.ImportUriResolver;
import org.eclipse.xtext.util.Pair;
import org.eclipse.xtext.validation.*;
import com.google.eclipse.protobuf.model.util.*;
import com.google.eclipse.protobuf.protobuf.*;
-import com.google.eclipse.protobuf.resource.ResourceSets;
import com.google.inject.Inject;
/**
@@ -37,85 +35,75 @@
@Inject private Imports imports;
@Inject private Protobufs protobufs;
@Inject private Resources resources;
- @Inject private ResourceSets resourceSets;
@Inject private ImportUriResolver uriResolver;
@Override public void register(EValidatorRegistrar registrar) {}
/**
* Verifies that {@code Import}s in the given root only refer to "proto2" files. If non-proto2 {@code Import}s are
- * found, this validator will create warning markers for such "imports".
+ * found, this validator will create warning markers for such {@code Import}s.
* @param root the root containing the imports to check.
*/
@Check public void checkNonProto2Imports(Protobuf root) {
- warnIfNonProto2ImportsFound(root.eResource());
- }
-
- private void warnIfNonProto2ImportsFound(Resource resource) {
- Protobuf root = resources.rootOf(resource);
if (!protobufs.isProto2(root)) {
return;
}
- ResourceSet resourceSet = resource.getResourceSet();
- boolean hasNonProto2 = false;
- List<Pair<Import, Resource>> resourcesToCheck = newArrayList();
- Set<URI> checked = newHashSet();
- checked.add(resource.getURI());
+ Set<Protobuf> currentlyChecking = newHashSet(root);
+ HashMap<Protobuf, IsProto2> alreadyChecked = newHashMap();
+ hasNonProto2Imports(root, currentlyChecking, alreadyChecked);
+ }
+
+ private boolean hasNonProto2Imports(Protobuf root, Set<Protobuf> currentlyChecking,
+ Map<Protobuf, IsProto2> alreadyChecked) {
+ IsProto2 isProto2 = alreadyChecked.get(root);
+ if (isProto2 != null) {
+ return isProto2 == IsProto2.NO;
+ }
+ currentlyChecking.add(root);
+ Set<Pair<Import, Protobuf>> importsToCheck = newHashSet();
+ boolean hasNonProto2Imports = false;
for (Import anImport : protobufs.importsIn(root)) {
- Resource imported = importedResource(resourceSet, anImport);
- checked.add(imported.getURI());
- if (!protobufs.isProto2(resources.rootOf(imported))) {
- hasNonProto2 = true;
+ Resource imported = imports.importedResource(anImport);
+ if (imported == null) {
+ continue;
+ }
+ Protobuf importedRoot = resources.rootOf(imported);
+ isProto2 = alreadyChecked.get(importedRoot);
+ if (isProto2 != null) {
+ // resource was already checked.
+ if (isProto2 == IsProto2.NO) {
+ hasNonProto2Imports = true;
+ warnNonProto2ImportFoundIn(anImport);
+ }
+ continue;
+ }
+ if (!protobufs.isProto2(importedRoot)) {
+ alreadyChecked.put(importedRoot, IsProto2.NO);
+ hasNonProto2Imports = true;
warnNonProto2ImportFoundIn(anImport);
continue;
}
- resourcesToCheck.add(pair(anImport, imported));
- }
- if (hasNonProto2) {
- return;
- }
- for (Pair<Import, Resource> p : resourcesToCheck) {
- if (hasNonProto2(p, checked, resourceSet)) {
- warnNonProto2ImportFoundIn(p.getFirst());
- break;
- }
- }
- }
-
- private boolean hasNonProto2(Pair<Import, Resource> toCheck, Set<URI> alreadyChecked, ResourceSet resourceSet) {
- Protobuf root = resources.rootOf(toCheck.getSecond());
- if (!protobufs.isProto2(root)) {
- return false;
- }
- List<Pair<Import, Resource>> resourcesToCheck = newArrayList();
- for (Import anImport : protobufs.importsIn(root)) {
- Resource imported = importedResource(resourceSet, anImport);
- if (alreadyChecked.contains(imported.getURI())) {
+ // we have a circular dependency
+ if (currentlyChecking.contains(importedRoot)) {
continue;
}
- if (!protobufs.isProto2(resources.rootOf(imported))) {
- return true;
- }
- resourcesToCheck.add(pair(toCheck.getFirst(), imported));
+ // this is a proto2 file. Need to check its imports.
+ importsToCheck.add(pair(anImport, importedRoot));
}
- for (Pair<Import, Resource> p : resourcesToCheck) {
- if (hasNonProto2(p, alreadyChecked, resourceSet)) {
- return true;
+ for (Pair<Import, Protobuf> importToCheck : importsToCheck) {
+ if (hasNonProto2Imports(importToCheck.getSecond(), currentlyChecking, alreadyChecked)) {
+ hasNonProto2Imports = true;
+ warnNonProto2ImportFoundIn(importToCheck.getFirst());
}
}
- return false;
- }
-
- private Resource importedResource(ResourceSet resourceSet, Import anImport) {
- URI resolvedUri = imports.resolvedUriOf(anImport);
- if (resolvedUri != null) {
- return resourceSets.findResource(resourceSet, resolvedUri);
- }
- return null;
+ isProto2 = hasNonProto2Imports ? IsProto2.NO : IsProto2.YES;
+ alreadyChecked.put(root, isProto2);
+ currentlyChecking.remove(root);
+ return hasNonProto2Imports;
}
private void warnNonProto2ImportFoundIn(Import anImport) {
- acceptWarning(importingNonProto2, anImport, IMPORT__IMPORT_URI, INSIGNIFICANT_INDEX, null);
+ warning(importingNonProto2, anImport, IMPORT__IMPORT_URI, INSIGNIFICANT_INDEX);
}
/**
@@ -132,4 +120,8 @@
error(format(importNotFound, anImport.getImportURI()), IMPORT__IMPORT_URI);
}
}
+
+ private static enum IsProto2 {
+ YES, NO;
+ }
}