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.google.common.collect.Maps;
020 import kotlin.collections.CollectionsKt;
021 import org.jetbrains.annotations.NotNull;
022 import org.jetbrains.annotations.Nullable;
023 import org.jetbrains.kotlin.descriptors.*;
024 import org.jetbrains.kotlin.psi.*;
025 import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
026 import org.jetbrains.kotlin.resolve.lazy.DeclarationScopeProvider;
027 import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyScriptDescriptor;
028 import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
029
030 import java.io.PrintStream;
031 import java.util.Collection;
032 import java.util.LinkedHashSet;
033 import java.util.Map;
034 import java.util.Set;
035
036 public class TopDownAnalysisContext implements BodiesResolveContext {
037
038 private final DataFlowInfo outerDataFlowInfo;
039
040 private final Map<KtClassOrObject, ClassDescriptorWithResolutionScopes> classes = Maps.newLinkedHashMap();
041 private final Map<KtAnonymousInitializer, ClassDescriptorWithResolutionScopes> anonymousInitializers = Maps.newLinkedHashMap();
042 private final Set<KtFile> files = new LinkedHashSet<KtFile>();
043 private final Map<KtSecondaryConstructor, ClassConstructorDescriptor> secondaryConstructors = Maps.newLinkedHashMap();
044
045 private final Map<KtNamedFunction, SimpleFunctionDescriptor> functions = Maps.newLinkedHashMap();
046 private final Map<KtProperty, PropertyDescriptor> properties = Maps.newLinkedHashMap();
047 private final Map<KtParameter, PropertyDescriptor> primaryConstructorParameterProperties = Maps.newHashMap();
048 private final Map<KtTypeAlias, TypeAliasDescriptor> typeAliases = Maps.newLinkedHashMap();
049 private Map<KtCallableDeclaration, CallableMemberDescriptor> members = null;
050
051 private final Map<KtScript, LazyScriptDescriptor> scripts = Maps.newLinkedHashMap();
052
053 private final TopDownAnalysisMode topDownAnalysisMode;
054 private final DeclarationScopeProvider declarationScopeProvider;
055
056 private StringBuilder debugOutput;
057
058 public TopDownAnalysisContext(
059 @NotNull TopDownAnalysisMode topDownAnalysisMode,
060 @NotNull DataFlowInfo outerDataFlowInfo,
061 @NotNull DeclarationScopeProvider declarationScopeProvider
062 ) {
063 this.topDownAnalysisMode = topDownAnalysisMode;
064 this.outerDataFlowInfo = outerDataFlowInfo;
065 this.declarationScopeProvider = declarationScopeProvider;
066 }
067
068 @Override
069 @NotNull
070 public TopDownAnalysisMode getTopDownAnalysisMode() {
071 return topDownAnalysisMode;
072 }
073
074 public void debug(Object message) {
075 if (debugOutput != null) {
076 debugOutput.append(message).append("\n");
077 }
078 }
079
080 @SuppressWarnings("UnusedDeclaration")
081 /*package*/ void enableDebugOutput() {
082 if (debugOutput == null) {
083 debugOutput = new StringBuilder();
084 }
085 }
086
087 /*package*/ void printDebugOutput(PrintStream out) {
088 if (debugOutput != null) {
089 out.print(debugOutput);
090 }
091 }
092
093 @Override
094 public Map<KtClassOrObject, ClassDescriptorWithResolutionScopes> getDeclaredClasses() {
095 return classes;
096 }
097
098 @Override
099 public Map<KtAnonymousInitializer, ClassDescriptorWithResolutionScopes> getAnonymousInitializers() {
100 return anonymousInitializers;
101 }
102
103 @Override
104 public Map<KtSecondaryConstructor, ClassConstructorDescriptor> getSecondaryConstructors() {
105 return secondaryConstructors;
106 }
107
108 @Override
109 public Collection<KtFile> getFiles() {
110 return files;
111 }
112
113 public void addFile(@NotNull KtFile file) {
114 files.add(file);
115 }
116
117 @Override
118 @NotNull
119 public Map<KtScript, LazyScriptDescriptor> getScripts() {
120 return scripts;
121 }
122
123 public Map<KtParameter, PropertyDescriptor> getPrimaryConstructorParameterProperties() {
124 return primaryConstructorParameterProperties;
125 }
126
127 @Override
128 public Map<KtProperty, PropertyDescriptor> getProperties() {
129 return properties;
130 }
131
132 @Nullable
133 @Override
134 public LexicalScope getDeclaringScope(@NotNull KtDeclaration declaration) {
135 return declarationScopeProvider.getResolutionScopeForDeclaration(declaration);
136 }
137
138 @Override
139 public Map<KtNamedFunction, SimpleFunctionDescriptor> getFunctions() {
140 return functions;
141 }
142
143 @Override
144 public Map<KtTypeAlias, TypeAliasDescriptor> getTypeAliases() {
145 return typeAliases;
146 }
147
148 @NotNull
149 public Map<KtCallableDeclaration, CallableMemberDescriptor> getMembers() {
150 if (members == null) {
151 members = Maps.newLinkedHashMap();
152 members.putAll(functions);
153 members.putAll(properties);
154 members.putAll(primaryConstructorParameterProperties);
155 }
156 return members;
157 }
158
159 @Override
160 @NotNull
161 public DataFlowInfo getOuterDataFlowInfo() {
162 return outerDataFlowInfo;
163 }
164
165 @NotNull
166 public Collection<ClassDescriptorWithResolutionScopes> getAllClasses() {
167 return CollectionsKt.plus(getDeclaredClasses().values(), getScripts().values());
168 }
169 }