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