diff --git a/platform/core-api/src/com/intellij/patterns/ElementPatternCondition.java b/platform/core-api/src/com/intellij/patterns/ElementPatternCondition.java index 68284cb63de1..fd527cee6cb6 100644 --- a/platform/core-api/src/com/intellij/patterns/ElementPatternCondition.java +++ b/platform/core-api/src/com/intellij/patterns/ElementPatternCondition.java @@ -27,7 +27,7 @@ import java.util.List; * @author peter */ @SuppressWarnings("ForLoopReplaceableByForEach") -public class ElementPatternCondition { +public final class ElementPatternCondition { private final InitialPatternCondition myInitialCondition; private final List> myConditions; @@ -37,8 +37,12 @@ public class ElementPatternCondition { myConditions = Collections.emptyList(); } - protected ElementPatternCondition(final ElementPatternCondition original, - final PatternCondition condition) { + ElementPatternCondition(InitialPatternCondition initialCondition, List> conditions) { + myInitialCondition = initialCondition; + myConditions = conditions; + } + + private ElementPatternCondition(ElementPatternCondition original, PatternCondition condition) { myInitialCondition = original.getInitialCondition(); myConditions = new SmartList>(original.getConditions()); myConditions.add(condition); diff --git a/platform/core-api/src/com/intellij/patterns/ObjectPattern.java b/platform/core-api/src/com/intellij/patterns/ObjectPattern.java index 5a6a9c62054b..fd86e3fd7113 100644 --- a/platform/core-api/src/com/intellij/patterns/ObjectPattern.java +++ b/platform/core-api/src/com/intellij/patterns/ObjectPattern.java @@ -24,24 +24,23 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; +import java.util.*; /** * @author peter */ public abstract class ObjectPattern> implements Cloneable, ElementPattern { - private ElementPatternCondition myCondition; + private InitialPatternCondition myInitialCondition; + private Object myConditions; protected ObjectPattern(@NotNull final InitialPatternCondition condition) { - myCondition = new ElementPatternCondition(condition); + myInitialCondition = condition; + myConditions = null; } protected ObjectPattern(final Class aClass) { - final Condition checker = InstanceofCheckerGenerator.getInstance().getInstanceofChecker(aClass); - myCondition = new ElementPatternCondition(new InitialPatternCondition(aClass) { + this(new InitialPatternCondition(aClass) { + final Condition checker = InstanceofCheckerGenerator.getInstance().getInstanceofChecker(aClass); public boolean accepts(@Nullable final Object o, final ProcessingContext context) { return checker.value(o); } @@ -49,15 +48,38 @@ public abstract class ObjectPattern> impl } public final boolean accepts(@Nullable Object t) { - return myCondition.accepts(t, new ProcessingContext()); + return accepts(t, new ProcessingContext()); } + @SuppressWarnings("unchecked") public boolean accepts(@Nullable final Object o, final ProcessingContext context) { - return myCondition.accepts(o, context); + if (!myInitialCondition.accepts(o, context)) return false; + if (myConditions == null) return true; + if (o == null) return false; + + if (myConditions instanceof PatternCondition) { + return ((PatternCondition)myConditions).accepts(o, context); + } + + List> list = (List>)myConditions; + final int listSize = list.size(); + //noinspection ForLoopReplaceableByForEach + for (int i = 0; i < listSize; i++) { + if (!list.get(i).accepts((T)o, context)) return false; + } + return true; } - public final ElementPatternCondition getCondition() { - return myCondition; + @SuppressWarnings("unchecked") + public final ElementPatternCondition getCondition() { + if (myConditions == null) { + return new ElementPatternCondition(myInitialCondition); + } + if (myConditions instanceof PatternCondition) { + PatternCondition singleCondition = (PatternCondition)myConditions; + return new ElementPatternCondition(myInitialCondition, Collections.>singletonList(singleCondition)); + } + return new ElementPatternCondition(myInitialCondition, (List)myConditions); } public Self andNot(final ElementPattern pattern) { @@ -172,14 +194,17 @@ public abstract class ObjectPattern> impl } public Self with(final PatternCondition pattern) { - final ElementPatternCondition condition = myCondition.append(pattern); + final ElementPatternCondition condition = getCondition().append(pattern); return adapt(condition); } private Self adapt(final ElementPatternCondition condition) { try { final ObjectPattern s = (ObjectPattern)clone(); - s.myCondition = condition; + s.myInitialCondition = condition.getInitialCondition(); + List> conditions = condition.getConditions(); + s.myConditions = conditions.isEmpty() ? null : conditions.size() == 1 ? conditions.get(0) : conditions; + //noinspection unchecked return (Self)s; } catch (CloneNotSupportedException e) { @@ -196,7 +221,7 @@ public abstract class ObjectPattern> impl } public String toString() { - return myCondition.toString(); + return getCondition().toString(); } public static class Capture extends ObjectPattern> {