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.KotlinPackage;
021 import kotlin.jvm.functions.Function1;
022 import org.jetbrains.annotations.NotNull;
023 import org.jetbrains.annotations.Nullable;
024 import org.jetbrains.kotlin.descriptors.*;
025 import org.jetbrains.kotlin.psi.*;
026 import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
027 import org.jetbrains.kotlin.resolve.lazy.DeclarationScopeProvider;
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<JetClassOrObject, ClassDescriptorWithResolutionScopes> classes = Maps.newLinkedHashMap();
041 private final Map<JetClassInitializer, ClassDescriptorWithResolutionScopes> anonymousInitializers = Maps.newLinkedHashMap();
042 private final Set<JetFile> files = new LinkedHashSet<JetFile>();
043 private final Map<JetSecondaryConstructor, ConstructorDescriptor> secondaryConstructors = Maps.newLinkedHashMap();
044
045 private final Map<JetNamedFunction, SimpleFunctionDescriptor> functions = Maps.newLinkedHashMap();
046 private final Map<JetProperty, PropertyDescriptor> properties = Maps.newLinkedHashMap();
047 private final Map<JetParameter, PropertyDescriptor> primaryConstructorParameterProperties = Maps.newHashMap();
048 private Map<JetCallableDeclaration, CallableMemberDescriptor> members = null;
049
050 private final Map<JetScript, ScriptDescriptor> scripts = Maps.newLinkedHashMap();
051
052 private final TopDownAnalysisMode topDownAnalysisMode;
053 private final DeclarationScopeProvider declarationScopeProvider;
054
055 private StringBuilder debugOutput;
056
057 public TopDownAnalysisContext(
058 @NotNull TopDownAnalysisMode topDownAnalysisMode,
059 @NotNull DataFlowInfo outerDataFlowInfo,
060 @NotNull DeclarationScopeProvider declarationScopeProvider
061 ) {
062 this.topDownAnalysisMode = topDownAnalysisMode;
063 this.outerDataFlowInfo = outerDataFlowInfo;
064 this.declarationScopeProvider = declarationScopeProvider;
065 }
066
067 @Override
068 @NotNull
069 public TopDownAnalysisMode getTopDownAnalysisMode() {
070 return topDownAnalysisMode;
071 }
072
073 public void debug(Object message) {
074 if (debugOutput != null) {
075 debugOutput.append(message).append("\n");
076 }
077 }
078
079 @SuppressWarnings("UnusedDeclaration")
080 /*package*/ void enableDebugOutput() {
081 if (debugOutput == null) {
082 debugOutput = new StringBuilder();
083 }
084 }
085
086 /*package*/ void printDebugOutput(PrintStream out) {
087 if (debugOutput != null) {
088 out.print(debugOutput);
089 }
090 }
091
092 @Override
093 public Map<JetClassOrObject, ClassDescriptorWithResolutionScopes> getDeclaredClasses() {
094 return classes;
095 }
096
097 @Override
098 public Map<JetClassInitializer, ClassDescriptorWithResolutionScopes> getAnonymousInitializers() {
099 return anonymousInitializers;
100 }
101
102 @Override
103 public Map<JetSecondaryConstructor, ConstructorDescriptor> getSecondaryConstructors() {
104 return secondaryConstructors;
105 }
106
107 @Override
108 public Collection<JetFile> getFiles() {
109 return files;
110 }
111
112 public void addFile(@NotNull JetFile file) {
113 files.add(file);
114 }
115
116 @Override
117 @NotNull
118 public Map<JetScript, ScriptDescriptor> getScripts() {
119 return scripts;
120 }
121
122 public Map<JetParameter, PropertyDescriptor> getPrimaryConstructorParameterProperties() {
123 return primaryConstructorParameterProperties;
124 }
125
126 @Override
127 public Map<JetProperty, PropertyDescriptor> getProperties() {
128 return properties;
129 }
130
131 @Nullable
132 @Override
133 public LexicalScope getDeclaringScope(@NotNull JetDeclaration declaration) {
134 return declarationScopeProvider.getResolutionScopeForDeclaration(declaration);
135 }
136
137 @Override
138 public Map<JetNamedFunction, SimpleFunctionDescriptor> getFunctions() {
139 return functions;
140 }
141
142 @NotNull
143 public Map<JetCallableDeclaration, CallableMemberDescriptor> getMembers() {
144 if (members == null) {
145 members = Maps.newLinkedHashMap();
146 members.putAll(functions);
147 members.putAll(properties);
148 members.putAll(primaryConstructorParameterProperties);
149 }
150 return members;
151 }
152
153 @Override
154 @NotNull
155 public DataFlowInfo getOuterDataFlowInfo() {
156 return outerDataFlowInfo;
157 }
158
159 @NotNull
160 public Collection<ClassDescriptorWithResolutionScopes> getAllClasses() {
161 // SCRIPT: all classes are declared classes + script classes
162 Collection<ClassDescriptorWithResolutionScopes> scriptClasses = KotlinPackage.map(
163 getScripts().values(),
164 new Function1<ScriptDescriptor, ClassDescriptorWithResolutionScopes>() {
165 @Override
166 public ClassDescriptorWithResolutionScopes invoke(ScriptDescriptor scriptDescriptor) {
167 return (ClassDescriptorWithResolutionScopes) scriptDescriptor.getClassDescriptor();
168 }
169 }
170 );
171 return KotlinPackage.plus(getDeclaredClasses().values(), scriptClasses);
172 }
173 }