Fixed: [Issue 4] Make auto-complete of '[packed = true]' available only to primitive types
https://code.google.com/p/protobuf-dt/issues/detail?id=4
Both "smart semicolon" command and content assist now check that the property is repeated *and* primitive before inserting or proposing 'packed=true'.
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/SmartSemicolonHandler.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/SmartSemicolonHandler.java
index 2ccb99f..6912347 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/SmartSemicolonHandler.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/commands/SmartSemicolonHandler.java
@@ -20,9 +20,12 @@
import org.eclipse.xtext.ui.editor.contentassist.antlr.ParserBasedContentAssistContextFactory;
import org.eclipse.xtext.util.concurrent.IUnitOfWork;
-import com.google.eclipse.protobuf.protobuf.*;
-import com.google.eclipse.protobuf.ui.grammar.*;
-import com.google.eclipse.protobuf.ui.util.*;
+import com.google.eclipse.protobuf.protobuf.Literal;
+import com.google.eclipse.protobuf.protobuf.Property;
+import com.google.eclipse.protobuf.ui.grammar.CompoundElements;
+import com.google.eclipse.protobuf.ui.grammar.Keywords;
+import com.google.eclipse.protobuf.ui.util.Literals;
+import com.google.eclipse.protobuf.ui.util.Properties;
import com.google.inject.Inject;
/**
@@ -101,21 +104,36 @@
private String contentToInsert(String line, Property property) {
boolean hasIndexAlready = PROPERTY_WITH_INDEX.matcher(line).matches();
- if (hasIndexAlready) return semicolon;
+ if (hasIndexAlready) {
+ // we can still insert '[packed = true]' if necessary
+ if (shouldInsertPackedOption(property)) {
+ String content = compoundElements.packedInBrackets() + semicolon;
+ return addSpaceAtBeginning(line, content);
+ }
+ return semicolon;
+ }
int index = properties.calculateIndexOf(property);
- if (REPEATED.equals(property.getModifier())) {
+ if (shouldInsertPackedOption(property)) {
String format = "= %d " + compoundElements.packedInBrackets() + "%s";
return indexAndSemicolonToInsert(format, line, index);
}
return defaultIndexAndSemicolonToInsert(line, index);
}
+ private boolean shouldInsertPackedOption(Property property) {
+ return REPEATED.equals(property.getModifier()) && properties.isPrimitiveProperty(property);
+ }
+
private String defaultIndexAndSemicolonToInsert(String line, int index) {
return indexAndSemicolonToInsert("= %d%s", line, index);
}
private String indexAndSemicolonToInsert(String format, String line, int index) {
String content = String.format(format, index, semicolon);
- return (line.endsWith(" ")) ? content : " " + content;
+ return addSpaceAtBeginning(line, content);
+ }
+
+ private String addSpaceAtBeginning(String line, String contentToInsert) {
+ return (line.endsWith(" ")) ? contentToInsert : " " + contentToInsert;
}
}
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 253046f..2afcb2d 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
@@ -24,7 +24,8 @@
import com.google.eclipse.protobuf.protobuf.*;
import com.google.eclipse.protobuf.protobuf.Enum;
import com.google.eclipse.protobuf.scoping.GlobalScope;
-import com.google.eclipse.protobuf.ui.grammar.*;
+import com.google.eclipse.protobuf.ui.grammar.CompoundElements;
+import com.google.eclipse.protobuf.ui.grammar.Keywords;
import com.google.eclipse.protobuf.ui.labeling.Images;
import com.google.eclipse.protobuf.ui.util.*;
import com.google.eclipse.protobuf.util.EObjectFinder;
@@ -197,13 +198,16 @@
}
acceptor.accept(proposal);
}
- if (REPEATED.equals(modifier)) proposeAndAccept(compoundElements.packedInBrackets(), context, acceptor);
+ if (REPEATED.equals(modifier) && properties.isPrimitiveProperty(p))
+ proposeAndAccept(compoundElements.packedInBrackets(), context, acceptor);
return true;
}
private void proposePackedOption(ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
- Modifier modifier = extractModifierFromModel(context);
- if (!REPEATED.equals(modifier)) return;
+ Property p = extractPropertyFrom(context);
+ if (p == null) return;
+ Modifier modifier = p.getModifier();
+ if (!REPEATED.equals(modifier) || !properties.isPrimitiveProperty(p)) return;
proposeAndAccept(compoundElements.packed(), context, acceptor);
}
@@ -225,11 +229,16 @@
}
private Modifier extractModifierFromModel(ContentAssistContext context) {
+ Property p = extractPropertyFrom(context);
+ return (p == null) ? null : p.getModifier();
+ }
+
+ private Property extractPropertyFrom(ContentAssistContext context) {
EObject model = context.getCurrentModel();
// this is most likely a bug in Xtext:
if (!(model instanceof Property)) model = context.getPreviousModel();
if (!(model instanceof Property)) return null;
- return ((Property) model).getModifier();
+ return (Property) model;
}
private boolean isStringProperty(Property p) {
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/grammar/Keywords.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/grammar/Keywords.java
index 7030ca6..da6154f 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/grammar/Keywords.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/grammar/Keywords.java
@@ -12,9 +12,11 @@
import java.util.List;
-import org.eclipse.xtext.*;
+import org.eclipse.xtext.IGrammarAccess;
+import org.eclipse.xtext.Keyword;
-import com.google.inject.*;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
/**
* @author alruiz@google.com (Alex Ruiz)
@@ -25,6 +27,7 @@
private Keyword bool;
private Keyword boolTrue;
private Keyword boolFalse;
+ private Keyword bytes;
private Keyword openingBracket;
private Keyword closingBracket;
private Keyword defaultValue;
@@ -39,6 +42,7 @@
if (assignIfIsBool(k)) continue;
if (assignIfIsBoolTrue(k)) continue;
if (assignIfIsBoolFalse(k)) continue;
+ if (assignIfIsBytes(k)) continue;
if (assignIfIsOpeningBracket(k)) continue;
if (assignIfIsClosingBracket(k)) continue;
if (assignIfIsDefaultValue(k)) continue;
@@ -67,6 +71,12 @@
return true;
}
+ private boolean assignIfIsBytes(Keyword k) {
+ if (!isKeywordValue(k, "bytes")) return false;
+ bytes = k;
+ return true;
+ }
+
private boolean assignIfIsOpeningBracket(Keyword k) {
if (!isKeywordValue(k, "[")) return false;
openingBracket = k;
@@ -125,6 +135,10 @@
return boolFalse;
}
+ public Keyword bytes() {
+ return bytes;
+ }
+
public Keyword openingBracket() {
return openingBracket;
}
diff --git a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Properties.java b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Properties.java
index 7e2fadc..74d1b0b 100644
--- a/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Properties.java
+++ b/com.google.eclipse.protobuf.ui/src/com/google/eclipse/protobuf/ui/util/Properties.java
@@ -27,6 +27,13 @@
@Inject private Keywords keywords;
+ public boolean isPrimitiveProperty(Property p) {
+ AbstractTypeReference r = p.getType();
+ if (!(r instanceof ScalarTypeReference)) return false;
+ String typeName = ((ScalarTypeReference) r).getScalar().getName();
+ return !keywords.string().getValue().equals(typeName) && !keywords.bytes().getValue().equals(typeName);
+ }
+
public boolean isStringProperty(Property p) {
return keywords.string().getValue().equals(nameOfTypeIn(p));
}