From a318dff29594f54266137d547ce562bbcc2892c4 Mon Sep 17 00:00:00 2001 From: "Eugene.Kudelevsky" Date: Tue, 11 May 2010 06:03:14 +0400 Subject: [PATCH] support for filter suffixes --- .../template/zencoding/FilterToken.java | 31 ++++++++++++ .../zencoding/XmlZenCodingFilter.java | 43 ++++++++++++++++ ...rImpl.java => XmlZenCodingFilterImpl.java} | 10 +++- .../zencoding/XmlZenCodingInterpreter.java | 50 ++++++++++++------- .../zencoding/XmlZenCodingTemplate.java | 2 +- .../template/zencoding/ZenCodingFilter.java | 9 +++- .../template/zencoding/ZenCodingTemplate.java | 12 +++++ 7 files changed, 135 insertions(+), 22 deletions(-) create mode 100644 xml/impl/src/com/intellij/codeInsight/template/zencoding/FilterToken.java create mode 100644 xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingFilter.java rename xml/impl/src/com/intellij/codeInsight/template/zencoding/{ZenCodingFilterImpl.java => XmlZenCodingFilterImpl.java} (96%) diff --git a/xml/impl/src/com/intellij/codeInsight/template/zencoding/FilterToken.java b/xml/impl/src/com/intellij/codeInsight/template/zencoding/FilterToken.java new file mode 100644 index 000000000000..4a79f392a302 --- /dev/null +++ b/xml/impl/src/com/intellij/codeInsight/template/zencoding/FilterToken.java @@ -0,0 +1,31 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.template.zencoding; + +/** + * @author Eugene.Kudelevsky + */ +public class FilterToken extends Token { + private final String mySuffix; + + public FilterToken(String suffix) { + mySuffix = suffix; + } + + public String getSuffix() { + return mySuffix; + } +} diff --git a/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingFilter.java b/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingFilter.java new file mode 100644 index 000000000000..6a54754ad259 --- /dev/null +++ b/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingFilter.java @@ -0,0 +1,43 @@ +/* + * Copyright 2000-2010 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.codeInsight.template.zencoding; + +import com.intellij.openapi.util.Pair; +import com.intellij.psi.PsiElement; +import com.intellij.psi.xml.XmlTag; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * @author Eugene.Kudelevsky + */ +public abstract class XmlZenCodingFilter implements ZenCodingFilter { + @NotNull + public String toString(@NotNull TemplateToken token, @NotNull PsiElement context) { + if (!(token instanceof XmlTemplateToken)) { + throw new IllegalArgumentException(); + } + return toString(((XmlTemplateToken)token).getTag(), context); + } + + protected abstract String toString(@NotNull XmlTag tag, @NotNull PsiElement context); + + @NotNull + public abstract String buildAttributesString(@NotNull List> attribute2value, int numberInIteration); + + public abstract boolean isMyContext(@NotNull PsiElement context); +} diff --git a/xml/impl/src/com/intellij/codeInsight/template/zencoding/ZenCodingFilterImpl.java b/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingFilterImpl.java similarity index 96% rename from xml/impl/src/com/intellij/codeInsight/template/zencoding/ZenCodingFilterImpl.java rename to xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingFilterImpl.java index 6fa11d738bff..7c39e883deab 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/zencoding/ZenCodingFilterImpl.java +++ b/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingFilterImpl.java @@ -35,7 +35,7 @@ import java.util.List; /** * @author Eugene.Kudelevsky */ -public class ZenCodingFilterImpl implements ZenCodingFilter { +public class XmlZenCodingFilterImpl extends XmlZenCodingFilter { @NotNull public String toString(@NotNull XmlTag tag, @NotNull PsiElement context) { FileType fileType = context.getContainingFile().getFileType(); @@ -64,6 +64,14 @@ public class ZenCodingFilterImpl implements ZenCodingFilter { return true; } + public String getSuffix() { + return null; + } + + public boolean isDefaultFilter() { + return true; + } + private static String getAttributeString(String name, String value) { return name + "=\"" + value + '"'; } diff --git a/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingInterpreter.java b/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingInterpreter.java index 1788fb8c5f28..3600106a09cf 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingInterpreter.java +++ b/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingInterpreter.java @@ -104,6 +104,15 @@ class XmlZenCodingInterpreter { } private void invoke(int startIndex) { + String filter = null; + + if (myTokens.size() > 0) { + Token lastToken = myTokens.get(myTokens.size() - 1); + if (lastToken instanceof FilterToken) { + filter = ((FilterToken)lastToken).getSuffix(); + } + } + final int n = myTokens.size(); TemplateToken templateToken = null; int number = -1; @@ -117,7 +126,7 @@ class XmlZenCodingInterpreter { if (sign == '+' || (mySurroundedText == null && sign == ZenCodingTemplate.MARKER)) { final Object key = new Object(); myCallback.fixStartOfTemplate(key); - invokeTemplate(templateToken, myCallback, 0); + invokeTemplate(templateToken, myCallback, 0, filter); myState = State.WORD; if (myCallback.getOffset() != myCallback.getEndOfTemplate(key)) { myCallback.fixEndOffset(); @@ -128,7 +137,7 @@ class XmlZenCodingInterpreter { templateToken = null; } else if (sign == '>' || (mySurroundedText != null && sign == ZenCodingTemplate.MARKER)) { - startTemplateAndGotoChild(templateToken); + startTemplateAndGotoChild(templateToken, filter); templateToken = null; } else if (sign == '*') { @@ -162,16 +171,16 @@ class XmlZenCodingInterpreter { if (token instanceof MarkerToken || token instanceof OperationToken) { char sign = token instanceof OperationToken ? ((OperationToken)token).getSign() : ZenCodingTemplate.MARKER; if (sign == '+' || (mySurroundedText == null && sign == ZenCodingTemplate.MARKER)) { - invokeTemplateSeveralTimes(templateToken, 0, number); + invokeTemplateSeveralTimes(templateToken, 0, number, filter); templateToken = null; } else if (number > 1) { - invokeTemplateAndProcessTail(templateToken, 0, number, i + 1); + invokeTemplateAndProcessTail(templateToken, 0, number, i + 1, filter); return; } else { assert number == 1; - startTemplateAndGotoChild(templateToken); + startTemplateAndGotoChild(templateToken, filter); templateToken = null; } myState = State.WORD; @@ -188,21 +197,22 @@ class XmlZenCodingInterpreter { finish(); } - private void startTemplateAndGotoChild(TemplateToken templateToken) { + private void startTemplateAndGotoChild(TemplateToken templateToken, String filter) { final Object key = new Object(); myCallback.fixStartOfTemplate(key); - invokeTemplate(templateToken, myCallback, 0); + invokeTemplate(templateToken, myCallback, 0, filter); myState = State.WORD; gotoChild(key); } private void invokeTemplateSeveralTimes(final TemplateToken templateToken, final int startIndex, - final int count) { + final int count, + String filter) { final Object key = new Object(); myCallback.fixStartOfTemplate(key); for (int i = startIndex; i < count; i++) { - invokeTemplate(templateToken, myCallback, i); + invokeTemplate(templateToken, myCallback, i, filter); myState = State.WORD; if (myCallback.getOffset() != myCallback.getEndOfTemplate(key)) { myCallback.fixEndOffset(); @@ -219,13 +229,14 @@ class XmlZenCodingInterpreter { private void invokeTemplateAndProcessTail(final TemplateToken templateToken, final int startIndex, final int count, - final int tailStart) { + final int tailStart, + String filter) { final Object key = new Object(); myCallback.fixStartOfTemplate(key); for (int i = startIndex; i < count; i++) { Object iterKey = new Object(); myCallback.fixStartOfTemplate(iterKey); - invokeTemplate(templateToken, myCallback, i); + invokeTemplate(templateToken, myCallback, i, filter); gotoChild(iterKey); interpret(myTokens, tailStart, myCallback, State.WORD, mySurroundedText); if (myCallback.getOffset() != myCallback.getEndOfTemplate(key)) { @@ -288,13 +299,14 @@ class XmlZenCodingInterpreter { return filter.buildAttributesString(attribute2value, numberInIteration); } } - return new ZenCodingFilterImpl().buildAttributesString(attribute2value, numberInIteration); + return new XmlZenCodingFilterImpl().buildAttributesString(attribute2value, numberInIteration); } private static void invokeTemplate(TemplateToken token, final CustomTemplateCallback callback, - int numberInIteration) { + int numberInIteration, + String filter) { if (token instanceof XmlTemplateToken && token.getTemplate() != null) { XmlTemplateToken xmlTemplateToken = (XmlTemplateToken)token; List> attr2value = new ArrayList>(xmlTemplateToken.getAttribute2Value()); @@ -309,7 +321,7 @@ class XmlZenCodingInterpreter { iterator.remove(); } } - String s = filter(tag, callback); + String s = filterXml(tag, callback, filter); assert s != null; modifiedTemplate.setString(s); removeVariablesWhichHasNoSegment(modifiedTemplate); @@ -327,14 +339,16 @@ class XmlZenCodingInterpreter { } @Nullable - private static String filter(XmlTag tag, CustomTemplateCallback callback) { + private static String filterXml(XmlTag tag, CustomTemplateCallback callback, String filterSuffix) { PsiElement context = callback.getContext(); for (ZenCodingFilter filter : ZenCodingFilter.EP_NAME.getExtensions()) { - if (filter.isMyContext(context)) { - return filter.toString(tag, context); + if ((filterSuffix == null && filter.isDefaultFilter()) || (filterSuffix != null && filterSuffix.equals(filter.getSuffix()))) { + if (filter instanceof XmlZenCodingFilter && filter.isDefaultFilter() && filter.isMyContext(context)) { + return ((XmlZenCodingFilter)filter).toString(tag, context); + } } } - return new ZenCodingFilterImpl().toString(tag, context); + return new XmlZenCodingFilterImpl().toString(tag, context); } private static void fail() { diff --git a/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingTemplate.java b/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingTemplate.java index 078f266c6010..080397ba94f5 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingTemplate.java +++ b/xml/impl/src/com/intellij/codeInsight/template/zencoding/XmlZenCodingTemplate.java @@ -282,7 +282,7 @@ public class XmlZenCodingTemplate extends ZenCodingTemplate { return true; } } - return new ZenCodingFilterImpl().isMyContext(context); + return new XmlZenCodingFilterImpl().isMyContext(context); } public static boolean startZenCoding(Editor editor, PsiFile file, String abbreviation) { diff --git a/xml/impl/src/com/intellij/codeInsight/template/zencoding/ZenCodingFilter.java b/xml/impl/src/com/intellij/codeInsight/template/zencoding/ZenCodingFilter.java index e6af19654fd4..1a92cc307b7b 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/zencoding/ZenCodingFilter.java +++ b/xml/impl/src/com/intellij/codeInsight/template/zencoding/ZenCodingFilter.java @@ -18,8 +18,8 @@ package com.intellij.codeInsight.template.zencoding; import com.intellij.openapi.extensions.ExtensionPointName; import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiElement; -import com.intellij.psi.xml.XmlTag; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -30,10 +30,15 @@ public interface ZenCodingFilter { ExtensionPointName EP_NAME = new ExtensionPointName("com.intellij.xml.zenCodingFilter"); @NotNull - String toString(@NotNull XmlTag tag, @NotNull PsiElement context); + String toString(@NotNull TemplateToken token, @NotNull PsiElement context); @NotNull String buildAttributesString(@NotNull List> attribute2value, int numberInIteration); boolean isMyContext(@NotNull PsiElement context); + + @Nullable + String getSuffix(); + + boolean isDefaultFilter(); } diff --git a/xml/impl/src/com/intellij/codeInsight/template/zencoding/ZenCodingTemplate.java b/xml/impl/src/com/intellij/codeInsight/template/zencoding/ZenCodingTemplate.java index cb9a70bc117c..392b0c3d2500 100644 --- a/xml/impl/src/com/intellij/codeInsight/template/zencoding/ZenCodingTemplate.java +++ b/xml/impl/src/com/intellij/codeInsight/template/zencoding/ZenCodingTemplate.java @@ -55,6 +55,14 @@ public abstract class ZenCodingTemplate implements CustomLiveTemplate { @Nullable private List parse(@NotNull String text, @NotNull CustomTemplateCallback callback) { + String filter = null; + + int filterDelim = text.indexOf('|'); + if (filterDelim >= 0 && filterDelim < text.length() - 1) { + filter = text.substring(filterDelim + 1); + text = text.substring(0, filterDelim); + } + text += MARKER; StringBuilder templateKeyBuilder = new StringBuilder(); List result = new ArrayList(); @@ -81,6 +89,10 @@ public abstract class ZenCodingTemplate implements CustomLiveTemplate { return null; } } + + if (filter != null) { + result.add(new FilterToken(filter)); + } return result; }