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 017package org.jetbrains.jet.lang.descriptors; 018 019import org.jetbrains.annotations.NotNull; 020import org.jetbrains.annotations.Nullable; 021import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; 022import org.jetbrains.jet.lang.descriptors.impl.*; 023import org.jetbrains.jet.lang.psi.*; 024import org.jetbrains.jet.lang.resolve.BindingContext; 025import org.jetbrains.jet.lang.resolve.DescriptorResolver; 026import org.jetbrains.jet.lang.resolve.ScriptNameUtil; 027import org.jetbrains.jet.lang.resolve.name.FqName; 028import org.jetbrains.jet.lang.resolve.name.Name; 029import org.jetbrains.jet.lang.resolve.scopes.JetScope; 030import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler; 031import org.jetbrains.jet.lang.resolve.scopes.WritableScope; 032import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; 033import org.jetbrains.jet.lang.resolve.scopes.receivers.ScriptReceiver; 034import org.jetbrains.jet.lang.types.JetType; 035import org.jetbrains.jet.lang.types.TypeSubstitutor; 036import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; 037 038import java.util.Collections; 039import java.util.HashSet; 040import java.util.List; 041 042public 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}