@Override
  protected void generateDeclaration() {
    BothSignatureWriter sw = new BothSignatureWriter(BothSignatureWriter.Mode.CLASS);
    if (samType != null) {
      typeMapper.writeFormalTypeParameters(samType.getType().getConstructor().getParameters(), sw);
    }
    sw.writeSuperclass();
    superClassAsmType = typeMapper.mapSupertype(superClassType, sw);
    sw.writeSuperclassEnd();
    String[] superInterfaceAsmTypes = new String[superInterfaceTypes.size()];
    for (int i = 0; i < superInterfaceTypes.size(); i++) {
      JetType superInterfaceType = superInterfaceTypes.get(i);
      sw.writeInterface();
      superInterfaceAsmTypes[i] = typeMapper.mapSupertype(superInterfaceType, sw).getInternalName();
      sw.writeInterfaceEnd();
    }

    v.defineClass(
        element,
        V1_6,
        ACC_FINAL | ACC_SUPER | visibilityFlag,
        asmType.getInternalName(),
        sw.makeJavaGenericSignature(),
        superClassAsmType.getInternalName(),
        superInterfaceAsmTypes);

    InlineCodegenUtil.initDefaultSourceMappingIfNeeded(context, this, state);

    v.visitSource(element.getContainingFile().getName(), null);
  }
  public ClosureCodegen(
      @NotNull GenerationState state,
      @NotNull JetElement element,
      @Nullable SamType samType,
      @NotNull ClosureContext context,
      @NotNull KotlinSyntheticClass.Kind syntheticClassKind,
      @NotNull FunctionGenerationStrategy strategy,
      @NotNull MemberCodegen<?> parentCodegen,
      @NotNull ClassBuilder classBuilder) {
    super(state, parentCodegen, context, element, classBuilder);

    this.funDescriptor = context.getFunctionDescriptor();
    this.classDescriptor = context.getContextDescriptor();
    this.samType = samType;
    this.syntheticClassKind = syntheticClassKind;
    this.strategy = strategy;

    if (samType == null) {
      this.superInterfaceTypes = new ArrayList<JetType>();

      JetType superClassType = null;
      for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
        ClassifierDescriptor classifier = supertype.getConstructor().getDeclarationDescriptor();
        if (DescriptorUtils.isTrait(classifier)) {
          superInterfaceTypes.add(supertype);
        } else {
          assert superClassType == null
              : "Closure class can't have more than one superclass: " + funDescriptor;
          superClassType = supertype;
        }
      }
      assert superClassType != null : "Closure class should have a superclass: " + funDescriptor;

      this.superClassType = superClassType;
    } else {
      this.superInterfaceTypes = Collections.singletonList(samType.getType());
      this.superClassType = getBuiltIns(funDescriptor).getAnyType();
    }

    this.closure = bindingContext.get(CLOSURE, classDescriptor);
    assert closure != null : "Closure must be calculated for class: " + classDescriptor;

    this.asmType = typeMapper.mapClass(classDescriptor);

    visibilityFlag = AsmUtil.getVisibilityAccessFlagForAnonymous(classDescriptor);
  }