• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014, Google Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  *     * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *     * Neither the name of Google Inc. nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 package org.jf.smalidea.psi.impl;
33 
34 import com.google.common.collect.ImmutableList;
35 import com.intellij.lang.ASTNode;
36 import com.intellij.psi.PsiElement;
37 import com.intellij.psi.impl.source.tree.CompositePsiElement;
38 import com.intellij.psi.tree.IElementType;
39 import org.jetbrains.annotations.NotNull;
40 import org.jetbrains.annotations.Nullable;
41 
42 import java.lang.reflect.Array;
43 import java.util.ArrayList;
44 import java.util.List;
45 
46 public abstract class SmaliCompositeElement extends CompositePsiElement {
SmaliCompositeElement(IElementType type)47     public SmaliCompositeElement(IElementType type) {
48         super(type);
49     }
50 
51     @NotNull
52     @SuppressWarnings("unchecked")
findChildrenByType(IElementType elementType)53     protected List<ASTNode> findChildrenByType(IElementType elementType) {
54         List<ASTNode> result = ImmutableList.of();
55         ASTNode child = getNode().getFirstChildNode();
56         while (child != null) {
57             if (elementType == child.getElementType()) {
58                 if (result.size() == 0) {
59                     result = new ArrayList<ASTNode>();
60                 }
61                 result.add((ASTNode)child.getPsi());
62             }
63             child = child.getTreeNext();
64         }
65         return result;
66     }
67 
68     @NotNull
69     @SuppressWarnings("unchecked")
findChildrenByClass(Class<T> aClass)70     protected <T> T[] findChildrenByClass(Class<T> aClass) {
71         List<T> result = new ArrayList<T>();
72         for (PsiElement cur = getFirstChild(); cur != null; cur = cur.getNextSibling()) {
73             if (aClass.isInstance(cur)) result.add((T)cur);
74         }
75         return result.toArray((T[]) Array.newInstance(aClass, result.size()));
76     }
77 
78     @Nullable
79     @SuppressWarnings("unchecked")
findChildByClass(Class<T> aClass)80     protected <T> T findChildByClass(Class<T> aClass) {
81         for (PsiElement cur = getFirstChild(); cur != null; cur = cur.getNextSibling()) {
82             if (aClass.isInstance(cur)) return (T)cur;
83         }
84         return null;
85     }
86 
87     @Nullable
88     @SuppressWarnings("unchecked")
findAncestorByClass(Class<T> aClass)89     protected <T> T findAncestorByClass(Class<T> aClass) {
90         PsiElement parent = getParent();
91         while (parent != null) {
92             if (aClass.isInstance(parent)) {
93                 return (T)parent;
94             }
95             parent = parent.getParent();
96         }
97         return null;
98     }
99 
100     @Nullable
101     @SuppressWarnings("unchecked")
findNextSiblingByClass(@otNull Class<T> cls)102     public <T> T findNextSiblingByClass(@NotNull Class<T> cls) {
103         PsiElement prev = getNextSibling();
104         while (true) {
105             if (prev == null) {
106                 return null;
107             } else if (cls.isInstance(prev)) {
108                 return (T)prev;
109             }
110             prev = prev.getNextSibling();
111         }
112     }
113 
114     @Nullable
115     @SuppressWarnings("unchecked")
findPrevSiblingByClass(@otNull Class<T> cls)116     public <T> T findPrevSiblingByClass(@NotNull Class<T> cls) {
117         PsiElement prev = getPrevSibling();
118         while (true) {
119             if (prev == null) {
120                 return null;
121             } else if (cls.isInstance(prev)) {
122                 return (T)prev;
123             }
124             prev = prev.getPrevSibling();
125         }
126     }
127 }
128