001 /* 002 * Copyright 2010-2015 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.kotlin.resolve; 018 019 import com.intellij.openapi.util.Key; 020 import org.jetbrains.annotations.NotNull; 021 import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor; 022 import org.jetbrains.kotlin.descriptors.ScriptDescriptor; 023 import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor; 024 import org.jetbrains.kotlin.descriptors.impl.ScriptDescriptorImpl; 025 import org.jetbrains.kotlin.name.FqName; 026 import org.jetbrains.kotlin.name.Name; 027 import org.jetbrains.kotlin.psi.JetFile; 028 import org.jetbrains.kotlin.psi.JetScript; 029 import org.jetbrains.kotlin.resolve.scopes.RedeclarationHandler; 030 import org.jetbrains.kotlin.resolve.scopes.WritableScope; 031 import org.jetbrains.kotlin.resolve.scopes.WritableScopeImpl; 032 033 import javax.inject.Inject; 034 import java.util.List; 035 import java.util.Map; 036 037 import static org.jetbrains.kotlin.resolve.source.SourcePackage.toSourceElement; 038 039 // SCRIPT: Resolve declarations in scripts 040 public class ScriptHeaderResolver { 041 042 public static final Key<Integer> PRIORITY_KEY = Key.create(JetScript.class.getName() + ".priority"); 043 044 @NotNull 045 private MutablePackageFragmentProvider packageFragmentProvider; 046 @NotNull 047 private BindingTrace trace; 048 049 @Inject 050 public void setPackageFragmentProvider(@NotNull MutablePackageFragmentProvider packageFragmentProvider) { 051 this.packageFragmentProvider = packageFragmentProvider; 052 } 053 054 @Inject 055 public void setTrace(@NotNull BindingTrace trace) { 056 this.trace = trace; 057 } 058 059 060 061 public void processScriptHierarchy(@NotNull TopDownAnalysisContext c, @NotNull JetScript script, @NotNull WritableScope outerScope) { 062 JetFile file = script.getContainingJetFile(); 063 FqName fqName = file.getPackageFqName(); 064 PackageFragmentDescriptor ns = packageFragmentProvider.getOrCreateFragment(fqName); 065 066 Integer priority = getScriptPriority(script); 067 068 FqName nameForScript = ScriptNameUtil.classNameForScript(script); 069 Name className = nameForScript.shortName(); 070 ScriptDescriptorImpl scriptDescriptor = new ScriptDescriptorImpl(ns, priority, outerScope, className, toSourceElement(script)); 071 072 WritableScopeImpl scriptScope = new WritableScopeImpl(outerScope, scriptDescriptor, RedeclarationHandler.DO_NOTHING, "script"); 073 scriptScope.changeLockLevel(WritableScope.LockLevel.BOTH); 074 scriptDescriptor.setScopeForBodyResolution(scriptScope); 075 076 c.getScripts().put(script, scriptDescriptor); 077 078 trace.record(BindingContext.SCRIPT, script, scriptDescriptor); 079 080 outerScope.addClassifierDescriptor(scriptDescriptor.getClassDescriptor()); 081 } 082 083 public static int getScriptPriority(@NotNull JetScript script) { 084 Integer priority = script.getUserData(PRIORITY_KEY); 085 return priority == null ? 0 : priority; 086 } 087 088 public static void resolveScriptDeclarations(@NotNull TopDownAnalysisContext c) { 089 for (Map.Entry<JetScript, ScriptDescriptor> e : c.getScripts().entrySet()) { 090 JetScript declaration = e.getKey(); 091 ScriptDescriptorImpl descriptor = (ScriptDescriptorImpl) e.getValue(); 092 093 List<ValueParameterDescriptor> valueParameters = ScriptParameterResolver.resolveScriptParameters( 094 declaration, 095 descriptor 096 ); 097 098 descriptor.setValueParameters(valueParameters); 099 100 WritableScope scope = descriptor.getScopeForBodyResolution(); 101 scope.setImplicitReceiver(descriptor.getThisAsReceiverParameter()); 102 for (ValueParameterDescriptor valueParameterDescriptor : valueParameters) { 103 scope.addVariableDescriptor(valueParameterDescriptor); 104 } 105 } 106 } 107 108 }