001    /*
002     * Copyright 2010-2014 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.lazy.descriptors;
018    
019    import kotlin.Function1;
020    import kotlin.KotlinPackage;
021    import org.jetbrains.annotations.NotNull;
022    import org.jetbrains.annotations.Nullable;
023    import org.jetbrains.jet.lang.descriptors.*;
024    import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl;
025    import org.jetbrains.jet.lang.resolve.BindingTrace;
026    import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
027    import org.jetbrains.jet.lang.resolve.lazy.data.JetScriptInfo;
028    import org.jetbrains.jet.lang.resolve.lazy.declarations.ClassMemberDeclarationProvider;
029    import org.jetbrains.jet.lang.resolve.name.Name;
030    
031    import java.util.Collection;
032    import java.util.Set;
033    
034    // SCRIPT: Members of a script class
035    public class LazyScriptClassMemberScope extends LazyClassMemberScope {
036        protected LazyScriptClassMemberScope(
037                @NotNull ResolveSession resolveSession,
038                @NotNull ClassMemberDeclarationProvider declarationProvider,
039                @NotNull LazyClassDescriptor thisClass,
040                @NotNull BindingTrace trace
041        ) {
042            super(resolveSession, declarationProvider, thisClass, trace);
043        }
044    
045        @NotNull
046        @Override
047        protected Collection<DeclarationDescriptor> computeExtraDescriptors() {
048            return KotlinPackage.plus(
049                    super.computeExtraDescriptors(),
050                    KotlinPackage.plus(
051                        getProperties(Name.identifier(ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME)),
052                        getPropertiesForScriptParameters()
053                    )
054            );
055        }
056    
057        private Collection<VariableDescriptor> getPropertiesForScriptParameters() {
058            return KotlinPackage.flatMap(
059                    getPrimaryConstructor().getValueParameters(),
060                    new Function1<ValueParameterDescriptor, Iterable<? extends VariableDescriptor>>() {
061                        @Override
062                        public Iterable<? extends VariableDescriptor> invoke(ValueParameterDescriptor descriptor) {
063                            return getProperties(descriptor.getName());
064                        }
065                    }
066            );
067        }
068    
069        @Override
070        protected void getNonDeclaredProperties(@NotNull Name name, @NotNull Set<VariableDescriptor> result) {
071            super.getNonDeclaredProperties(name, result);
072    
073            JetScriptInfo scriptInfo = (JetScriptInfo) declarationProvider.getOwnerInfo();
074    
075            if (name.asString().equals(ScriptDescriptor.LAST_EXPRESSION_VALUE_FIELD_NAME)) {
076                result.add(ScriptDescriptorImpl.createScriptResultProperty(resolveSession.getScriptDescriptor(scriptInfo.getScript())));
077            }
078        }
079    
080        @Override
081        protected void createPropertiesFromPrimaryConstructorParameters(@NotNull Name name, @NotNull Set<VariableDescriptor> result) {
082            JetScriptInfo scriptInfo = (JetScriptInfo) declarationProvider.getOwnerInfo();
083    
084            // From primary constructor parameters
085            ConstructorDescriptor primaryConstructor = getPrimaryConstructor();
086            if (primaryConstructor == null) return;
087    
088            for (ValueParameterDescriptor valueParameterDescriptor : primaryConstructor.getValueParameters()) {
089                if (!name.equals(valueParameterDescriptor.getName())) continue;
090    
091                result.add(
092                        ScriptDescriptorImpl.createPropertyFromScriptParameter(
093                                   resolveSession.getScriptDescriptor(scriptInfo.getScript()),
094                                   valueParameterDescriptor
095                        )
096                );
097            }
098        }
099    
100        @Override
101        @Nullable
102        protected ConstructorDescriptor resolvePrimaryConstructor() {
103            JetScriptInfo scriptInfo = (JetScriptInfo) declarationProvider.getOwnerInfo();
104            ScriptDescriptor scriptDescriptor = resolveSession.getScriptDescriptor(scriptInfo.getScript());
105            ConstructorDescriptorImpl constructor = ScriptDescriptorImpl.createConstructor(scriptDescriptor,
106                                                                                           scriptDescriptor.getScriptCodeDescriptor()
107                                                                                                   .getValueParameters());
108            setDeferredReturnType(constructor);
109            return constructor;
110        }
111    }