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