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