Repository: JuliaLang/julia
File: contrib/juliac/abi_export.jl (Julia)

Code before:
        indented_println("{")
        indented_println("  \"id\": ", ctx.type_ids[dt], ",")
        indented_println("  \"kind\": \"pointer\",")
        indented_println("  \"name\": ", type_name_json(dt), ",")
        indented_println("  \"pointee_type_id\": ", pointee_type_id)
        print(ctx.io, " " ^ indent, "}")
    end
end

function emit_field_info!(ctx::TypeEmitter, @nospecialize(dt::DataType), field::Int; indent::Int = 0)
    desc = Base.DataTypeFieldDesc(dt)[field]
    type_id = ctx.type_ids[fieldtype(dt, field)]
    print(ctx.io, " " ^ indent)
    print(ctx.io, "{")
    print(ctx.io, " \"name\": ", field_name_json(dt, field), ",")
    print(ctx.io, " \"type_id\": ", type_id, ",")
    print(ctx.io, " \"offset\": ", desc.offset)
    print(ctx.io, " }")
end

function emit_struct_info!(ctx::TypeEmitter, @nospecialize(dt::DataType); indent::Int = 0)
    type_id = ctx.type_ids[dt]
    let indented_println(args...) = println(ctx.io, " " ^ indent, args...)
        indented_println("{")
        indented_println("  \"id\": ", type_id, ",")
        indented_println("  \"kind\": \"struct\",")
        indented_println("  \"name\": ", type_name_json(dt), ",")
        indented_println("  \"size\": ", Core.sizeof(dt), ",")
        indented_println("  \"alignment\": ", Base.datatype_alignment(dt), ",")
        indented_println("  \"fields\": [")
        for i = 1:Base.datatype_nfields(dt)
            emit_field_info!(ctx, dt, i; indent = indent + 4)
            println(ctx.io, i == Base.datatype_nfields(dt) ? "" : ",")
        end
        indented_println("  ]")
        print(ctx.io, " " ^ indent, "}")
    end
end

function emit_primitive_type!(ctx::TypeEmitter, @nospecialize(dt::DataType); indent::Int = 0)
    type_id = ctx.type_ids[dt]
    let indented_println(args...) = println(ctx.io, " " ^ indent, args...)
        indented_println("{")
        indented_println("  \"id\": ", type_id, ",")
        indented_println("  \"kind\": \"primitive\",")
        indented_println("  \"name\": ", type_name_json(dt), ",")
        indented_println("  \"signed\": ", (dt <: Signed), ",")
        indented_println("  \"bits\": ", 8 * Base.packedsize(dt), ",") # size for reinterpret / in-register
        indented_println("  \"size\": ", Base.aligned_sizeof(dt), ",") # size with padding / in-memory
        indented_println("  \"alignment\": ", Base.datatype_alignment(dt))
        print(ctx.io, " " ^ indent, "}")

Review comment (suggestion):
```suggestion
        indented_println(ismutabletype(dt) ?("  \"kind\": \"mutable struct\",") : "  \"kind\": \"struct\",")
```

Code after:
        indented_println("{")
        indented_println("  \"id\": ", ctx.type_ids[dt], ",")
        indented_println("  \"kind\": \"pointer\",")
        indented_println("  \"name\": ", type_name_json(dt), ",")
        indented_println("  \"pointee_type_id\": ", pointee_type_id)
        print(ctx.io, " " ^ indent, "}")
    end
end

function emit_field_info!(ctx::TypeEmitter, @nospecialize(dt::DataType), field::Int; indent::Int = 0)
    desc = Base.DataTypeFieldDesc(dt)[field]
    type_id = ctx.type_ids[fieldtype(dt, field)]
    print(ctx.io, " " ^ indent)
    print(ctx.io, "{")
    print(ctx.io, " \"name\": ", field_name_json(dt, field), ",")
    print(ctx.io, " \"type_id\": ", type_id, ",")
    print(ctx.io, " \"offset\": ", desc.offset, ",")
    print(ctx.io, " \"isptr\": ", desc.isptr, ",")
    print(ctx.io, " \"isfieldatomic\": ", Base.isfieldatomic(dt, field))
    print(ctx.io, " }")
end

function emit_struct_info!(ctx::TypeEmitter, @nospecialize(dt::DataType); indent::Int = 0)
    type_id = ctx.type_ids[dt]
    let indented_println(args...) = println(ctx.io, " " ^ indent, args...)
        indented_println("{")
        indented_println("  \"id\": ", type_id, ",")
        indented_println(ismutabletype(dt) ? "  \"kind\": \"mutable struct\"," : "  \"kind\": \"struct\",")
        indented_println("  \"name\": ", type_name_json(dt), ",")
        indented_println("  \"size\": ", Core.sizeof(dt), ",")
        indented_println("  \"alignment\": ", Base.datatype_alignment(dt), ",")
        indented_println("  \"fields\": [")
        for i = 1:Base.datatype_nfields(dt)
            emit_field_info!(ctx, dt, i; indent = indent + 4)
            println(ctx.io, i == Base.datatype_nfields(dt) ? "" : ",")
        end
        indented_println("  ]")
        print(ctx.io, " " ^ indent, "}")
    end
end

function emit_primitive_type!(ctx::TypeEmitter, @nospecialize(dt::DataType); indent::Int = 0)
    type_id = ctx.type_ids[dt]
    let indented_println(args...) = println(ctx.io, " " ^ indent, args...)
        indented_println("{")
        indented_println("  \"id\": ", type_id, ",")
        indented_println("  \"kind\": \"primitive\",")
        indented_println("  \"name\": ", type_name_json(dt), ",")
        indented_println("  \"signed\": ", (dt <: Signed), ",")
        indented_println("  \"bits\": ", 8 * Base.packedsize(dt), ",") # size for reinterpret / in-register
        indented_println("  \"size\": ", Base.aligned_sizeof(dt), ",") # size with padding / in-memory