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