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.resolve; 018 019 import com.google.common.collect.Lists; 020 import com.intellij.openapi.util.Key; 021 import org.jetbrains.annotations.NotNull; 022 import org.jetbrains.jet.lang.descriptors.*; 023 import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; 024 import org.jetbrains.jet.lang.descriptors.impl.NamespaceDescriptorImpl; 025 import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl; 026 import org.jetbrains.jet.lang.parsing.JetScriptDefinition; 027 import org.jetbrains.jet.lang.parsing.JetScriptDefinitionProvider; 028 import org.jetbrains.jet.lang.psi.JetFile; 029 import org.jetbrains.jet.lang.psi.JetNamespaceHeader; 030 import org.jetbrains.jet.lang.psi.JetScript; 031 import org.jetbrains.jet.lang.resolve.name.FqName; 032 import org.jetbrains.jet.lang.resolve.scopes.JetScope; 033 import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler; 034 import org.jetbrains.jet.lang.resolve.scopes.WritableScope; 035 import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; 036 import org.jetbrains.jet.lang.types.DependencyClassByQualifiedNameResolver; 037 import org.jetbrains.jet.lang.types.JetType; 038 import org.jetbrains.jet.lang.types.TypeUtils; 039 import org.jetbrains.jet.lang.types.ref.JetTypeName; 040 041 import javax.inject.Inject; 042 import java.util.*; 043 044 public class ScriptHeaderResolver { 045 046 public static final Key<Integer> PRIORITY_KEY = Key.create(JetScript.class.getName() + ".priority"); 047 048 @NotNull 049 private NamespaceFactory namespaceFactory; 050 @NotNull 051 private DependencyClassByQualifiedNameResolver dependencyClassByQualifiedNameResolver; 052 @NotNull 053 private TopDownAnalysisContext context; 054 @NotNull 055 private BindingTrace trace; 056 @NotNull 057 private TopDownAnalysisParameters topDownAnalysisParameters; 058 059 @Inject 060 public void setNamespaceFactory(@NotNull NamespaceFactory namespaceFactory) { 061 this.namespaceFactory = namespaceFactory; 062 } 063 064 @Inject 065 public void setDependencyClassByQualifiedNameResolver(@NotNull DependencyClassByQualifiedNameResolver dependencyClassByQualifiedNameResolver) { 066 this.dependencyClassByQualifiedNameResolver = dependencyClassByQualifiedNameResolver; 067 } 068 069 @Inject 070 public void setContext(@NotNull TopDownAnalysisContext context) { 071 this.context = context; 072 } 073 074 @Inject 075 public void setTrace(@NotNull BindingTrace trace) { 076 this.trace = trace; 077 } 078 079 @Inject 080 public void setTopDownAnalysisParameters(@NotNull TopDownAnalysisParameters topDownAnalysisParameters) { 081 this.topDownAnalysisParameters = topDownAnalysisParameters; 082 } 083 084 085 @NotNull 086 private ClassDescriptor resolveClass(@NotNull FqName className) { 087 ClassDescriptor classDescriptor = dependencyClassByQualifiedNameResolver.resolveClass(className); 088 if (classDescriptor == null) { 089 throw new IllegalStateException("dependency class not found by name: " + className); 090 } 091 return classDescriptor; 092 } 093 094 @NotNull 095 public JetType resolveTypeName(@NotNull JetTypeName typeName) { 096 List<JetType> typeArguments = new ArrayList<JetType>(); 097 for (JetTypeName typeArgumentName : typeName.getArguments()) { 098 typeArguments.add(resolveTypeName(typeArgumentName)); 099 } 100 ClassDescriptor classDescriptor = resolveClass(typeName.getClassName()); 101 return TypeUtils.substituteParameters(classDescriptor, typeArguments); 102 } 103 104 105 @NotNull 106 private ValueParameterDescriptor resolveScriptParameter( 107 @NotNull AnalyzerScriptParameter scriptParameter, 108 int index, 109 @NotNull ScriptDescriptor script) { 110 JetType type = resolveTypeName(scriptParameter.getType()); 111 return new ValueParameterDescriptorImpl(script, index, Collections.<AnnotationDescriptor>emptyList(), scriptParameter.getName(), type, false, null); 112 } 113 114 public void processScriptHierarchy(@NotNull JetScript script, @NotNull JetScope outerScope) { 115 JetFile file = (JetFile) script.getContainingFile(); 116 JetNamespaceHeader namespaceHeader = file.getNamespaceHeader(); 117 FqName fqName = namespaceHeader != null ? new FqName(namespaceHeader.getQualifiedName()) : FqName.ROOT; 118 NamespaceDescriptorImpl ns = namespaceFactory.createNamespaceDescriptorPathIfNeeded(fqName); 119 120 Integer priority = script.getUserData(PRIORITY_KEY); 121 if (priority == null) { 122 priority = 0; 123 } 124 125 ScriptDescriptor scriptDescriptor = new ScriptDescriptor(ns, priority, script, outerScope); 126 //WriteThroughScope scriptScope = new WriteThroughScope( 127 // outerScope, ns.getMemberScope(), new TraceBasedRedeclarationHandler(trace)); 128 WritableScopeImpl scriptScope = new WritableScopeImpl(outerScope, scriptDescriptor, RedeclarationHandler.DO_NOTHING, "script"); 129 scriptScope.changeLockLevel(WritableScope.LockLevel.BOTH); 130 131 context.getScriptScopes().put(script, scriptScope); 132 context.getScripts().put(script, scriptDescriptor); 133 134 trace.record(BindingContext.SCRIPT, script, scriptDescriptor); 135 136 ((WritableScope)outerScope).addClassifierDescriptor(scriptDescriptor.getClassDescriptor()); 137 } 138 139 public void resolveScriptDeclarations() { 140 for (Map.Entry<JetScript, ScriptDescriptor> e : context.getScripts().entrySet()) { 141 JetScript declaration = e.getKey(); 142 ScriptDescriptor descriptor = e.getValue(); 143 WritableScope scope = context.getScriptScopes().get(declaration); 144 145 List<ValueParameterDescriptor> valueParameters = Lists.newArrayList(); 146 147 scope.setImplicitReceiver(descriptor.getThisAsReceiverParameter()); 148 149 JetFile file = (JetFile) declaration.getContainingFile(); 150 JetScriptDefinition scriptDefinition = JetScriptDefinitionProvider.getInstance(file.getProject()).findScriptDefinition(file); 151 152 int index = 0; 153 List<AnalyzerScriptParameter> scriptParameters = !scriptDefinition.getScriptParameters().isEmpty() 154 ? scriptDefinition.getScriptParameters() 155 : topDownAnalysisParameters.getScriptParameters(); 156 157 for (AnalyzerScriptParameter scriptParameter : scriptParameters) { 158 ValueParameterDescriptor parameter = resolveScriptParameter(scriptParameter, index, descriptor); 159 valueParameters.add(parameter); 160 scope.addVariableDescriptor(parameter); 161 ++index; 162 } 163 164 descriptor.setValueParameters(valueParameters); 165 } 166 } 167 }