Browse Source

use native component as context and to infer parameters types

Nicolas Cannasse 7 months ago
parent
commit
d985796b3d
2 changed files with 46 additions and 22 deletions
  1. 32 19
      hide/comp/DomkitEditor.hx
  2. 14 3
      hrt/impl/DomkitViewer.hx

+ 32 - 19
hide/comp/DomkitEditor.hx

@@ -53,6 +53,7 @@ class DomkitChecker extends ScriptEditor.ScriptChecker {
 	var t_string : Type;
 	var t_string : Type;
 	var parsers : Array<domkit.CssValue.ValueParser>;
 	var parsers : Array<domkit.CssValue.ValueParser>;
 	var lastVariables : Map<String, domkit.CssValue> = new Map();
 	var lastVariables : Map<String, domkit.CssValue> = new Map();
+	var currentComponent : hscript.Checker.CClass;
 	public var usedEnums : Array<{ path : String, constrs : Array<String> }> = [];
 	public var usedEnums : Array<{ path : String, constrs : Array<String> }> = [];
 	public var params : Map<String, Type> = new Map();
 	public var params : Map<String, Type> = new Map();
 	public var components : Map<String, TypedComponent>;
 	public var components : Map<String, TypedComponent>;
@@ -111,15 +112,31 @@ class DomkitChecker extends ScriptEditor.ScriptChecker {
 		case Node(null) if( expr.children.length == 1 ): expr = expr.children[0];
 		case Node(null) if( expr.children.length == 1 ): expr = expr.children[0];
 		default:
 		default:
 		}
 		}
-		switch( expr.kind ) {
-		case Node(name) if( name != null ):
-			var comp = resolveComp(name.split(":")[0]);
-			if( comp != null && comp.classDef != null )
-				checker.setGlobal("this",TInst(comp.classDef,[]));
-		default:
-		}
 		try {
 		try {
-			checkDMLRec(expr, true);
+			for( c in expr.children ) {
+				var prev = @:privateAccess checker.locals.copy();
+				var prevGlobals = @:privateAccess checker.globals.copy();
+
+				currentComponent = null;
+				switch( c.kind ) {
+				case Node(name):
+					var comp = resolveComp(name.split(":")[0]);
+					if( comp != null && comp.classDef != null ) {
+						currentComponent = comp.classDef;
+						checker.setGlobals(comp.classDef, true);
+						checker.setGlobal("this",TInst(comp.classDef,[]));
+					}
+					defineComponent(name, c, params);
+				default:
+					continue;
+				}
+				for( c in c.children )
+					checkDMLRec(c);
+				@:privateAccess {
+					checker.locals = prev;
+					checker.globals = prevGlobals;
+				}
+			}
 		} catch( e : hscript.Expr.Error ) {
 		} catch( e : hscript.Expr.Error ) {
 			throw new domkit.Error(e.toString(), e.pmin, e.pmax);
 			throw new domkit.Error(e.toString(), e.pmin, e.pmax);
 		}
 		}
