001    /*
002     * Copyright 2010-2016 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.kotlin.descriptors.ClassDescriptor;
024    import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
025    import org.jetbrains.kotlin.descriptors.PropertyDescriptor;
026    import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
027    import org.jetbrains.kotlin.utils.Printer;
028    
029    public final class ScopeUtils {
030        private ScopeUtils() {}
031    
032        @NotNull
033        public static MemberScope getStaticNestedClassesScope(@NotNull ClassDescriptor descriptor) {
034            MemberScope innerClassesScope = descriptor.getUnsubstitutedInnerClassesScope();
035            return new FilteringScope(innerClassesScope, new Function1<DeclarationDescriptor, Boolean>() {
036                @Override
037                public Boolean invoke(DeclarationDescriptor descriptor) {
038                    return descriptor instanceof ClassDescriptor && !((ClassDescriptor) descriptor).isInner();
039                }
040            });
041        }
042    
043        public static LexicalScope makeScopeForPropertyHeader(
044                @NotNull LexicalScope parent,
045                @NotNull final PropertyDescriptor propertyDescriptor
046        ) {
047            return new LexicalScopeImpl(parent, propertyDescriptor, false, null, LexicalScopeKind.PROPERTY_HEADER,
048                                        // redeclaration on type parameters should be reported early, see: DescriptorResolver.resolvePropertyDescriptor()
049                                        LocalRedeclarationChecker.DO_NOTHING.INSTANCE,
050                                        new Function1<LexicalScopeImpl.InitializeHandler, Unit>() {
051                                            @Override
052                                            public Unit invoke(LexicalScopeImpl.InitializeHandler handler) {
053                                                for (TypeParameterDescriptor typeParameterDescriptor : propertyDescriptor.getTypeParameters()) {
054                                                    handler.addClassifierDescriptor(typeParameterDescriptor);
055                                                }
056                                                return Unit.INSTANCE;
057                                            }
058                                        });
059        }
060    
061        @NotNull
062        public static LexicalScope makeScopeForPropertyInitializer(
063                @NotNull LexicalScope propertyHeader,
064                @NotNull PropertyDescriptor propertyDescriptor
065        ) {
066            return new LexicalScopeImpl(propertyHeader, propertyDescriptor, false, null, LexicalScopeKind.PROPERTY_INITIALIZER_OR_DELEGATE);
067        }
068    
069        @NotNull
070        public static LexicalScope makeScopeForDelegateConventionFunctions(
071                @NotNull LexicalScope parent,
072                @NotNull PropertyDescriptor propertyDescriptor
073        ) {
074            // todo: very strange scope!
075            return new LexicalScopeImpl(parent, propertyDescriptor, true, propertyDescriptor.getExtensionReceiverParameter(),
076                                        LexicalScopeKind.PROPERTY_DELEGATE_METHOD
077            );
078        }
079    
080        // TestOnly
081        @NotNull
082        public static String printStructure(@Nullable MemberScope scope) {
083            StringBuilder out = new StringBuilder();
084            Printer p = new Printer(out);
085            if (scope == null) {
086                p.println("null");
087            }
088            else {
089                scope.printScopeStructure(p);
090            }
091            return out.toString();
092        }
093    }