001    /*
002     * Copyright 2010-2013 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 org.jetbrains.annotations.NotNull;
021    import org.jetbrains.jet.lang.resolve.java.structure.*;
022    import org.jetbrains.jet.lang.resolve.name.Name;
023    
024    import java.util.ArrayList;
025    import java.util.Collection;
026    import java.util.Collections;
027    
028    @SuppressWarnings("unchecked")
029    public class JavaElementCollectionFromPsiArrayUtil {
030        private JavaElementCollectionFromPsiArrayUtil() {
031        }
032    
033        private interface Factory<Psi, Java> {
034            @NotNull
035            Java create(@NotNull Psi psi);
036        }
037    
038        private static class Factories {
039            private static final Factory<PsiClass, JavaClassImpl> CLASSES = new Factory<PsiClass, JavaClassImpl>() {
040                @NotNull
041                @Override
042                public JavaClassImpl create(@NotNull PsiClass psiClass) {
043                    return new JavaClassImpl(psiClass);
044                }
045            };
046    
047            private static final Factory<PsiPackage, JavaPackageImpl> PACKAGES = new Factory<PsiPackage, JavaPackageImpl>() {
048                @NotNull
049                @Override
050                public JavaPackageImpl create(@NotNull PsiPackage psiPackage) {
051                    return new JavaPackageImpl(psiPackage);
052                }
053            };
054    
055            private static final Factory<PsiMethod, JavaMethodImpl> METHODS = new Factory<PsiMethod, JavaMethodImpl>() {
056                @NotNull
057                @Override
058                public JavaMethodImpl create(@NotNull PsiMethod psiMethod) {
059                    return new JavaMethodImpl(psiMethod);
060                }
061            };
062    
063            private static final Factory<PsiField, JavaFieldImpl> FIELDS = new Factory<PsiField, JavaFieldImpl>() {
064                @NotNull
065                @Override
066                public JavaFieldImpl create(@NotNull PsiField psiField) {
067                    return new JavaFieldImpl(psiField);
068                }
069            };
070    
071            private static final Factory<PsiParameter, JavaValueParameterImpl> VALUE_PARAMETERS =
072                    new Factory<PsiParameter, JavaValueParameterImpl>() {
073                @NotNull
074                @Override
075                public JavaValueParameterImpl create(@NotNull PsiParameter psiParameter) {
076                    return new JavaValueParameterImpl(psiParameter);
077                }
078            };
079    
080            private static final Factory<PsiTypeParameter, JavaTypeParameterImpl> TYPE_PARAMETERS =
081                    new Factory<PsiTypeParameter, JavaTypeParameterImpl>() {
082                @NotNull
083                @Override
084                public JavaTypeParameterImpl create(@NotNull PsiTypeParameter psiTypeParameter) {
085                    return new JavaTypeParameterImpl(psiTypeParameter);
086                }
087            };
088    
089            private static final Factory<PsiType, JavaTypeImpl<?>> TYPES = new Factory<PsiType, JavaTypeImpl<?>>() {
090                @NotNull
091                @Override
092                public JavaTypeImpl<?> create(@NotNull PsiType psiType) {
093                    return JavaTypeImpl.create(psiType);
094                }
095            };
096    
097            private static final Factory<PsiClassType, JavaClassifierTypeImpl> CLASSIFIER_TYPES =
098                    new Factory<PsiClassType, JavaClassifierTypeImpl>() {
099                @NotNull
100                @Override
101                public JavaClassifierTypeImpl create(@NotNull PsiClassType psiClassType) {
102                    return new JavaClassifierTypeImpl(psiClassType);
103                }
104            };
105    
106            private static final Factory<PsiAnnotation, JavaAnnotationImpl> ANNOTATIONS = new Factory<PsiAnnotation, JavaAnnotationImpl>() {
107                @NotNull
108                @Override
109                public JavaAnnotationImpl 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> Collection<Java> convert(@NotNull Psi[] elements, @NotNull Factory<Psi, Java> factory) {
138            if (elements.length == 0) return Collections.emptyList();
139            Collection<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        public static Collection<JavaClass> classes(@NotNull PsiClass[] classes) {
148            return (Collection) convert(classes, Factories.CLASSES);
149        }
150    
151        @NotNull
152        public static Collection<JavaPackage> packages(@NotNull PsiPackage[] packages) {
153            return (Collection) convert(packages, Factories.PACKAGES);
154        }
155    
156        @NotNull
157        public static Collection<JavaMethod> methods(@NotNull PsiMethod[] methods) {
158            return (Collection) convert(methods, Factories.METHODS);
159        }
160    
161        @NotNull
162        public static Collection<JavaField> fields(@NotNull PsiField[] fields) {
163            return (Collection) convert(fields, Factories.FIELDS);
164        }
165    
166        @NotNull
167        public static Collection<JavaValueParameter> valueParameters(@NotNull PsiParameter[] parameters) {
168            return (Collection) convert(parameters, Factories.VALUE_PARAMETERS);
169        }
170    
171        @NotNull
172        public static Collection<JavaTypeParameter> typeParameters(@NotNull PsiTypeParameter[] typeParameters) {
173            return (Collection) convert(typeParameters, Factories.TYPE_PARAMETERS);
174        }
175    
176        @NotNull
177        public static Collection<JavaType> types(@NotNull PsiType[] types) {
178            return (Collection) convert(types, Factories.TYPES);
179        }
180    
181        @NotNull
182        public static Collection<JavaClassifierType> classifierTypes(@NotNull PsiClassType[] classTypes) {
183            return (Collection) convert(classTypes, Factories.CLASSIFIER_TYPES);
184        }
185    
186        @NotNull
187        public static Collection<JavaAnnotation> annotations(@NotNull PsiAnnotation[] annotations) {
188            return (Collection) convert(annotations, Factories.ANNOTATIONS);
189        }
190    
191        @NotNull
192        public static Collection<JavaAnnotationArgument> namelessAnnotationArguments(@NotNull PsiAnnotationMemberValue[] memberValues) {
193            return (Collection) convert(memberValues, Factories.NAMELESS_ANNOTATION_ARGUMENTS);
194        }
195    
196        @NotNull
197        public static Collection<JavaAnnotationArgument> namedAnnotationArguments(@NotNull PsiNameValuePair[] nameValuePairs) {
198            return (Collection) convert(nameValuePairs, Factories.NAMED_ANNOTATION_ARGUMENTS);
199        }
200    }