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