001 /*
002 * Copyright 2010-2013 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.descriptors;
018
019 import org.jetbrains.annotations.NotNull;
020 import org.jetbrains.annotations.Nullable;
021 import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
022 import org.jetbrains.jet.lang.descriptors.impl.*;
023 import org.jetbrains.jet.lang.psi.*;
024 import org.jetbrains.jet.lang.resolve.BindingContext;
025 import org.jetbrains.jet.lang.resolve.DescriptorResolver;
026 import org.jetbrains.jet.lang.resolve.ScriptNameUtil;
027 import org.jetbrains.jet.lang.resolve.name.FqName;
028 import org.jetbrains.jet.lang.resolve.name.Name;
029 import org.jetbrains.jet.lang.resolve.scopes.JetScope;
030 import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler;
031 import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
032 import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
033 import org.jetbrains.jet.lang.resolve.scopes.receivers.ScriptReceiver;
034 import org.jetbrains.jet.lang.types.JetType;
035 import org.jetbrains.jet.lang.types.TypeSubstitutor;
036 import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
037
038 import java.util.Collections;
039 import java.util.HashSet;
040 import java.util.List;
041
042 public class ScriptDescriptor extends DeclarationDescriptorNonRootImpl {
043 private static final Name NAME = Name.special("<script>");
044
045 private final int priority;
046
047 private JetType returnType;
048 private List<ValueParameterDescriptor> valueParameters;
049
050 private final ScriptCodeDescriptor scriptCodeDescriptor = new ScriptCodeDescriptor(this);
051 private final ReceiverParameterDescriptor implicitReceiver = new ReceiverParameterDescriptorImpl(this,
052 // Putting Any here makes no sense,
053 // it is simply copied from someplace else
054 // during a refactoring
055 KotlinBuiltIns.getInstance().getAnyType(),
056 new ScriptReceiver(this));
057
058 private final ClassDescriptorImpl classDescriptor;
059
060 private final WritableScopeImpl classScope;
061
062 public ScriptDescriptor(@Nullable DeclarationDescriptor containingDeclaration, int priority, JetScript script, JetScope scriptScope) {
063 super(containingDeclaration, Collections.<AnnotationDescriptor>emptyList(), NAME);
064 this.priority = priority;
065
066 String className = ScriptNameUtil.classNameForScript((JetFile) script.getContainingFile()).replace('/','.');
067
068 classDescriptor = new ClassDescriptorImpl(
069 containingDeclaration,
070 Collections.<AnnotationDescriptor>emptyList(),
071 Modality.FINAL,
072 new FqName(className).shortName());
073 classScope = new WritableScopeImpl(scriptScope, containingDeclaration, RedeclarationHandler.DO_NOTHING, "script members");
074 classScope.changeLockLevel(WritableScope.LockLevel.BOTH);
075 classDescriptor.initialize(
076 false,
077 Collections.<TypeParameterDescriptor>emptyList(),
078 Collections.singletonList(KotlinBuiltIns.getInstance().getAnyType()),
079 classScope,
080 new HashSet<ConstructorDescriptor>(),
081 null,
082 false);
083 }
084
085 public void initialize(@NotNull JetType returnType, JetScript declaration, BindingContext bindingContext) {
086 this.returnType = returnType;
087 scriptCodeDescriptor.initialize(implicitReceiver, valueParameters, returnType);
088
089 PropertyDescriptorImpl propertyDescriptor = new PropertyDescriptorImpl(classDescriptor,
090 Collections.<AnnotationDescriptor>emptyList(),
091 Modality.FINAL,
092 Visibilities.PUBLIC,
093 false,
094 Name.identifier(ScriptNameUtil.LAST_EXPRESSION_VALUE_FIELD_NAME),
095 CallableMemberDescriptor.Kind.DECLARATION);
096 propertyDescriptor.setType(
097 returnType,
098 Collections.<TypeParameterDescriptor>emptyList(),
099 classDescriptor.getThisAsReceiverParameter(),
100 ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER);
101 propertyDescriptor.initialize(null, null);
102 classScope.addPropertyDescriptor(propertyDescriptor);
103
104 for (JetDeclaration jetDeclaration : declaration.getDeclarations()) {
105 if(jetDeclaration instanceof JetProperty) {
106 VariableDescriptor descriptor = bindingContext.get(BindingContext.VARIABLE, jetDeclaration);
107 assert descriptor != null;
108 initializeWithDefaultGetterSetter((PropertyDescriptorImpl) descriptor);
109 classScope.addPropertyDescriptor(descriptor);
110 }
111 else if(jetDeclaration instanceof JetNamedFunction) {
112 SimpleFunctionDescriptor descriptor = bindingContext.get(BindingContext.FUNCTION, jetDeclaration);
113 assert descriptor != null;
114 SimpleFunctionDescriptor copy =
115 descriptor.copy(classDescriptor, descriptor.getModality(), descriptor.getVisibility(), CallableMemberDescriptor.Kind.DECLARATION, false);
116 classScope.addFunctionDescriptor(copy);
117 }
118 }
119 }
120
121 public static void initializeWithDefaultGetterSetter(PropertyDescriptorImpl propertyDescriptor) {
122 PropertyGetterDescriptorImpl getter = propertyDescriptor.getGetter();
123 if(getter == null) {
124 getter = propertyDescriptor.getVisibility() != Visibilities.PRIVATE ? DescriptorResolver.createDefaultGetter(propertyDescriptor) : null;
125 if(getter != null)
126 getter.initialize(propertyDescriptor.getType());
127 }
128
129 PropertySetterDescriptor setter = propertyDescriptor.getSetter();
130 if(setter == null) {
131 setter = propertyDescriptor.isVar() ? DescriptorResolver.createDefaultSetter(propertyDescriptor) : null;
132 }
133 propertyDescriptor.initialize(getter, setter);
134 }
135
136 public int getPriority() {
137 return priority;
138 }
139
140 @NotNull
141 public JetType getReturnType() {
142 return returnType;
143 }
144
145 @NotNull
146 public List<ValueParameterDescriptor> getValueParameters() {
147 return valueParameters;
148 }
149
150 @NotNull
151 public ScriptCodeDescriptor getScriptCodeDescriptor() {
152 return scriptCodeDescriptor;
153 }
154
155 @NotNull
156 public ReceiverParameterDescriptor getThisAsReceiverParameter() {
157 return implicitReceiver;
158 }
159
160 @Override
161 public DeclarationDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
162 throw new IllegalStateException("nothing to substitute in script");
163 }
164
165 @Override
166 public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
167 return visitor.visitScriptDescriptor(this, data);
168 }
169
170 public void setValueParameters(@NotNull List<ValueParameterDescriptor> valueParameters) {
171 this.valueParameters = valueParameters;
172 ConstructorDescriptorImpl constructorDescriptor =
173 new ConstructorDescriptorImpl(classDescriptor, Collections.<AnnotationDescriptor>emptyList(), true)
174 .initialize(Collections.<TypeParameterDescriptor>emptyList(), valueParameters, Visibilities.PUBLIC);
175 constructorDescriptor.setReturnType(classDescriptor.getDefaultType());
176
177 classDescriptor.getConstructors().add(constructorDescriptor);
178 classDescriptor.setPrimaryConstructor(constructorDescriptor);
179
180 for (ValueParameterDescriptor parameter : valueParameters) {
181 PropertyDescriptorImpl propertyDescriptor = new PropertyDescriptorImpl(classDescriptor,
182 Collections.<AnnotationDescriptor>emptyList(),
183 Modality.FINAL,
184 Visibilities.PUBLIC,
185 false,
186 parameter.getName(),
187 CallableMemberDescriptor.Kind.DECLARATION);
188 propertyDescriptor.setType(
189 parameter.getType(),
190 Collections.<TypeParameterDescriptor>emptyList(),
191 classDescriptor.getThisAsReceiverParameter(), ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER);
192 //PropertyGetterDescriptor getter = DescriptorResolver.createDefaultGetter(propertyDescriptor);
193 //getter.initialize(propertyDescriptor.getType());
194 propertyDescriptor.initialize(null, null);
195 classScope.addPropertyDescriptor(propertyDescriptor);
196 }
197 }
198
199 public ClassDescriptor getClassDescriptor() {
200 return classDescriptor;
201 }
202 }