Browse Source

add --json

Simon Krajewski 7 years ago
parent
commit
f0efbc3ce2
3 changed files with 707 additions and 8 deletions
  1. 21 8
      src/compiler/main.ml
  2. 368 0
      src/generators/genjson.ml
  3. 318 0
      std/haxe/rtti/JsonModuleTypes.hx

+ 21 - 8
src/compiler/main.ml

@@ -463,6 +463,7 @@ and init ctx =
 	let classes = ref [([],"Std")] in
 try
 	let xml_out = ref None in
+	let json_out = ref None in
 	let swf_header = ref None in
 	let cmds = ref [] in
 	let config_macros = ref [] in
@@ -689,6 +690,10 @@ try
 			Parser.use_doc := true;
 			xml_out := Some file
 		),"<file>","generate XML types description");
+		("Services",["--json"],[],Arg.String (fun file ->
+			Parser.use_doc := true;
+			json_out := Some file
+		),"<file>","generate JSON types description");
 		("Services",["--gen-hx-classes"],[], Arg.Unit (fun() ->
 			force_typing := true;
 			pre_compilation := (fun() ->
@@ -832,14 +837,22 @@ try
 		Filters.run com tctx main;
 		t();
 		if ctx.has_error then raise Abort;
-		(match !xml_out with
-		| None -> ()
-		| Some "hx" ->
-			Genxml.generate_hx com
-		| Some file ->
-			Common.log com ("Generating xml: " ^ file);
-			Path.mkdir_from_path file;
-			Genxml.generate com file);
+		begin match !xml_out with
+			| None -> ()
+			| Some "hx" ->
+				Genxml.generate_hx com
+			| Some file ->
+				Common.log com ("Generating xml: " ^ file);
+				Path.mkdir_from_path file;
+				Genxml.generate com file
+		end;
+		begin match !json_out with
+			| None -> ()
+			| Some file ->
+				Common.log com ("Generating json : " ^ file);
+				Path.mkdir_from_path file;
+				Genjson.generate com file
+		end;
 		if not !no_output then generate tctx ext !xml_out !interp !swf_header;
 	end;
 	Sys.catch_break false;

+ 368 - 0
src/generators/genjson.ml

@@ -0,0 +1,368 @@
+open Ast
+open Globals
+open Common
+open Type
+open Meta
+
+type context = {
+	com : Common.context;
+}
+
+let jnull = Json.JNull
+let jstring s = Json.JString s
+let jint i = Json.JInt i
+let jbool b = Json.JBool b
+let jarray l = Json.JArray l
+let jobject l = Json.JObject l
+
+let jtodo = Json.JNull
+let jopt f o = Option.map_default f Json.JNull o
+let jlist f o = jarray (List.map f o)
+
+let generate_path path =
+	jobject [
+		"pack",jarray (List.map jstring (fst path));
+		"name",jstring (snd path)
+	]
+
+let generate_adt ctx tpath name args =
+	let field = ("kind",jstring name) in
+	let fields = match args with
+		| None -> [field]
+		| Some arg -> [field;("args",arg)]
+	in
+	jobject fields
+
+let class_ref ctx c = generate_path c.cl_path
+let enum_ref ctx en = generate_path en.e_path
+let typedef_ref ctx td = generate_path td.t_path
+let abstract_ref ctx a = generate_path a.a_path
+let classfield_ref ctx cf = jstring cf.cf_name
+
+let generate_pos ctx p =
+	jobject [
+		"file",jstring p.pfile;
+		"min",jint p.pmin;
+		"max",jint p.pmax;
+	]
+
+(* AST expr *)
+
+let rec generate_binop ctx op =
+	let name,args = match op with
+	| OpAdd -> "OpAdd",None
+	| OpMult -> "OpMult",None
+	| OpDiv -> "OpDiv",None
+	| OpSub -> "OpSub",None
+	| OpAssign -> "OpAssign",None
+	| OpEq -> "OpEq",None
+	| OpNotEq -> "OpNotEq",None
+	| OpGt -> "OpGt",None
+	| OpGte -> "OpGte",None
+	| OpLt -> "OpLt",None
+	| OpLte -> "OpLte",None
+	| OpAnd -> "OpAnd",None
+	| OpOr -> "OpOr",None
+	| OpXor -> "OpXor",None
+	| OpBoolAnd -> "OpBoolAnd",None
+	| OpBoolOr -> "OpBoolOr",None
+	| OpShl -> "OpShl",None
+	| OpShr -> "OpShr",None
+	| OpUShr -> "OpUShr",None
+	| OpMod -> "OpMod",None
+	| OpAssignOp op -> "OpAssignOp", (Some (generate_binop ctx op))
+	| OpInterval -> "OpInterval",None
+	| OpArrow -> "OpArrow",None
+	| OpIn -> "OpIn",None
+	in
+	generate_adt ctx (Some (["haxe";"macro"],"Binop")) name args
+
+let generate_unop ctx op =
+	let name = match op with
+		| Increment -> "OpIncrement"
+		| Decrement -> "OpDecrement"
+		| Not -> "OpNot"
+		| Neg -> "OpNeg"
+		| NegBits -> "OpNegBits"
+	in
+	jstring name
+
+let rec generate_expr ctx e =
+	jtodo
+
+(* metadata *)
+
+and generate_metadata_entry ctx (m,el,p) =
+	jobject [
+		"name",jstring (Meta.to_string m);
+		"params",jlist (generate_expr ctx) el;
+		"pos",generate_pos ctx p;
+	]
+
+and generate_metadata ctx ml =
+	let ml = List.filter (fun (m,_,_) ->
+		let (_,(_,flags)) = Meta.get_info m in
+		not (List.mem UsedInternally flags)
+	) ml in
+	jlist (generate_metadata_entry ctx) ml
+
+(* type instance *)
+
+let rec generate_type ctx t =
+	let rec loop t = match t with
+		| TMono r ->
+			begin match !r with
+			| None -> "TMono",None
+			| Some t -> loop t
+			end
+		| TLazy f -> loop (lazy_type f)
+		| TDynamic t -> "TDynamic",Some (if t == t_dynamic then jnull else generate_type ctx t)
+		| TInst(c,tl) -> "TInst",Some (generate_path_with_params ctx c.cl_path tl)
+		| TEnum(en,tl) -> "TEnum",Some (generate_path_with_params ctx en.e_path tl)
+		| TType(td,tl) -> "TType",Some (generate_path_with_params ctx td.t_path tl)
+		| TAbstract(a,tl) -> "TAbstract",Some (generate_path_with_params ctx a.a_path tl)
+		| TAnon an -> "TAnonymous", Some(generate_anon an)
+		| TFun(tl,tr) -> "TFun", Some (generate_function_signature tl tr)
+	and generate_function_argument (name,opt,t) =
+		jobject [
+			"name",jstring name;
+			"opt",jbool opt;
+			"t",generate_type ctx t;
+		]
+	and generate_function_signature tl tr =
+		jobject [
+			"args",jlist generate_function_argument tl;
+			"ret",generate_type ctx tr;
+		]
+	and generate_anon an =
+		let generate_anon_fields () =
+			let fields = PMap.fold (fun cf acc -> generate_class_field ctx cf :: acc) an.a_fields [] in
+			jarray fields
+		in
+		let generate_anon_status () =
+			let name,args = match !(an.a_status) with
+				| Closed -> "AClosed",None
+				| Opened -> "AOpened",None
+				| Const -> "AConst",None
+				| Extend tl -> "AExtend", Some (generate_types ctx tl)
+				| Statics c -> "AClassStatics",Some (class_ref ctx c)
+				| EnumStatics en -> "AEnumStatics",Some (enum_ref ctx en)
+				| AbstractStatics a -> "AAbstractStatics", Some (abstract_ref ctx a)
+			in
+			generate_adt ctx None name args
+		in
+		jobject [
+			"fields",generate_anon_fields();
+			"status",generate_anon_status ();
+		]
+	in
+	let name,args = loop t in
+	generate_adt ctx None name args
+
+and generate_types ctx tl =
+	jlist (generate_type ctx) tl
+
+and generate_path_with_params ctx path tl =
+	jobject [
+		"path",generate_path path;
+		"params",generate_types ctx tl;
+	]
+
+(* type parameter *)
+
+and generate_type_parameter ctx (s,t) =
+	let generate_constraints () = match follow t with
+		| TInst({cl_kind = KTypeParameter tl},_) -> generate_types ctx tl
+		| _ -> assert false
+	in
+	jobject [
+		"name",jstring s;
+		"constraints",generate_constraints ();
+	]
+
+(* texpr *)
+
+and generate_texpr ctx e =
+	jtodo
+
+(* fields *)
+
+and generate_class_field ctx cf =
+	let generate_class_kind () =
+		let generate_var_access va =
+			let name,args = match va with
+				| AccNormal -> "AccNormal",None
+				| AccNo -> "AccNo",None
+				| AccNever -> "AccNever",None
+				| AccCtor -> "AccCtor",None
+				| AccResolve -> "AccResolve",None
+				| AccCall -> "AccCall",None
+				| AccInline -> "AccInline",None
+				| AccRequire(s,so) -> "AccRequire",Some (jobject ["require",jstring s;"message",jopt jstring so])
+			in
+			generate_adt ctx None name args
+		in
+		let generate_method_kind m =
+			let name = match m with
+				| MethNormal -> "MethNormal"
+				| MethInline -> "MethInline"
+				| MethDynamic -> "MethDynamic"
+				| MethMacro -> "MethMacro"
+			in
+			jstring name
+		in
+		let name,args = match cf.cf_kind with
+			| Var vk -> "FVar",Some (jobject ["read",generate_var_access vk.v_read;"write",generate_var_access vk.v_write])
+			| Method m -> "FMethod", Some (generate_method_kind m)
+		in
+		generate_adt ctx None name args
+	in
+	jobject [
+		"name",jstring cf.cf_name;
+		"type",generate_type ctx cf.cf_type;
+		"isPublic",jbool cf.cf_public;
+		"params",jlist (generate_type_parameter ctx) cf.cf_params;
+		"meta",generate_metadata ctx cf.cf_meta;
+		"kind",generate_class_kind ();
+		"expr",jopt (generate_texpr ctx) cf.cf_expr;
+		"pos",generate_pos ctx cf.cf_pos;
+		"doc",jopt jstring cf.cf_doc;
+		"overloads",jlist (classfield_ref ctx) cf.cf_overloads;
+	]
+
+let generate_enum_field ctx ef =
+	jobject [
+		"name",jstring ef.ef_name;
+		"type",generate_type ctx ef.ef_type;
+		"pos",generate_pos ctx ef.ef_pos;
+		"meta",generate_metadata ctx ef.ef_meta;
+		"index",jint ef.ef_index;
+		"doc",jopt jstring ef.ef_doc;
+		"params",jlist (generate_type_parameter ctx) ef.ef_params;
+	]
+
+(* module type *)
+
+let generate_module_type_fields ctx inf =
+	[
+		"pack",jlist jstring (fst inf.mt_path);
+		"name",jstring (snd inf.mt_path);
+		"module",jstring (snd inf.mt_module.m_path);
+		"pos",generate_pos ctx inf.mt_pos;
+		"isPrivate",jbool inf.mt_private;
+		"params",jlist (generate_type_parameter ctx) inf.mt_params;
+		"meta",generate_metadata ctx inf.mt_meta;
+		"doc",jopt jstring inf.mt_doc;
+	]
+
+let generate_class ctx c =
+	let generate_class_kind ck =
+		let ctor,args = match ck with
+		| KNormal -> "KNormal",None
+		| KTypeParameter tl -> "KTypeParameter",Some (generate_types ctx tl)
+		| KExpr e -> "KExpr",Some (generate_expr ctx e)
+		| KGeneric -> "KGeneric",None
+		| KGenericInstance(c,tl) -> "KGenericInstance",Some (generate_path_with_params ctx c.cl_path tl)
+		| KMacroType -> "KMacroType",None
+		| KGenericBuild _ -> "KGenericBuild",None
+		| KAbstractImpl a -> "KAbstractImpl",Some (abstract_ref ctx a)
+		in
+		generate_adt ctx (Some (["haxe";"macro"],"ClassKind")) ctor args
+	in
+	let generate_class_relation (c,tl) =
+		jobject [
+			"t",class_ref ctx c;
+			"params",generate_types ctx tl;
+		]
+	in
+	[
+		"kind",generate_class_kind c.cl_kind;
+		"isInterface",jbool c.cl_interface;
+		"superClass",jopt generate_class_relation c.cl_super;
+		"interfaces",jlist generate_class_relation c.cl_implements;
+		"fields",jlist (generate_class_field ctx) c.cl_ordered_fields;
+		"statics",jlist (generate_class_field ctx) c.cl_ordered_statics;
+		"constructor",jopt (generate_class_field ctx) c.cl_constructor;
+		"init",jopt (generate_texpr ctx) c.cl_init;
+		"overrides",jlist (classfield_ref ctx) c.cl_overrides;
+		"isExtern",jbool c.cl_extern;
+	]
+
+let generate_enum ctx e =
+	let generate_enum_constructors () =
+		jarray (List.map (fun s ->
+			let ef = PMap.find s e.e_constrs in
+			generate_enum_field ctx ef
+		) e.e_names)
+	in
+	[
+		"constructors",generate_enum_constructors ();
+		"isExtern",jbool e.e_extern;
+	]
+
+let generate_typedef ctx td =
+	[
+		"type",generate_type ctx td.t_type;
+	]
+
+let generate_abstract ctx a =
+	let generate_cast_relation t cfo =
+		jobject [
+			"t",generate_type ctx t;
+			"field",jopt (classfield_ref ctx) cfo
+		]
+	in
+	let generate_casts fields casts =
+		let l1 = List.map (fun (t,cf) -> generate_cast_relation t (Some cf)) fields in
+		let l2 = List.map (fun t -> generate_cast_relation t None) casts in
+		jarray (l1 @ l2)
+	in
+	let generate_binop (op,cf) =
+		jobject [
+			"op",generate_binop ctx op;
+			"field",classfield_ref ctx cf;
+		]
+	in
+	let generate_unop (op,flag,cf) =
+		jobject [
+			"op",generate_unop ctx op;
+			"postFix",jbool (flag = Postfix);
+			"field",classfield_ref ctx cf;
+		]
+	in
+	[
+		"type",generate_type ctx a.a_this;
+		"impl",jopt (class_ref ctx) a.a_impl;
+		"binops",jlist generate_binop a.a_ops;
+		"unops",jlist generate_unop a.a_unops;
+		"from",generate_casts a.a_from_field a.a_from;
+		"to",generate_casts a.a_to_field a.a_to;
+		"array",jlist (classfield_ref ctx) a.a_array;
+		"resolve",jopt (classfield_ref ctx) a.a_resolve;
+	]
+
+let generate_module_type ctx mt =
+	let fields1 = generate_module_type_fields ctx (t_infos mt) in
+	let kind,fields2 = match mt with
+		| TClassDecl c -> "class",generate_class ctx c
+		| TEnumDecl e -> "enum",generate_enum ctx e
+		| TTypeDecl t -> "typedef",generate_typedef ctx t
+		| TAbstractDecl a -> "abstract",generate_abstract ctx a
+	in
+	let fields1 = ("kind",jstring kind) :: fields1 @ [("args",jobject fields2)] in
+	jobject fields1
+
+let create_context com = {
+	com = com;
+}
+
+let generate com file =
+	let t = Timer.timer ["generate";"json";"construct"] in
+	let ctx = create_context com in
+	let json = jarray (List.map (generate_module_type ctx) com.types) in
+	t();
+	let t = Timer.timer ["generate";"json";"write"] in
+	let ch = open_out_bin file in
+	Json.write_json (output_string ch) json;
+	close_out ch;
+	t()

+ 318 - 0
std/haxe/rtti/JsonModuleTypes.hx

@@ -0,0 +1,318 @@
+/*
+ * Copyright (C)2005-2018 Haxe Foundation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+package haxe.rtti;
+
+typedef JsonTodo = Dynamic;
+
+typedef JsonPos = {
+	var file:String;
+	var min:Int;
+	var max:Int;
+}
+
+typedef JsonDoc = Null<String>;
+
+/* Type instance */
+
+typedef JsonPath = {
+	var pack: Array<String>;
+	var name: String;
+}
+
+typedef JsonPathWithParams = {
+	var path: JsonPath;
+	var params: JsonTypes;
+}
+
+typedef JsonFunctionArgument = {
+	var name: String;
+	var opt: Bool;
+	var t: JsonType<Dynamic>;
+}
+
+typedef JsonFunctionSignature = {
+	var args: Array<JsonFunctionArgument>;
+	var ret: JsonType<Dynamic>;
+}
+
+enum abstract JsonAnonStatusKind<T>(String) {
+	var AClosed = "AClosed";
+	var AOpened = "AOpened";
+	var AConst = "AConst";
+	var AExtend:JsonAnonStatusKind<JsonTypes> = "AExtend";
+	var AClassStatics:JsonAnonStatusKind<JsonPath> = "AClassStatics";
+	var AEnumStatics:JsonAnonStatusKind<JsonPath> = "AEnumStatics";
+	var AAbstractStatics:JsonAnonStatusKind<JsonPath> = "AAbstractStatics";
+}
+
+typedef JsonAnonStatus<T> = {
+	var kind: JsonAnonStatusKind<T>;
+	var args: T;
+}
+
+typedef JsonAnon = {
+	var fields: JsonClassFields;
+	var status: JsonAnonStatus<Dynamic>;
+}
+
+enum abstract JsonTypeKind<T>(String) {
+	var TMono = "TMono";
+	var TInst:JsonTypeKind<JsonPath> = "TInst";
+	var TEnum:JsonTypeKind<JsonPath> = "TEnum";
+	var TType:JsonTypeKind<JsonPath> = "TType";
+	var TAbstract:JsonTypeKind<JsonPath> = "TAbstract";
+	var TFun:JsonTypeKind<JsonFunctionSignature> = "TFun";
+	var TAnonymous:JsonTypeKind<JsonAnon> = "TAnonymous";
+	var TDynamic:JsonTypeKind<Null<JsonType<Dynamic>>> = "TDynamic";
+}
+
+typedef JsonType<T> = {
+	var kind: JsonTypeKind<T>;
+	var args: T;
+}
+
+typedef JsonTypes = Array<JsonType<Dynamic>>;
+
+/* Type parameters */
+
+typedef JsonTypeParameter = {
+	var name: String;
+	var constraints: JsonTypes;
+}
+
+typedef JsonTypeParameters = Array<JsonTypeParameter>;
+
+/* Expr */
+
+enum abstract JsonBinopKind<T>(String) {
+	var OpAdd = "OpAdd";
+	var OpMult = "OpMult";
+	var OpDiv = "OpDiv";
+	var OpSub = "OpSub";
+	var OpAssign = "OpAssign";
+	var OpEq = "OpEq";
+	var OpNotEq = "OpNotEq";
+	var OpGt = "OpGt";
+	var OpGte = "OpGte";
+	var OpLt = "OpLt";
+	var OpLte = "OpLte";
+	var OpAnd = "OpAnd";
+	var OpOr = "OpOr";
+	var OpXor = "OpXor";
+	var OpBoolAnd = "OpBoolAnd";
+	var OpBoolOr = "OpBoolOr";
+	var OpShl = "OpShl";
+	var OpShr = "OpShr";
+	var OpUShr = "OpUShr";
+	var OpMod = "OpMod";
+	var OpAssignOp:JsonBinopKind<JsonBinop<Dynamic>> = "OpAssignOp";
+	var OpInterval = "OpInterval";
+	var OpArrow = "OpArrow";
+	var OpIn = "OpIn";
+}
+
+typedef JsonBinop<T> = {
+	var kind: JsonBinopKind<T>;
+	var args: T;
+}
+
+enum abstract JsonUnop(String) {
+	var OpIncrement = "OpIncrement";
+	var OpDecrement = "OpDecrement";
+	var OpNot = "OpNot";
+	var OpNeg = "OpNeg";
+	var OpNegBits = "OpNegBits";
+}
+
+typedef JsonExpr = JsonTodo;
+
+typedef JsonMetadataEntry = {
+	var name: String;
+	var args: Array<JsonExpr>;
+	var pos: JsonPos;
+}
+
+typedef JsonMetadata = Array<JsonMetadataEntry>;
+
+typedef JsonTExpr = JsonTodo;
+
+/* Fields */
+
+enum abstract JsonVarAccessKind<T>(String) {
+	var AccNormal = "AccNormal";
+	var AccNo = "AccNo";
+	var AccNever = "AccNever";
+	var AccResolve = "AccResolve";
+	var AccCall = "AccCall";
+	var AccInline = "AccInline";
+	var AccRequire:JsonVarAccessKind<{ require: String, message: Null<String> }> = "AccRequire";
+	var AccCtor = "AccCtor";
+}
+
+typedef JsonVarAccess<T> = {
+	var kind: JsonVarAccessKind<T>;
+	var args: T;
+}
+
+enum abstract JsonMethodKind(String) {
+	var MethNormal = "MethNormal";
+	var MethInline = "MethInline";
+	var MethDynamic = "MethDynamic";
+	var MethMacro = "MethMacro";
+}
+
+enum abstract JsonFieldKindKind<T>(String) {
+	var FVar:JsonFieldKindKind<{ read: JsonVarAccess<Dynamic>, write: JsonVarAccess<Dynamic> }> = "FVar";
+	var FMethod:JsonFieldKindKind<JsonMethodKind> = "FMethod";
+}
+
+typedef JsonFieldKind<T> = {
+	var kind: JsonFieldKindKind<T>;
+	var args: T;
+}
+
+typedef JsonClassField = {
+	var name: String;
+	var type: JsonType<Dynamic>;
+	var isPublic: Bool;
+	var params: JsonTypeParameters;
+	var meta: JsonMetadata;
+	var kind: JsonFieldKind<Dynamic>;
+	var expr: JsonTExpr;
+	var pos: JsonPos;
+	var doc: JsonDoc;
+	var overloads: JsonClassFields;
+}
+
+typedef JsonClassFields = Array<JsonClassField>;
+
+typedef JsonClassFieldReference = String;
+
+typedef JsonEnumField = {
+	var name: String;
+	var type: JsonType<Dynamic>;
+	var pos: JsonPos;
+	var meta: JsonMetadata;
+	var index: Int;
+	var doc: JsonDoc;
+	var params: JsonTypeParameters;
+}
+
+typedef JsonEnumFields = Array<JsonEnumField>;
+
+/* Class */
+
+enum abstract JsonClassKindKind<T>(String) {
+	var KNormal = "KNormal";
+	var KTypeParameter:JsonClassKindKind<JsonTypes> = "KTypeParameter";
+	var KExtension:JsonClassKindKind<JsonPathWithParams> = "KExtension";
+	var KExpr:JsonClassKindKind<JsonExpr> = "KExpr";
+	var KGeneric = "KGeneric";
+	var KGenericInstance:JsonClassKindKind<JsonPathWithParams> = "KGenericInstance";
+	var KMacroType = "KMacroType";
+	var KAbstractImpl:JsonClassKindKind<JsonPath> = "KAbstractImpl";
+	var KGenericBuild = "KGenericBuild";
+}
+
+typedef JsonClassKind<T> = {
+	var kind:JsonClassKindKind<T>;
+	var args: T;
+}
+
+typedef JsonClass = {
+	var kind: JsonClassKind<Dynamic>;
+	var isInterface: Bool;
+	var isExtern: Bool;
+	var superClass: Null<JsonPathWithParams>;
+	var interfaces: Array<JsonPathWithParams>;
+	var fields: JsonClassFields;
+	var statics: JsonClassFields;
+	var constructor: Null<JsonClassField>;
+	var init: Null<JsonTExpr>;
+	var overrides: Array<JsonClassFieldReference>;
+}
+
+/* Enum */
+
+typedef JsonEnum = {
+	var constructors: JsonEnumFields;
+	var isExtern: Bool;
+}
+
+/* Typedef */
+
+typedef JsonTypedef = {
+	var type: JsonType<Dynamic>;
+}
+
+/* Abstract */
+
+typedef JsonAbstractBinop = {
+	var op: JsonBinop<Dynamic>;
+	var field: JsonClassFieldReference;
+}
+
+typedef JsonAbstractUnop = {
+	var op: JsonUnop;
+	var postFix: Bool;
+	var field: JsonClassFieldReference;
+}
+
+typedef JsonAbstractCast = {
+	var t:JsonType<Dynamic>;
+	var field: JsonClassFieldReference;
+}
+
+typedef JsonAbstract = {
+	var type: JsonType<Dynamic>;
+	var impl: Null<JsonPath>;
+	var binops: Array<JsonAbstractBinop>;
+	var unops: Array<JsonAbstractUnop>;
+	var from: Array<JsonAbstractCast>;
+	var to: Array<JsonAbstractCast>;
+	var array: JsonClassFields;
+	var resolve: Null<JsonClassFieldReference>;
+}
+
+/* Module type */
+
+enum abstract JsonModuleTypeKind<T>(String) {
+	var Class:JsonModuleTypeKind<JsonClass> = "class";
+	var Enum:JsonModuleTypeKind<JsonEnum> = "enum";
+	var Typedef:JsonModuleTypeKind<JsonTypedef> = "typedef";
+	var Abstract:JsonModuleTypeKind<JsonAbstract> = "abstract";
+}
+
+typedef JsonModuleType<T> = {
+	var pack: Array<String>;
+	var name: String;
+	var module: String;
+	var pos: JsonPos;
+	var isPrivate: Bool;
+	var params: JsonTypeParameters;
+	var meta: JsonMetadata;
+	var doc: JsonDoc;
+	var kind: JsonModuleTypeKind<T>;
+	var args: T;
+}
+
+typedef JsonModuleTypes = Array<JsonModuleType<Dynamic>>;