From 5c561fc69c7bba8c5fead507a1244e1abca4943a Mon Sep 17 00:00:00 2001 From: ninemine <1371605831@qq.com> Date: Mon, 27 Oct 2025 10:48:19 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9EUndefinedIdentifiersAsStrings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MemberElements/FunctionCall.cs | 26 ++++++++++++++++++- .../MemberElements/Identifier.cs | 21 +++++++++++++++ PublicTypes/ExpressionOptions.cs | 10 +++++++ 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/ExpressionElements/MemberElements/FunctionCall.cs b/ExpressionElements/MemberElements/FunctionCall.cs index f89fe39..cfe0c94 100644 --- a/ExpressionElements/MemberElements/FunctionCall.cs +++ b/ExpressionElements/MemberElements/FunctionCall.cs @@ -218,11 +218,15 @@ namespace Flee.ExpressionElements.MemberElements return; } + // 允许void返回类型的函数,将其返回值视为0 + // Void return type functions are allowed and treated as returning 0 + /* // Any function reference in an expression must return a value if (object.ReferenceEquals(this.Method.ReturnType, typeof(void))) { base.ThrowCompileException("FunctionHasNoReturnValue", CompileExceptionReason.FunctionHasNoReturnValue, MyName); } + */ } public override void Emit(FleeILGenerator ilg, IServiceProvider services) @@ -342,7 +346,21 @@ namespace Flee.ExpressionElements.MemberElements this.EmitParamArrayArguments(parameters, elements, ilg, services); } - MemberElement.EmitMethodCall(this.ResultType, nextRequiresAddress, this.Method, ilg); + // 检查方法是否返回void + bool isVoidMethod = object.ReferenceEquals(this.Method.ReturnType, typeof(void)); + + if (isVoidMethod) + { + // 对于void方法,使用原始的ReturnType调用方法,然后将0压入栈 + MemberElement.EmitMethodCall(this.Method.ReturnType, nextRequiresAddress, this.Method, ilg); + // 将0压入栈作为返回值 + ilg.Emit(OpCodes.Ldc_I4_0); + } + else + { + // 对于非void方法,正常调用 + MemberElement.EmitMethodCall(this.ResultType, nextRequiresAddress, this.Method, ilg); + } } private void EmitExtensionFunctionInternal(ParameterInfo[] parameters, ExpressionElement[] elements, FleeILGenerator ilg, IServiceProvider services) @@ -397,6 +415,12 @@ namespace Flee.ExpressionElements.MemberElements } else { + // 如果方法返回void,将其视为返回int类型(值为0) + // If method returns void, treat it as returning int (value 0) + if (object.ReferenceEquals(this.Method.ReturnType, typeof(void))) + { + return typeof(int); + } return this.Method.ReturnType; } } diff --git a/ExpressionElements/MemberElements/Identifier.cs b/ExpressionElements/MemberElements/Identifier.cs index 734461d..e8f0918 100644 --- a/ExpressionElements/MemberElements/Identifier.cs +++ b/ExpressionElements/MemberElements/Identifier.cs @@ -25,6 +25,7 @@ namespace Flee.ExpressionElements.MemberElements private PropertyDescriptor _myPropertyDescriptor; private Type _myVariableType; private Type _myCalcEngineReferenceType; + private bool _isStringLiteral; public IdentifierElement(string name) { this.MyName = name; @@ -60,6 +61,13 @@ namespace Flee.ExpressionElements.MemberElements if (MyPrevious == null) { + // 检查是否启用了未定义标识符作为字符串的选项 + if (MyOptions.UndefinedIdentifiersAsStrings) + { + // 将此标识符标记为字符串字面量 + _isStringLiteral = true; + return; + } base.ThrowCompileException("NoIdentifierWithName", CompileExceptionReason.UndefinedName, MyName); } else @@ -140,6 +148,13 @@ namespace Flee.ExpressionElements.MemberElements { base.Emit(ilg, services); + // 如果是字符串字面量,直接发出字符串加载指令 + if (_isStringLiteral) + { + ilg.Emit(OpCodes.Ldstr, MyName); + return; + } + this.EmitFirst(ilg); if ((_myCalcEngineReferenceType != null)) @@ -354,6 +369,12 @@ namespace Flee.ExpressionElements.MemberElements { get { + // 如果是字符串字面量,返回 string 类型 + if (_isStringLiteral) + { + return typeof(string); + } + if ((_myCalcEngineReferenceType != null)) { return _myCalcEngineReferenceType; diff --git a/PublicTypes/ExpressionOptions.cs b/PublicTypes/ExpressionOptions.cs index 288c616..c1eb386 100644 --- a/PublicTypes/ExpressionOptions.cs +++ b/PublicTypes/ExpressionOptions.cs @@ -36,6 +36,7 @@ namespace Flee.PublicTypes _myProperties.SetToDefault("ResultType"); _myProperties.SetToDefault("IsGeneric"); _myProperties.SetToDefault("IntegersAsDoubles"); + _myProperties.SetToDefault("UndefinedIdentifiersAsStrings"); _myProperties.SetValue("ParseCulture", CultureInfo.CurrentCulture); this.SetParseCulture(this.ParseCulture); _myProperties.SetValue("RealLiteralDataType", RealLiteralDataType.Double); @@ -149,6 +150,15 @@ namespace Flee.PublicTypes get { return _myProperties.GetValue("RealLiteralDataType"); } set { _myProperties.SetValue("RealLiteralDataType", value); } } + + /// + /// 当标识符未定义时,是否自动将其转换为字符串字面量 + /// + public bool UndefinedIdentifiersAsStrings + { + get { return _myProperties.GetValue("UndefinedIdentifiersAsStrings"); } + set { _myProperties.SetValue("UndefinedIdentifiersAsStrings", value); } + } #endregion #region "Properties - Non Public"