001 /*
002 * Copyright 2010-2015 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package org.jetbrains.kotlin.load.java.structure.impl;
018
019 import com.intellij.psi.*;
020 import com.intellij.psi.search.GlobalSearchScope;
021 import kotlin.KotlinPackage;
022 import kotlin.jvm.functions.Function1;
023 import org.jetbrains.annotations.NotNull;
024 import org.jetbrains.kotlin.load.java.structure.*;
025 import org.jetbrains.kotlin.name.Name;
026
027 import java.util.ArrayList;
028 import java.util.Collection;
029 import java.util.Collections;
030 import java.util.List;
031
032 public class JavaElementCollectionFromPsiArrayUtil {
033 private JavaElementCollectionFromPsiArrayUtil() {
034 }
035
036 private interface Factory<Psi, Java> {
037 @NotNull
038 Java create(@NotNull Psi psi);
039 }
040
041 private static class Factories {
042 private static final Factory<PsiClass, JavaClass> CLASSES = new Factory<PsiClass, JavaClass>() {
043 @NotNull
044 @Override
045 public JavaClass create(@NotNull PsiClass psiClass) {
046 return new JavaClassImpl(psiClass);
047 }
048 };
049
050 private static final Factory<PsiMethod, JavaMethod> METHODS = new Factory<PsiMethod, JavaMethod>() {
051 @NotNull
052 @Override
053 public JavaMethod create(@NotNull PsiMethod psiMethod) {
054 return new JavaMethodImpl(psiMethod);
055 }
056 };
057
058 private static final Factory<PsiMethod, JavaConstructor> CONSTRUCTORS = new Factory<PsiMethod, JavaConstructor>() {
059 @NotNull
060 @Override
061 public JavaConstructor create(@NotNull PsiMethod psiMethod) {
062 return new JavaConstructorImpl(psiMethod);
063 }
064 };
065
066 private static final Factory<PsiField, JavaField> FIELDS = new Factory<PsiField, JavaField>() {
067 @NotNull
068 @Override
069 public JavaField create(@NotNull PsiField psiField) {
070 return new JavaFieldImpl(psiField);
071 }
072 };
073
074 private static final Factory<PsiParameter, JavaValueParameter> VALUE_PARAMETERS = new Factory<PsiParameter, JavaValueParameter>() {
075 @NotNull
076 @Override
077 public JavaValueParameter create(@NotNull PsiParameter psiParameter) {
078 return new JavaValueParameterImpl(psiParameter);
079 }
080 };
081
082 private static final Factory<PsiTypeParameter, JavaTypeParameter> TYPE_PARAMETERS =
083 new Factory<PsiTypeParameter, JavaTypeParameter>() {
084 @NotNull
085 @Override
086 public JavaTypeParameter create(@NotNull PsiTypeParameter psiTypeParameter) {
087 return new JavaTypeParameterImpl(psiTypeParameter);
088 }
089 };
090
091 private static final Factory<PsiType, JavaType> TYPES = new Factory<PsiType, JavaType>() {
092 @NotNull
093 @Override
094 public JavaType create(@NotNull PsiType psiType) {
095 return JavaTypeImpl.create(psiType);
096 }
097 };
098
099 private static final Factory<PsiClassType, JavaClassifierType> CLASSIFIER_TYPES = new Factory<PsiClassType, JavaClassifierType>() {
100 @NotNull
101 @Override
102 public JavaClassifierType create(@NotNull PsiClassType psiClassType) {
103 return new JavaClassifierTypeImpl(psiClassType);
104 }
105 };
106
107 private static final Factory<PsiAnnotation, JavaAnnotation> ANNOTATIONS = new Factory<PsiAnnotation, JavaAnnotation>() {
108 @NotNull
109 @Override
110 public JavaAnnotation create(@NotNull PsiAnnotation psiAnnotation) {
111 return new JavaAnnotationImpl(psiAnnotation);
112 }
113 };
114
115 private static final Factory<PsiNameValuePair, JavaAnnotationArgument> NAMED_ANNOTATION_ARGUMENTS =
116 new Factory<PsiNameValuePair, JavaAnnotationArgument>() {
117 @NotNull
118 @Override
119 public JavaAnnotationArgument create(@NotNull PsiNameValuePair psiNameValuePair) {
120 String name = psiNameValuePair.getName();
121 PsiAnnotationMemberValue value = psiNameValuePair.getValue();
122 assert value != null : "Annotation argument value cannot be null: " + name;
123 return JavaAnnotationArgumentImpl.Factory.create(value, name == null ? null : Name.identifier(name));
124 }
125 };
126 }
127
128 @NotNull
129 private static <Psi, Java> List<Java> convert(@NotNull Psi[] elements, @NotNull Factory<Psi, Java> factory) {
130 if (elements.length == 0) return Collections.emptyList();
131 List<Java> result = new ArrayList<Java>(elements.length);
132 for (Psi element : elements) {
133 result.add(factory.create(element));
134 }
135 return result;
136 }
137
138 @NotNull
139 private static <Psi, Java> List<Java> convert(@NotNull Iterable<Psi> elements, @NotNull final Factory<Psi, Java> factory) {
140 if (!elements.iterator().hasNext()) return Collections.emptyList();
141 return KotlinPackage.map(elements, new Function1<Psi, Java>() {
142 @Override
143 public Java invoke(Psi psi) {
144 return factory.create(psi);
145 }
146 });
147 }
148
149 @NotNull
150 public static Collection<JavaClass> classes(@NotNull PsiClass[] classes) {
151 return convert(classes, Factories.CLASSES);
152 }
153
154 @NotNull
155 public static Collection<JavaClass> classes(@NotNull Iterable<PsiClass> classes) {
156 return convert(classes, Factories.CLASSES);
157 }
158
159 @NotNull
160 public static Collection<JavaPackage> packages(@NotNull PsiPackage[] packages, @NotNull final GlobalSearchScope scope) {
161 return convert(packages, new Factory<PsiPackage, JavaPackage>() {
162 @NotNull
163 @Override
164 public JavaPackage create(@NotNull PsiPackage aPackage) {
165 return new JavaPackageImpl(aPackage, scope);
166 }
167 });
168 }
169
170 @NotNull
171 public static Collection<JavaMethod> methods(@NotNull PsiMethod[] methods) {
172 return convert(methods, Factories.METHODS);
173 }
174
175 @NotNull
176 public static Collection<JavaMethod> methods(@NotNull Iterable<PsiMethod> methods) {
177 return convert(methods, Factories.METHODS);
178 }
179
180 @NotNull
181 public static Collection<JavaConstructor> constructors(@NotNull Iterable<PsiMethod> methods) {
182 return convert(methods, Factories.CONSTRUCTORS);
183 }
184
185 @NotNull
186 public static Collection<JavaField> fields(@NotNull Iterable<PsiField> fields) {
187 return convert(fields, Factories.FIELDS);
188 }
189
190 @NotNull
191 public static List<JavaValueParameter> valueParameters(@NotNull PsiParameter[] parameters) {
192 return convert(parameters, Factories.VALUE_PARAMETERS);
193 }
194
195 @NotNull
196 public static List<JavaTypeParameter> typeParameters(@NotNull PsiTypeParameter[] typeParameters) {
197 return convert(typeParameters, Factories.TYPE_PARAMETERS);
198 }
199
200 @NotNull
201 public static List<JavaType> types(@NotNull PsiType[] types) {
202 return convert(types, Factories.TYPES);
203 }
204
205 @NotNull
206 public static Collection<JavaClassifierType> classifierTypes(@NotNull PsiClassType[] classTypes) {
207 return convert(classTypes, Factories.CLASSIFIER_TYPES);
208 }
209
210 @NotNull
211 public static Collection<JavaAnnotation> annotations(@NotNull PsiAnnotation[] annotations) {
212 return convert(annotations, Factories.ANNOTATIONS);
213 }
214
215 @NotNull
216 public static Collection<JavaAnnotationArgument> namedAnnotationArguments(@NotNull PsiNameValuePair[] nameValuePairs) {
217 return convert(nameValuePairs, Factories.NAMED_ANNOTATION_ARGUMENTS);
218 }
219 }