From 2d56c8ad24fab3e77195b1f4db2835140db1518c Mon Sep 17 00:00:00 2001 From: peter Date: Mon, 30 May 2016 15:57:11 +0200 Subject: [PATCH] IDEA-156772 Some Live Templates lost their "applicable context" IntelliJ 2016.2 EAP --- .../template/LiveTemplateTest.groovy | 17 ++++++++-- .../template/impl/TemplateContext.java | 31 ++++++++++++++----- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy index 5cf4f3996813..b4219ced7135 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy @@ -583,6 +583,19 @@ class Outer { assert write.children.size() == 3 : JDOMUtil.writeElement(write) } + public void "test use default context when empty"() { + def context = new TemplateContext() + context.readTemplateContext(new Element("context")) + + def defContext = new TemplateContext() + def commentContext = TemplateContextType.EP_NAME.findExtension(JavaCommentContextType) + defContext.putValue(commentContext, true) + + context.setDefaultContext(defContext) + assert context.isEnabled(commentContext) + assert !context.isEnabled(TemplateContextType.EP_NAME.findExtension(JavaCodeContextType.Generic)) + } + private boolean isApplicable(String text, TemplateImpl inst) throws IOException { configureFromFileText("a.java", text); return TemplateManagerImpl.isApplicable(myFixture.getFile(), getEditor().getCaretModel().getOffset(), inst); @@ -1057,7 +1070,7 @@ class Foo {{ }} """ } - + public void "test add new line on enter outside editing variable"() { myFixture.configureByText 'a.java', """ class Foo {{ @@ -1074,7 +1087,7 @@ class Foo {{ }} """ } - + public void "test type tab character on tab outside editing variable"() { myFixture.configureByText 'a.java', """ class Foo {{ diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateContext.java b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateContext.java index eef4bb1f79ac..1e273434fef4 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateContext.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/impl/TemplateContext.java @@ -82,7 +82,8 @@ public class TemplateContext { } // used during initialization => no sync - void setDefaultContext(@NotNull TemplateContext defContext) { + @VisibleForTesting + public void setDefaultContext(@NotNull TemplateContext defContext) { HashMap copy = new HashMap(myContextStates); myContextStates.clear(); myContextStates.putAll(defContext.myContextStates); @@ -100,14 +101,30 @@ public class TemplateContext { } } + myContextStates.putAll(makeInheritanceExplicit()); + } + + /** + * Mark contexts explicitly as excluded which are excluded because some of their bases is explicitly marked as excluded. + * Otherwise that `excluded` status will be forgotten if the base context is enabled. + */ + @NotNull + private Map makeInheritanceExplicit() { Map explicitStates = ContainerUtil.newHashMap(); - for (TemplateContextType type : TemplateManagerImpl.getAllContextTypes()) { - if (getOwnValue(type) == null) { - Iterable bases = JBIterable.generate(type, TemplateContextType::getBaseContextType); - explicitStates.put(type.getContextId(), ContainerUtil.getFirstItem(ContainerUtil.mapNotNull(bases, this::getOwnValue), false)); - } + for (TemplateContextType type : ContainerUtil.filter(TemplateManagerImpl.getAllContextTypes(), this::isDisabledByInheritance)) { + explicitStates.put(type.getContextId(), false); } - myContextStates.putAll(explicitStates); + return explicitStates; + } + + private boolean isDisabledByInheritance(TemplateContextType type) { + return !hasOwnValue(type) && + !isEnabled(type) && + JBIterable.generate(type, TemplateContextType::getBaseContextType).filter(this::hasOwnValue).first() != null; + } + + private boolean hasOwnValue(TemplateContextType t) { + return getOwnValue(t) != null; } @VisibleForTesting