<commit_before>/*
 * Copyright (c) 2015, <NAME>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
package cdb;
import haxe.macro.Context;
using haxe.macro.Tools;

class Module {

	#if macro
	static function makeFakeEnum( tname : String, curMod, pos, values : Array<String> ) : haxe.macro.Expr.TypeDefinition {
		var fields : Array<haxe.macro.Expr.Field> = [for( i in 0...values.length ) { name : values[i], pos : pos, kind : FVar(null, macro $v { i } ) } ];
		var tint = macro : Int;
		fields.push( {
			name : "COUNT",
			pos : pos,
			kind : FVar(null, macro $v { values.length } ),
			access : [APublic, AStatic, AInline],
		});
		fields.push( {
			name : "NAMES",
			pos : pos,
			kind : FVar(null, macro $v { values } ),
			access : [APublic, AStatic],
		});
		fields.push( {
			name : "ofInt",
			pos : pos,
			kind : FFun({
				args : [ { name : "v", type : tint } ],
				ret : tname.toComplex(),
				expr : macro return cast v,
			}),
			access : [APublic, AStatic, AInline],
		});
		fields.push( {
			name : "toInt",
			pos : pos,
			kind : FFun( {
				args : [],
				ret : tint,
				expr : macro return this,
			}),
			access : [APublic, AInline],
		});
		return {
			pos : pos,
			name : tname,
			pack : curMod,
			kind : TDAbstract(tint),
			meta : [{ name : ":enum", pos : pos },{ name : ":fakeEnum", pos : pos }],
			fields : fields,
		};
	}
	#end

	static function getSheetLines( sheets : Array<Data.SheetData>, s : Data.SheetData ) {
		if( s.props.dataFiles != null )
			return [];
		if( !s.props.hide )
			return s.lines;
		var name = s.name.split("@");
		var col = name.pop();
		var parent = name.join("@");
		var psheet = null;
		for( sp in sheets )
			if( sp.name == parent ) {
				psheet = sp;
				break;
			}
		if( psheet == null )
			return s.lines;
		var out = [];
		for( o in getSheetLines(sheets,psheet) ) {
			var objs : Array<Dynamic> = Reflect.field(o, col);
			if( objs != null )
				for( o in objs )
					out.push(o);
		}
		return out;
	}

	public static function build( file : String, ?typeName : String ) {
		#if !macro
		throw "This can only be called in a macro";
		#else
		var pos = Context.currentPos();
		var path = try Context.resolvePath(file) catch( e : Dynamic ) null;
		if( path == null ) {
			var r = Context.definedValue("resourcesPath");
			if( r != null ) {
				r = r.split("\\").join("/");
				if( !StringTools.endsWith(r, "/") ) r += "/";
				try path = Context.resolvePath(r + file) catch( e : Dynamic ) null;
			}
		}
		if( path == null )
			try path = Context.resolvePath("res/" + file) catch( e : Dynamic ) null;
		if( path == null )
			Context.error("File not found " + file, pos);
		var data = Parser.parse(sys.io.File.getContent(path), false);
		var r_chars = ~/[^A-Za-z0-9_]/g;
		function makeTypeName( name : String ) {
			var t = r_chars.replace(name, "_");
			t = t.substr(0, 1).toUpperCase() + t.substr(1);
			return t;
		}
		function fieldName( name : String ) {
			return r_chars.replace(name, "_");
		}
		var types = new Array<haxe.macro.Expr.TypeDefinition>();
		var curMod = Context.getLocalModule().split(".");
		var modName = curMod.pop();
		if( typeName != null ) modName = typeName;

		var typesCache = new Map<String,String>();
		var hsheets = new Map();
		for( s in data.sheets )
			hsheets.set(s.name, s);

		for( s in data.sheets ) {
			var tname = makeTypeName(s.name);
			var tkind = tname + "Kind";
			var idField = null;
			var fields : Array<haxe.macro.Expr.Field> = [];
			var realFields : Array<haxe.macro.Expr.Field> = [];
			var ids : Array<haxe.macro.Expr.Field> = [];
			for( c in s.columns ) {
				var t = switch( c.type ) {
				case TInt, TColor: macro : Int;
				case TFloat: macro : Float;
				case TBool: macro : Bool;
				case TString, TFile: macro : String;
				case TList:
					var t = makeTypeName(s.name + "@" + c.name).toComplex();
					macro : cdb.Types.ArrayRead<$t>;
				case TRef(t): makeTypeName(t).toComplex();
				case TImage: macro : String;
				case TId:
					tkind.toComplex();
				case TEnum(values):
					var t = makeTypeName(s.name + "@" + c.name);
					types.push(makeFakeEnum(t,curMod,pos,values));
					t.toComplex();
				case TCustom(name):
					name.toComplex();
				case TFlags(values):
					var t = makeTypeName(s.name + "@" + c.name);
					types.push(makeFakeEnum(t, curMod, pos, values));
					var t = t.toComplex();
					macro : cdb.Types.Flags<$t>;
				case TLayer(t):
					var t = makeTypeName(t).toComplex();
					macro : cdb.Types.Layer<$t>;
				case TTilePos:<commit_msg>allow shared definition for flags/enum with same field name<commit_after>/*
 * Copyright (c) 2015, <NAME>
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */
package cdb;
import haxe.macro.Context;
using haxe.macro.Tools;

class Module {

