2 * Copyright (c) 2000-2005 by JetBrains s.r.o. All Rights Reserved.
3 * Use is subject to license terms.
5 package com
.intellij
.patterns
;
7 import org
.jetbrains
.annotations
.NotNull
;
8 import org
.jetbrains
.annotations
.Nullable
;
10 import java
.util
.Arrays
;
15 public abstract class TreeElementPattern
<ParentType
, T
extends ParentType
, Self
extends TreeElementPattern
<ParentType
, T
, Self
>>
16 extends ObjectPattern
<T
, Self
> {
18 protected TreeElementPattern(@NotNull final NullablePatternCondition condition
) {
22 protected TreeElementPattern(final Class
<T
> aClass
) {
27 protected abstract ParentType
getParent(@NotNull ParentType parentType
);
29 protected abstract ParentType
[] getChildren(@NotNull final ParentType parentType
);
31 public Self
withParent(@NotNull final Class
<?
extends ParentType
> type
) {
32 return withParent(StandardPatterns
.type(type
));
35 public Self
withParent(@NotNull final ElementPattern pattern
) {
36 return withSuperParent(1, pattern
);
39 public Self
withChild(@NotNull final ElementPattern pattern
) {
40 return withChildren(StandardPatterns
.<ParentType
>collection().atLeastOne(pattern
));
43 public Self
withFirstChild(@NotNull final ElementPattern pattern
) {
44 return withChildren(StandardPatterns
.<ParentType
>collection().first(pattern
));
47 public Self
withLastChild(@NotNull final ElementPattern pattern
) {
48 return withChildren(StandardPatterns
.<ParentType
>collection().last(pattern
));
51 public Self
withChildren(@NotNull final ElementPattern pattern
) {
52 return with(new PatternCondition
<T
>() {
53 public boolean accepts(@NotNull final T t
, final MatchingContext matchingContext
, @NotNull final TraverseContext traverseContext
) {
54 return pattern
.accepts(Arrays
.asList(getChildren(t
)), matchingContext
, traverseContext
);
59 public Self
isFirstAcceptedChild(@NotNull final ElementPattern pattern
) {
60 return with(new PatternCondition
<T
>() {
61 public boolean accepts(@NotNull final T t
, final MatchingContext matchingContext
, @NotNull final TraverseContext traverseContext
) {
62 final ParentType parent
= getParent(t
);
64 final ParentType
[] children
= getChildren(parent
);
65 for (ParentType child
: children
) {
66 if (pattern
.accepts(child
, matchingContext
, traverseContext
)) {
77 public Self
withSuperParent(final int level
, @NotNull final ElementPattern pattern
) {
78 return with(new PatternCondition
<T
>() {
79 public boolean accepts(@NotNull final T t
, final MatchingContext matchingContext
, @NotNull final TraverseContext traverseContext
) {
80 ParentType parent
= t
;
81 for (int i
= 0; i
< level
; i
++) {
82 if (parent
== null) return false;
83 parent
= getParent(parent
);
85 return pattern
.accepts(parent
, matchingContext
, traverseContext
);
88 public String
toString() {
89 return "withSuperParent(" + level
+ ", " + pattern
+ ")";
94 public Self
inside(@NotNull final ElementPattern pattern
) {
95 return inside(false, pattern
);
98 public Self
inside(final boolean strict
, @NotNull final ElementPattern pattern
) {
99 return with(new PatternCondition
<T
>() {
100 public boolean accepts(@NotNull final T t
, final MatchingContext matchingContext
, @NotNull final TraverseContext traverseContext
) {
101 ParentType element
= strict ?
getParent(t
) : t
;
102 while (element
!= null) {
103 if (pattern
.accepts(element
, matchingContext
, traverseContext
)) return true;
104 element
= getParent(element
);