diff --git a/config/Datas/test/test_null.xlsx b/config/Datas/test/test_null.xlsx new file mode 100644 index 0000000..3e79a4e Binary files /dev/null and b/config/Datas/test/test_null.xlsx differ diff --git a/config/Defines/test.xml b/config/Defines/test.xml index 812bbb3..0cca258 100644 --- a/config/Defines/test.xml +++ b/config/Defines/test.xml @@ -185,6 +185,16 @@ + + + + + + + + +
+ @@ -199,4 +209,5 @@
+ \ No newline at end of file diff --git a/src/Luban.Job.Cfg/Luban.Job.Cfg.csproj b/src/Luban.Job.Cfg/Luban.Job.Cfg.csproj index b269046..edfff9c 100644 --- a/src/Luban.Job.Cfg/Luban.Job.Cfg.csproj +++ b/src/Luban.Job.Cfg/Luban.Job.Cfg.csproj @@ -20,4 +20,8 @@ + + + + diff --git a/src/Luban.Job.Cfg/Source/DataVisitors/BinaryExportor.cs b/src/Luban.Job.Cfg/Source/DataVisitors/BinaryExportor.cs index 4927196..66fe3d6 100644 --- a/src/Luban.Job.Cfg/Source/DataVisitors/BinaryExportor.cs +++ b/src/Luban.Job.Cfg/Source/DataVisitors/BinaryExportor.cs @@ -94,12 +94,12 @@ namespace Luban.Job.Cfg.DataVisitors var bean = type.Type; if (bean.IsAbstractType) { - // null 时特殊处理 - if (type.ImplType == null) - { - x.WriteInt(0); - return; - } + // 调整设计后,多态bean不会为空 + //if (type.ImplType == null) + //{ + // x.WriteInt(0); + // return; + //} x.WriteInt(type.ImplType.Id); } int index = -1; @@ -111,8 +111,7 @@ namespace Luban.Job.Cfg.DataVisitors { continue; } - - if (defField.CType.Apply(NeedMarshalBoolPrefixVisitor.Ins)) + if (defField.CType.IsNullable) { if (field != null) { diff --git a/src/Luban.Job.Cfg/Source/DataVisitors/ValidatorVisitor.cs b/src/Luban.Job.Cfg/Source/DataVisitors/ValidatorVisitor.cs index 8ef1d2a..72e2cec 100644 --- a/src/Luban.Job.Cfg/Source/DataVisitors/ValidatorVisitor.cs +++ b/src/Luban.Job.Cfg/Source/DataVisitors/ValidatorVisitor.cs @@ -113,7 +113,7 @@ namespace Luban.Job.Cfg.DataVisitors public void Accept(DBean record, DefAssembly assembly) { - if (record.ImplType == null) + if (record == null) { return; } diff --git a/src/Luban.Job.Cfg/Source/Defs/DefBean.cs b/src/Luban.Job.Cfg/Source/Defs/DefBean.cs index 1167453..0f2fd48 100644 --- a/src/Luban.Job.Cfg/Source/Defs/DefBean.cs +++ b/src/Luban.Job.Cfg/Source/Defs/DefBean.cs @@ -12,6 +12,9 @@ namespace Luban.Job.Cfg.Defs { public const string TYPE_NAME_KEY = "__type__"; + public const string BEAN_NULL_STR = "{null}"; + + public const string BEAN_NOT_NULL_STR = "{}"; public string Alias { get; } diff --git a/src/Luban.Job.Cfg/Source/Defs/TTypeTemplateExtends.cs b/src/Luban.Job.Cfg/Source/Defs/TTypeTemplateExtends.cs index e3874bc..7965864 100644 --- a/src/Luban.Job.Cfg/Source/Defs/TTypeTemplateExtends.cs +++ b/src/Luban.Job.Cfg/Source/Defs/TTypeTemplateExtends.cs @@ -87,7 +87,7 @@ namespace Luban.Job.Cfg.Defs { var name = field.CsStyleName; TType type = field.CType; - if (field.CType.Apply(NeedMarshalBoolPrefixVisitor.Ins)) + if (field.CType.IsNullable) { return $"{{ var _exists bool; if _exists, err = {bufName}.ReadBool(); err != nil {{ return }}; if _exists {{ if _v.{name}, err = {type.Apply(GoDeserializeVisitor.Ins, bufName)}; err != nil {{ return }} }} }}"; } diff --git a/src/Luban.Job.Cfg/Source/Generate/CppBinCodeRender.cs b/src/Luban.Job.Cfg/Source/Generate/CppBinCodeRender.cs index 172f904..a0ea147 100644 --- a/src/Luban.Job.Cfg/Source/Generate/CppBinCodeRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/CppBinCodeRender.cs @@ -233,7 +233,6 @@ namespace {{x.top_module}} if (!_buf.readInt(id)) return false; switch (id) { - case 0 : { _out = nullptr; return true; } {{- for child in type.hierarchy_not_abstract_children}} case {{child.cpp_full_name}}::ID: { _out = new {{child.cpp_full_name}}(); if (_out->deserialize(_buf)) { return true; } else { delete _out; _out = nullptr; return false;} } {{-end}} diff --git a/src/Luban.Job.Cfg/Source/Generate/CsBinCodeRender.cs b/src/Luban.Job.Cfg/Source/Generate/CsBinCodeRender.cs index 855f2b3..9e2ecb9 100644 --- a/src/Luban.Job.Cfg/Source/Generate/CsBinCodeRender.cs +++ b/src/Luban.Job.Cfg/Source/Generate/CsBinCodeRender.cs @@ -59,7 +59,6 @@ public {{x.cs_class_modifier}} partial class {{name}} : {{if parent_def_type}} { {{if x.is_abstract_type}} switch (_buf.ReadInt()) { - case 0 : return null; {{- for child in x.hierarchy_not_abstract_children}} case {{child.full_name}}.ID: return new {{child.full_name}}(_buf); {{-end}} diff --git a/src/Luban.Job.Cfg/Source/TypeVisitors/ExcelDataCreator.cs b/src/Luban.Job.Cfg/Source/TypeVisitors/ExcelDataCreator.cs index 681cee2..2a53971 100644 --- a/src/Luban.Job.Cfg/Source/TypeVisitors/ExcelDataCreator.cs +++ b/src/Luban.Job.Cfg/Source/TypeVisitors/ExcelDataCreator.cs @@ -327,9 +327,13 @@ namespace Luban.Job.Cfg.TypeVisitors if (originBean.IsAbstractType) { string subType = x.Read().ToString(); - if (subType.ToLower().Trim() == "null") + if (subType.ToLower().Trim() == DefBean.BEAN_NULL_STR) { - return new DBean(originBean, null, null); + if (!type.IsNullable) + { + throw new InvalidExcelDataException($"type:{type.Bean.FullName}不是可空类型. 不能为空"); + } + return null; } string fullType = TypeUtil.MakeFullName(originBean.Namespace, subType); DefBean implType = (DefBean)originBean.GetNotAbstractChildType(subType); @@ -341,6 +345,18 @@ namespace Luban.Job.Cfg.TypeVisitors } else { + if (type.IsNullable) + { + string subType = x.Read().ToString().Trim(); + if (subType == DefBean.BEAN_NULL_STR) + { + return null; + } + else if (subType != DefBean.BEAN_NOT_NULL_STR) + { + throw new Exception($"type:{type.Bean.FullName} 可空标识 不合法(只能为{DefBean.BEAN_NOT_NULL_STR}或{DefBean.BEAN_NULL_STR})"); + } + } return new DBean(originBean, originBean, CreateBeanFields(originBean, x, ass)); } } diff --git a/src/Luban.Job.Cfg/Source/TypeVisitors/ExcelNamedRowDataCreator.cs b/src/Luban.Job.Cfg/Source/TypeVisitors/ExcelNamedRowDataCreator.cs index 0c7bf7b..2f4be6e 100644 --- a/src/Luban.Job.Cfg/Source/TypeVisitors/ExcelNamedRowDataCreator.cs +++ b/src/Luban.Job.Cfg/Source/TypeVisitors/ExcelNamedRowDataCreator.cs @@ -2,6 +2,7 @@ using Luban.Common.Utils; using Luban.Job.Cfg.Datas; using Luban.Job.Cfg.DataSources.Excel; using Luban.Job.Cfg.Defs; +using Luban.Job.Cfg.TypeVisitors; using Luban.Job.Common.Types; using Luban.Job.Common.TypeVisitors; using System; @@ -175,15 +176,20 @@ namespace Luban.Job.Cfg.TypeVisitors return list; } + public DType Accept(TBean type, Sheet.NamedRow row, bool multirow, bool nullable) { var originBean = (DefBean)type.Bean; if (originBean.IsAbstractType) { string subType = row.GetColumn(DefBean.TYPE_NAME_KEY, null, true).Read().ToString().Trim(); - if (subType.ToLower() == "null") + if (subType.ToLower() == DefBean.BEAN_NULL_STR) { - return new DBean(originBean, null, null); + if (!type.IsNullable) + { + throw new Exception($"type:{type} 不是可空类型 {type.Bean.FullName}? , 不能为空"); + } + return null; } string fullType = TypeUtil.MakeFullName(originBean.Namespace, subType); DefBean implType = (DefBean)originBean.GetNotAbstractChildType(subType); @@ -195,6 +201,19 @@ namespace Luban.Job.Cfg.TypeVisitors } else { + if (type.IsNullable) + { + string subType = row.GetColumn(DefBean.TYPE_NAME_KEY, null, true).Read().ToString().Trim(); + if (subType == DefBean.BEAN_NULL_STR) + { + return null; + } + else if (subType != DefBean.BEAN_NOT_NULL_STR) + { + throw new Exception($"type:{type.Bean.FullName} {DefBean.TYPE_NAME_KEY} 不合法(只能为{DefBean.BEAN_NOT_NULL_STR}或{DefBean.BEAN_NULL_STR})"); + } + } + return new DBean(originBean, originBean, CreateBeanFields(originBean, row)); } } diff --git a/src/Luban.Job.Common/Source/Defs/TTypeTemplateCommonExtends.cs b/src/Luban.Job.Common/Source/Defs/TTypeTemplateCommonExtends.cs index 2116ae3..af1490e 100644 --- a/src/Luban.Job.Common/Source/Defs/TTypeTemplateCommonExtends.cs +++ b/src/Luban.Job.Common/Source/Defs/TTypeTemplateCommonExtends.cs @@ -13,7 +13,7 @@ namespace Luban.Job.Common.Defs public static bool NeedMarshalBoolPrefix(TType type) { - return type.Apply(NeedMarshalBoolPrefixVisitor.Ins); + return type.IsNullable; } public static bool CsNeedInit(TType type) diff --git a/src/Luban.Job.Common/Source/TypeVisitors/CsDeserializeVisitor.cs b/src/Luban.Job.Common/Source/TypeVisitors/CsDeserializeVisitor.cs index 7861796..f52514d 100644 --- a/src/Luban.Job.Common/Source/TypeVisitors/CsDeserializeVisitor.cs +++ b/src/Luban.Job.Common/Source/TypeVisitors/CsDeserializeVisitor.cs @@ -19,9 +19,9 @@ namespace Luban.Job.Common.TypeVisitors } } - public override string Accept(TBean type, string bufName, string fieldName) - { - return type.Apply(CsUnderingDeserializeVisitor.Ins, bufName, fieldName); - } + //public override string Accept(TBean type, string bufName, string fieldName) + //{ + // return type.Apply(CsUnderingDeserializeVisitor.Ins, bufName, fieldName); + //} } } diff --git a/src/Luban.Job.Common/Source/TypeVisitors/NeedMarshalBoolPrefixVisitor.cs b/src/Luban.Job.Common/Source/TypeVisitors/NeedMarshalBoolPrefixVisitor.cs index 6a85626..e7bc370 100644 --- a/src/Luban.Job.Common/Source/TypeVisitors/NeedMarshalBoolPrefixVisitor.cs +++ b/src/Luban.Job.Common/Source/TypeVisitors/NeedMarshalBoolPrefixVisitor.cs @@ -2,13 +2,13 @@ using Luban.Job.Common.Types; namespace Luban.Job.Common.TypeVisitors { - public class NeedMarshalBoolPrefixVisitor : DecoratorFuncVisitor - { - public static NeedMarshalBoolPrefixVisitor Ins { get; } = new NeedMarshalBoolPrefixVisitor(); + //public class NeedMarshalBoolPrefixVisitor : DecoratorFuncVisitor + //{ + // //public static NeedMarshalBoolPrefixVisitor Ins { get; } = new NeedMarshalBoolPrefixVisitor(); - public override bool DoAccept(TType type) - { - return type.IsNullable && !(type is TBean bean && bean.IsDynamic); - } - } + // public override bool DoAccept(TType type) + // { + // return type.IsNullable && !(type is TBean bean && bean.IsDynamic); + // } + //} } diff --git a/src/Luban.Job.Common/Source/Types/TBean.cs b/src/Luban.Job.Common/Source/Types/TBean.cs index de09636..789f0e4 100644 --- a/src/Luban.Job.Common/Source/Types/TBean.cs +++ b/src/Luban.Job.Common/Source/Types/TBean.cs @@ -10,8 +10,7 @@ namespace Luban.Job.Common.Types public T GetBeanAs() where T : DefBeanBase => (T)Bean; - // TODO bean 允许指定是否可空 - public TBean(DefBeanBase defBean, bool isNullable) : base(defBean.IsAbstractType) + public TBean(DefBeanBase defBean, bool isNullable) : base(isNullable) { this.Bean = defBean; }