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