// 收集所有 字段,属性,方法 public void Collect() { var bindingFlags = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static; var fields = type.GetFields(bindingFlags); foreach (var field in fields) { if (field.IsSpecialName) { bindingManager.Info("skip special field: {0}", field.Name); continue; } if (field.FieldType.IsPointer) { bindingManager.Info("skip pointer field: {0}", field.Name); continue; } if (field.IsDefined(typeof(JSOmitAttribute), false)) { bindingManager.Info("skip omitted field: {0}", field.Name); continue; } if (field.IsDefined(typeof(ObsoleteAttribute), false)) { bindingManager.Info("skip obsolete field: {0}", field.Name); continue; } if (transform != null && transform.IsMemberBlocked(field.Name)) { bindingManager.Info("skip blocked field: {0}", field.Name); continue; } AddField(field); } var events = type.GetEvents(bindingFlags); foreach (var evt in events) { if (evt.IsSpecialName) { bindingManager.Info("skip special event: {0}", evt.Name); continue; } if (evt.EventHandlerType.IsPointer) { bindingManager.Info("skip pointer event: {0}", evt.Name); continue; } if (evt.IsDefined(typeof(ObsoleteAttribute), false)) { bindingManager.Info("skip obsolete event: {0}", evt.Name); continue; } if (evt.IsDefined(typeof(JSOmitAttribute), false)) { bindingManager.Info("skip omitted event: {0}", evt.Name); continue; } if (transform != null && transform.IsMemberBlocked(evt.Name)) { bindingManager.Info("skip blocked event: {0}", evt.Name); continue; } AddEvent(evt); } var properties = type.GetProperties(bindingFlags); foreach (var property in properties) { if (property.IsSpecialName) { bindingManager.Info("skip special property: {0}", property.Name); continue; } if (property.PropertyType.IsPointer) { bindingManager.Info("skip pointer property: {0}", property.Name); continue; } if (property.IsDefined(typeof(JSOmitAttribute), false)) { bindingManager.Info("skip omitted property: {0}", property.Name); continue; } if (property.IsDefined(typeof(ObsoleteAttribute), false)) { bindingManager.Info("skip obsolete property: {0}", property.Name); continue; } if (transform != null && transform.IsMemberBlocked(property.Name)) { bindingManager.Info("skip blocked property: {0}", property.Name); continue; } //TODO: 索引访问 if (property.Name == "Item") { if (property.CanRead && property.GetMethod != null) { if (BindingManager.IsUnsupported(property.GetMethod)) { bindingManager.Info("skip unsupported get-method: {0}", property.GetMethod); continue; } AddMethod(property.GetMethod, true, "$GetValue"); } if (property.CanWrite && property.SetMethod != null) { if (BindingManager.IsUnsupported(property.SetMethod)) { bindingManager.Info("skip unsupported set-method: {0}", property.SetMethod); continue; } AddMethod(property.SetMethod, true, "$SetValue"); } // bindingManager.Info("skip indexer property: {0}", property.Name); continue; } AddProperty(property); } if (!type.IsAbstract) { var constructors = type.GetConstructors(); foreach (var constructor in constructors) { if (constructor.IsDefined(typeof(JSOmitAttribute), false)) { bindingManager.Info("skip omitted constructor: {0}", constructor); continue; } if (constructor.IsDefined(typeof(ObsoleteAttribute), false)) { bindingManager.Info("skip obsolete constructor: {0}", constructor); continue; } if (BindingManager.ContainsPointer(constructor)) { bindingManager.Info("skip pointer constructor: {0}", constructor); continue; } AddConstructor(constructor); } } var methods = type.GetMethods(bindingFlags); foreach (var method in methods) { if (BindingManager.IsGenericMethod(method)) { bindingManager.Info("skip generic method: {0}", method); continue; } if (BindingManager.ContainsPointer(method)) { bindingManager.Info("skip unsafe (pointer) method: {0}", method); continue; } if (method.IsSpecialName) { bindingManager.Info("skip special method: {0}", method); continue; } if (method.IsDefined(typeof(JSOmitAttribute), false)) { bindingManager.Info("skip omitted method: {0}", method); continue; } if (method.IsDefined(typeof(ObsoleteAttribute), false)) { bindingManager.Info("skip obsolete method: {0}", method); continue; } if (transform != null && transform.IsMemberBlocked(method.Name)) { bindingManager.Info("skip blocked method: {0}", method.Name); continue; } // if (IsPropertyMethod(method)) // { // continue; // } do { if (IsExtensionMethod(method)) { var targetType = method.GetParameters()[0].ParameterType; var targetInfo = bindingManager.GetExportedType(targetType); if (targetInfo != null) { targetInfo.AddMethod(method); break; } // else fallthrough (as normal static method) } AddMethod(method); } while (false); } }
public override void Dispose() { using (new PreservedCodeGen(cg)) { using (new RegFuncCodeGen(cg)) { using (new RegFuncNamespaceCodeGen(cg, bindingInfo)) { var constructor = bindingInfo.constructors.available ? bindingInfo.constructors.name : "object_private_ctor"; if (!bindingInfo.constructors.available && !bindingInfo.type.IsAbstract) { if (bindingInfo.type.IsSubclassOf(typeof(Component))) { // 因为 ts 泛型约束需要 new() 形式, 所以在定义中产生一个 public 定义 // 例如: GetComponent<T extends Component>(type: { new(): T }): T cg.tsDeclare.AppendLine("/*protected*/ constructor()"); } else { cg.tsDeclare.AppendLine("protected constructor()"); } } cg.cs.AppendLine("duk_begin_class(ctx, \"{0}\", typeof({1}), {2});", bindingInfo.jsName, this.cg.bindingManager.GetCSTypeFullName(bindingInfo.type), constructor); foreach (var kv in bindingInfo.methods) { var regName = kv.Value.regName; var funcName = kv.Value.name; var bStatic = false; string redirect; if (this.bindingInfo.transform != null && this.bindingInfo.transform.TryRedirectMethod(regName, out redirect)) { funcName = redirect; } cg.cs.AppendLine("duk_add_method(ctx, \"{0}\", {1}, {2});", regName, funcName, bStatic ? -2 : -1); } foreach (var kv in bindingInfo.staticMethods) { var regName = kv.Value.regName; var funcName = kv.Value.name; var bStatic = true; string redirect; if (this.bindingInfo.transform != null && this.bindingInfo.transform.TryRedirectMethod(regName, out redirect)) { funcName = redirect; } cg.cs.AppendLine("duk_add_method(ctx, \"{0}\", {1}, {2});", regName, funcName, bStatic ? -2 : -1); } foreach (var kv in bindingInfo.properties) { var bindingInfo = kv.Value; if (bindingInfo.staticPair.IsValid()) { var tsPropertyVar = BindingManager.GetTSVariable(bindingInfo.regName); cg.cs.AppendLine("duk_add_property(ctx, \"{0}\", {1}, {2}, {3});", tsPropertyVar, bindingInfo.staticPair.getterName != null ? bindingInfo.staticPair.getterName : "null", bindingInfo.staticPair.setterName != null ? bindingInfo.staticPair.setterName : "null", -2); var tsPropertyPrefix = "static "; if (bindingInfo.staticPair.setterName == null) { tsPropertyPrefix += "readonly "; } var tsPropertyType = this.cg.bindingManager.GetTSTypeFullName(bindingInfo.propertyInfo.PropertyType); cg.tsDeclare.AppendLine($"{tsPropertyPrefix}{tsPropertyVar}: {tsPropertyType}"); } if (bindingInfo.instancePair.IsValid()) { var tsPropertyVar = BindingManager.GetTSVariable(bindingInfo.regName); cg.cs.AppendLine("duk_add_property(ctx, \"{0}\", {1}, {2}, {3});", tsPropertyVar, bindingInfo.instancePair.getterName != null ? bindingInfo.instancePair.getterName : "null", bindingInfo.instancePair.setterName != null ? bindingInfo.instancePair.setterName : "null", -1); var tsPropertyPrefix = ""; if (bindingInfo.instancePair.setterName == null) { tsPropertyPrefix += "readonly "; } var tsPropertyType = this.cg.bindingManager.GetTSTypeFullName(bindingInfo.propertyInfo.PropertyType); cg.tsDeclare.AppendLine($"{tsPropertyPrefix}{tsPropertyVar}: {tsPropertyType}"); } } foreach (var kv in bindingInfo.fields) { var bindingInfo = kv.Value; var bStatic = bindingInfo.isStatic; var tsFieldVar = BindingManager.GetTSVariable(bindingInfo.regName); if (bindingInfo.constantValue != null) { var cv = bindingInfo.constantValue; cg.cs.AppendLine($"duk_add_const(ctx, \"{tsFieldVar}\", {cv}, {-2});"); } else { cg.cs.AppendLine("duk_add_field(ctx, \"{0}\", {1}, {2}, {3});", tsFieldVar, bindingInfo.getterName != null ? bindingInfo.getterName : "null", bindingInfo.setterName != null ? bindingInfo.setterName : "null", bStatic ? -2 : -1); } var tsFieldPrefix = bStatic ? "static " : ""; if (bindingInfo.setterName == null) { tsFieldPrefix += "readonly "; } var tsFieldType = this.cg.bindingManager.GetTSTypeFullName(bindingInfo.fieldInfo.FieldType); cg.tsDeclare.AppendLine($"{tsFieldPrefix}{tsFieldVar}: {tsFieldType}"); } foreach (var kv in bindingInfo.events) { var eventBindingInfo = kv.Value; var bStatic = eventBindingInfo.isStatic; //NOTE: 静态事件在绑定过程直接定义, 非静态事件推迟到构造时直接赋值创建 var tsFieldVar = BindingManager.GetTSVariable(eventBindingInfo.regName); var tsFieldType = this.cg.bindingManager.GetTSTypeFullName(eventBindingInfo.eventInfo.EventHandlerType); var tsFieldPrefix = ""; if (bStatic) { tsFieldPrefix += "static "; cg.cs.AppendLine($"duk_add_event(ctx, \"{tsFieldVar}\", {eventBindingInfo.adderName}, {eventBindingInfo.removerName}, -2);"); } else { cg.cs.AppendLine($"duk_add_property(ctx, \"{tsFieldVar}\", {eventBindingInfo.proxyName}, null, -1);"); } cg.tsDeclare.AppendLine($"{tsFieldPrefix}{tsFieldVar}: DuktapeJS.event<{tsFieldType}>"); } cg.cs.AppendLine("duk_end_class(ctx);"); } } base.Dispose(); } this.cg.tsDeclare.DecTabLevel(); this.cg.tsDeclare.AppendLine("}"); }
public static void ClearBindings() { BindingManager.Cleanup(Prefs.Load(Prefs.PATH).outDir, null, null); AssetDatabase.Refresh(); }
public virtual void OnPostGenerateDelegate(BindingManager bindingManager, DelegateBindingInfo bindingInfo) { }
public virtual void OnCleanup(BindingManager bindingManager) { }
public virtual bool OnExportingType(BindingManager bindingManager, Type type) { return(false); }
public virtual void OnPostGenerateType(BindingManager bindingManager, TypeBindingInfo bindingInfo) { }
public virtual void OnPostCollectTypes(BindingManager bindingManager) { }
public virtual void OnPostExporting(BindingManager bindingManager) { }
public virtual void OnPostCollectAssemblies(BindingManager bindingManager) { }
public virtual void OnInitialize(BindingManager bindingManager) { }
protected List <ParameterInfo> WriteTSDeclaration(T method, MethodBaseBindingInfo <T> bindingInfo) { var isExtension = method.IsDefined(typeof(System.Runtime.CompilerServices.ExtensionAttribute)); var refParameters = new List <ParameterInfo>(); string tsMethodDeclaration; this.cg.AppendJSDoc(method); if (this.cg.bindingManager.GetTSMethodDeclaration(method, out tsMethodDeclaration)) { this.cg.tsDeclare.AppendLine(tsMethodDeclaration); return(refParameters); } var isRaw = method.IsDefined(typeof(JSCFunctionAttribute)); //TODO: 需要处理参数类型归并问题, 因为如果类型没有导入 ts 中, 可能会在声明中出现相同参数列表的定义 // 在 MethodVariant 中创建每个方法对应的TS类型名参数列表, 完全相同的不再输出 var prefix = ""; if (method.IsStatic && !isExtension) { prefix = "static "; } string tsMethodRename; if (this.cg.bindingManager.GetTSMethodRename(method, out tsMethodRename)) { this.cg.tsDeclare.Append($"{prefix}{tsMethodRename}("); } else { this.cg.tsDeclare.Append($"{prefix}{bindingInfo.regName}("); } if (isRaw) { this.cg.tsDeclare.AppendL("...uncertain: any[]): any /* uncertain */"); this.cg.tsDeclare.AppendLine(); } else { var parameters = method.GetParameters(); if (isExtension) { ArrayUtility.RemoveAt(ref parameters, 0); } for (var i = 0; i < parameters.Length; i++) { var parameter = parameters[i]; var parameter_prefix = ""; var parameterType = parameter.ParameterType; if (parameter.IsOut && parameterType.IsByRef) { // parameter_prefix = "/*out*/ "; refParameters.Add(parameter); } else if (parameterType.IsByRef) { // parameter_prefix = "/*ref*/ "; refParameters.Add(parameter); } if (parameter.IsDefined(typeof(ParamArrayAttribute), false) && i == parameters.Length - 1) { var elementType = parameterType.GetElementType(); var elementTS = this.cg.bindingManager.GetTSTypeFullName(elementType); var parameterVarName = BindingManager.GetTSVariable(parameter.Name); this.cg.tsDeclare.AppendL($"{parameter_prefix}...{parameterVarName}: {elementTS}[]"); } else { var parameterTS = this.cg.bindingManager.GetTSTypeFullName(parameterType, parameter.IsOut); var parameterVarName = BindingManager.GetTSVariable(parameter.Name); this.cg.tsDeclare.AppendL($"{parameter_prefix}{parameterVarName}: {parameterTS}"); } if (i != parameters.Length - 1) { this.cg.tsDeclare.AppendL(", "); } } this.cg.tsDeclare.AppendL($")"); WriteTSReturn(method, refParameters); } return(refParameters); }