From dd25873b58ceb931c86d860d9af9d5a68e02c534 Mon Sep 17 00:00:00 2001 From: walon Date: Mon, 25 Oct 2021 21:45:10 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E9=87=8D=E6=9E=84=E3=80=91=E9=87=8D?= =?UTF-8?q?=E6=9E=84=20validator?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Luban.Job.Cfg/Source/Defs/DefField.cs | 204 ++---------------- .../Source/Utils/ValidatorUtil.cs | 75 +++++++ .../Source/Validators/IValidator.cs | 2 - .../Source/Validators/PathValidator.cs | 10 +- .../Source/Validators/RangeValidator.cs | 8 +- .../Source/Validators/RefValidator.cs | 40 ++-- .../Source/Validators/ValidatorFactory.cs | 10 +- .../Source/Defs/DefFieldBase.cs | 2 +- .../Source/Defs/IProcessor.cs | 1 + src/Luban.Job.Common/Source/Types/TArray.cs | 20 +- src/Luban.Job.Common/Source/Types/TBool.cs | 13 +- src/Luban.Job.Common/Source/Types/TByte.cs | 13 +- src/Luban.Job.Common/Source/Types/TBytes.cs | 11 +- .../Source/Types/TDateTime.cs | 13 +- src/Luban.Job.Common/Source/Types/TDouble.cs | 13 +- src/Luban.Job.Common/Source/Types/TFint.cs | 13 +- src/Luban.Job.Common/Source/Types/TFloat.cs | 11 +- src/Luban.Job.Common/Source/Types/TFlong.cs | 13 +- src/Luban.Job.Common/Source/Types/TFshort.cs | 13 +- src/Luban.Job.Common/Source/Types/TInt.cs | 13 +- src/Luban.Job.Common/Source/Types/TList.cs | 20 ++ src/Luban.Job.Common/Source/Types/TLong.cs | 17 +- src/Luban.Job.Common/Source/Types/TMap.cs | 25 +++ src/Luban.Job.Common/Source/Types/TSet.cs | 20 ++ src/Luban.Job.Common/Source/Types/TShort.cs | 13 +- src/Luban.Job.Common/Source/Types/TString.cs | 13 +- src/Luban.Job.Common/Source/Types/TText.cs | 13 +- src/Luban.Job.Common/Source/Types/TType.cs | 10 +- src/Luban.Job.Common/Source/Types/TVector2.cs | 13 +- src/Luban.Job.Common/Source/Types/TVector3.cs | 13 +- src/Luban.Job.Common/Source/Types/TVector4.cs | 13 +- 31 files changed, 246 insertions(+), 422 deletions(-) create mode 100644 src/Luban.Job.Cfg/Source/Utils/ValidatorUtil.cs diff --git a/src/Luban.Job.Cfg/Source/Defs/DefField.cs b/src/Luban.Job.Cfg/Source/Defs/DefField.cs index 272bcad..9291f39 100644 --- a/src/Luban.Job.Cfg/Source/Defs/DefField.cs +++ b/src/Luban.Job.Cfg/Source/Defs/DefField.cs @@ -2,6 +2,7 @@ using Luban.Common.Utils; using Luban.Job.Cfg.DataCreators; using Luban.Job.Cfg.Datas; using Luban.Job.Cfg.RawDefs; +using Luban.Job.Cfg.Utils; using Luban.Job.Cfg.Validators; using Luban.Job.Common.Defs; using Luban.Job.Common.Types; @@ -24,16 +25,6 @@ namespace Luban.Job.Cfg.Defs public RefValidator Ref { get; private set; } - //public RefValidator KeyRef { get; private set; } - - //public RefValidator ValueRef { get; private set; } - - //public List Validators { get; } = new List(); - - //public List KeyValidators { get; } = new List(); - - //public List ValueValidators { get; } = new List(); - // 如果ref了多个表,不再生成 xxx_ref之类的字段,也不会resolve public bool GenRef => Ref != null && Ref.Tables.Count == 1; @@ -126,197 +117,20 @@ namespace Luban.Job.Cfg.Defs this.RawDefine = f; } - - private void CompileValidatorsForType(TType type) - { - foreach (var valName in ValidatorFactory.ValidatorNames) - { - if (type.Tags != null && type.Tags.TryGetValue(valName, out var valValue)) - { - type.Processors.Add(ValidatorFactory.Create(valName, valValue)); - } - } - } - - private void CompileValidatorsForArrayLink(TType elementType) - { - CompileValidatorsForType(elementType); - - var valueRef = this.CType.Processors.Find(v => v is RefValidator); - if (valueRef != null) - { - this.CType.Processors.Remove(valueRef); - elementType.Processors.Add(valueRef); - } - var valuePath = this.CType.Processors.Find(v => v is PathValidator); - if (valuePath != null) - { - this.CType.Processors.Remove(valuePath); - elementType.Processors.Add(valuePath); - } - } - public override void Compile() { base.Compile(); - CompileValidatorsForType(CType); - - switch (this.CType) + ValidatorUtil.CreateValidators(CType); + var selfRef = this.CType.Processors.Find(v => v is RefValidator); + if (selfRef != null) { - case TArray ta: - { - CompileValidatorsForArrayLink(ta.ElementType); - break; - } - case TList ta: - { - CompileValidatorsForArrayLink(ta.ElementType); - break; - } - case TSet ta: - { - CompileValidatorsForArrayLink(ta.ElementType); - break; - } - case TMap ta: - { - CompileValidatorsForType(ta.KeyType); - CompileValidatorsForType(ta.ValueType); - break; - } - default: - { - var selfRef = this.CType.Processors.Find(v => v is RefValidator); - if (selfRef != null) - { - this.Ref = (RefValidator)selfRef; - } - break; - } - } - - switch (CType) - { - case TArray t: - { - if (t.ElementType is TBean e && !e.IsDynamic && e.Bean.HierarchyFields.Count == 0) - { - throw new Exception($"container element type:'{e.Bean.FullName}' can't be empty bean"); - } - if (t.ElementType is TText) - { - throw new Exception($"bean:{HostType.FullName} field:{Name} container element type can't text"); - } - break; - } - case TList t: - { - if (t.ElementType is TBean e && !e.IsDynamic && e.Bean.HierarchyFields.Count == 0) - { - throw new Exception($"container element type:'{e.Bean.FullName}' can't be empty bean"); - } - if (t.ElementType is TText) - { - throw new Exception($"bean:{HostType.FullName} field:{Name} container element type can't text"); - } - break; - } - case TSet t: - { - if (t.ElementType is TText) - { - throw new Exception($"bean:{HostType.FullName} field:{Name} container element type can't text"); - } - break; - } - case TMap t: - { - if (t.KeyType is TText) - { - throw new Exception($"bean:{HostType.FullName} field:{Name} container key type can't text"); - } - if (t.ValueType is TText) - { - throw new Exception($"bean:{HostType.FullName} field:{Name} container value type can't text"); - } - break; - } + this.Ref = (RefValidator)selfRef; } } - private void ValidateRef(RefValidator val, TType refVarType) + private void ValidateIndex() { - foreach (var table in val.Tables) - { - var cfgTable = Assembly.GetCfgTable(RefValidator.GetActualTableName(table)); - if (cfgTable == null) - { - throw new Exception($"type:'{HostType.FullName}' field:'{Name}' ref 引用的表:'{table}' 不存在"); - } - if (!cfgTable.NeedExport) - { - throw new Exception($"type:'{HostType.FullName}' field:'{Name}' ref 引用的表:'{table}' 没有导出"); - } - if (!cfgTable.IsMapTable) - { - throw new Exception($"type:'{HostType.FullName}' field:'{Name}' ref 引用的表:'{table}'不是普通表,无法进行引用检查"); - } - var keyType = cfgTable.KeyTType; - if (keyType.GetType() != refVarType.GetType()) - { - throw new Exception($"type:'{HostType.FullName}' field:'{Name}' 类型:'{refVarType}' 与 被引用的表:'{cfgTable.FullName}' key类型:'{keyType}' 不一致"); - } - } - } - - private void CompileValidator(TType type) - { - foreach (var p in CType.Processors) - { - if (p is IValidator val) - { - val.Compile(this); - if (val is RefValidator refVal) - { - ValidateRef(refVal, type); - } - } - } - } - - public override void PostCompile() - { - base.PostCompile(); - - CompileValidator(CType); - - - switch (this.CType) - { - case TArray ta: - { - CompileValidator(ta.ElementType); - break; - } - case TList ta: - { - CompileValidator(ta.ElementType); - break; - } - case TSet ta: - { - CompileValidator(ta.ElementType); - break; - } - case TMap ta: - { - CompileValidator(ta.KeyType); - CompileValidator(ta.ValueType); - break; - } - } - Index = CType.GetTag("index"); if (!string.IsNullOrEmpty(Index)) @@ -341,5 +155,11 @@ namespace Luban.Job.Cfg.Defs } } } + + public override void PostCompile() + { + base.PostCompile(); + ValidateIndex(); + } } } diff --git a/src/Luban.Job.Cfg/Source/Utils/ValidatorUtil.cs b/src/Luban.Job.Cfg/Source/Utils/ValidatorUtil.cs new file mode 100644 index 0000000..7d5838b --- /dev/null +++ b/src/Luban.Job.Cfg/Source/Utils/ValidatorUtil.cs @@ -0,0 +1,75 @@ +using Luban.Job.Cfg.Validators; +using Luban.Job.Common.Types; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Luban.Job.Cfg.Utils +{ + static class ValidatorUtil + { + + + private static void CreateValidatorsForType(TType type) + { + foreach (var valName in ValidatorFactory.ValidatorNames) + { + if (type.Tags.TryGetValue(valName, out var valValue)) + { + type.Processors.Add(ValidatorFactory.Create(type, valName, valValue)); + } + } + } + + private static void CreateValidatorsForArrayLike(TType containerType, TType elementType) + { + if (containerType.Tags.Remove("ref", out var refStr)) + { + elementType.Tags.TryAdd("ref", refStr); + } + if (containerType.Tags.Remove("path", out var pathStr)) + { + elementType.Tags.TryAdd("path", pathStr); + } + + CreateValidatorsForType(elementType); + CreateValidatorsForType(containerType); + } + + public static void CreateValidators(TType type) + { + switch (type) + { + case TArray ta: + { + CreateValidatorsForArrayLike(type, ta.ElementType); + break; + } + case TList ta: + { + CreateValidatorsForArrayLike(type, ta.ElementType); + break; + } + case TSet ta: + { + CreateValidatorsForArrayLike(type, ta.ElementType); + break; + } + case TMap ta: + { + CreateValidatorsForType(ta.KeyType); + CreateValidatorsForType(ta.ValueType); + CreateValidatorsForType(type); + break; + } + default: + { + CreateValidatorsForType(type); + break; + } + } + } + } +} diff --git a/src/Luban.Job.Cfg/Source/Validators/IValidator.cs b/src/Luban.Job.Cfg/Source/Validators/IValidator.cs index 460196c..dfc1fa1 100644 --- a/src/Luban.Job.Cfg/Source/Validators/IValidator.cs +++ b/src/Luban.Job.Cfg/Source/Validators/IValidator.cs @@ -7,8 +7,6 @@ namespace Luban.Job.Cfg.Validators { public interface IValidator : IProcessor { - void Compile(DefField def); - void Validate(ValidatorContext ctx, TType type, DType data); } } diff --git a/src/Luban.Job.Cfg/Source/Validators/PathValidator.cs b/src/Luban.Job.Cfg/Source/Validators/PathValidator.cs index b3cfebd..8016c46 100644 --- a/src/Luban.Job.Cfg/Source/Validators/PathValidator.cs +++ b/src/Luban.Job.Cfg/Source/Validators/PathValidator.cs @@ -1,5 +1,6 @@ using Luban.Job.Cfg.Datas; using Luban.Job.Cfg.Defs; +using Luban.Job.Common.Defs; using Luban.Job.Common.Types; using System; using System.Collections.Generic; @@ -156,10 +157,13 @@ namespace Luban.Job.Cfg.Validators public string RawPattern { get; } + public TType Type { get; } + internal IPathPattern PathPattern { get; private set; } - public PathValidator(string pathPattern) + public PathValidator(TType type, string pathPattern) { + Type = type; this.RawPattern = pathPattern; } @@ -202,12 +206,12 @@ namespace Luban.Job.Cfg.Validators } } - private void ThrowCompileError(DefField def, string err) + private void ThrowCompileError(DefFieldBase def, string err) { throw new System.ArgumentException($"{((DefBean)(def.HostType)).FullName} 字段:{def.Name} {RawPattern} 定义不合法. {err}"); } - public void Compile(DefField def) + public void Compile(DefFieldBase def) { string[] ss = RawPattern.Split(';'); if (ss.Length < 1) diff --git a/src/Luban.Job.Cfg/Source/Validators/RangeValidator.cs b/src/Luban.Job.Cfg/Source/Validators/RangeValidator.cs index 3732be5..c092de7 100644 --- a/src/Luban.Job.Cfg/Source/Validators/RangeValidator.cs +++ b/src/Luban.Job.Cfg/Source/Validators/RangeValidator.cs @@ -1,5 +1,6 @@ using Luban.Job.Cfg.Datas; using Luban.Job.Cfg.Defs; +using Luban.Job.Common.Defs; using Luban.Job.Common.Types; using System; @@ -11,6 +12,8 @@ namespace Luban.Job.Cfg.Validators public string Name => NAME; + public TType Type { get; } + private readonly string _str; private long? _min; @@ -23,8 +26,9 @@ namespace Luban.Job.Cfg.Validators private bool _includeMaxBound; - public RangeValidator(string strRange) + public RangeValidator(TType type, string strRange) { + Type = type; _str = strRange.Trim(); } @@ -66,7 +70,7 @@ namespace Luban.Job.Cfg.Validators } } - public void Compile(DefField def) + public void Compile(DefFieldBase def) { void ThrowError() { diff --git a/src/Luban.Job.Cfg/Source/Validators/RefValidator.cs b/src/Luban.Job.Cfg/Source/Validators/RefValidator.cs index 439f22d..5191c60 100644 --- a/src/Luban.Job.Cfg/Source/Validators/RefValidator.cs +++ b/src/Luban.Job.Cfg/Source/Validators/RefValidator.cs @@ -1,6 +1,7 @@ using Luban.Job.Cfg.Datas; using Luban.Job.Cfg.DataVisitors; using Luban.Job.Cfg.Defs; +using Luban.Job.Common.Defs; using Luban.Job.Common.Types; using System; using System.Collections.Generic; @@ -10,11 +11,6 @@ namespace Luban.Job.Cfg.Validators { public class RefValidator : IValidator { - public const string NAME = "ref"; - - public List Tables { get; } - - public string FirstTable => GetActualTableName(Tables[0]); public static string GetActualTableName(string table) { @@ -25,8 +21,17 @@ namespace Luban.Job.Cfg.Validators #endif } - public RefValidator(List tables) + public const string NAME = "ref"; + + public List Tables { get; } + + public string FirstTable => GetActualTableName(Tables[0]); + + public TType Type { get; } + + public RefValidator(TType type, List tables) { + Type = type; this.Tables = new List(tables); } @@ -92,13 +97,16 @@ namespace Luban.Job.Cfg.Validators } } - public void Compile(DefField def) + public void Compile(DefFieldBase def) { + string hostTypeName = def.HostType.FullName; + string fieldName = def.Name; if (Tables.Count == 0) { - throw new Exception($"结构:{ def.HostType.FullName } 字段: { def.Name} ref 不能为空"); + throw new Exception($"结构:{ hostTypeName } 字段: { fieldName} ref 不能为空"); } + var assembly = ((DefField)def).Assembly; foreach (var table in Tables) { #if !LUBAN_LITE @@ -106,17 +114,25 @@ namespace Luban.Job.Cfg.Validators #else string actualTable = table.EndsWith("?") ? table.Substring(0, table.Length - 1) : table; #endif - var ct = def.Assembly.GetCfgTable(actualTable); + var ct = assembly.GetCfgTable(actualTable); if (ct == null) { - throw new Exception($"结构:{def.HostType.FullName} 字段:{def.Name} ref:{table} 不存在"); + throw new Exception($"结构:{hostTypeName} 字段:{fieldName} ref:{table} 不存在"); + } + if (!ct.NeedExport) + { + throw new Exception($"type:'{hostTypeName}' field:'{fieldName}' ref 引用的表:'{table}' 没有导出"); } if (ct.IsOneValueTable) { - throw new Exception($"结构:{def.HostType.FullName} 字段:{def.Name} ref:{table} 是单值表,不能执行引用检查"); + throw new Exception($"结构:{hostTypeName} 字段:{fieldName} ref:{table} 是单值表,不能执行引用检查"); + } + var keyType = ct.KeyTType; + if (keyType.GetType() != Type.GetType()) + { + throw new Exception($"type:'{hostTypeName}' field:'{fieldName}' 类型:'{Type.GetType()}' 与 被引用的表:'{ct.FullName}' key类型:'{keyType.GetType()}' 不一致"); } } - } } } diff --git a/src/Luban.Job.Cfg/Source/Validators/ValidatorFactory.cs b/src/Luban.Job.Cfg/Source/Validators/ValidatorFactory.cs index 8a7437c..1aeb015 100644 --- a/src/Luban.Job.Cfg/Source/Validators/ValidatorFactory.cs +++ b/src/Luban.Job.Cfg/Source/Validators/ValidatorFactory.cs @@ -1,4 +1,6 @@ +using Luban.Job.Cfg.Defs; using Luban.Job.Cfg.RawDefs; +using Luban.Job.Common.Types; using System; using System.Collections.Generic; using System.Linq; @@ -13,22 +15,22 @@ namespace Luban.Job.Cfg.Validators public static List ValidatorNames => s_validatorNames; - public static IValidator Create(string type, string rule) + public static IValidator Create(TType field, string type, string rule) { s_logger.Debug("== create validator {type}:{rule}", type, rule); switch (type) { case RefValidator.NAME: { - return new RefValidator(rule.Split(',').ToList()); + return new RefValidator(field, rule.Split(',').ToList()); } case PathValidator.NAME: { - return new PathValidator(rule);//.Split(',').ToList()); + return new PathValidator(field, rule);//.Split(',').ToList()); } case RangeValidator.NAME: { - return new RangeValidator(rule); + return new RangeValidator(field, rule); } default: throw new NotSupportedException("unknown validator type:" + type); diff --git a/src/Luban.Job.Common/Source/Defs/DefFieldBase.cs b/src/Luban.Job.Common/Source/Defs/DefFieldBase.cs index 03195fd..08bd540 100644 --- a/src/Luban.Job.Common/Source/Defs/DefFieldBase.cs +++ b/src/Luban.Job.Common/Source/Defs/DefFieldBase.cs @@ -145,7 +145,7 @@ namespace Luban.Job.Common.Defs public virtual void PostCompile() { - // 检查 字段类型 与 所引用的表的key是否一致 + CType.Compile(this); } public static void CompileFields(DefTypeBase hostType, List fields, bool verifyId) where T : DefFieldBase diff --git a/src/Luban.Job.Common/Source/Defs/IProcessor.cs b/src/Luban.Job.Common/Source/Defs/IProcessor.cs index 822d6a9..6a3f4a5 100644 --- a/src/Luban.Job.Common/Source/Defs/IProcessor.cs +++ b/src/Luban.Job.Common/Source/Defs/IProcessor.cs @@ -8,5 +8,6 @@ namespace Luban.Job.Common.Defs { public interface IProcessor { + void Compile(DefFieldBase def); } } diff --git a/src/Luban.Job.Common/Source/Types/TArray.cs b/src/Luban.Job.Common/Source/Types/TArray.cs index f1cea66..a4a16b4 100644 --- a/src/Luban.Job.Common/Source/Types/TArray.cs +++ b/src/Luban.Job.Common/Source/Types/TArray.cs @@ -1,3 +1,4 @@ +using Luban.Job.Common.Defs; using Luban.Job.Common.TypeVisitors; using System; using System.Collections.Generic; @@ -6,7 +7,6 @@ namespace Luban.Job.Common.Types { public class TArray : TType { - public static TArray Create(bool isNullable, Dictionary tags, TType elementType) { return new TArray(isNullable, tags, elementType); @@ -26,6 +26,24 @@ namespace Luban.Job.Common.Types public override bool IsCollection => true; + public override void Compile(DefFieldBase field) + { + base.Compile(field); + + foreach (var p in ElementType.Processors) + { + p.Compile(field); + } + + if (ElementType is TBean e && !e.IsDynamic && e.Bean.HierarchyFields.Count == 0) + { + throw new Exception($"container element type:'{e.Bean.FullName}' can't be empty bean"); + } + if (ElementType is TText) + { + throw new Exception($"bean:{field.HostType.FullName} field:{field.Name} container element type can't be text"); + } + } public override void Apply(ITypeActionVisitor visitor, T x) { diff --git a/src/Luban.Job.Common/Source/Types/TBool.cs b/src/Luban.Job.Common/Source/Types/TBool.cs index f00e132..a4f42c4 100644 --- a/src/Luban.Job.Common/Source/Types/TBool.cs +++ b/src/Luban.Job.Common/Source/Types/TBool.cs @@ -5,20 +5,9 @@ namespace Luban.Job.Common.Types { public class TBool : TType { - private static TBool Ins { get; } = new TBool(false, null); - - private static TBool NullableIns { get; } = new TBool(true, null); - public static TBool Create(bool isNullable, Dictionary tags) { - if (tags == null || tags.Count == 0) - { - return isNullable ? NullableIns : Ins; - } - else - { - return new TBool(isNullable, tags); - } + return new TBool(isNullable, tags); } private TBool(bool isNullable, Dictionary tags) : base(isNullable, tags) diff --git a/src/Luban.Job.Common/Source/Types/TByte.cs b/src/Luban.Job.Common/Source/Types/TByte.cs index 74f8f7a..7eb1e73 100644 --- a/src/Luban.Job.Common/Source/Types/TByte.cs +++ b/src/Luban.Job.Common/Source/Types/TByte.cs @@ -5,20 +5,9 @@ namespace Luban.Job.Common.Types { public class TByte : TType { - private static TByte Ins { get; } = new TByte(false, null); - - private static TByte NullableIns { get; } = new TByte(true, null); - public static TByte Create(bool isNullable, Dictionary tags) { - if (tags == null) - { - return isNullable ? NullableIns : Ins; - } - else - { - return new TByte(isNullable, tags); - } + return new TByte(isNullable, tags); } private TByte(bool isNullable, Dictionary tags) : base(isNullable, tags) diff --git a/src/Luban.Job.Common/Source/Types/TBytes.cs b/src/Luban.Job.Common/Source/Types/TBytes.cs index 5f23e1f..d15d274 100644 --- a/src/Luban.Job.Common/Source/Types/TBytes.cs +++ b/src/Luban.Job.Common/Source/Types/TBytes.cs @@ -6,18 +6,9 @@ namespace Luban.Job.Common.Types { public class TBytes : TType { - private static TBytes Ins { get; } = new TBytes(false, null); - public static TBytes Create(bool isNullable, Dictionary tags) { - if (tags == null) - { - return isNullable ? new TBytes(true, null) : Ins; - } - else - { - return new TBytes(isNullable, tags); - } + return new TBytes(isNullable, tags); } private TBytes(bool isNullable, Dictionary tags) : base(isNullable, tags) diff --git a/src/Luban.Job.Common/Source/Types/TDateTime.cs b/src/Luban.Job.Common/Source/Types/TDateTime.cs index 4ddb289..3c50656 100644 --- a/src/Luban.Job.Common/Source/Types/TDateTime.cs +++ b/src/Luban.Job.Common/Source/Types/TDateTime.cs @@ -6,20 +6,9 @@ namespace Luban.Job.Common.Types { public class TDateTime : TType { - private static TDateTime Ins { get; } = new TDateTime(false, null); - - private static TDateTime NullableIns { get; } = new TDateTime(true, null); - public static TDateTime Create(bool isNullable, Dictionary tags) { - if (tags == null) - { - return isNullable ? NullableIns : Ins; - } - else - { - return new TDateTime(isNullable, tags); - } + return new TDateTime(isNullable, tags); } private TDateTime(bool isNullable, Dictionary tags) : base(isNullable, tags) diff --git a/src/Luban.Job.Common/Source/Types/TDouble.cs b/src/Luban.Job.Common/Source/Types/TDouble.cs index da36ad2..dcf1f09 100644 --- a/src/Luban.Job.Common/Source/Types/TDouble.cs +++ b/src/Luban.Job.Common/Source/Types/TDouble.cs @@ -5,20 +5,9 @@ namespace Luban.Job.Common.Types { public class TDouble : TType { - private static TDouble Ins { get; } = new TDouble(false, null); - - private static TDouble NullableIns { get; } = new TDouble(true, null); - public static TDouble Create(bool isNullable, Dictionary tags) { - if (tags == null) - { - return isNullable ? NullableIns : Ins; - } - else - { - return new TDouble(isNullable, tags); - } + return new TDouble(isNullable, tags); } private TDouble(bool isNullable, Dictionary tags) : base(isNullable, tags) diff --git a/src/Luban.Job.Common/Source/Types/TFint.cs b/src/Luban.Job.Common/Source/Types/TFint.cs index 7bba5db..07f94a2 100644 --- a/src/Luban.Job.Common/Source/Types/TFint.cs +++ b/src/Luban.Job.Common/Source/Types/TFint.cs @@ -5,20 +5,9 @@ namespace Luban.Job.Common.Types { public class TFint : TType { - private static TFint Ins { get; } = new TFint(false, null); - - private static TFint NullableIns { get; } = new TFint(true, null); - public static TFint Create(bool isNullable, Dictionary tags) { - if (tags == null) - { - return isNullable ? NullableIns : Ins; - } - else - { - return new TFint(isNullable, tags); - } + return new TFint(isNullable, tags); } private TFint(bool isNullable, Dictionary tags) : base(isNullable, tags) diff --git a/src/Luban.Job.Common/Source/Types/TFloat.cs b/src/Luban.Job.Common/Source/Types/TFloat.cs index 00e1644..8f35ade 100644 --- a/src/Luban.Job.Common/Source/Types/TFloat.cs +++ b/src/Luban.Job.Common/Source/Types/TFloat.cs @@ -7,18 +7,9 @@ namespace Luban.Job.Common.Types { public static TFloat Ins { get; } = new TFloat(false, null); - private static TFloat NullableIns { get; } = new TFloat(true, null); - public static TFloat Create(bool isNullable, Dictionary tags) { - if (tags == null) - { - return isNullable ? NullableIns : Ins; - } - else - { - return new TFloat(isNullable, tags); - } + return new TFloat(isNullable, tags); } private TFloat(bool isNullable, Dictionary tags) : base(isNullable, tags) diff --git a/src/Luban.Job.Common/Source/Types/TFlong.cs b/src/Luban.Job.Common/Source/Types/TFlong.cs index 3855652..e41e868 100644 --- a/src/Luban.Job.Common/Source/Types/TFlong.cs +++ b/src/Luban.Job.Common/Source/Types/TFlong.cs @@ -5,20 +5,9 @@ namespace Luban.Job.Common.Types { public class TFlong : TType { - private static TFlong Ins { get; } = new TFlong(false, null); - - private static TFlong NullableIns { get; } = new TFlong(true, null); - public static TFlong Create(bool isNullable, Dictionary tags) { - if (tags == null) - { - return isNullable ? NullableIns : Ins; - } - else - { - return new TFlong(isNullable, tags); - } + return new TFlong(isNullable, tags); } private TFlong(bool isNullable, Dictionary tags) : base(isNullable, tags) diff --git a/src/Luban.Job.Common/Source/Types/TFshort.cs b/src/Luban.Job.Common/Source/Types/TFshort.cs index 93e5ee5..3d2799d 100644 --- a/src/Luban.Job.Common/Source/Types/TFshort.cs +++ b/src/Luban.Job.Common/Source/Types/TFshort.cs @@ -5,20 +5,9 @@ namespace Luban.Job.Common.Types { public class TFshort : TType { - private static TFshort Ins { get; } = new TFshort(false, null); - - private static TFshort NullableIns { get; } = new TFshort(true, null); - public static TFshort Create(bool isNullable, Dictionary tags) { - if (tags == null) - { - return isNullable ? NullableIns : Ins; - } - else - { - return new TFshort(isNullable, tags); - } + return new TFshort(isNullable, tags); } private TFshort(bool isNullable, Dictionary tags) : base(isNullable, tags) diff --git a/src/Luban.Job.Common/Source/Types/TInt.cs b/src/Luban.Job.Common/Source/Types/TInt.cs index 981babc..bb335e5 100644 --- a/src/Luban.Job.Common/Source/Types/TInt.cs +++ b/src/Luban.Job.Common/Source/Types/TInt.cs @@ -5,20 +5,9 @@ namespace Luban.Job.Common.Types { public class TInt : TType { - private static TInt Ins { get; } = new TInt(false, null); - - private static TInt NullableIns { get; } = new TInt(true, null); - public static TInt Create(bool isNullable, Dictionary tags) { - if (tags == null) - { - return isNullable ? NullableIns : Ins; - } - else - { - return new TInt(isNullable, tags); - } + return new TInt(isNullable, tags); } private TInt(bool isNullable, Dictionary tags) : base(isNullable, tags) diff --git a/src/Luban.Job.Common/Source/Types/TList.cs b/src/Luban.Job.Common/Source/Types/TList.cs index dd0c2bf..d672998 100644 --- a/src/Luban.Job.Common/Source/Types/TList.cs +++ b/src/Luban.Job.Common/Source/Types/TList.cs @@ -1,3 +1,4 @@ +using Luban.Job.Common.Defs; using Luban.Job.Common.TypeVisitors; using System; using System.Collections.Generic; @@ -28,6 +29,25 @@ namespace Luban.Job.Common.Types public override bool IsCollection => true; + public override void Compile(DefFieldBase field) + { + base.Compile(field); + + foreach (var p in ElementType.Processors) + { + p.Compile(field); + } + + if (ElementType is TBean e && !e.IsDynamic && e.Bean.HierarchyFields.Count == 0) + { + throw new Exception($"container element type:'{e.Bean.FullName}' can't be empty bean"); + } + if (ElementType is TText) + { + throw new Exception($"bean:{field.HostType.FullName} field:{field.Name} container element type can't be text"); + } + } + public override void Apply(ITypeActionVisitor visitor, T x) { visitor.Accept(this, x); diff --git a/src/Luban.Job.Common/Source/Types/TLong.cs b/src/Luban.Job.Common/Source/Types/TLong.cs index 7de448b..1282495 100644 --- a/src/Luban.Job.Common/Source/Types/TLong.cs +++ b/src/Luban.Job.Common/Source/Types/TLong.cs @@ -5,24 +5,9 @@ namespace Luban.Job.Common.Types { public class TLong : TType { - private static TLong Ins { get; } = new TLong(false, null, false); - - private static TLong NullableIns { get; } = new TLong(true, null, false); - - private static TLong BigIns { get; } = new TLong(false, null, true); - - private static TLong NullableBigIns { get; } = new TLong(true, null, true); - public static TLong Create(bool isNullable, Dictionary tags, bool isBigInt) { - if (tags == null) - { - return isNullable ? NullableIns : Ins; - } - else - { - return new TLong(isNullable, tags, isBigInt); - } + return new TLong(isNullable, tags, isBigInt); } public bool IsBigInt { get; } diff --git a/src/Luban.Job.Common/Source/Types/TMap.cs b/src/Luban.Job.Common/Source/Types/TMap.cs index dc4969d..ce48958 100644 --- a/src/Luban.Job.Common/Source/Types/TMap.cs +++ b/src/Luban.Job.Common/Source/Types/TMap.cs @@ -1,3 +1,4 @@ +using Luban.Job.Common.Defs; using Luban.Job.Common.TypeVisitors; using System; using System.Collections.Generic; @@ -33,6 +34,30 @@ namespace Luban.Job.Common.Types public override bool IsCollection => true; + public override void Compile(DefFieldBase field) + { + base.Compile(field); + + foreach (var p in KeyType.Processors) + { + p.Compile(field); + } + + foreach (var p in ValueType.Processors) + { + p.Compile(field); + } + + if (KeyType is TText) + { + throw new Exception($"bean:{field.HostType.FullName} field:{field.Name} container key type can't be text"); + } + if (ValueType is TText) + { + throw new Exception($"bean:{field.HostType.FullName} field:{field.Name} container value type can't be text"); + } + } + public override void Apply(ITypeActionVisitor visitor, T x) { visitor.Accept(this, x); diff --git a/src/Luban.Job.Common/Source/Types/TSet.cs b/src/Luban.Job.Common/Source/Types/TSet.cs index 942f3bc..22979f1 100644 --- a/src/Luban.Job.Common/Source/Types/TSet.cs +++ b/src/Luban.Job.Common/Source/Types/TSet.cs @@ -1,3 +1,4 @@ +using Luban.Job.Common.Defs; using Luban.Job.Common.TypeVisitors; using System; using System.Collections.Generic; @@ -28,6 +29,25 @@ namespace Luban.Job.Common.Types public override bool IsCollection => true; + public override void Compile(DefFieldBase field) + { + base.Compile(field); + + foreach (var p in ElementType.Processors) + { + p.Compile(field); + } + + if (ElementType is TBean beanType) + { + throw new Exception($"bean:{field.HostType.FullName} field:{field.Name} element type can't be bean:{beanType.Bean.FullName}"); + } + if (ElementType is TText) + { + throw new Exception($"bean:{field.HostType.FullName} field:{field.Name} container element type can't be text"); + } + } + public override void Apply(ITypeActionVisitor visitor, T x) { visitor.Accept(this, x); diff --git a/src/Luban.Job.Common/Source/Types/TShort.cs b/src/Luban.Job.Common/Source/Types/TShort.cs index d1cda43..f569c09 100644 --- a/src/Luban.Job.Common/Source/Types/TShort.cs +++ b/src/Luban.Job.Common/Source/Types/TShort.cs @@ -5,20 +5,9 @@ namespace Luban.Job.Common.Types { public class TShort : TType { - private static TShort Ins { get; } = new TShort(false, null); - - private static TShort NullableIns { get; } = new TShort(true, null); - public static TShort Create(bool isNullable, Dictionary tags) { - if (tags == null) - { - return isNullable ? NullableIns : Ins; - } - else - { - return new TShort(isNullable, tags); - } + return new TShort(isNullable, tags); } private TShort(bool isNullable, Dictionary tags) : base(isNullable, tags) diff --git a/src/Luban.Job.Common/Source/Types/TString.cs b/src/Luban.Job.Common/Source/Types/TString.cs index 2c1c15a..4bd14a6 100644 --- a/src/Luban.Job.Common/Source/Types/TString.cs +++ b/src/Luban.Job.Common/Source/Types/TString.cs @@ -5,20 +5,9 @@ namespace Luban.Job.Common.Types { public class TString : TType { - private static TString Ins { get; } = new TString(false, null); - - private static TString NullableIns { get; } = new TString(true, null); - public static TString Create(bool isNullable, Dictionary tags) { - if (tags == null) - { - return isNullable ? NullableIns : Ins; - } - else - { - return new TString(isNullable, tags); - } + return new TString(isNullable, tags); } private TString(bool isNullable, Dictionary tags) : base(isNullable, tags) diff --git a/src/Luban.Job.Common/Source/Types/TText.cs b/src/Luban.Job.Common/Source/Types/TText.cs index 0f92348..ccbe80b 100644 --- a/src/Luban.Job.Common/Source/Types/TText.cs +++ b/src/Luban.Job.Common/Source/Types/TText.cs @@ -7,20 +7,9 @@ namespace Luban.Job.Common.Types { public const string L10N_FIELD_SUFFIX = "_l10n_key"; - private static TText Ins { get; } = new TText(false, null); - - private static TText NullableIns { get; } = new TText(true, null); - public static TText Create(bool isNullable, Dictionary tags) { - if (tags == null) - { - return isNullable ? NullableIns : Ins; - } - else - { - return new TText(isNullable, tags); - } + return new TText(isNullable, tags); } private TText(bool isNullable, Dictionary tags) : base(isNullable, tags) diff --git a/src/Luban.Job.Common/Source/Types/TType.cs b/src/Luban.Job.Common/Source/Types/TType.cs index 370cb66..b31174b 100644 --- a/src/Luban.Job.Common/Source/Types/TType.cs +++ b/src/Luban.Job.Common/Source/Types/TType.cs @@ -15,7 +15,7 @@ namespace Luban.Job.Common.Types protected TType(bool isNullable, Dictionary tags) { IsNullable = isNullable; - Tags = tags; + Tags = tags ?? new Dictionary(); } public bool HasTag(string attrName) @@ -30,6 +30,14 @@ namespace Luban.Job.Common.Types public abstract bool TryParseFrom(string s); + public virtual void Compile(DefFieldBase field) + { + foreach (var p in Processors) + { + p.Compile(field); + } + } + public virtual bool IsCollection => false; public virtual bool IsBean => false; diff --git a/src/Luban.Job.Common/Source/Types/TVector2.cs b/src/Luban.Job.Common/Source/Types/TVector2.cs index 0a6cb58..6a599a1 100644 --- a/src/Luban.Job.Common/Source/Types/TVector2.cs +++ b/src/Luban.Job.Common/Source/Types/TVector2.cs @@ -6,20 +6,9 @@ namespace Luban.Job.Common.Types { public class TVector2 : TType { - private static TVector2 Ins { get; } = new TVector2(false, null); - - private static TVector2 NullableIns { get; } = new TVector2(true, null); - public static TVector2 Create(bool isNullable, Dictionary tags) { - if (tags == null) - { - return isNullable ? NullableIns : Ins; - } - else - { - return new TVector2(isNullable, tags); - } + return new TVector2(isNullable, tags); } private TVector2(bool isNullable, Dictionary tags) : base(isNullable, tags) diff --git a/src/Luban.Job.Common/Source/Types/TVector3.cs b/src/Luban.Job.Common/Source/Types/TVector3.cs index 0c84385..ab2afcb 100644 --- a/src/Luban.Job.Common/Source/Types/TVector3.cs +++ b/src/Luban.Job.Common/Source/Types/TVector3.cs @@ -6,20 +6,9 @@ namespace Luban.Job.Common.Types { public class TVector3 : TType { - private static TVector3 Ins { get; } = new TVector3(false, null); - - private static TVector3 NullableIns { get; } = new TVector3(true, null); - public static TVector3 Create(bool isNullable, Dictionary tags) { - if (tags == null) - { - return isNullable ? NullableIns : Ins; - } - else - { - return new TVector3(isNullable, tags); - } + return new TVector3(isNullable, tags); } private TVector3(bool isNullable, Dictionary tags) : base(isNullable, tags) diff --git a/src/Luban.Job.Common/Source/Types/TVector4.cs b/src/Luban.Job.Common/Source/Types/TVector4.cs index 63ff5f3..89b8c0d 100644 --- a/src/Luban.Job.Common/Source/Types/TVector4.cs +++ b/src/Luban.Job.Common/Source/Types/TVector4.cs @@ -6,20 +6,9 @@ namespace Luban.Job.Common.Types { public class TVector4 : TType { - private static TVector4 Ins { get; } = new TVector4(false, null); - - private static TVector4 NullableIns { get; } = new TVector4(true, null); - public static TVector4 Create(bool isNullable, Dictionary tags) { - if (tags == null) - { - return isNullable ? NullableIns : Ins; - } - else - { - return new TVector4(isNullable, tags); - } + return new TVector4(isNullable, tags); } private TVector4(bool isNullable, Dictionary tags) : base(isNullable, tags)