@@ -544,7 +561,7 @@ class DomkitChecker extends ScriptEditor.ScriptChecker {
 			c.arguments = parent == null ? [] : parent.arguments;
 			c.arguments = parent == null ? [] : parent.arguments;
 		else {
 		else {
 			c.arguments = [];
 			c.arguments = [];
-			for( a in e.arguments ) {
+			for( i => a in e.arguments ) {
 				var type = null;
 				var type = null;
 				var name = switch( a.value ) {
 				var name = switch( a.value ) {
 				case Code(c) if( IDENT.match(c) ):
 				case Code(c) if( IDENT.match(c) ):
@@ -566,6 +583,11 @@ class DomkitChecker extends ScriptEditor.ScriptChecker {
 					domkitError("Invalid parameter", a.pmin, a.pmax);
 					domkitError("Invalid parameter", a.pmin, a.pmax);
 					continue;
 					continue;
 				}
 				}
+				if( type == null && currentComponent != null ) {
+					var args = switch( currentComponent.constructor?.t ) { case null: null; case TFun(args,_): args; default: null; };
+					if( args != null && args[i].name == name )
+						type = args[i].t;
+				}
 				if( type == null )
 				if( type == null )
 					type = params.get(name);
 					type = params.get(name);
 				if( type == null )
 				if( type == null )
@@ -584,17 +606,8 @@ class DomkitChecker extends ScriptEditor.ScriptChecker {
 		return c;
 		return c;
 	}
 	}
 
 
-	function checkDMLRec( e : domkit.MarkupParser.Markup, isRoot=false ) {
+	function checkDMLRec( e : domkit.MarkupParser.Markup ) {
 		switch( e.kind ) {
 		switch( e.kind ) {
-		case Node(null):
-			for( c in e.children )
-				checkDMLRec(c,isRoot);
-		case Node(name) if( isRoot ):
-			var prev = @:privateAccess checker.locals.copy();
-			defineComponent(name, e, params);
-			for( c in e.children )
-				checkDMLRec(c);
-			@:privateAccess checker.locals = prev;
 		case Node(name):
 		case Node(name):
 			var c = resolveComp(name);
 			var c = resolveComp(name);
 			if( c == null )
 			if( c == null )

+ 14 - 3
hrt/impl/DomkitViewer.hx

@@ -394,10 +394,19 @@ class DomkitViewer extends h2d.Object {
 					var parentType = parts[1] ?? "flow";
 					var parentType = parts[1] ?? "flow";
 					var compParent = resolveComponent(parentType, m.pmin);
 					var compParent = resolveComponent(parentType, m.pmin);
 					var comp = domkit.Component.get(name, true);
 					var comp = domkit.Component.get(name, true);
+					var inst : Dynamic = null;
 					if( comp == null ) {
 					if( comp == null ) {
 						comp = new domkit.Component(name,null,compParent);
 						comp = new domkit.Component(name,null,compParent);
 						domkit.CssStyle.CssData.registerComponent(comp);
 						domkit.CssStyle.CssData.registerComponent(comp);
 						loadedComponents.push(cast comp);
 						loadedComponents.push(cast comp);
+					} else {
+						var compClass = @:privateAccess comp.classValue;
+						if( compClass != null ) {
+							inst = Type.createEmptyInstance(compClass);
+							interp.setContext(inst);
+							for( f in Reflect.fields(vparams) )
+								try Reflect.setProperty(inst, f, Reflect.field(vparams,f)) catch( e : Dynamic ) {}
+						}
 					}
 					}
 					var args = [];
 					var args = [];
 					if( m.arguments != null ) {
 					if( m.arguments != null ) {
@@ -416,7 +425,7 @@ class DomkitViewer extends h2d.Object {
 							error("Invalid argument decl", arg.pmin, arg.pmax);
 							error("Invalid argument decl", arg.pmin, arg.pmax);
 						}
 						}
 					}
 					}
-					var make = makeComponent.bind(res, m, comp, args, interp);
+					var make = makeComponent.bind(res, m, comp, args, interp, inst);
 					tmpCompMap.set(name, make);
 					tmpCompMap.set(name, make);
 					inf.comps.push(make);
 					inf.comps.push(make);
 				default:
 				default:
@@ -462,7 +471,7 @@ class DomkitViewer extends h2d.Object {
 		}
 		}
 	}
 	}
 
 
-	function makeComponent( res : hxd.res.Resource, m : Markup, comp : domkit.Component<Dynamic,Dynamic>, argNames : Array<String>, interp : DomkitInterp, args : Array<Dynamic>, parent : h2d.Object ) : h2d.Object {
+	function makeComponent( res : hxd.res.Resource, m : Markup, comp : domkit.Component<Dynamic,Dynamic>, argNames : Array<String>, interp : DomkitInterp, inst : Dynamic, args : Array<Dynamic>, parent : h2d.Object ) : h2d.Object {
 		var prev = interp.variables.copy();
 		var prev = interp.variables.copy();
 		var obj = null;
 		var obj = null;
 		handleErrors(res, function() {
 		handleErrors(res, function() {
@@ -475,8 +484,10 @@ class DomkitViewer extends h2d.Object {
 			else
 			else
 				@:privateAccess obj.dom.component = cast comp;
 				@:privateAccess obj.dom.component = cast comp;
 			if( args.length > 0 && argNames.length > 0 ) {
 			if( args.length > 0 && argNames.length > 0 ) {
-				for( i => arg in argNames )
+				for( i => arg in argNames ) {
 					interp.variables.set(arg, args[i]);
 					interp.variables.set(arg, args[i]);
+					if( inst != null ) try Reflect.setProperty(inst, arg, args[i]) catch( e : Dynamic ) {};
+				}
 			}
 			}
 		});
 		});
 		for( c in m.children )
 		for( c in m.children )