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;
018    
019    import org.jetbrains.annotations.NotNull;
020    import org.jetbrains.annotations.Nullable;
021    import org.jetbrains.jet.lang.descriptors.*;
022    import org.jetbrains.jet.lang.resolve.DescriptorUtils;
023    import org.jetbrains.jet.lang.resolve.java.provider.ClassPsiDeclarationProvider;
024    import org.jetbrains.jet.lang.resolve.java.provider.PackagePsiDeclarationProvider;
025    import org.jetbrains.jet.lang.resolve.java.provider.PsiDeclarationProvider;
026    import org.jetbrains.jet.lang.resolve.java.resolver.*;
027    import org.jetbrains.jet.lang.resolve.name.FqName;
028    import org.jetbrains.jet.lang.resolve.name.Name;
029    import org.jetbrains.jet.lang.resolve.scopes.JetScope;
030    import org.jetbrains.jet.lang.types.DependencyClassByQualifiedNameResolver;
031    import org.jetbrains.jet.lang.types.JetType;
032    
033    import javax.inject.Inject;
034    import java.util.Collection;
035    import java.util.List;
036    import java.util.Set;
037    
038    public class JavaDescriptorResolver implements DependencyClassByQualifiedNameResolver {
039    
040        public static final Name JAVA_ROOT = Name.special("<java_root>");
041    
042        public static final Visibility PACKAGE_VISIBILITY = new Visibility("package", false) {
043            @Override
044            protected boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
045                return DescriptorUtils.isInSameNamespace(what, from);
046            }
047    
048            @Override
049            protected Integer compareTo(@NotNull Visibility visibility) {
050                if (this == visibility) return 0;
051                if (visibility == Visibilities.PRIVATE) return 1;
052                return -1;
053            }
054    
055            @Override
056            public String toString() {
057                return "public/*package*/";
058            }
059    
060            @NotNull
061            @Override
062            public Visibility normalize() {
063                return Visibilities.INTERNAL;
064            }
065        };
066    
067        public static final Visibility PROTECTED_STATIC_VISIBILITY = new Visibility("protected_static", false) {
068            @Override
069            protected boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
070                ClassDescriptor fromClass = DescriptorUtils.getParentOfType(from, ClassDescriptor.class, false);
071                if (fromClass == null) return false;
072    
073                ClassDescriptor whatClass;
074                // protected static class
075                if (what instanceof ClassDescriptor) {
076                    DeclarationDescriptor containingDeclaration = what.getContainingDeclaration();
077                    assert containingDeclaration instanceof ClassDescriptor : "Only static nested classes can have protected_static visibility";
078                    whatClass = (ClassDescriptor) containingDeclaration;
079                }
080                // protected static function or property
081                else {
082                    DeclarationDescriptor whatDeclarationDescriptor = what.getContainingDeclaration();
083                    assert whatDeclarationDescriptor instanceof NamespaceDescriptor : "Only static declarations can have protected_static visibility";
084                    whatClass = DescriptorUtils.getClassForCorrespondingJavaNamespace((NamespaceDescriptor) whatDeclarationDescriptor);
085                }
086    
087                assert whatClass != null : "Couldn't find ClassDescriptor for protected static member " + what;
088    
089                if (DescriptorUtils.isSubclass(fromClass, whatClass)) {
090                    return true;
091                }
092                return isVisible(what, fromClass.getContainingDeclaration());
093            }
094    
095            @Override
096            public String toString() {
097                return "protected/*protected static*/";
098            }
099    
100            @NotNull
101            @Override
102            public Visibility normalize() {
103                return Visibilities.PROTECTED;
104            }
105        };
106    
107        public static final Visibility PROTECTED_AND_PACKAGE = new Visibility("protected_and_package", false) {
108            @Override
109            protected boolean isVisible(@NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
110                if (DescriptorUtils.isInSameNamespace(what, from)) {
111                    return true;
112                }
113    
114                ClassDescriptor whatClass = DescriptorUtils.getParentOfType(what, ClassDescriptor.class, false);
115                if (whatClass == null) return false;
116    
117                ClassDescriptor fromClass = DescriptorUtils.getParentOfType(from, ClassDescriptor.class, false);
118                if (fromClass == null) return false;
119    
120                if (DescriptorUtils.isSubclass(fromClass, whatClass)) {
121                    return true;
122                }
123                return isVisible(what, fromClass.getContainingDeclaration());
124            }
125    
126            @Override
127            protected Integer compareTo(@NotNull Visibility visibility) {
128                if (this == visibility) return 0;
129                if (visibility == Visibilities.INTERNAL) return null;
130                if (visibility == Visibilities.PRIVATE) return 1;
131                return -1;
132            }
133    
134            @Override
135            public String toString() {
136                return "protected/*protected and package*/";
137            }
138    
139            @NotNull
140            @Override
141            public Visibility normalize() {
142                return Visibilities.PROTECTED;
143            }
144        };
145    
146        private JavaPropertyResolver propertiesResolver;
147        private JavaClassResolver classResolver;
148        private JavaConstructorResolver constructorResolver;
149        private JavaFunctionResolver functionResolver;
150        private JavaNamespaceResolver namespaceResolver;
151        private JavaInnerClassResolver innerClassResolver;
152    
153        @Inject
154        public void setFunctionResolver(JavaFunctionResolver functionResolver) {
155            this.functionResolver = functionResolver;
156        }
157    
158        @Inject
159        public void setClassResolver(JavaClassResolver classResolver) {
160            this.classResolver = classResolver;
161        }
162    
163        @Inject
164        public void setNamespaceResolver(JavaNamespaceResolver namespaceResolver) {
165            this.namespaceResolver = namespaceResolver;
166        }
167    
168        @Inject
169        public void setPropertiesResolver(JavaPropertyResolver propertiesResolver) {
170            this.propertiesResolver = propertiesResolver;
171        }
172    
173        @Inject
174        public void setConstructorResolver(JavaConstructorResolver constructorResolver) {
175            this.constructorResolver = constructorResolver;
176        }
177    
178        @Inject
179        public void setInnerClassResolver(JavaInnerClassResolver innerClassResolver) {
180            this.innerClassResolver = innerClassResolver;
181        }
182    
183        @Nullable
184        public ClassDescriptor resolveClass(@NotNull FqName qualifiedName, @NotNull DescriptorSearchRule searchRule) {
185            return classResolver.resolveClass(qualifiedName, searchRule);
186        }
187    
188        @Override
189        public ClassDescriptor resolveClass(@NotNull FqName qualifiedName) {
190            return classResolver.resolveClass(qualifiedName);
191        }
192    
193        @NotNull
194        public Collection<ConstructorDescriptor> resolveConstructors(
195                @NotNull ClassPsiDeclarationProvider classData, @NotNull ClassDescriptor classDescriptor
196        ) {
197            return constructorResolver.resolveConstructors(classData, classDescriptor);
198        }
199    
200        @Nullable
201        public NamespaceDescriptor resolveNamespace(@NotNull FqName qualifiedName, @NotNull DescriptorSearchRule searchRule) {
202            return namespaceResolver.resolveNamespace(qualifiedName, searchRule);
203        }
204    
205        @Override
206        public NamespaceDescriptor resolveNamespace(@NotNull FqName qualifiedName) {
207            return namespaceResolver.resolveNamespace(qualifiedName);
208        }
209    
210        @Nullable
211        public JetScope getJavaPackageScope(@NotNull NamespaceDescriptor namespaceDescriptor) {
212            return namespaceResolver.getJavaPackageScopeForExistingNamespaceDescriptor(namespaceDescriptor);
213        }
214    
215        @NotNull
216        public Set<VariableDescriptor> resolveFieldGroupByName(
217                @NotNull Name name,
218                @NotNull PsiDeclarationProvider data,
219                @NotNull ClassOrNamespaceDescriptor ownerDescriptor
220        ) {
221            return propertiesResolver.resolveFieldGroupByName(name, data, ownerDescriptor);
222        }
223    
224        @Nullable
225        public ClassDescriptor resolveClass(@NotNull FqName name, @NotNull DescriptorSearchRule searchRule, @NotNull PostponedTasks tasks) {
226            return classResolver.resolveClass(name, searchRule, tasks);
227        }
228    
229        public static class ValueParameterDescriptors {
230            private final JetType receiverType;
231            private final List<ValueParameterDescriptor> descriptors;
232    
233            public ValueParameterDescriptors(@Nullable JetType receiverType, @NotNull List<ValueParameterDescriptor> descriptors) {
234                this.receiverType = receiverType;
235                this.descriptors = descriptors;
236            }
237    
238            @Nullable
239            public JetType getReceiverType() {
240                return receiverType;
241            }
242    
243            @NotNull
244            public List<ValueParameterDescriptor> getDescriptors() {
245                return descriptors;
246            }
247        }
248    
249        @NotNull
250        public Set<FunctionDescriptor> resolveFunctionGroup(
251                @NotNull Name methodName,
252                @NotNull ClassPsiDeclarationProvider scopeData,
253                @NotNull ClassOrNamespaceDescriptor ownerDescriptor
254        ) {
255            return functionResolver.resolveFunctionGroup(methodName, scopeData, ownerDescriptor);
256        }
257    
258        @NotNull
259        public Set<FunctionDescriptor> resolveFunctionGroup(
260                @NotNull Name methodName,
261                @NotNull PackagePsiDeclarationProvider scopeData,
262                @NotNull NamespaceDescriptor ownerDescriptor
263        ) {
264            return functionResolver.resolveFunctionGroup(methodName, scopeData, ownerDescriptor);
265        }
266    
267        @NotNull
268        public List<ClassDescriptor> resolveInnerClasses(@NotNull ClassPsiDeclarationProvider declarationProvider) {
269            return innerClassResolver.resolveInnerClasses(declarationProvider);
270        }
271    }