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<PsiField, JavaField> FIELDS = new Factory<PsiField, JavaField>() {
066                @NotNull
067                @Override
068                public JavaField create(@NotNull PsiField psiField) {
069                    return new JavaFieldImpl(psiField);
070                }
071            };
072    
073            private static final Factory<PsiParameter, JavaValueParameter> VALUE_PARAMETERS = new Factory<PsiParameter, JavaValueParameter>() {
074                @NotNull
075                @Override
076                public JavaValueParameter create(@NotNull PsiParameter psiParameter) {
077                    return new JavaValueParameterImpl(psiParameter);
078                }
079            };
080    
081            private static final Factory<PsiTypeParameter, JavaTypeParameter> TYPE_PARAMETERS =
082                    new Factory<PsiTypeParameter, JavaTypeParameter>() {
083                @NotNull
084                @Override
085                public JavaTypeParameter create(@NotNull PsiTypeParameter psiTypeParameter) {
086                    return new JavaTypeParameterImpl(psiTypeParameter);
087                }
088            };
089    
090            private static final Factory<PsiType, JavaType> TYPES = new Factory<PsiType, JavaType>() {
091                @NotNull
092                @Override
093                public JavaType create(@NotNull PsiType psiType) {
094                    return JavaTypeImpl.create(psiType);
095                }
096            };
097    
098            private static final Factory<PsiClassType, JavaClassifierType> CLASSIFIER_TYPES = new Factory<PsiClassType, JavaClassifierType>() {
099                @NotNull
100                @Override
101                public JavaClassifierType create(@NotNull PsiClassType psiClassType) {
102                    return new JavaClassifierTypeImpl(psiClassType);
103                }
104            };
105    
106            private static final Factory<PsiAnnotation, JavaAnnotation> ANNOTATIONS = new Factory<PsiAnnotation, JavaAnnotation>() {
107                @NotNull
108                @Override
109                public JavaAnnotation create(@NotNull PsiAnnotation psiAnnotation) {
110                    return new JavaAnnotationImpl(psiAnnotation);
111                }
112            };
113    
114            private static final Factory<PsiAnnotationMemberValue, JavaAnnotationArgument> NAMELESS_ANNOTATION_ARGUMENTS =
115                    new Factory<PsiAnnotationMemberValue, JavaAnnotationArgument>() {
116                @NotNull
117                @Override
118                public JavaAnnotationArgument create(@NotNull PsiAnnotationMemberValue psiAnnotationMemberValue) {
119                    return JavaAnnotationArgumentImpl.create(psiAnnotationMemberValue, null);
120                }
121            };
122    
123            private static final Factory<PsiNameValuePair, JavaAnnotationArgument> NAMED_ANNOTATION_ARGUMENTS =
124                    new Factory<PsiNameValuePair, JavaAnnotationArgument>() {
125                @NotNull
126                @Override
127                public JavaAnnotationArgument create(@NotNull PsiNameValuePair psiNameValuePair) {
128                    String name = psiNameValuePair.getName();
129                    PsiAnnotationMemberValue value = psiNameValuePair.getValue();
130                    assert value != null : "Annotation argument value cannot be null: " + name;
131                    return JavaAnnotationArgumentImpl.create(value, name == null ? null : Name.identifier(name));
132                }
133            };
134        }
135    
136        @NotNull
137        private static <Psi, Java> List<Java> convert(@NotNull Psi[] elements, @NotNull Factory<Psi, Java> factory) {
138            if (elements.length == 0) return Collections.emptyList();
139            List<Java> result = new ArrayList<Java>(elements.length);
140            for (Psi element : elements) {
141                result.add(factory.create(element));
142            }
143            return result;
144        }
145    
146        @NotNull
147        private static <Psi, Java> List<Java> convert(@NotNull Iterable<Psi> elements, @NotNull final Factory<Psi, Java> factory) {
148            if (!elements.iterator().hasNext()) return Collections.emptyList();
149            return KotlinPackage.map(elements, new Function1<Psi, Java>() {
150                @Override
151                public Java invoke(Psi psi) {
152                    return factory.create(psi);
153                }
154            });
155        }
156    
157        @NotNull
158        public static Collection<JavaClass> classes(@NotNull PsiClass[] classes) {
159            return convert(classes, Factories.CLASSES);
160        }
161    
162        @NotNull
163        public static Collection<JavaClass> classes(@NotNull Iterable<PsiClass> classes) {
164            return convert(classes, Factories.CLASSES);
165        }
166    
167        @NotNull
168        public static Collection<JavaPackage> packages(@NotNull PsiPackage[] packages) {
169            return convert(packages, Factories.PACKAGES);
170        }
171    
172        @NotNull
173        public static Collection<JavaMethod> methods(@NotNull PsiMethod[] methods) {
174            return convert(methods, Factories.METHODS);
175        }
176    
177        @NotNull
178        public static Collection<JavaField> fields(@NotNull PsiField[] fields) {
179            return convert(fields, Factories.FIELDS);
180        }
181    
182        @NotNull
183        public static List<JavaValueParameter> valueParameters(@NotNull PsiParameter[] parameters) {
184            return convert(parameters, Factories.VALUE_PARAMETERS);
185        }
186    
187        @NotNull
188        public static List<JavaTypeParameter> typeParameters(@NotNull PsiTypeParameter[] typeParameters) {
189            return convert(typeParameters, Factories.TYPE_PARAMETERS);
190        }
191    
192        @NotNull
193        public static List<JavaType> types(@NotNull PsiType[] types) {
194            return convert(types, Factories.TYPES);
195        }
196    
197        @NotNull
198        public static Collection<JavaClassifierType> classifierTypes(@NotNull PsiClassType[] classTypes) {
199            return convert(classTypes, Factories.CLASSIFIER_TYPES);
200        }
201    
202        @NotNull
203        public static Collection<JavaAnnotation> annotations(@NotNull PsiAnnotation[] annotations) {
204            return convert(annotations, Factories.ANNOTATIONS);
205        }
206    
207        @NotNull
208        public static List<JavaAnnotationArgument> namelessAnnotationArguments(@NotNull PsiAnnotationMemberValue[] memberValues) {
209            return convert(memberValues, Factories.NAMELESS_ANNOTATION_ARGUMENTS);
210        }
211    
212        @NotNull
213        public static Collection<JavaAnnotationArgument> namedAnnotationArguments(@NotNull PsiNameValuePair[] nameValuePairs) {
214            return convert(nameValuePairs, Factories.NAMED_ANNOTATION_ARGUMENTS);
215        }
216    }