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.base.Function;
020 import com.google.common.base.Functions;
021 import com.google.common.collect.Maps;
022 import com.intellij.psi.PsiElement;
023 import com.intellij.psi.PsiFile;
024 import org.jetbrains.annotations.NotNull;
025 import org.jetbrains.jet.lang.descriptors.*;
026 import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptorLite;
027 import org.jetbrains.jet.lang.descriptors.impl.MutablePackageFragmentDescriptor;
028 import org.jetbrains.jet.lang.psi.*;
029 import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
030 import org.jetbrains.jet.lang.resolve.scopes.JetScope;
031 import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
032 import org.jetbrains.jet.storage.ExceptionTracker;
033 import org.jetbrains.jet.storage.StorageManager;
034
035 import java.io.PrintStream;
036 import java.util.Collection;
037 import java.util.List;
038 import java.util.Map;
039
040 public class TopDownAnalysisContext implements BodiesResolveContext {
041
042 private DataFlowInfo outerDataFlowInfo = DataFlowInfo.EMPTY;
043
044 private final Map<JetClassOrObject, ClassDescriptorWithResolutionScopes> classes = Maps.newLinkedHashMap();
045 protected final Map<JetFile, MutablePackageFragmentDescriptor> packageFragments = Maps.newHashMap();
046 private List<MutableClassDescriptorLite> classesTopologicalOrder = null;
047
048 private final Map<JetDeclaration, JetScope> declaringScopes = Maps.newHashMap();
049 private final Map<JetNamedFunction, SimpleFunctionDescriptor> functions = Maps.newLinkedHashMap();
050 private final Map<JetProperty, PropertyDescriptor> properties = Maps.newLinkedHashMap();
051 private final Map<JetParameter, PropertyDescriptor> primaryConstructorParameterProperties = Maps.newHashMap();
052 private Map<JetDeclaration, CallableMemberDescriptor> members = null;
053
054 // File scopes - package scope extended with imports
055 protected final Map<JetFile, WritableScope> fileScopes = Maps.newHashMap();
056
057 public final Map<JetDeclarationContainer, DeclarationDescriptor> forDeferredResolver = Maps.newHashMap();
058
059 public final Map<JetDeclarationContainer, JetScope> normalScope = Maps.newHashMap();
060
061 private final Map<JetScript, ScriptDescriptor> scripts = Maps.newLinkedHashMap();
062 private final Map<JetScript, WritableScope> scriptScopes = Maps.newHashMap();
063
064 private StringBuilder debugOutput;
065
066 private TopDownAnalysisParameters topDownAnalysisParameters;
067
068 public TopDownAnalysisContext(@NotNull TopDownAnalysisParameters topDownAnalysisParameters) {
069 this.topDownAnalysisParameters = topDownAnalysisParameters;
070 }
071
072 @Override
073 @NotNull
074 public TopDownAnalysisParameters getTopDownAnalysisParameters() {
075 return topDownAnalysisParameters;
076 }
077
078 @Override
079 public void setTopDownAnalysisParameters(TopDownAnalysisParameters topDownAnalysisParameters) {
080 this.topDownAnalysisParameters = topDownAnalysisParameters;
081 }
082
083 public void debug(Object message) {
084 if (debugOutput != null) {
085 debugOutput.append(message).append("\n");
086 }
087 }
088
089 @SuppressWarnings("UnusedDeclaration")
090 /*package*/ void enableDebugOutput() {
091 if (debugOutput == null) {
092 debugOutput = new StringBuilder();
093 }
094 }
095
096 /*package*/ void printDebugOutput(PrintStream out) {
097 if (debugOutput != null) {
098 out.print(debugOutput);
099 }
100 }
101
102 @Override
103 public boolean completeAnalysisNeeded(@NotNull PsiElement element) {
104 PsiFile containingFile = element.getContainingFile();
105 boolean result = containingFile != null && topDownAnalysisParameters.getAnalyzeCompletely().apply(containingFile);
106 if (!result) {
107 debug(containingFile);
108 }
109 return result;
110 }
111
112 @Override
113 public Map<JetClassOrObject, ClassDescriptorWithResolutionScopes> getClasses() {
114 return classes;
115 }
116
117 public Map<JetFile, WritableScope> getFileScopes() {
118 return fileScopes;
119 }
120
121 public Map<JetFile, MutablePackageFragmentDescriptor> getPackageFragments() {
122 return packageFragments;
123 }
124
125 @NotNull
126 @Override
127 public StorageManager getStorageManager() {
128 return topDownAnalysisParameters.getStorageManager();
129 }
130
131 @NotNull
132 @Override
133 public ExceptionTracker getExceptionTracker() {
134 return topDownAnalysisParameters.getExceptionTracker();
135 }
136
137 @Override
138 public Collection<JetFile> getFiles() {
139 return packageFragments.keySet();
140 }
141
142 @Override
143 @NotNull
144 public Map<JetScript, ScriptDescriptor> getScripts() {
145 return scripts;
146 }
147
148 @Override
149 @NotNull
150 public Map<JetScript, WritableScope> getScriptScopes() {
151 return scriptScopes;
152 }
153
154 public Map<JetParameter, PropertyDescriptor> getPrimaryConstructorParameterProperties() {
155 return primaryConstructorParameterProperties;
156 }
157
158 @Override
159 public Map<JetProperty, PropertyDescriptor> getProperties() {
160 return properties;
161 }
162
163 @Override
164 public Function<JetDeclaration, JetScope> getDeclaringScopes() {
165 return Functions.forMap(declaringScopes);
166 }
167
168 public void registerDeclaringScope(@NotNull JetDeclaration declaration, @NotNull JetScope scope) {
169 declaringScopes.put(declaration, scope);
170 }
171
172 @Override
173 public Map<JetNamedFunction, SimpleFunctionDescriptor> getFunctions() {
174 return functions;
175 }
176
177 public Map<JetDeclaration, CallableMemberDescriptor> getMembers() {
178 if (members == null) {
179 members = Maps.newHashMap();
180 members.putAll(functions);
181 members.putAll(properties);
182 members.putAll(primaryConstructorParameterProperties);
183 }
184 return members;
185 }
186
187 @NotNull
188 public List<MutableClassDescriptorLite> getClassesTopologicalOrder() {
189 return classesTopologicalOrder;
190 }
191
192 public void setClassesTopologicalOrder(@NotNull List<MutableClassDescriptorLite> classesTopologicalOrder) {
193 this.classesTopologicalOrder = classesTopologicalOrder;
194 }
195
196 @Override
197 @NotNull
198 public DataFlowInfo getOuterDataFlowInfo() {
199 return outerDataFlowInfo;
200 }
201
202 public void setOuterDataFlowInfo(@NotNull DataFlowInfo outerDataFlowInfo) {
203 this.outerDataFlowInfo = outerDataFlowInfo;
204 }
205 }