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.resolve.scopes;
018    
019    import kotlin.Unit;
020    import kotlin.jvm.functions.Function1;
021    import org.jetbrains.annotations.NotNull;
022    import org.jetbrains.annotations.Nullable;
023    import org.jetbrains.annotations.TestOnly;
024    import org.jetbrains.kotlin.descriptors.*;
025    import org.jetbrains.kotlin.resolve.BindingTrace;
026    import org.jetbrains.kotlin.resolve.TraceBasedRedeclarationHandler;
027    import org.jetbrains.kotlin.utils.Printer;
028    
029    import java.util.List;
030    
031    public final class JetScopeUtils {
032        private JetScopeUtils() {}
033    
034        @NotNull
035        public static MemberScope getStaticNestedClassesScope(@NotNull ClassDescriptor descriptor) {
036            MemberScope innerClassesScope = descriptor.getUnsubstitutedInnerClassesScope();
037            return new FilteringScope(innerClassesScope, new Function1<DeclarationDescriptor, Boolean>() {
038                @Override
039                public Boolean invoke(DeclarationDescriptor descriptor) {
040                    return descriptor instanceof ClassDescriptor && !((ClassDescriptor) descriptor).isInner();
041                }
042            });
043        }
044    
045        public static LexicalScope makeScopeForPropertyAccessor(
046                @NotNull PropertyDescriptor propertyDescriptor,
047                @NotNull LexicalScope parentScope,
048                @NotNull BindingTrace trace
049        ) {
050            LexicalScope propertyDeclarationInnerScope =
051                    getPropertyDeclarationInnerScope(propertyDescriptor, parentScope,
052                                                     propertyDescriptor.getTypeParameters(),
053                                                     propertyDescriptor.getExtensionReceiverParameter(), trace);
054            return new LexicalScopeImpl(propertyDeclarationInnerScope, parentScope.getOwnerDescriptor(), false, null, "Accessor Scope");
055        }
056    
057        public static LexicalScope getPropertyDeclarationInnerScope(
058                @NotNull PropertyDescriptor propertyDescriptor,
059                @NotNull LexicalScope outerScope,
060                @NotNull RedeclarationHandler redeclarationHandler
061        ) {
062            return getPropertyDeclarationInnerScope(propertyDescriptor,
063                                                    outerScope,
064                                                    propertyDescriptor.getTypeParameters(),
065                                                    propertyDescriptor.getExtensionReceiverParameter(),
066                                                    redeclarationHandler,
067                                                    true);
068        }
069    
070        public static LexicalScope getPropertyDeclarationInnerScope(
071                @NotNull PropertyDescriptor propertyDescriptor,
072                @NotNull LexicalScope outerScope,
073                @NotNull List<? extends TypeParameterDescriptor> typeParameters,
074                @Nullable ReceiverParameterDescriptor receiver,
075                BindingTrace trace
076        ) {
077            return getPropertyDeclarationInnerScope(propertyDescriptor, outerScope, typeParameters, receiver, trace, true);
078        }
079    
080        public static LexicalScope getPropertyDeclarationInnerScopeForInitializer(
081                @NotNull PropertyDescriptor propertyDescriptor,
082                @NotNull LexicalScope outerScope,
083                @NotNull List<? extends TypeParameterDescriptor> typeParameters,
084                @Nullable ReceiverParameterDescriptor receiver,
085                BindingTrace trace
086        ) {
087            return getPropertyDeclarationInnerScope(propertyDescriptor, outerScope, typeParameters, receiver, trace, false);
088        }
089    
090        private static LexicalScope getPropertyDeclarationInnerScope(
091                @NotNull PropertyDescriptor propertyDescriptor,
092                @NotNull LexicalScope outerScope,
093                @NotNull List<? extends TypeParameterDescriptor> typeParameters,
094                @Nullable ReceiverParameterDescriptor receiver,
095                BindingTrace trace,
096                boolean addLabelForProperty
097        ) {
098            TraceBasedRedeclarationHandler redeclarationHandler = new TraceBasedRedeclarationHandler(trace);
099            return getPropertyDeclarationInnerScope(propertyDescriptor, outerScope, typeParameters, receiver, redeclarationHandler,
100                                                    addLabelForProperty);
101        }
102    
103        @NotNull
104        private static LexicalScope getPropertyDeclarationInnerScope(
105                @NotNull PropertyDescriptor propertyDescriptor,
106                @NotNull LexicalScope outerScope,
107                @NotNull final List<? extends TypeParameterDescriptor> typeParameters,
108                @Nullable ReceiverParameterDescriptor receiver,
109                @NotNull RedeclarationHandler redeclarationHandler,
110                boolean addLabelForProperty
111        ) {
112            return new LexicalScopeImpl(
113                    outerScope, propertyDescriptor, addLabelForProperty, receiver,
114                    "Property declaration inner scope",
115                    redeclarationHandler, new Function1<LexicalScopeImpl.InitializeHandler, Unit>() {
116                @Override
117                public Unit invoke(LexicalScopeImpl.InitializeHandler handler) {
118                    for (TypeParameterDescriptor typeParameterDescriptor : typeParameters) {
119                        handler.addClassifierDescriptor(typeParameterDescriptor);
120                    }
121                    return Unit.INSTANCE$;
122                }
123            });
124        }
125    
126        @TestOnly
127        @NotNull
128        public static String printStructure(@Nullable MemberScope scope) {
129            StringBuilder out = new StringBuilder();
130            Printer p = new Printer(out);
131            if (scope == null) {
132                p.println("null");
133            }
134            else {
135                scope.printScopeStructure(p);
136            }
137            return out.toString();
138        }
139    }