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.types.expressions;
018
019 import com.intellij.openapi.diagnostic.Logger;
020 import com.intellij.openapi.progress.ProcessCanceledException;
021 import kotlin.jvm.functions.Function0;
022 import org.jetbrains.annotations.NotNull;
023 import org.jetbrains.annotations.Nullable;
024 import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
025 import org.jetbrains.kotlin.diagnostics.Errors;
026 import org.jetbrains.kotlin.psi.*;
027 import org.jetbrains.kotlin.resolve.AnnotationChecker;
028 import org.jetbrains.kotlin.resolve.BindingContext;
029 import org.jetbrains.kotlin.resolve.BindingContextUtils;
030 import org.jetbrains.kotlin.resolve.bindingContextUtil.BindingContextUtilsKt;
031 import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind;
032 import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope;
033 import org.jetbrains.kotlin.types.DeferredType;
034 import org.jetbrains.kotlin.types.ErrorUtils;
035 import org.jetbrains.kotlin.types.KotlinType;
036 import org.jetbrains.kotlin.types.expressions.typeInfoFactory.TypeInfoFactoryKt;
037 import org.jetbrains.kotlin.util.PerformanceCounter;
038 import org.jetbrains.kotlin.util.ReenteringLazyValueComputationException;
039 import org.jetbrains.kotlin.utils.KotlinFrontEndException;
040
041 import static org.jetbrains.kotlin.diagnostics.Errors.TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM;
042
043 public abstract class ExpressionTypingVisitorDispatcher extends KtVisitor<KotlinTypeInfo, ExpressionTypingContext>
044 implements ExpressionTypingInternals {
045
046 public static final PerformanceCounter typeInfoPerfCounter = PerformanceCounter.Companion.create("Type info", true);
047
048 private static final Logger LOG = Logger.getInstance(ExpressionTypingVisitor.class);
049
050 public static class ForDeclarations extends ExpressionTypingVisitorDispatcher {
051 public ForDeclarations(@NotNull ExpressionTypingComponents components, @NotNull AnnotationChecker annotationChecker) {
052 super(components, annotationChecker);
053 }
054
055 @Override
056 protected ExpressionTypingVisitorForStatements getStatementVisitor(@NotNull ExpressionTypingContext context) {
057 return createStatementVisitor(context);
058 }
059 }
060
061 protected abstract ExpressionTypingVisitorForStatements getStatementVisitor(@NotNull ExpressionTypingContext context);
062
063 public static class ForBlock extends ExpressionTypingVisitorDispatcher {
064
065 private final ExpressionTypingVisitorForStatements visitorForBlock;
066
067 public ForBlock(
068 @NotNull ExpressionTypingComponents components,
069 @NotNull AnnotationChecker annotationChecker,
070 @NotNull LexicalWritableScope writableScope
071 ) {
072 super(components, annotationChecker);
073 this.visitorForBlock = new ExpressionTypingVisitorForStatements(
074 this, writableScope, basic, controlStructures, patterns, functions
075 );
076 }
077
078 @Override
079 protected ExpressionTypingVisitorForStatements getStatementVisitor(@NotNull ExpressionTypingContext context) {
080 return visitorForBlock;
081 }
082 }
083
084 private final ExpressionTypingComponents components;
085 @NotNull private final AnnotationChecker annotationChecker;
086 protected final BasicExpressionTypingVisitor basic;
087 protected final FunctionsTypingVisitor functions;
088 protected final ControlStructureTypingVisitor controlStructures;
089 protected final PatternMatchingTypingVisitor patterns;
090
091 private ExpressionTypingVisitorDispatcher(
092 @NotNull ExpressionTypingComponents components,
093 @NotNull AnnotationChecker annotationChecker
094 ) {
095 this.components = components;
096 this.annotationChecker = annotationChecker;
097 this.basic = new BasicExpressionTypingVisitor(this);
098 this.controlStructures = new ControlStructureTypingVisitor(this);
099 this.patterns = new PatternMatchingTypingVisitor(this);
100 this.functions = new FunctionsTypingVisitor(this);
101 }
102
103 @Override
104 @NotNull
105 public ExpressionTypingComponents getComponents() {
106 return components;
107 }
108
109 @NotNull
110 @Override
111 public KotlinTypeInfo checkInExpression(
112 @NotNull KtElement callElement,
113 @NotNull KtSimpleNameExpression operationSign,
114 @NotNull ValueArgument leftArgument,
115 @Nullable KtExpression right,
116 @NotNull ExpressionTypingContext context
117 ) {
118 return basic.checkInExpression(callElement, operationSign, leftArgument, right, context);
119 }
120
121 @Override
122 @NotNull
123 public final KotlinTypeInfo safeGetTypeInfo(@NotNull KtExpression expression, ExpressionTypingContext context) {
124 KotlinTypeInfo typeInfo = getTypeInfo(expression, context);
125 if (typeInfo.getType() != null) {
126 return typeInfo;
127 }
128 return typeInfo
129 .replaceType(ErrorUtils.createErrorType("Type for " + expression.getText()))
130 .replaceDataFlowInfo(context.dataFlowInfo);
131 }
132
133 @Override
134 @NotNull
135 public final KotlinTypeInfo getTypeInfo(@NotNull KtExpression expression, ExpressionTypingContext context) {
136 KotlinTypeInfo result = getTypeInfo(expression, context, this);
137 annotationChecker.checkExpression(expression, context.trace);
138 return result;
139 }
140
141 @Override
142 @NotNull
143 public final KotlinTypeInfo getTypeInfo(@NotNull KtExpression expression, ExpressionTypingContext context, boolean isStatement) {
144 if (!isStatement) return getTypeInfo(expression, context);
145 return getTypeInfo(expression, context, getStatementVisitor(context));
146 }
147
148 protected ExpressionTypingVisitorForStatements createStatementVisitor(ExpressionTypingContext context) {
149 return new ExpressionTypingVisitorForStatements(this,
150 ExpressionTypingUtils.newWritableScopeImpl(context, LexicalScopeKind.CODE_BLOCK),
151 basic, controlStructures, patterns, functions);
152 }
153
154 @Override
155 public void checkStatementType(@NotNull KtExpression expression, ExpressionTypingContext context) {
156 expression.accept(createStatementVisitor(context), context);
157 }
158
159 @NotNull
160 private static KotlinTypeInfo getTypeInfo(@NotNull final KtExpression expression, final ExpressionTypingContext context, final KtVisitor<KotlinTypeInfo, ExpressionTypingContext> visitor) {
161 return typeInfoPerfCounter.time(new Function0<KotlinTypeInfo>() {
162 @Override
163 public KotlinTypeInfo invoke() {
164 try {
165 KotlinTypeInfo recordedTypeInfo = BindingContextUtils.getRecordedTypeInfo(expression, context.trace.getBindingContext());
166 if (recordedTypeInfo != null) {
167 return recordedTypeInfo;
168 }
169 KotlinTypeInfo result;
170 try {
171 result = expression.accept(visitor, context);
172 // Some recursive definitions (object expressions) must put their types in the cache manually:
173 //noinspection ConstantConditions
174 if (context.trace.get(BindingContext.PROCESSED, expression)) {
175 KotlinType type = context.trace.getBindingContext().getType(expression);
176 return result.replaceType(type);
177 }
178
179 if (result.getType() instanceof DeferredType) {
180 result = result.replaceType(((DeferredType) result.getType()).getDelegate());
181 }
182 context.trace.record(BindingContext.EXPRESSION_TYPE_INFO, expression, result);
183 }
184 catch (ReenteringLazyValueComputationException e) {
185 context.trace.report(TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM.on(expression));
186 result = TypeInfoFactoryKt.noTypeInfo(context);
187 }
188
189 context.trace.record(BindingContext.PROCESSED, expression);
190
191 // todo save scope before analyze and fix debugger: see CodeFragmentAnalyzer.correctContextForExpression
192 BindingContextUtilsKt.recordScope(context.trace, context.scope, expression);
193 BindingContextUtilsKt.recordDataFlowInfo(context.replaceDataFlowInfo(result.getDataFlowInfo()), expression);
194 return result;
195 }
196 catch (ProcessCanceledException e) {
197 throw e;
198 }
199 catch (KotlinFrontEndException e) {
200 throw e;
201 }
202 catch (Throwable e) {
203 context.trace.report(Errors.EXCEPTION_FROM_ANALYZER.on(expression, e));
204 logOrThrowException(expression, e);
205 return TypeInfoFactoryKt.createTypeInfo(
206 ErrorUtils.createErrorType(e.getClass().getSimpleName() + " from analyzer"),
207 context
208 );
209 }
210 }
211 });
212 }
213
214 private static void logOrThrowException(@NotNull KtExpression expression, Throwable e) {
215 try {
216 // This trows AssertionError in CLI and reports the error in the IDE
217 LOG.error(
218 "Exception while analyzing expression at " + DiagnosticUtils.atLocation(expression) + ":\n" + expression.getText() + "\n",
219 e
220 );
221 }
222 catch (AssertionError errorFromLogger) {
223 // If we ended up here, we are in CLI, and the initial exception needs to be rethrown,
224 // simply throwing AssertionError causes its being wrapped over and over again
225 throw new KotlinFrontEndException(errorFromLogger.getMessage(), e);
226 }
227 }
228
229 //////////////////////////////////////////////////////////////////////////////////////////////
230
231 @Override
232 public KotlinTypeInfo visitFunctionLiteralExpression(@NotNull KtFunctionLiteralExpression expression, ExpressionTypingContext data) {
233 return functions.visitFunctionLiteralExpression(expression, data);
234 }
235
236 @Override
237 public KotlinTypeInfo visitNamedFunction(@NotNull KtNamedFunction function, ExpressionTypingContext data) {
238 return functions.visitNamedFunction(function, data);
239 }
240
241 //////////////////////////////////////////////////////////////////////////////////////////////
242
243 @Override
244 public KotlinTypeInfo visitThrowExpression(@NotNull KtThrowExpression expression, ExpressionTypingContext data) {
245 return controlStructures.visitThrowExpression(expression, data);
246 }
247
248 @Override
249 public KotlinTypeInfo visitReturnExpression(@NotNull KtReturnExpression expression, ExpressionTypingContext data) {
250 return controlStructures.visitReturnExpression(expression, data);
251 }
252
253 @Override
254 public KotlinTypeInfo visitContinueExpression(@NotNull KtContinueExpression expression, ExpressionTypingContext data) {
255 return controlStructures.visitContinueExpression(expression, data);
256 }
257
258 @Override
259 public KotlinTypeInfo visitIfExpression(@NotNull KtIfExpression expression, ExpressionTypingContext data) {
260 return controlStructures.visitIfExpression(expression, data);
261 }
262
263 @Override
264 public KotlinTypeInfo visitTryExpression(@NotNull KtTryExpression expression, ExpressionTypingContext data) {
265 return controlStructures.visitTryExpression(expression, data);
266 }
267
268 @Override
269 public KotlinTypeInfo visitForExpression(@NotNull KtForExpression expression, ExpressionTypingContext data) {
270 return controlStructures.visitForExpression(expression, data);
271 }
272
273 @Override
274 public KotlinTypeInfo visitWhileExpression(@NotNull KtWhileExpression expression, ExpressionTypingContext data) {
275 return controlStructures.visitWhileExpression(expression, data);
276 }
277
278 @Override
279 public KotlinTypeInfo visitDoWhileExpression(@NotNull KtDoWhileExpression expression, ExpressionTypingContext data) {
280 return controlStructures.visitDoWhileExpression(expression, data);
281 }
282
283 @Override
284 public KotlinTypeInfo visitBreakExpression(@NotNull KtBreakExpression expression, ExpressionTypingContext data) {
285 return controlStructures.visitBreakExpression(expression, data);
286 }
287
288 //////////////////////////////////////////////////////////////////////////////////////////////
289
290 @Override
291 public KotlinTypeInfo visitIsExpression(@NotNull KtIsExpression expression, ExpressionTypingContext data) {
292 return patterns.visitIsExpression(expression, data);
293 }
294
295 @Override
296 public KotlinTypeInfo visitWhenExpression(@NotNull KtWhenExpression expression, ExpressionTypingContext data) {
297 return patterns.visitWhenExpression(expression, data);
298 }
299
300 //////////////////////////////////////////////////////////////////////////////////////////////
301
302 @Override
303 public KotlinTypeInfo visitSimpleNameExpression(@NotNull KtSimpleNameExpression expression, ExpressionTypingContext data) {
304 return basic.visitSimpleNameExpression(expression, data);
305 }
306
307 @Override
308 public KotlinTypeInfo visitParenthesizedExpression(@NotNull KtParenthesizedExpression expression, ExpressionTypingContext data) {
309 return basic.visitParenthesizedExpression(expression, data);
310 }
311
312 @Override
313 public KotlinTypeInfo visitConstantExpression(@NotNull KtConstantExpression expression, ExpressionTypingContext data) {
314 return basic.visitConstantExpression(expression, data);
315 }
316
317 @Override
318 public KotlinTypeInfo visitBinaryWithTypeRHSExpression(@NotNull KtBinaryExpressionWithTypeRHS expression, ExpressionTypingContext data) {
319 return basic.visitBinaryWithTypeRHSExpression(expression, data);
320 }
321
322 @Override
323 public KotlinTypeInfo visitThisExpression(@NotNull KtThisExpression expression, ExpressionTypingContext data) {
324 return basic.visitThisExpression(expression, data);
325 }
326
327 @Override
328 public KotlinTypeInfo visitSuperExpression(@NotNull KtSuperExpression expression, ExpressionTypingContext data) {
329 return basic.visitSuperExpression(expression, data);
330 }
331
332 @Override
333 public KotlinTypeInfo visitBlockExpression(@NotNull KtBlockExpression expression, ExpressionTypingContext data) {
334 return basic.visitBlockExpression(expression, data);
335 }
336
337 @Override
338 public KotlinTypeInfo visitClassLiteralExpression(@NotNull KtClassLiteralExpression expression, ExpressionTypingContext data) {
339 return basic.visitClassLiteralExpression(expression, data);
340 }
341
342 @Override
343 public KotlinTypeInfo visitCallableReferenceExpression(@NotNull KtCallableReferenceExpression expression, ExpressionTypingContext data) {
344 return basic.visitCallableReferenceExpression(expression, data);
345 }
346
347 @Override
348 public KotlinTypeInfo visitObjectLiteralExpression(@NotNull KtObjectLiteralExpression expression, ExpressionTypingContext data) {
349 return basic.visitObjectLiteralExpression(expression, data);
350 }
351
352 @Override
353 public KotlinTypeInfo visitQualifiedExpression(@NotNull KtQualifiedExpression expression, ExpressionTypingContext data) {
354 return basic.visitQualifiedExpression(expression, data);
355 }
356
357 @Override
358 public KotlinTypeInfo visitCallExpression(@NotNull KtCallExpression expression, ExpressionTypingContext data) {
359 return basic.visitCallExpression(expression, data);
360 }
361
362 @Override
363 public KotlinTypeInfo visitUnaryExpression(@NotNull KtUnaryExpression expression, ExpressionTypingContext data) {
364 return basic.visitUnaryExpression(expression, data);
365 }
366
367 @Override
368 public KotlinTypeInfo visitLabeledExpression(@NotNull KtLabeledExpression expression, ExpressionTypingContext data) {
369 return basic.visitLabeledExpression(expression, data);
370 }
371
372 @Override
373 public KotlinTypeInfo visitBinaryExpression(@NotNull KtBinaryExpression expression, ExpressionTypingContext data) {
374 return basic.visitBinaryExpression(expression, data);
375 }
376
377 @Override
378 public KotlinTypeInfo visitArrayAccessExpression(@NotNull KtArrayAccessExpression expression, ExpressionTypingContext data) {
379 return basic.visitArrayAccessExpression(expression, data);
380 }
381
382 @Override
383 public KotlinTypeInfo visitDeclaration(@NotNull KtDeclaration dcl, ExpressionTypingContext data) {
384 return basic.visitDeclaration(dcl, data);
385 }
386
387 @Override
388 public KotlinTypeInfo visitRootPackageExpression(@NotNull KtRootPackageExpression expression, ExpressionTypingContext data) {
389 return basic.visitRootPackageExpression(expression, data);
390 }
391
392 @Override
393 public KotlinTypeInfo visitStringTemplateExpression(@NotNull KtStringTemplateExpression expression, ExpressionTypingContext data) {
394 return basic.visitStringTemplateExpression(expression, data);
395 }
396
397 @Override
398 public KotlinTypeInfo visitAnnotatedExpression(@NotNull KtAnnotatedExpression expression, ExpressionTypingContext data) {
399 return basic.visitAnnotatedExpression(expression, data);
400 }
401
402 @Override
403 public KotlinTypeInfo visitKtElement(@NotNull KtElement element, ExpressionTypingContext data) {
404 return element.accept(basic, data);
405 }
406 }