	#if macro
	static function makeFakeEnum( tname : String, curMod, pos, values : Array<String> ) : haxe.macro.Expr.TypeDefinition {
		var fields : Array<haxe.macro.Expr.Field> = [for( i in 0...values.length ) { name : values[i], pos : pos, kind : FVar(null, macro $v { i } ) } ];
		var tint = macro : Int;
		fields.push( {
			name : "COUNT",
			pos : pos,
			kind : FVar(null, macro $v { values.length } ),
			access : [APublic, AStatic, AInline],
		});
		fields.push( {
			name : "NAMES",
			pos : pos,
			kind : FVar(null, macro $v { values } ),
			access : [APublic, AStatic],
		});
		fields.push( {
			name : "ofInt",
			pos : pos,
			kind : FFun({
				args : [ { name : "v", type : tint } ],
				ret : tname.toComplex(),
				expr : macro return cast v,
			}),
			access : [APublic, AStatic, AInline],
		});
		fields.push( {
			name : "toInt",
			pos : pos,
			kind : FFun( {
				args : [],
				ret : tint,
				expr : macro return this,
			}),
			access : [APublic, AInline],
		});
		return {
			pos : pos,
			name : tname,
			pack : curMod,
			kind : TDAbstract(tint),
			meta : [{ name : ":enum", pos : pos },{ name : ":fakeEnum", pos : pos }],
			fields : fields,
		};
	}
	#end

	static function getSheetLines( sheets : Array<Data.SheetData>, s : Data.SheetData ) {
		if( s.props.dataFiles != null )
			return [];
		if( !s.props.hide )
			return s.lines;
		var name = s.name.split("@");
		var col = name.pop();
		var parent = name.join("@");
		var psheet = null;
		for( sp in sheets )
			if( sp.name == parent ) {
				psheet = sp;
				break;
			}
		if( psheet == null )
			return s.lines;
		var out = [];
		for( o in getSheetLines(sheets,psheet) ) {
			var objs : Array<Dynamic> = Reflect.field(o, col);
			if( objs != null )
				for( o in objs )
					out.push(o);
		}
		return out;
	}

	public static function build( file : String, ?typeName : String ) {
		#if !macro
		throw "This can only be called in a macro";
		#else
		var pos = Context.currentPos();
		var path = try Context.resolvePath(file) catch( e : Dynamic ) null;
		if( path == null ) {
			var r = Context.definedValue("resourcesPath");
			if( r != null ) {
				r = r.split("\\").join("/");
				if( !StringTools.endsWith(r, "/") ) r += "/";
				try path = Context.resolvePath(r + file) catch( e : Dynamic ) null;
			}
		}
		if( path == null )
			try path = Context.resolvePath("res/" + file) catch( e : Dynamic ) null;
		if( path == null )
			Context.error("File not found " + file, pos);
		var data = Parser.parse(sys.io.File.getContent(path), false);
		var r_chars = ~/[^A-Za-z0-9_]/g;
		function makeTypeName( name : String ) {
			var t = r_chars.replace(name, "_");
			t = t.substr(0, 1).toUpperCase() + t.substr(1);
			return t;
		}
		function fieldName( name : String ) {
			return r_chars.replace(name, "_");
		}
		var types = new Array<haxe.macro.Expr.TypeDefinition>();
		var curMod = Context.getLocalModule().split(".");
		var modName = curMod.pop();
		if( typeName != null ) modName = typeName;

		var typesCache = new Map<String,String>();
		var hsheets = new Map();
		for( s in data.sheets )
			hsheets.set(s.name, s);

		var defineEnums = new Map<String,String>();

		function makeEnum( c : Data.Column, tname : String, values : Array<String> ) {
			var key = c.name+":"+values.join("|");
			var prev = defineEnums.get(key);
			if( prev != null ) {
				types.push({
					name : tname,
					pack : curMod,
					kind : TDAlias(prev.toComplex()),
					pos : pos,
					fields : [],
				});
				return;
			}
			types.push(makeFakeEnum(tname,curMod,pos,values));
			defineEnums.set(key, tname);
		}

		for( s in data.sheets ) {
			var tname = makeTypeName(s.name);
			var tkind = tname + "Kind";
			var idField = null;
			var fields : Array<haxe.macro.Expr.Field> = [];
			var realFields : Array<haxe.macro.Expr.Field> = [];
			var ids : Array<haxe.macro.Expr.Field> = [];
			for( c in s.columns ) {
				var t = switch( c.type ) {
				case TInt, TColor: macro : Int;
				case TFloat: macro : Float;
				case TBool: macro : Bool;
				case TString, TFile: macro : String;
				case TList:
					var t = makeTypeName(s.name + "@" + c.name).toComplex();
					macro : cdb.Types.ArrayRead<$t>;
				case TRef(t): makeTypeName(t).toComplex();
				case TImage: macro : String;
				case TId:
					tkind.toComplex();
				case TEnum(values):
					var t = makeTypeName(s.name + "@" + c.name);
					makeEnum(c,t,values);
					t.toComplex();
				case TCustom(name):
					name.toComplex();
				case TFlags(values):
					var t = makeTypeName(s.name + "@" + c.name);
					makeEnum(c,t,values);
					var t = t.toComplex();
					macro : cdb.Types.Flags<$t>;
				case TLayer(t):
					var t = makeTypeName(t).toComplex();
					macro : cdb.Types.Layer<$t>;
				case TTilePos:
{'fraction_non_alphanumeric': 0.1513109305760709, 'fraction_numerical': 0.001846381093057607, 'mean_word_length': 2.917902350813743, 'pattern_counts': {'":': 5, '<': 31, '<?xml version=': 0, '>': 31, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5470820', 'n_tokens_mistral': 4438, 'n_tokens_neox': 3737, 'n_words': 1111}