Skip to content

Commit

Permalink
Merge branch 'add_global_metadata' into development
Browse files Browse the repository at this point in the history
Conflicts:
	.gitignore
  • Loading branch information
Simn committed Oct 9, 2014
2 parents 9bcbaf5 + 2150acc commit 6631a6b
Show file tree
Hide file tree
Showing 30 changed files with 146 additions and 74 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,6 @@ tests/unit/unit.py.res1.txt
tests/unit/unit.py.res2.bin
*.cmo
tests/sys/bin/
<<<<<<< HEAD
tests/optimization/dump/
tests/misc/projects/Issue3102/test.n
9 changes: 9 additions & 0 deletions interp.ml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ type extern_api = {
use_cache : unit -> bool;
format_string : string -> Ast.pos -> Ast.expr;
cast_or_unify : Type.t -> texpr -> Ast.pos -> Type.texpr;
add_global_metadata : string -> string -> (bool * bool * bool) -> unit;
}

type callstack = {
Expand Down Expand Up @@ -2401,6 +2402,14 @@ let macro_lib =
| _ -> error());
VNull
);
"add_global_metadata", Fun5 (fun v1 v2 v3 v4 v5 ->
match v1,v2,v3,v4,v5 with
| VString s1,VString s2,VBool b1,VBool b2,VBool b3 ->
(get_ctx()).curapi.add_global_metadata s1 s2 (b1,b2,b3);
VNull
| _ ->
error()
);
"custom_js", Fun1 (fun f ->
match f with
| VFunction (Fun1 _) ->
Expand Down
77 changes: 4 additions & 73 deletions std/haxe/macro/Compiler.hx
Original file line number Diff line number Diff line change
Expand Up @@ -270,87 +270,18 @@ class Compiler {
@param paths An Array of package, module or sub-type dot paths to keep.
@param recursive If true, recurses into sub-packages for package paths.
**/
public static function keep(?path : String, ?paths : Array<String>, ?recursive:Bool = true)
{
public static function keep(?path : String, ?paths : Array<String>, ?recursive:Bool = true) {
if (null == paths)
paths = [];
if (null != path)
paths.push(path);
for (path in paths) {
var found:Bool = false;
var moduleFirstCharacter:String = ((path.indexOf(".") < 0)?path:path.substring(path.lastIndexOf(".")+1)).charAt(0);
var startsWithUpperCase:Bool = (moduleFirstCharacter == moduleFirstCharacter.toUpperCase());//needed because FileSystem is not case sensitive
var moduleRoot = (path.indexOf(".") < 0)?"":path.substring(0, path.lastIndexOf("."));
var moduleRootFirstCharacter:String = ((moduleRoot.indexOf(".") < 0)?moduleRoot:moduleRoot.substring(moduleRoot.lastIndexOf(".")+1)).charAt(0);
var rootStartsWithUpperCase:Bool = (moduleRootFirstCharacter == moduleRootFirstCharacter.toUpperCase());//needed because FileSystem is not case sensitive
for ( classPath in Context.getClassPath() ) {
var moduleRootPath = (moduleRoot == "")?"":(classPath + moduleRoot.split(".").join("/") + ".hx");
var fullPath = classPath + path.split(".").join("/");
var isValidModule:Bool = startsWithUpperCase && sys.FileSystem.exists(fullPath + ".hx");
var isValidSubType:Bool = !isValidModule && moduleRootPath != "" && rootStartsWithUpperCase && sys.FileSystem.exists(moduleRootPath);
var isValidDirectory:Bool = !isValidSubType && sys.FileSystem.exists(fullPath) && sys.FileSystem.isDirectory(fullPath);
if ( !isValidDirectory && !isValidModule && !isValidSubType)
continue;
else
found = true;

if(isValidDirectory) {
for( file in sys.FileSystem.readDirectory(fullPath) ) {
if( StringTools.endsWith(file, ".hx") ) {
var module = path + "." + file.substr(0, file.length - 3);
keepModule(module);
} else if( recursive && sys.FileSystem.isDirectory(fullPath + "/" + file) )
keep(path + "." + file, true);
}
} else if(isValidModule){
keepModule(path);
} else if(isValidSubType){
keepSubType(path);
}
}

if (!found)
Context.warning("file or directory not found, can't keep: "+path, Context.currentPos());
}
}

private static function keepSubType( path : String )
{
var module = path.substring(0, path.lastIndexOf("."));
var typeName = path.substring(path.lastIndexOf(".") + 1);
var subType:Type.BaseType = null;
for (type in Context.getModule(module)) {
switch(type) {
case TInst(_.get() => cls, _) if (cls.name == typeName):
subType = cls;
break;
case TEnum(_.get() => en, _) if (en.name == typeName):
subType = en;
break;
default:
//
}
addGlobalMetadata(path, "@:keep", recursive, true, true);
}

if (subType == null)
Context.warning('Cannot keep $path: type not found or is not a class or enum', Context.currentPos());
else
subType.meta.add(":keep", [], subType.pos);
}

private static function keepModule( path : String )
{
var types = Context.getModule(path);
for (type in types) {
switch(type) {
case TInst(_.get() => cls, _) if (!cls.kind.match(KAbstractImpl(_))):
cls.meta.add(":keep", [], cls.pos);
case TEnum(_.get() => en, _):
en.meta.add(":keep", [], en.pos);
default:
//
}
}
public static function addGlobalMetadata(pathFilter:String, meta:String, ?recursive:Bool = true, ?toTypes:Bool = true, ?toFields:Bool = false) {
untyped load("add_global_metadata",5)(untyped pathFilter.__s, meta.__s, recursive, toTypes, toFields);
}

/**
Expand Down
11 changes: 11 additions & 0 deletions tests/misc/projects/Issue3102/Main.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Main {
static function main() {
var test:Dynamic = new Test();
test.get12();
}
}

class Test {
public function new() { }
public function get12() return 12;
}
8 changes: 8 additions & 0 deletions tests/misc/projects/Issue3102/Main2.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import pack1.pack2.Test;

class Main2 {
static function main() {
var test = Type.createInstance(Type.resolveClass("pack1.pack2.Test"), []);
test.get12();
}
}
3 changes: 3 additions & 0 deletions tests/misc/projects/Issue3102/compile-each.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-dce full
-main Main
-x test
3 changes: 3 additions & 0 deletions tests/misc/projects/Issue3102/compile2-each.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-dce full
-main Main2
-x test
2 changes: 2 additions & 0 deletions tests/misc/projects/Issue3102/keep-field-not-rec.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
compile-each.hxml
--macro keep('Main.Test.get12', false)
2 changes: 2 additions & 0 deletions tests/misc/projects/Issue3102/keep-field.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
compile-each.hxml
--macro keep('Main.Test.get12')
3 changes: 3 additions & 0 deletions tests/misc/projects/Issue3102/keep-field2.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
compile2-each.hxml
--macro keep('pack1.pack2.Test.get12')
--macro keep('pack1.pack2.Test.new')
2 changes: 2 additions & 0 deletions tests/misc/projects/Issue3102/keep-module-not-rec-fail.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
compile-each.hxml
--macro keep('Main', false)
2 changes: 2 additions & 0 deletions tests/misc/projects/Issue3102/keep-module.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
compile-each.hxml
--macro keep('Main')
2 changes: 2 additions & 0 deletions tests/misc/projects/Issue3102/keep-module2.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
compile2-each.hxml
--macro keep('pack1.pack2.Test')
2 changes: 2 additions & 0 deletions tests/misc/projects/Issue3102/keep-pack1-not-rec-fail.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
compile2-each.hxml
--macro keep('pack1', false)
2 changes: 2 additions & 0 deletions tests/misc/projects/Issue3102/keep-pack1.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
compile2-each.hxml
--macro keep('pack1')
2 changes: 2 additions & 0 deletions tests/misc/projects/Issue3102/keep-pack2-not-rec.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
compile2-each.hxml
--macro keep('pack1.pack2', false)
2 changes: 2 additions & 0 deletions tests/misc/projects/Issue3102/keep-pack2.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
compile2-each.hxml
--macro keep('pack1.pack2')
2 changes: 2 additions & 0 deletions tests/misc/projects/Issue3102/keep-pack3-fail.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
compile2-each.hxml
--macro keep('pack1.pack3')
2 changes: 2 additions & 0 deletions tests/misc/projects/Issue3102/keep-pack4-fail.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
compile2-each.hxml
--macro keep('pack1.pack2.pack3')
2 changes: 2 additions & 0 deletions tests/misc/projects/Issue3102/keep-type-not-rec.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
compile-each.hxml
--macro keep('Main.Test', false)
2 changes: 2 additions & 0 deletions tests/misc/projects/Issue3102/keep-type.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
compile-each.hxml
--macro keep('Main.Test')
8 changes: 8 additions & 0 deletions tests/misc/projects/Issue3102/pack1/pack2/Test.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package pack1.pack2;

class Test {
public function new() { }
public function get12() {
return 12;
}
}
13 changes: 13 additions & 0 deletions tests/misc/projects/Issue3129/Build.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import haxe.macro.Expr;
import haxe.macro.Context;

class Build {
macro static public function build():Array<Field> {
var field = (macro class X {
public function test() { }
}).fields[0];
var fields = Context.getBuildFields();
fields.push(field);
return fields;
}
}
10 changes: 10 additions & 0 deletions tests/misc/projects/Issue3129/Main.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class Main {

static function main() {
var m = new Main();
m.test();
}

public function new() { }

}
3 changes: 3 additions & 0 deletions tests/misc/projects/Issue3129/compile.hxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
--macro addGlobalMetadata('Main', '@:build(Build.build())')
-main Main
-x test
Binary file added tests/misc/projects/Issue3129/test.n
Binary file not shown.
3 changes: 2 additions & 1 deletion tests/misc/src/Main.hx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class Main {
var path = Path.join([dirPath, file]);
if (FileSystem.isDirectory(path)) {
browse(path);
} else if (file.endsWith(".hxml")) {
} else if (file.endsWith(".hxml") && !file.endsWith("-each.hxml")) {
var old = Sys.getCwd();
Sys.setCwd(dirPath);
Sys.println('Running haxe $path');
Expand Down Expand Up @@ -73,6 +73,7 @@ class Main {

static function runCommand(command:String, args:Array<String>, expectFailure:Bool, expectStderr:String) {
var proc = new sys.io.Process(command, args);
proc.stdout.readAll();
var exit = proc.exitCode();
var success = exit == 0;
var result = switch [success, expectFailure] {
Expand Down
1 change: 1 addition & 0 deletions typecore.ml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ type typer_globals = {
mutable std : module_def;
mutable hook_generate : (unit -> unit) list;
type_patches : (path, (string * bool, type_patch) Hashtbl.t * type_patch) Hashtbl.t;
mutable global_metadata : (string list * Ast.metadata_entry * (bool * bool * bool)) list;
mutable get_build_infos : unit -> (module_type * t list * Ast.class_field list) option;
delayed_macros : (unit -> unit) DynArray.t;
mutable global_using : tclass list;
Expand Down
30 changes: 30 additions & 0 deletions typeload.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1479,6 +1479,31 @@ let init_core_api ctx c =
| None, Some { cf_public = false } -> ()
| _ -> error "Constructor differs from core type" c.cl_pos)

let check_global_metadata ctx f_add mpath tpath so =
let sl1 = if mpath = tpath then
(fst tpath) @ [snd tpath]
else
(fst mpath) @ [snd mpath;snd tpath]
in
let sl1,field_mode = match so with None -> sl1,false | Some s -> sl1 @ [s],true in
List.iter (fun (sl2,m,(recursive,to_types,to_fields)) ->
let rec loop sl1 sl2 = match sl1,sl2 with
| [],[] ->
true
(* always recurse into types of package paths *)
| (s1 :: s11 :: _),[s2] when is_lower_ident s2 && not (is_lower_ident s11)->
s1 = s2
| _,[] ->
recursive
| [],_ ->
false
| (s1 :: sl1),(s2 :: sl2) ->
s1 = s2 && loop sl1 sl2
in
let add = ((field_mode && to_fields) || (not field_mode && to_types)) && (sl2 = [""] || loop sl1 sl2) in
if add then f_add m
) ctx.g.global_metadata

let patch_class ctx c fields =
let h = (try Some (Hashtbl.find ctx.g.type_patches c.cl_path) with Not_found -> None) in
match h with
Expand Down Expand Up @@ -1808,6 +1833,7 @@ let init_class ctx c p context_init herits fields =

let loop_cf f =
let name = f.cff_name in
check_global_metadata ctx (fun m -> f.cff_meta <- m :: f.cff_meta) c.cl_module.m_path c.cl_path (Some name);
let p = f.cff_pos in
if name.[0] = '$' && ctx.com.display = DMNone then error "Field names starting with a dollar are not allowed" p;
let stat = List.mem AStatic f.cff_access in
Expand Down Expand Up @@ -2468,6 +2494,7 @@ let rec init_module_type ctx context_init do_init (decl,p) =
context_init := (fun() -> ctx.m.module_using <- filter_classes types @ ctx.m.module_using) :: !context_init
| EClass d ->
let c = (match get_type d.d_name with TClassDecl c -> c | _ -> assert false) in
check_global_metadata ctx (fun m -> c.cl_meta <- m :: c.cl_meta) c.cl_module.m_path c.cl_path None;
let herits = d.d_flags in
if Meta.has Meta.Generic c.cl_meta && c.cl_params <> [] then c.cl_kind <- KGeneric;
if Meta.has Meta.GenericBuild c.cl_meta then c.cl_kind <- KGenericBuild d.d_data;
Expand All @@ -2489,6 +2516,7 @@ let rec init_module_type ctx context_init do_init (decl,p) =
let e = (match get_type d.d_name with TEnumDecl e -> e | _ -> assert false) in
let ctx = { ctx with type_params = e.e_params } in
let h = (try Some (Hashtbl.find ctx.g.type_patches e.e_path) with Not_found -> None) in
check_global_metadata ctx (fun m -> e.e_meta <- m :: e.e_meta) e.e_module.m_path e.e_path None;
(match h with
| None -> ()
| Some (h,hcl) ->
Expand Down Expand Up @@ -2608,6 +2636,7 @@ let rec init_module_type ctx context_init do_init (decl,p) =
if !is_flat then e.e_meta <- (Meta.FlatEnum,[],e.e_pos) :: e.e_meta;
| ETypedef d ->
let t = (match get_type d.d_name with TTypeDecl t -> t | _ -> assert false) in
check_global_metadata ctx (fun m -> t.t_meta <- m :: t.t_meta) t.t_module.m_path t.t_path None;
let ctx = { ctx with type_params = t.t_params } in
let tt = load_complex_type ctx p d.d_data in
(*
Expand All @@ -2625,6 +2654,7 @@ let rec init_module_type ctx context_init do_init (decl,p) =
| _ -> assert false);
| EAbstract d ->
let a = (match get_type d.d_name with TAbstractDecl a -> a | _ -> assert false) in
check_global_metadata ctx (fun m -> a.a_meta <- m :: a.a_meta) a.a_module.m_path a.a_path None;
let ctx = { ctx with type_params = a.a_params } in
let is_type = ref false in
let load_type t from =
Expand Down
10 changes: 10 additions & 0 deletions typer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -4413,6 +4413,15 @@ let make_macro_api ctx p =
Interp.cast_or_unify = (fun t e p ->
Codegen.AbstractCast.cast_or_unify_raise ctx t e p
);
Interp.add_global_metadata = (fun s1 s2 config ->
let meta = (match parse_string ctx.com (s2 ^ " typedef T = T") null_pos false with
| _,[ETypedef t,_] -> t.d_meta
| _ -> assert false
) in
List.iter (fun m ->
ctx.g.global_metadata <- (ExtString.String.nsplit s1 ".",m,config) :: ctx.g.global_metadata;
) meta;
);
}

let rec init_macro_interp ctx mctx mint =
Expand Down Expand Up @@ -4744,6 +4753,7 @@ let rec create com =
modules = Hashtbl.create 0;
types_module = Hashtbl.create 0;
type_patches = Hashtbl.create 0;
global_metadata = [];
delayed = [];
debug_delayed = [];
delayed_macros = DynArray.create();
Expand Down

0 comments on commit 6631a6b

Please sign in to comment.