diff options
5 files changed, 66 insertions, 5 deletions
diff --git a/org.eclipse.text.tests/META-INF/MANIFEST.MF b/org.eclipse.text.tests/META-INF/MANIFEST.MF index 40ec27473bd..05f4275457f 100644 --- a/org.eclipse.text.tests/META-INF/MANIFEST.MF +++ b/org.eclipse.text.tests/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Plugin.name Bundle-SymbolicName: org.eclipse.text.tests -Bundle-Version: 3.12.700.qualifier +Bundle-Version: 3.12.800.qualifier Bundle-Vendor: %Plugin.providerName Bundle-Localization: plugin Export-Package: diff --git a/org.eclipse.text.tests/pom.xml b/org.eclipse.text.tests/pom.xml index c83c53954f1..0df48e1a2b6 100644 --- a/org.eclipse.text.tests/pom.xml +++ b/org.eclipse.text.tests/pom.xml @@ -19,7 +19,7 @@ </parent> <groupId>org.eclipse.text</groupId> <artifactId>org.eclipse.text.tests</artifactId> - <version>3.12.700-SNAPSHOT</version> + <version>3.12.800-SNAPSHOT</version> <packaging>eclipse-test-plugin</packaging> <properties> <testSuite>${project.artifactId}</testSuite> diff --git a/org.eclipse.text.tests/src/org/eclipse/text/tests/templates/TemplateVariablesWordSelectionTest.java b/org.eclipse.text.tests/src/org/eclipse/text/tests/templates/TemplateVariablesWordSelectionTest.java index df8be90928f..efbb97a54d9 100644 --- a/org.eclipse.text.tests/src/org/eclipse/text/tests/templates/TemplateVariablesWordSelectionTest.java +++ b/org.eclipse.text.tests/src/org/eclipse/text/tests/templates/TemplateVariablesWordSelectionTest.java @@ -26,6 +26,7 @@ import org.eclipse.jface.text.templates.TemplateBuffer; import org.eclipse.jface.text.templates.TemplateContextType; import org.eclipse.jface.text.templates.TemplateTranslator; import org.eclipse.jface.text.templates.TemplateVariable; +import org.eclipse.jface.text.templates.TemplateVariableType; public class TemplateVariablesWordSelectionTest { @@ -65,6 +66,29 @@ public class TemplateVariablesWordSelectionTest { assertBufferStringAndVariables(expected.toString(), buffer); } + @Test + public void testMulti() throws Exception { + TemplateBuffer buffer = new TemplateTranslator() { + + @Override + protected TemplateVariable createVariable(TemplateVariableType type, String name, int[] offsets) { + if ("petType".equals(name)) { + String[] pets = new String[] { "cat", "dog", "other" }; + TemplateVariable variable = new TemplateVariable(type.getName(), name, pets, offsets); + variable.setUnambiguous(true); + return variable; + } + return super.createVariable(type, name, offsets); + } + }.translate("My favorite pet is a ${petType:String}, I love my ${petType}."); + assertEquals("My favorite pet is a cat, I love my cat.", buffer.getString()); + fType.resolve(buffer, fContext); + + StringBuilder expected = new StringBuilder(); + expected.append("My favorite pet is a cat, I love my cat."); + assertBufferStringAndVariables(expected.toString(), buffer); + } + /** * Ensures that {@link TemplateBuffer#getString()} equals the expected String and that all * {@link TemplateBuffer#getVariables()} are resolved and unambiguous. diff --git a/org.eclipse.text/META-INF/MANIFEST.MF b/org.eclipse.text/META-INF/MANIFEST.MF index c67cfa9b713..fbcad6f8538 100644 --- a/org.eclipse.text/META-INF/MANIFEST.MF +++ b/org.eclipse.text/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.text -Bundle-Version: 3.10.400.qualifier +Bundle-Version: 3.10.500.qualifier Bundle-Vendor: %providerName Bundle-Localization: plugin Export-Package: diff --git a/org.eclipse.text/src/org/eclipse/jface/text/templates/TemplateTranslator.java b/org.eclipse.text/src/org/eclipse/jface/text/templates/TemplateTranslator.java index dcb00151040..c56d826edb7 100644 --- a/org.eclipse.text/src/org/eclipse/jface/text/templates/TemplateTranslator.java +++ b/org.eclipse.text/src/org/eclipse/jface/text/templates/TemplateTranslator.java @@ -14,10 +14,15 @@ package org.eclipse.jface.text.templates; import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; +import java.util.SortedMap; +import java.util.TreeMap; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -221,9 +226,39 @@ public class TemplateTranslator { buffer.append(string.substring(complete)); TemplateVariable[] vars= createVariables(variables); + fixOffsetsAndBuffer(buffer, vars); return new TemplateBuffer(buffer.toString(), vars); } + /** + * In cases default value is provided dynamically when instantiating the variable (so not part + * of the {@link VariableDescription}), the buffer would actually contain incorrect text (name instead + * of default value) and offsets can also be inconsistent if variable name and default value have different + * length. This methods fix both buffer and variable offsets to ensure default value is used. + * @param buffer the default template string + * @param vars variables + */ + private void fixOffsetsAndBuffer(StringBuilder buffer, TemplateVariable[] vars) { + SortedMap<Integer, TemplateVariable> varsByOffset = new TreeMap<>(); + for (TemplateVariable var : vars) { + for (int offset : var.getOffsets()) { + varsByOffset.put(Integer.valueOf(offset), var); + } + } + int totalOffsetDelta = 0; + Map<TemplateVariable, Collection<Integer>> fixedOffsets = new HashMap<>(vars.length, 1.f); + for (Entry<Integer, TemplateVariable> entry : varsByOffset.entrySet()) { + final int initialOffset = entry.getKey().intValue(); + TemplateVariable variable = entry.getValue(); + final int fixedOffset = initialOffset + totalOffsetDelta; + fixedOffsets.computeIfAbsent(variable, v -> new ArrayList<>(v.getOffsets().length)).add(Integer.valueOf(fixedOffset)); + int currentOffsetDelta = variable.getDefaultValue().length() - variable.getName().length(); + buffer.replace(fixedOffset, fixedOffset + variable.getName().length(), variable.getDefaultValue()); + totalOffsetDelta += currentOffsetDelta; + } + fixedOffsets.forEach((variable, fixs) -> variable.setOffsets(fixs.stream().mapToInt(Integer::valueOf).toArray())); + } + private TemplateVariableType createType(String typeName, String paramString) { if (typeName == null) return null; @@ -237,7 +272,7 @@ public class TemplateTranslator { String argument= matcher.group(); if (argument.charAt(0) == '\'') { // argumentText - argument= argument.substring(1, argument.length() - 1).replaceAll("''", "'"); //$NON-NLS-1$ //$NON-NLS-2$ + argument= argument.substring(1, argument.length() - 1).replace("''", "'"); //$NON-NLS-1$ //$NON-NLS-2$ } params.add(argument); @@ -260,10 +295,11 @@ public class TemplateTranslator { * @param name the name of the variable * @param type the variable type, <code>null</code> for not defined * @param offset the buffer offset of the variable + * @return the variable description found or created for that name * @throws TemplateException if merging the type fails * @since 3.3 */ - private void updateOrCreateVariable(Map<String, VariableDescription> variables, String name, TemplateVariableType type, int offset) throws TemplateException { + private VariableDescription updateOrCreateVariable(Map<String, VariableDescription> variables, String name, TemplateVariableType type, int offset) throws TemplateException { VariableDescription varDesc= variables.get(name); if (varDesc == null) { varDesc= new VariableDescription(name, type); @@ -272,6 +308,7 @@ public class TemplateTranslator { varDesc.mergeType(type); } varDesc.fOffsets.add(Integer.valueOf(offset)); + return varDesc; } /** |