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