@Override public JetTypeInfo visitObjectLiteralExpression( @NotNull final JetObjectLiteralExpression expression, final ExpressionTypingContext context) { DelegatingBindingTrace delegatingBindingTrace = context.trace.get(TRACE_DELTAS_CACHE, expression.getObjectDeclaration()); if (delegatingBindingTrace != null) { delegatingBindingTrace.addAllMyDataTo(context.trace); JetType type = context.trace.get(EXPRESSION_TYPE, expression); return DataFlowUtils.checkType(type, expression, context, context.dataFlowInfo); } final JetType[] result = new JetType[1]; final TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create( context.trace, "trace to resolve object literal expression", expression); ObservableBindingTrace.RecordHandler<PsiElement, ClassDescriptor> handler = new ObservableBindingTrace.RecordHandler<PsiElement, ClassDescriptor>() { @Override public void handleRecord( WritableSlice<PsiElement, ClassDescriptor> slice, PsiElement declaration, final ClassDescriptor descriptor) { if (slice == CLASS && declaration == expression.getObjectDeclaration()) { JetType defaultType = DeferredType.create( context.trace, createRecursionIntolerantLazyValueWithDefault( ErrorUtils.createErrorType("Recursive dependency"), new Function0<JetType>() { @Override public JetType invoke() { return descriptor.getDefaultType(); } })); result[0] = defaultType; if (!context.trace.get(PROCESSED, expression)) { temporaryTrace.record(EXPRESSION_TYPE, expression, defaultType); temporaryTrace.record(PROCESSED, expression); } } } }; ObservableBindingTrace traceAdapter = new ObservableBindingTrace(temporaryTrace); traceAdapter.addHandler(CLASS, handler); TopDownAnalyzer.processClassOrObject( context.replaceBindingTrace(traceAdapter).replaceContextDependency(INDEPENDENT), context.scope.getContainingDeclaration(), expression.getObjectDeclaration()); DelegatingBindingTrace cloneDelta = new DelegatingBindingTrace( new BindingTraceContext().getBindingContext(), "cached delta trace for object literal expression resolve", expression); temporaryTrace.addAllMyDataTo(cloneDelta); context.trace.record(TRACE_DELTAS_CACHE, expression.getObjectDeclaration(), cloneDelta); temporaryTrace.commit(); return DataFlowUtils.checkType(result[0], expression, context, context.dataFlowInfo); }
@Override public JetTypeInfo visitFunctionLiteralExpression( @NotNull JetFunctionLiteralExpression expression, ExpressionTypingContext context) { JetBlockExpression bodyExpression = expression.getFunctionLiteral().getBodyExpression(); if (bodyExpression == null) return null; Name callerName = getCallerName(expression); if (callerName != null) { context.labelResolver.enterLabeledElement(new LabelName(callerName.asString()), expression); } JetType expectedType = context.expectedType; boolean functionTypeExpected = !noExpectedType(expectedType) && KotlinBuiltIns.getInstance().isFunctionOrExtensionFunctionType(expectedType); AnonymousFunctionDescriptor functionDescriptor = createFunctionDescriptor(expression, context, functionTypeExpected); JetType safeReturnType = computeReturnType(expression, context, functionDescriptor, functionTypeExpected); functionDescriptor.setReturnType(safeReturnType); JetType receiver = DescriptorUtils.getReceiverParameterType(functionDescriptor.getReceiverParameter()); List<JetType> valueParametersTypes = DescriptorUtils.getValueParametersTypes(functionDescriptor.getValueParameters()); JetType resultType = KotlinBuiltIns.getInstance() .getFunctionType( Collections.<AnnotationDescriptor>emptyList(), receiver, valueParametersTypes, safeReturnType); if (!noExpectedType(expectedType) && KotlinBuiltIns.getInstance().isFunctionOrExtensionFunctionType(expectedType)) { // all checks were done before return JetTypeInfo.create(resultType, context.dataFlowInfo); } if (callerName != null) { context.labelResolver.exitLabeledElement(expression); } return DataFlowUtils.checkType(resultType, expression, context, context.dataFlowInfo); }