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