001    /*
002     * Copyright 2010-2014 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.jet.lang.resolve.java.structure.impl;
018    
019    import com.intellij.psi.*;
020    import kotlin.Function1;
021    import kotlin.KotlinPackage;
022    import org.jetbrains.annotations.NotNull;
023    import org.jetbrains.jet.lang.resolve.java.structure.*;
024    import org.jetbrains.jet.lang.resolve.name.Name;
025    
026    import java.util.ArrayList;
027    import java.util.Collection;
028    import java.util.Collections;
029    import java.util.List;
030    
031    public class JavaElementCollectionFromPsiArrayUtil {
032        private JavaElementCollectionFromPsiArrayUtil() {
033        }
034    
035        private interface Factory<Psi, Java> {
036            @NotNull
037            Java create(@NotNull Psi psi);
038        }
039    
040        private static class Factories {
041            private static final Factory<PsiClass, JavaClass> CLASSES = new Factory<PsiClass, JavaClass>() {
042                @NotNull
043                @Override
044                public JavaClass create(@NotNull PsiClass psiClass) {
045                    return new JavaClassImpl(psiClass);
046                }
047            };
048    
049            private static final Factory<PsiPackage, JavaPackage> PACKAGES = new Factory<PsiPackage, JavaPackage>() {
050                @NotNull
051                @Override
052                public JavaPackage create(@NotNull PsiPackage psiPackage) {
053                    return new JavaPackageImpl(psiPackage);
054                }
055            };
056    
057            private static final Factory<PsiMethod, JavaMethod> METHODS = new Factory<PsiMethod, JavaMethod>() {
058                @NotNull
059                @Override
060                public JavaMethod create(@NotNull PsiMethod psiMethod) {
061                    return new JavaMethodImpl(psiMethod);
062                }
063            };
064    
065            private static final Factory<PsiMethod, JavaConstructor> CONSTRUCTORS = new Factory<PsiMethod, JavaConstructor>() {
066                @NotNull
067                @Override
068                public JavaConstructor create(@NotNull PsiMethod psiMethod) {
069                    return new JavaConstructorImpl(psiMethod);
070                }
071            };
072    
073            private static final Factory<PsiField, JavaField> FIELDS = new Factory<PsiField, JavaField>() {
074                @NotNull
075                @Override
076                public JavaField create(@NotNull PsiField psiField) {
077                    return new JavaFieldImpl(psiField);
078                }
079            };
080    
081            private static final Factory<PsiParameter, JavaValueParameter> VALUE_PARAMETERS = new Factory<PsiParameter, JavaValueParameter>() {
082                @NotNull
083                @Override
084                public JavaValueParameter create(@NotNull PsiParameter psiParameter) {
085                    return new JavaValueParameterImpl(psiParameter);
086                }
087            };
088    
089            private static final Factory<PsiTypeParameter, JavaTypeParameter> TYPE_PARAMETERS =
090                    new Factory<PsiTypeParameter, JavaTypeParameter>() {
091                @NotNull
092                @Override
093                public JavaTypeParameter create(@NotNull PsiTypeParameter psiTypeParameter) {
094                    return new JavaTypeParameterImpl(psiTypeParameter);
095                }
096            };
097    
098            private static final Factory<PsiType, JavaType> TYPES = new Factory<PsiType, JavaType>() {
099                @NotNull
100                @Override
101                public JavaType create(@NotNull PsiType psiType) {
102                    return JavaTypeImpl.create(psiType);
103                }
104            };
105    
106            private static final Factory<PsiClassType, JavaClassifierType> CLASSIFIER_TYPES = new Factory<PsiClassType, JavaClassifierType>() {
107                @NotNull
108                @Override
109                public JavaClassifierType create(@NotNull PsiClassType psiClassType) {
110                    return new JavaClassifierTypeImpl(psiClassType);
111                }
112            };
113    
114            private static final Factory<PsiAnnotation, JavaAnnotation> ANNOTATIONS = new Factory<PsiAnnotation, JavaAnnotation>() {
115                @NotNull
116                @Override
117                public JavaAnnotation create(@NotNull PsiAnnotation psiAnnotation) {
118                    return new JavaAnnotationImpl(psiAnnotation);
119                }
120            };
121    
122            private static final Factory<PsiNameValuePair, JavaAnnotationArgument> NAMED_ANNOTATION_ARGUMENTS =
123                    new Factory<PsiNameValuePair, JavaAnnotationArgument>() {
124                @NotNull
125                @Override
126                public JavaAnnotationArgument create(@NotNull PsiNameValuePair psiNameValuePair) {
127                    String name = psiNameValuePair.getName();
128                    PsiAnnotationMemberValue value = psiNameValuePair.getValue();
129                    assert value != null : "Annotation argument value cannot be null: " + name;
130                    return JavaAnnotationArgumentImpl.OBJECT$.create(value, name == null ? null : Name.identifier(name));
131                }
132            };
133        }
134    
135        @NotNull
136        private static <Psi, Java> List<Java> convert(@NotNull Psi[] elements, @NotNull Factory<Psi, Java> factory) {
137            if (elements.length == 0) return Collections.emptyList();
138            List<Java> result = new ArrayList<Java>(elements.length);
139            for (Psi element : elements) {
140                result.add(factory.create(element));
141            }
142            return result;
143        }
144    
145        @NotNull
146        private static <Psi, Java> List<Java> convert(@NotNull Iterable<Psi> elements, @NotNull final Factory<Psi, Java> factory) {
147            if (!elements.iterator().hasNext()) return Collections.emptyList();
148            return KotlinPackage.map(elements, new Function1<Psi, Java>() {
149                @Override
150                public Java invoke(Psi psi) {
151                    return factory.create(psi);
152                }
153            });
154        }
155    
156        @NotNull
157        public static Collection<JavaClass> classes(@NotNull PsiClass[] classes) {
158            return convert(classes, Factories.CLASSES);
159        }
160    
161        @NotNull
162        public static Collection<JavaClass> classes(@NotNull Iterable<PsiClass> classes) {
163            return convert(classes, Factories.CLASSES);
164        }
165    
166        @NotNull
167        public static Collection<JavaPackage> packages(@NotNull PsiPackage[] packages) {
168            return convert(packages, Factories.PACKAGES);
169        }
170    
171        @NotNull
172        public static Collection<JavaMethod> methods(@NotNull PsiMethod[] methods) {
173            return convert(methods, Factories.METHODS);
174        }
175    
176        @NotNull
177        public static Collection<JavaMethod> methods(@NotNull Iterable<PsiMethod> methods) {
178            return convert(methods, Factories.METHODS);
179        }
180    
181        @NotNull
182        public static Collection<JavaConstructor> constructors(@NotNull PsiMethod[] methods) {
183            return convert(methods, Factories.CONSTRUCTORS);
184        }
185    
186        @NotNull
187        public static Collection<JavaField> fields(@NotNull PsiField[] fields) {
188            return convert(fields, Factories.FIELDS);
189        }
190    
191        @NotNull
192        public static List<JavaValueParameter> valueParameters(@NotNull PsiParameter[] parameters) {
193            return convert(parameters, Factories.VALUE_PARAMETERS);
194        }
195    
196        @NotNull
197        public static List<JavaTypeParameter> typeParameters(@NotNull PsiTypeParameter[] typeParameters) {
198            return convert(typeParameters, Factories.TYPE_PARAMETERS);
199        }
200    
201        @NotNull
202        public static List<JavaType> types(@NotNull PsiType[] types) {
203            return convert(types, Factories.TYPES);
204        }
205    
206        @NotNull
207        public static Collection<JavaClassifierType> classifierTypes(@NotNull PsiClassType[] classTypes) {
208            return convert(classTypes, Factories.CLASSIFIER_TYPES);
209        }
210    
211        @NotNull
212        public static Collection<JavaAnnotation> annotations(@NotNull PsiAnnotation[] annotations) {
213            return convert(annotations, Factories.ANNOTATIONS);
214        }
215    
216        @NotNull
217        public static Collection<JavaAnnotationArgument> namedAnnotationArguments(@NotNull PsiNameValuePair[] nameValuePairs) {
218            return convert(nameValuePairs, Factories.NAMED_ANNOTATION_ARGUMENTS);
219        }
220    }