@Override public void visitObjectLiteralExpression(JetObjectLiteralExpression expression) { ClassDescriptor classDescriptor = bindingContext.get(CLASS, expression.getObjectDeclaration()); if (classDescriptor == null) { // working around a problem with shallow analysis super.visitObjectLiteralExpression(expression); return; } final String name = inventAnonymousClassName(expression.getObjectDeclaration()); recordClosure( bindingTrace, expression.getObjectDeclaration(), classDescriptor, peekFromStack(classStack), JvmClassName.byInternalName(name), false); classStack.push(classDescriptor); //noinspection ConstantConditions nameStack.push(bindingContext.get(FQN, classDescriptor).getInternalName()); super.visitObjectLiteralExpression(expression); nameStack.pop(); classStack.pop(); }
@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); }
public GeneratedAnonymousClassDescriptor generateObjectLiteral( JetObjectLiteralExpression literal, ObjectOrClosureCodegen closure) { JetObjectDeclaration objectDeclaration = literal.getObjectDeclaration(); Pair<String, ClassBuilder> nameAndVisitor = forAnonymousSubclass(objectDeclaration); closure.cv = nameAndVisitor.getSecond(); closure.name = nameAndVisitor.getFirst(); final CodegenContext objectContext = closure.context.intoAnonymousClass( closure, getBindingContext().get(BindingContext.CLASS, objectDeclaration), OwnerKind.IMPLEMENTATION, typeMapper); new ImplementationBodyCodegen( objectDeclaration, objectContext, nameAndVisitor.getSecond(), this) .generate(); ConstructorDescriptor constructorDescriptor = closure.state.getBindingContext().get(BindingContext.CONSTRUCTOR, objectDeclaration); CallableMethod callableMethod = closure .state .getTypeMapper() .mapToCallableMethod( constructorDescriptor, OwnerKind.IMPLEMENTATION, typeMapper.hasThis0(constructorDescriptor.getContainingDeclaration())); return new GeneratedAnonymousClassDescriptor( nameAndVisitor.first, callableMethod.getSignature().getAsmMethod(), objectContext.outerWasUsed, null); }
@NotNull public static JvmClassName classNameForAnonymousClass( @NotNull BindingContext bindingContext, @NotNull JetElement expression) { if (expression instanceof JetObjectLiteralExpression) { JetObjectLiteralExpression jetObjectLiteralExpression = (JetObjectLiteralExpression) expression; expression = jetObjectLiteralExpression.getObjectDeclaration(); } ClassDescriptor descriptor = bindingContext.get(CLASS, expression); if (descriptor == null) { SimpleFunctionDescriptor functionDescriptor = bindingContext.get(FUNCTION, expression); assert functionDescriptor != null; return classNameForAnonymousClass(bindingContext, functionDescriptor); } return fqn(bindingContext, descriptor); }
@Override public JetType visitObjectLiteralExpression( final JetObjectLiteralExpression expression, final ExpressionTypingContext context) { final JetType[] result = new JetType[1]; 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, new LazyValueWithDefault<JetType>( ErrorUtils.createErrorType("Recursive dependency")) { @Override protected JetType compute() { return descriptor.getDefaultType(); } }); result[0] = defaultType; if (!context.trace.get(PROCESSED, expression)) { context.trace.record(EXPRESSION_TYPE, expression, defaultType); context.trace.record(PROCESSED, expression); } } } }; ObservableBindingTrace traceAdapter = new ObservableBindingTrace(context.trace); traceAdapter.addHandler(CLASS, handler); TopDownAnalyzer.processObject( context.semanticServices, traceAdapter, context.scope, context.scope.getContainingDeclaration(), expression.getObjectDeclaration()); return DataFlowUtils.checkType(result[0], expression, context); }