2025-07-11 20:52:21 +08:00
|
|
|
|
using Serein.Library;
|
|
|
|
|
|
using Serein.Library.Utils;
|
2025-07-09 21:49:26 +08:00
|
|
|
|
using Serein.Script.Node;
|
2025-07-13 17:34:03 +08:00
|
|
|
|
using Serein.Script.Node.FlowControl;
|
2025-07-09 21:49:26 +08:00
|
|
|
|
using Serein.Script.Symbol;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
2025-07-23 15:57:57 +08:00
|
|
|
|
using System.Diagnostics.CodeAnalysis;
|
2025-07-09 21:49:26 +08:00
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Reactive;
|
2025-07-11 20:52:21 +08:00
|
|
|
|
using System.Reflection;
|
2025-07-16 16:16:19 +08:00
|
|
|
|
using System.Reflection.Emit;
|
2025-07-09 21:49:26 +08:00
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
using System.Xml.Linq;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Serein.Script
|
|
|
|
|
|
{
|
2025-07-11 20:52:21 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 脚本类型分析
|
|
|
|
|
|
/// </summary>
|
2025-07-09 21:49:26 +08:00
|
|
|
|
public class SereinScriptTypeAnalysis
|
|
|
|
|
|
{
|
2025-07-11 23:43:27 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 符号表
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public Dictionary<ASTNode, Type> NodeSymbolInfos { get; } = new Dictionary<ASTNode, Type>();
|
2025-07-09 21:49:26 +08:00
|
|
|
|
|
2025-07-23 15:57:57 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 记录方法节点是否需要进行异步调用
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public Dictionary<ASTNode, bool> AsyncMethods { get; } = new Dictionary<ASTNode, bool>();
|
|
|
|
|
|
|
|
|
|
|
|
public void Reset()
|
|
|
|
|
|
{
|
|
|
|
|
|
NodeSymbolInfos.Clear(); // 清空符号表
|
|
|
|
|
|
AsyncMethods.Clear();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-13 17:34:03 +08:00
|
|
|
|
public void LoadSymbol(Dictionary<string,Type> identifierNodes)
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach(var kvp in identifierNodes)
|
|
|
|
|
|
{
|
|
|
|
|
|
var name = kvp.Key;
|
|
|
|
|
|
var type = kvp.Value;
|
|
|
|
|
|
var identifierNode = new IdentifierNode(name);
|
|
|
|
|
|
NodeSymbolInfos[identifierNode] = type;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-07-16 16:16:19 +08:00
|
|
|
|
public void Analysis(ProgramNode astNode)
|
2025-07-11 20:52:21 +08:00
|
|
|
|
{
|
2025-07-13 17:34:03 +08:00
|
|
|
|
//NodeSymbolInfos.Clear();
|
2025-07-11 20:52:21 +08:00
|
|
|
|
for (int i = 0; i < astNode.Statements.Count; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
var node = astNode.Statements[i];
|
|
|
|
|
|
Analysis(node);
|
|
|
|
|
|
}
|
2025-07-11 23:43:27 +08:00
|
|
|
|
|
2025-07-16 16:16:19 +08:00
|
|
|
|
|
|
|
|
|
|
var returnNodes = NodeSymbolInfos.Keys.Where(node => node is ReturnNode).ToArray();
|
2025-07-11 20:52:21 +08:00
|
|
|
|
if (returnNodes.Length == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
NodeSymbolInfos[astNode] = typeof(void); // 程序无返回值
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (returnNodes.Length == 1)
|
|
|
|
|
|
{
|
|
|
|
|
|
var ifNodes = astNode.Statements.Where(node => node is IfNode).ToArray();
|
|
|
|
|
|
|
|
|
|
|
|
NodeSymbolInfos[astNode] = NodeSymbolInfos[returnNodes[0]]; // 确定的返回值
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2025-07-16 16:16:19 +08:00
|
|
|
|
var firstReturnType = NodeSymbolInfos[returnNodes[0]]; // 第一个返回值
|
|
|
|
|
|
foreach(var item in returnNodes)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(NodeSymbolInfos[item] != firstReturnType)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new Exception("类型检查异常,存在不同分支返回值类型不一致");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
NodeSymbolInfos[astNode] = NodeSymbolInfos[returnNodes[0]]; // 确定的返回值
|
2025-07-11 20:52:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-07-11 23:43:27 +08:00
|
|
|
|
|
2025-07-23 15:57:57 +08:00
|
|
|
|
|
2025-07-11 23:43:27 +08:00
|
|
|
|
|
2025-07-11 20:52:21 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 类型获取
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="node"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
/// <exception cref="Exception"></exception>
|
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
2025-07-11 23:43:27 +08:00
|
|
|
|
private Type Analysis(ASTNode node)
|
2025-07-11 20:52:21 +08:00
|
|
|
|
{
|
|
|
|
|
|
switch (node)
|
|
|
|
|
|
{
|
|
|
|
|
|
case ProgramNode programNode: // 程序开始节点
|
|
|
|
|
|
NodeSymbolInfos[programNode] = typeof(void);
|
|
|
|
|
|
return typeof(void);
|
|
|
|
|
|
case ReturnNode returnNode: // 程序退出节点
|
2025-07-11 23:43:27 +08:00
|
|
|
|
Type AnalysisReturnNode(ReturnNode returnNode)
|
2025-07-11 20:52:21 +08:00
|
|
|
|
{
|
2025-07-11 23:43:27 +08:00
|
|
|
|
var resultType = Analysis(returnNode.Value);
|
2025-07-11 20:52:21 +08:00
|
|
|
|
NodeSymbolInfos[returnNode.Value] = resultType;
|
|
|
|
|
|
NodeSymbolInfos[returnNode] = resultType;
|
|
|
|
|
|
return resultType;
|
|
|
|
|
|
}
|
2025-07-11 23:43:27 +08:00
|
|
|
|
return AnalysisReturnNode(returnNode);
|
2025-07-11 20:52:21 +08:00
|
|
|
|
case NullNode nullNode: // null
|
|
|
|
|
|
NodeSymbolInfos[nullNode] = typeof(object);
|
|
|
|
|
|
return typeof(object);
|
|
|
|
|
|
case CharNode charNode: // char字面量
|
|
|
|
|
|
NodeSymbolInfos[charNode] = typeof(char);
|
|
|
|
|
|
return typeof(char);
|
|
|
|
|
|
case StringNode stringNode: // 字符串字面量
|
|
|
|
|
|
NodeSymbolInfos[stringNode] = typeof(string);
|
|
|
|
|
|
return typeof(string);
|
|
|
|
|
|
case BooleanNode booleanNode: // 布尔值字面量
|
|
|
|
|
|
NodeSymbolInfos[booleanNode] = typeof(bool);
|
|
|
|
|
|
return typeof(bool);
|
|
|
|
|
|
case NumberIntNode numberIntNode: // int整型数值字面量
|
|
|
|
|
|
NodeSymbolInfos[numberIntNode] = typeof(int);
|
|
|
|
|
|
return typeof(int);
|
|
|
|
|
|
case NumberLongNode numberLongNode: // long整型数值字面量
|
|
|
|
|
|
NodeSymbolInfos[numberLongNode] = typeof(long);
|
|
|
|
|
|
return typeof(long);
|
|
|
|
|
|
case NumberFloatNode numberFloatNode: // float浮点数值字面量
|
|
|
|
|
|
NodeSymbolInfos[numberFloatNode] = typeof(float);
|
|
|
|
|
|
return typeof(float);
|
|
|
|
|
|
case NumberDoubleNode numberDoubleNode: // double浮点数值字面量
|
|
|
|
|
|
NodeSymbolInfos[numberDoubleNode] = typeof(double);
|
|
|
|
|
|
return typeof(double);
|
|
|
|
|
|
case IdentifierNode identifierNode: // 变量定义
|
2025-07-11 23:43:27 +08:00
|
|
|
|
Type AnalysisIdentifierNode(IdentifierNode identifierNode)
|
2025-07-11 20:52:21 +08:00
|
|
|
|
{
|
|
|
|
|
|
var cacheNode = NodeSymbolInfos.Keys.FirstOrDefault(n => n is IdentifierNode idNode && idNode.Name == identifierNode.Name);
|
|
|
|
|
|
Type type = cacheNode is null ? typeof(object) : NodeSymbolInfos[cacheNode];
|
|
|
|
|
|
NodeSymbolInfos[identifierNode] = type;
|
|
|
|
|
|
return type;
|
|
|
|
|
|
}
|
2025-07-11 23:43:27 +08:00
|
|
|
|
return AnalysisIdentifierNode(identifierNode);
|
2025-07-11 20:52:21 +08:00
|
|
|
|
case IfNode ifNode: // if语句结构
|
2025-07-11 23:43:27 +08:00
|
|
|
|
Type AnalysisIfNode(IfNode ifNode)
|
2025-07-11 20:52:21 +08:00
|
|
|
|
{
|
2025-07-11 23:43:27 +08:00
|
|
|
|
var conditionType = Analysis(ifNode.Condition); // 获取条件语句部分的返回类型
|
2025-07-11 20:52:21 +08:00
|
|
|
|
NodeSymbolInfos[ifNode.Condition] = conditionType;
|
|
|
|
|
|
if (conditionType == typeof(bool?) || conditionType == typeof(bool))
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var item in ifNode.TrueBranch)
|
|
|
|
|
|
{
|
2025-07-11 23:43:27 +08:00
|
|
|
|
var itemType = Analysis(item); // 解析真分支的语句块
|
2025-07-11 20:52:21 +08:00
|
|
|
|
NodeSymbolInfos[item] = itemType;
|
|
|
|
|
|
}
|
|
|
|
|
|
foreach (var item in ifNode.FalseBranch)
|
|
|
|
|
|
{
|
2025-07-11 23:43:27 +08:00
|
|
|
|
var itemType = Analysis(item); // 解析假分支的语句块
|
2025-07-11 20:52:21 +08:00
|
|
|
|
NodeSymbolInfos[item] = itemType;
|
|
|
|
|
|
}
|
|
|
|
|
|
NodeSymbolInfos[ifNode] = typeof(void);
|
|
|
|
|
|
return typeof(void); // if语句不产生类型
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new NotImplementedException("if...else...条件返回值不为布尔类型变量");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-07-11 23:43:27 +08:00
|
|
|
|
return AnalysisIfNode(ifNode);
|
2025-07-11 20:52:21 +08:00
|
|
|
|
case WhileNode whileNode: // while语句结构
|
2025-07-11 23:43:27 +08:00
|
|
|
|
Type AnalysisWhileNode(WhileNode whileNode)
|
2025-07-11 20:52:21 +08:00
|
|
|
|
{
|
2025-07-11 23:43:27 +08:00
|
|
|
|
var conditionType = Analysis(whileNode.Condition); // 获取条件语句部分的返回类型
|
2025-07-11 20:52:21 +08:00
|
|
|
|
NodeSymbolInfos[whileNode.Condition] = conditionType;
|
|
|
|
|
|
if (conditionType == typeof(bool?) || conditionType == typeof(bool))
|
|
|
|
|
|
{
|
|
|
|
|
|
foreach (var item in whileNode.Body)
|
|
|
|
|
|
{
|
2025-07-11 23:43:27 +08:00
|
|
|
|
var itemType = Analysis(item); // 解析真分支的语句块
|
2025-07-11 20:52:21 +08:00
|
|
|
|
NodeSymbolInfos[item] = itemType;
|
|
|
|
|
|
}
|
|
|
|
|
|
NodeSymbolInfos[whileNode] = typeof(void); // while流程不产生类型
|
|
|
|
|
|
return typeof(void); // if语句不产生类型
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
throw new NotImplementedException("if...else...条件返回值不为布尔类型变量");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-07-11 23:43:27 +08:00
|
|
|
|
return AnalysisWhileNode(whileNode);
|
2025-07-11 20:52:21 +08:00
|
|
|
|
case AssignmentNode assignmentNode:
|
|
|
|
|
|
// 对象赋值语句(let x;默认赋值null。默认类型object)
|
2025-07-11 23:43:27 +08:00
|
|
|
|
Type AnalysisAssignmentNode(AssignmentNode assignmentNode)
|
2025-07-11 20:52:21 +08:00
|
|
|
|
{
|
2025-07-11 23:43:27 +08:00
|
|
|
|
var targetType = Analysis(assignmentNode.Target);
|
|
|
|
|
|
var valueType = Analysis (assignmentNode.Value);
|
2025-07-11 20:52:21 +08:00
|
|
|
|
if (!targetType.IsAssignableFrom(valueType))
|
2025-07-29 14:25:31 +08:00
|
|
|
|
throw new Exception($"赋值类型不匹配:需要 {targetType},实际为 {valueType}");
|
2025-07-11 20:52:21 +08:00
|
|
|
|
NodeSymbolInfos[assignmentNode.Value] = valueType;
|
|
|
|
|
|
NodeSymbolInfos[assignmentNode.Target] = valueType;
|
|
|
|
|
|
NodeSymbolInfos[assignmentNode] = typeof(void); // 赋值语句不产生类型
|
|
|
|
|
|
return targetType;
|
|
|
|
|
|
}
|
2025-07-11 23:43:27 +08:00
|
|
|
|
return AnalysisAssignmentNode(assignmentNode);
|
2025-07-11 20:52:21 +08:00
|
|
|
|
case BinaryOperationNode binaryOperationNode: // 二元运算操作
|
2025-07-11 23:43:27 +08:00
|
|
|
|
Type AnalysisBinaryOperationNode(BinaryOperationNode binaryOperationNode)
|
2025-07-11 20:52:21 +08:00
|
|
|
|
{
|
2025-07-11 23:43:27 +08:00
|
|
|
|
var leftType = Analysis(binaryOperationNode.Left); // 递归判断左值类型
|
|
|
|
|
|
var rightType = Analysis(binaryOperationNode.Right); // 递归判断右值类型
|
2025-07-11 20:52:21 +08:00
|
|
|
|
var op = binaryOperationNode.Operator;
|
|
|
|
|
|
var resultType = BinaryOperationEvaluator.EvaluateType(leftType, op, rightType);
|
|
|
|
|
|
NodeSymbolInfos[binaryOperationNode.Left] = leftType;
|
|
|
|
|
|
NodeSymbolInfos[binaryOperationNode.Right] = rightType;
|
|
|
|
|
|
NodeSymbolInfos[binaryOperationNode] = resultType;
|
|
|
|
|
|
return resultType;
|
|
|
|
|
|
}
|
2025-07-11 23:43:27 +08:00
|
|
|
|
return AnalysisBinaryOperationNode(binaryOperationNode);
|
2025-07-11 20:52:21 +08:00
|
|
|
|
case CollectionIndexNode collectionIndexNode: // 集合类型操作,获取集合操作后返回的类型
|
2025-07-11 23:43:27 +08:00
|
|
|
|
Type AnalysisCollectionIndexNode(CollectionIndexNode collectionIndexNode)
|
2025-07-11 20:52:21 +08:00
|
|
|
|
{
|
2025-07-11 23:43:27 +08:00
|
|
|
|
var collectionType = Analysis(collectionIndexNode.Collection); // 分析集合类型(变量,对象成员)
|
|
|
|
|
|
var indexExprType = Analysis(collectionIndexNode.Index); // 分析索引类型
|
2025-07-11 20:52:21 +08:00
|
|
|
|
if (!TryGetIndexerType(collectionType, out var expectedIndexType, out var resultType))
|
|
|
|
|
|
throw new Exception($"类型 {collectionType} 不支持索引操作");
|
|
|
|
|
|
|
|
|
|
|
|
if (!expectedIndexType.IsAssignableFrom(indexExprType))
|
|
|
|
|
|
throw new Exception($"索引类型不匹配:需要 {expectedIndexType},实际为 {indexExprType}");
|
|
|
|
|
|
NodeSymbolInfos[collectionIndexNode.Collection] = collectionType;
|
|
|
|
|
|
NodeSymbolInfos[collectionIndexNode.Index] = indexExprType;
|
|
|
|
|
|
NodeSymbolInfos[collectionIndexNode] = resultType;
|
|
|
|
|
|
return resultType;
|
|
|
|
|
|
}
|
2025-07-11 23:43:27 +08:00
|
|
|
|
return AnalysisCollectionIndexNode(collectionIndexNode);
|
2025-07-13 17:34:03 +08:00
|
|
|
|
case CollectionAssignmentNode collectionAssignmentNode: // 集合赋值操作
|
|
|
|
|
|
Type AnalysisCollectionAssignmentNode(CollectionAssignmentNode collectionAssignmentNode)
|
|
|
|
|
|
{
|
|
|
|
|
|
var resultType = Analysis(collectionAssignmentNode.Collection); // 分析集合返回返回类型
|
|
|
|
|
|
var valueType = Analysis(collectionAssignmentNode.Value); // 分析赋值的类型
|
|
|
|
|
|
if (!resultType.IsAssignableFrom(valueType))
|
|
|
|
|
|
throw new Exception($"类型 {resultType} 不支持索引操作");
|
|
|
|
|
|
|
|
|
|
|
|
NodeSymbolInfos[collectionAssignmentNode.Collection] = resultType;
|
|
|
|
|
|
NodeSymbolInfos[collectionAssignmentNode.Value] = valueType;
|
|
|
|
|
|
NodeSymbolInfos[collectionAssignmentNode] = typeof(void); // 赋值语句不产生类型
|
|
|
|
|
|
return typeof(void);
|
|
|
|
|
|
}
|
|
|
|
|
|
return AnalysisCollectionAssignmentNode(collectionAssignmentNode);
|
2025-07-11 20:52:21 +08:00
|
|
|
|
case ClassTypeDefinitionNode classTypeDefinitionNode: // 类型定义
|
2025-07-11 23:43:27 +08:00
|
|
|
|
Type AnalysisClassTypeDefinitionNode(ClassTypeDefinitionNode classTypeDefinitionNode)
|
2025-07-11 20:52:21 +08:00
|
|
|
|
{
|
2025-07-16 16:16:19 +08:00
|
|
|
|
|
|
|
|
|
|
var classType = Analysis(classTypeDefinitionNode.ClassType); // 查询类型
|
|
|
|
|
|
NodeSymbolInfos[classTypeDefinitionNode] = classType;
|
|
|
|
|
|
|
|
|
|
|
|
foreach (var kvp in classTypeDefinitionNode.Propertys)
|
|
|
|
|
|
{
|
|
|
|
|
|
TypeNode propertyNode = kvp.Value;
|
|
|
|
|
|
var propertyType = Analysis(propertyNode); // 查询属性类型
|
|
|
|
|
|
NodeSymbolInfos[propertyNode] = propertyType;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-11 20:52:21 +08:00
|
|
|
|
NodeSymbolInfos[classTypeDefinitionNode] = classType;
|
|
|
|
|
|
return classType;
|
|
|
|
|
|
}
|
2025-07-11 23:43:27 +08:00
|
|
|
|
return AnalysisClassTypeDefinitionNode(classTypeDefinitionNode);
|
2025-07-16 16:16:19 +08:00
|
|
|
|
case TypeNode typeNode:
|
|
|
|
|
|
Type AnalysisTypeNode(TypeNode typeNode)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 类型搜寻优先级: 挂载类型 > 脚本中定义类型 > C#类型
|
|
|
|
|
|
Type resultType = GetTypeOfString(typeNode.TypeName); // 从自定义类型查询类型
|
|
|
|
|
|
NodeSymbolInfos[typeNode] = resultType;
|
|
|
|
|
|
return resultType;
|
|
|
|
|
|
}
|
|
|
|
|
|
return AnalysisTypeNode(typeNode);
|
2025-07-11 20:52:21 +08:00
|
|
|
|
case ObjectInstantiationNode objectInstantiationNode: // 类型实例化
|
2025-07-11 23:43:27 +08:00
|
|
|
|
Type AnalysisObjectInstantiationNode(ObjectInstantiationNode objectInstantiationNode)
|
2025-07-11 20:52:21 +08:00
|
|
|
|
{
|
2025-07-16 16:16:19 +08:00
|
|
|
|
Type resultType = Analysis(objectInstantiationNode.Type);
|
|
|
|
|
|
foreach(var item in objectInstantiationNode.CtorAssignments)
|
2025-07-11 20:52:21 +08:00
|
|
|
|
{
|
2025-07-16 16:16:19 +08:00
|
|
|
|
Analysis(item);
|
2025-07-11 20:52:21 +08:00
|
|
|
|
}
|
|
|
|
|
|
NodeSymbolInfos[objectInstantiationNode] = resultType;
|
|
|
|
|
|
return resultType;
|
|
|
|
|
|
}
|
2025-07-11 23:43:27 +08:00
|
|
|
|
return AnalysisObjectInstantiationNode(objectInstantiationNode);
|
2025-07-16 16:16:19 +08:00
|
|
|
|
case CtorAssignmentNode ctorAssignmentNode: // 构造器赋值
|
|
|
|
|
|
Type AnalysisCtorAssignmentNode(CtorAssignmentNode ctorAssignmentNode)
|
|
|
|
|
|
{
|
|
|
|
|
|
Type classType = Analysis(ctorAssignmentNode.Class);
|
|
|
|
|
|
Type valueType = Analysis(ctorAssignmentNode.Value);
|
|
|
|
|
|
//ctorAssignmentNode.MemberName
|
|
|
|
|
|
var property = classType.GetProperty(ctorAssignmentNode.MemberName);
|
|
|
|
|
|
if (property is null)
|
|
|
|
|
|
throw new Exception($"类型 {classType} 没有成员 {ctorAssignmentNode.MemberName}");
|
|
|
|
|
|
var propertyType = property.PropertyType;
|
|
|
|
|
|
if (!propertyType.IsAssignableFrom(valueType))
|
|
|
|
|
|
throw new Exception($"类型异常:构造器赋值需要 {propertyType},实际为 {valueType}");
|
|
|
|
|
|
|
|
|
|
|
|
NodeSymbolInfos[ctorAssignmentNode.Class] = classType;
|
|
|
|
|
|
NodeSymbolInfos[ctorAssignmentNode.Value] = valueType;
|
|
|
|
|
|
NodeSymbolInfos[ctorAssignmentNode] = propertyType;
|
|
|
|
|
|
return valueType;
|
|
|
|
|
|
}
|
|
|
|
|
|
return AnalysisCtorAssignmentNode(ctorAssignmentNode);
|
2025-07-23 15:57:57 +08:00
|
|
|
|
/*case ExpressionNode expressionNode: // 类型表达式(链式调用)
|
2025-07-13 17:34:03 +08:00
|
|
|
|
Type AnalysisObjectMemberExpressionNode(ExpressionNode expressionNode)
|
2025-07-11 20:52:21 +08:00
|
|
|
|
{
|
|
|
|
|
|
// 1. 对象成员获取 MemberAccessNode
|
|
|
|
|
|
// 2. 对象方法调用 MemberFunctionCallNode
|
|
|
|
|
|
// 3. 对象集合成员获取 CollectionIndexNode
|
2025-07-13 17:34:03 +08:00
|
|
|
|
Type? resultType = Analysis(expressionNode.Value);
|
|
|
|
|
|
NodeSymbolInfos[expressionNode.Value] = resultType;
|
|
|
|
|
|
NodeSymbolInfos[expressionNode] = resultType;
|
2025-07-11 20:52:21 +08:00
|
|
|
|
return resultType;
|
|
|
|
|
|
}
|
2025-07-23 15:57:57 +08:00
|
|
|
|
return AnalysisObjectMemberExpressionNode(expressionNode);*/
|
2025-07-11 20:52:21 +08:00
|
|
|
|
case MemberAccessNode memberAccessNode: // 对象成员访问
|
2025-07-11 23:43:27 +08:00
|
|
|
|
Type AnalysisMemberAccessNode(MemberAccessNode memberAccessNode)
|
2025-07-11 20:52:21 +08:00
|
|
|
|
{
|
2025-07-11 23:43:27 +08:00
|
|
|
|
var objectType = Analysis(memberAccessNode.Object);
|
2025-07-11 20:52:21 +08:00
|
|
|
|
var property = objectType.GetProperty(memberAccessNode.MemberName);
|
|
|
|
|
|
if (property is null)
|
|
|
|
|
|
throw new Exception($"类型 {objectType} 没有成员 {memberAccessNode.MemberName}");
|
|
|
|
|
|
NodeSymbolInfos[memberAccessNode.Object] = objectType;
|
|
|
|
|
|
NodeSymbolInfos[memberAccessNode] = property.PropertyType;
|
|
|
|
|
|
return property.PropertyType;
|
|
|
|
|
|
}
|
2025-07-11 23:43:27 +08:00
|
|
|
|
return AnalysisMemberAccessNode(memberAccessNode);
|
2025-07-11 20:52:21 +08:00
|
|
|
|
case MemberAssignmentNode memberAssignmentNode: // 对象成员赋值
|
2025-07-11 23:43:27 +08:00
|
|
|
|
Type AnalysisMemberAssignmentNode(MemberAssignmentNode memberAssignmentNode)
|
2025-07-11 20:52:21 +08:00
|
|
|
|
{
|
2025-07-11 23:43:27 +08:00
|
|
|
|
var objectType = Analysis(memberAssignmentNode.Object);
|
2025-07-16 16:16:19 +08:00
|
|
|
|
if(objectType == typeof(object))
|
|
|
|
|
|
{
|
|
|
|
|
|
/*var property = objectType.GetProperty(memberAssignmentNode.MemberName);
|
|
|
|
|
|
if (property is null)
|
|
|
|
|
|
throw new Exception($"类型异常:类型 {objectType} 没有成员 {memberAssignmentNode.MemberName}");
|
|
|
|
|
|
var propertyType = property.PropertyType;
|
|
|
|
|
|
var valueType = Analysis(memberAssignmentNode.Value);
|
|
|
|
|
|
if (!propertyType.IsAssignableFrom(valueType))
|
|
|
|
|
|
throw new Exception($"类型异常:赋值需要 {propertyType},实际为 {valueType}");*/
|
|
|
|
|
|
NodeSymbolInfos[memberAssignmentNode.Object] = typeof(object);
|
|
|
|
|
|
NodeSymbolInfos[memberAssignmentNode.Value] = typeof(object);
|
|
|
|
|
|
NodeSymbolInfos[memberAssignmentNode] = typeof(void);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
var property = objectType.GetProperty(memberAssignmentNode.MemberName);
|
|
|
|
|
|
if (property is null)
|
|
|
|
|
|
throw new Exception($"类型异常:类型 {objectType} 没有成员 {memberAssignmentNode.MemberName}");
|
|
|
|
|
|
var propertyType = property.PropertyType;
|
|
|
|
|
|
var valueType = Analysis(memberAssignmentNode.Value);
|
|
|
|
|
|
if (!propertyType.IsAssignableFrom(valueType))
|
|
|
|
|
|
throw new Exception($"类型异常:赋值需要 {propertyType},实际为 {valueType}");
|
|
|
|
|
|
NodeSymbolInfos[memberAssignmentNode.Object] = propertyType;
|
|
|
|
|
|
NodeSymbolInfos[memberAssignmentNode.Value] = valueType;
|
|
|
|
|
|
NodeSymbolInfos[memberAssignmentNode] = typeof(void);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-11 20:52:21 +08:00
|
|
|
|
return typeof(void); // 对象成员赋值语句不产生类型
|
|
|
|
|
|
}
|
2025-07-11 23:43:27 +08:00
|
|
|
|
return AnalysisMemberAssignmentNode(memberAssignmentNode);
|
2025-07-11 20:52:21 +08:00
|
|
|
|
case MemberFunctionCallNode memberFunctionCallNode: // 对象方法调用
|
2025-07-11 23:43:27 +08:00
|
|
|
|
Type AnalysisMemberFunctionCallNode(MemberFunctionCallNode memberFunctionCallNode)
|
2025-07-11 20:52:21 +08:00
|
|
|
|
{
|
2025-07-11 23:43:27 +08:00
|
|
|
|
var objectType = Analysis(memberFunctionCallNode.Object);
|
|
|
|
|
|
var types = memberFunctionCallNode.Arguments.Select(arg => Analysis(arg)).ToArray();
|
2025-07-11 20:52:21 +08:00
|
|
|
|
var methodInfo = objectType.GetMethod(memberFunctionCallNode.FunctionName, types);
|
|
|
|
|
|
if (methodInfo is null)
|
|
|
|
|
|
throw new Exception($"类型 {objectType} 没有方法 {memberFunctionCallNode.FunctionName}");
|
|
|
|
|
|
for (int index = 0; index < memberFunctionCallNode.Arguments.Count; index++)
|
|
|
|
|
|
{
|
|
|
|
|
|
ASTNode argNode = memberFunctionCallNode.Arguments[index];
|
|
|
|
|
|
Type argType = types[index];
|
|
|
|
|
|
NodeSymbolInfos[argNode] = argType;
|
|
|
|
|
|
}
|
2025-07-30 21:15:07 +08:00
|
|
|
|
var isAsync = EmitHelper.IsGenericTask(methodInfo.ReturnType, out var taskResult);
|
2025-07-23 15:57:57 +08:00
|
|
|
|
var methodReturnType = isAsync ? taskResult : methodInfo.ReturnType;
|
|
|
|
|
|
AsyncMethods[memberFunctionCallNode] = isAsync;
|
2025-07-11 20:52:21 +08:00
|
|
|
|
NodeSymbolInfos[memberFunctionCallNode.Object] = objectType;
|
2025-07-23 15:57:57 +08:00
|
|
|
|
NodeSymbolInfos[memberFunctionCallNode] = methodReturnType;
|
|
|
|
|
|
return methodReturnType;
|
2025-07-16 16:16:19 +08:00
|
|
|
|
|
|
|
|
|
|
|
2025-07-11 20:52:21 +08:00
|
|
|
|
}
|
2025-07-11 23:43:27 +08:00
|
|
|
|
return AnalysisMemberFunctionCallNode(memberFunctionCallNode);
|
2025-07-11 20:52:21 +08:00
|
|
|
|
case FunctionCallNode functionCallNode: // 外部挂载的函数调用
|
2025-07-11 23:43:27 +08:00
|
|
|
|
Type AnalysisFunctionCallNode(FunctionCallNode functionCallNode)
|
2025-07-11 20:52:21 +08:00
|
|
|
|
{
|
2025-07-16 16:16:19 +08:00
|
|
|
|
if(!SereinScript.FunctionInfos.TryGetValue(functionCallNode.FunctionName, out var methodInfo))
|
2025-07-11 20:52:21 +08:00
|
|
|
|
{
|
|
|
|
|
|
throw new Exception($"脚本没有挂载方法 {functionCallNode.FunctionName}");
|
|
|
|
|
|
}
|
2025-07-11 23:43:27 +08:00
|
|
|
|
var types = functionCallNode.Arguments.Select(arg => Analysis(arg)).ToArray();
|
2025-07-11 20:52:21 +08:00
|
|
|
|
for (int index = 0; index < functionCallNode.Arguments.Count; index++)
|
|
|
|
|
|
{
|
|
|
|
|
|
ASTNode argNode = functionCallNode.Arguments[index];
|
|
|
|
|
|
Type argType = types[index];
|
|
|
|
|
|
NodeSymbolInfos[argNode] = argType;
|
|
|
|
|
|
}
|
2025-07-30 21:15:07 +08:00
|
|
|
|
var isAsync = EmitHelper.IsGenericTask(methodInfo.ReturnType, out var taskResult);
|
2025-07-23 15:57:57 +08:00
|
|
|
|
var methodReturnType = isAsync ? taskResult : methodInfo.ReturnType;
|
|
|
|
|
|
AsyncMethods[functionCallNode] = isAsync;
|
|
|
|
|
|
NodeSymbolInfos[functionCallNode] = methodReturnType;
|
|
|
|
|
|
return methodReturnType;
|
2025-07-11 20:52:21 +08:00
|
|
|
|
}
|
2025-07-11 23:43:27 +08:00
|
|
|
|
return AnalysisFunctionCallNode(functionCallNode);
|
2025-07-11 20:52:21 +08:00
|
|
|
|
default: // 未定义的节点类型
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
throw new NotImplementedException();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-07-13 17:34:03 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 类型分析
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="node"></param>
|
|
|
|
|
|
/// <exception cref="NotImplementedException"></exception>
|
|
|
|
|
|
private void Analysis1(ASTNode node)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (node)
|
|
|
|
|
|
{
|
|
|
|
|
|
case ProgramNode programNode: // 程序开始节点
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ReturnNode returnNode: // 程序退出节点
|
|
|
|
|
|
Analysis(returnNode); // 解析变量定义的类型
|
|
|
|
|
|
break;
|
|
|
|
|
|
case NullNode nullNode: // null
|
|
|
|
|
|
case CharNode charNode: // char字面量
|
|
|
|
|
|
case StringNode stringNode: // 字符串字面量
|
|
|
|
|
|
case BooleanNode booleanNode: // 布尔值字面量
|
|
|
|
|
|
case NumberIntNode numberIntNode: // int整型数值字面量
|
|
|
|
|
|
case NumberLongNode numberLongNode: // long整型数值字面量
|
|
|
|
|
|
case NumberFloatNode numberFloatNode: // float浮点数值字面量
|
|
|
|
|
|
case NumberDoubleNode numberDoubleNode: // double浮点数值字面量
|
|
|
|
|
|
Analysis(node);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case IdentifierNode identifierNode: // 变量定义
|
|
|
|
|
|
void AnalysisIdentifierNode(IdentifierNode identifierNode)
|
|
|
|
|
|
{
|
|
|
|
|
|
Analysis(identifierNode); // 解析变量定义的类型
|
|
|
|
|
|
}
|
|
|
|
|
|
AnalysisIdentifierNode(identifierNode);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case IfNode ifNode: // if语句结构
|
|
|
|
|
|
void AnalysisIfNode(IfNode ifNode)
|
|
|
|
|
|
{
|
|
|
|
|
|
Analysis(ifNode);
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
AnalysisIfNode(ifNode);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case WhileNode whileNode: // while语句结构
|
|
|
|
|
|
void AnalysisWhileNode(WhileNode whileNode)
|
|
|
|
|
|
{
|
|
|
|
|
|
Analysis(whileNode);
|
|
|
|
|
|
}
|
|
|
|
|
|
AnalysisWhileNode(whileNode);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case AssignmentNode assignmentNode: // 对象赋值语句(let x;默认赋值null。默认类型object)
|
|
|
|
|
|
void AnalysisAssignmentNode(AssignmentNode assignmentNode)
|
|
|
|
|
|
{
|
|
|
|
|
|
Analysis(assignmentNode);
|
|
|
|
|
|
}
|
|
|
|
|
|
AnalysisAssignmentNode(assignmentNode);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case BinaryOperationNode binaryOperationNode: // 二元运算操作
|
|
|
|
|
|
void AnalysisBinaryOperationNode(BinaryOperationNode binaryOperationNode)
|
|
|
|
|
|
{
|
|
|
|
|
|
Analysis(binaryOperationNode);
|
|
|
|
|
|
}
|
|
|
|
|
|
AnalysisBinaryOperationNode(binaryOperationNode);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case CollectionIndexNode collectionIndexNode: // 集合类型操作
|
|
|
|
|
|
void AnalysisCollectionIndexNode(CollectionIndexNode collectionIndexNode)
|
|
|
|
|
|
{
|
|
|
|
|
|
Analysis(collectionIndexNode);
|
|
|
|
|
|
}
|
|
|
|
|
|
AnalysisCollectionIndexNode(collectionIndexNode);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ClassTypeDefinitionNode classTypeDefinitionNode: // 类型定义
|
|
|
|
|
|
Analysis(classTypeDefinitionNode);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ObjectInstantiationNode objectInstantiationNode: // 类型实例化
|
|
|
|
|
|
Analysis(objectInstantiationNode);
|
|
|
|
|
|
break;
|
2025-07-23 15:57:57 +08:00
|
|
|
|
/* case ExpressionNode expressionNode: // 类型表达式(链式调用)
|
2025-07-13 17:34:03 +08:00
|
|
|
|
Analysis(expressionNode.Value);
|
2025-07-23 15:57:57 +08:00
|
|
|
|
break;*/
|
2025-07-13 17:34:03 +08:00
|
|
|
|
case MemberAccessNode memberAccessNode: // 对象成员访问
|
|
|
|
|
|
Analysis(memberAccessNode);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case MemberAssignmentNode memberAssignmentNode: // 对象成员赋值
|
|
|
|
|
|
void AnalysisMemberAssignmentNode(MemberAssignmentNode memberAssignmentNode)
|
|
|
|
|
|
{
|
|
|
|
|
|
Analysis(memberAssignmentNode);
|
|
|
|
|
|
}
|
|
|
|
|
|
AnalysisMemberAssignmentNode(memberAssignmentNode);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case MemberFunctionCallNode memberFunctionCallNode: // 对象方法调用
|
|
|
|
|
|
Analysis(memberFunctionCallNode);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case FunctionCallNode functionCallNode: // 外部挂载的函数调用
|
|
|
|
|
|
Analysis(functionCallNode);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default: // 未定义的节点类型
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-07-23 15:57:57 +08:00
|
|
|
|
private void ToILCompiler(ASTNode node)
|
2025-07-11 20:52:21 +08:00
|
|
|
|
{
|
|
|
|
|
|
switch (node)
|
|
|
|
|
|
{
|
|
|
|
|
|
case ProgramNode programNode: // 程序开始节点
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ReturnNode returnNode: // 程序退出节点
|
|
|
|
|
|
break;
|
|
|
|
|
|
case NullNode nullNode: // null
|
|
|
|
|
|
break;
|
|
|
|
|
|
case CharNode charNode: // char字面量
|
|
|
|
|
|
break;
|
|
|
|
|
|
case StringNode stringNode: // 字符串字面量
|
|
|
|
|
|
break;
|
|
|
|
|
|
case BooleanNode booleanNode: // 布尔值字面量
|
|
|
|
|
|
break;
|
|
|
|
|
|
case NumberIntNode numberIntNode: // int整型数值字面量
|
|
|
|
|
|
break;
|
|
|
|
|
|
case NumberLongNode numberLongNode: // long整型数值字面量
|
|
|
|
|
|
break;
|
|
|
|
|
|
case NumberFloatNode numberFloatNode: // float浮点数值字面量
|
|
|
|
|
|
break;
|
|
|
|
|
|
case NumberDoubleNode numberDoubleNode: // double浮点数值字面量
|
|
|
|
|
|
break;
|
|
|
|
|
|
case IdentifierNode identifierNode: // 变量定义
|
|
|
|
|
|
break;
|
|
|
|
|
|
case IfNode ifNode: // if语句结构
|
|
|
|
|
|
break;
|
|
|
|
|
|
case WhileNode whileNode: // while语句结构
|
|
|
|
|
|
break;
|
|
|
|
|
|
case AssignmentNode assignmentNode: // 对象赋值语句(let x;默认赋值null。默认类型object)
|
|
|
|
|
|
break;
|
|
|
|
|
|
case BinaryOperationNode binaryOperationNode: // 二元运算操作
|
|
|
|
|
|
break;
|
2025-07-13 17:34:03 +08:00
|
|
|
|
case CollectionAssignmentNode collectionAssignmentNode:
|
|
|
|
|
|
break;
|
2025-07-11 20:52:21 +08:00
|
|
|
|
case CollectionIndexNode collectionIndexNode: // 集合类型操作
|
|
|
|
|
|
break;
|
|
|
|
|
|
case ClassTypeDefinitionNode classTypeDefinitionNode: // 类型定义
|
|
|
|
|
|
break;
|
2025-07-16 16:16:19 +08:00
|
|
|
|
case TypeNode typeNode: // 类型
|
|
|
|
|
|
break;
|
2025-07-11 20:52:21 +08:00
|
|
|
|
case ObjectInstantiationNode objectInstantiationNode: // 类型实例化
|
|
|
|
|
|
break;
|
2025-07-23 15:57:57 +08:00
|
|
|
|
case CtorAssignmentNode ctorAssignmentNode: // 构造器赋值
|
2025-07-11 20:52:21 +08:00
|
|
|
|
break;
|
|
|
|
|
|
case MemberAccessNode memberAccessNode: // 对象成员访问
|
|
|
|
|
|
break;
|
|
|
|
|
|
case MemberAssignmentNode memberAssignmentNode: // 对象成员赋值
|
|
|
|
|
|
break;
|
|
|
|
|
|
case MemberFunctionCallNode memberFunctionCallNode: // 对象方法调用
|
|
|
|
|
|
break;
|
|
|
|
|
|
case FunctionCallNode functionCallNode: // 外部挂载的函数调用
|
|
|
|
|
|
break;
|
|
|
|
|
|
default: // 未定义的节点类型
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-07-16 16:16:19 +08:00
|
|
|
|
public static Type GetTypeOfString(string typeName)
|
|
|
|
|
|
{
|
|
|
|
|
|
Type? resultType = null;
|
|
|
|
|
|
resultType = DynamicObjectHelper.GetCacheType(typeName); // 从自定义类型查询类型
|
|
|
|
|
|
if (resultType != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return resultType;
|
|
|
|
|
|
}
|
2025-07-30 21:15:07 +08:00
|
|
|
|
resultType = Type.GetType(typeName); // 从命名空间查询类型
|
|
|
|
|
|
if (resultType != null)
|
2025-07-16 16:16:19 +08:00
|
|
|
|
{
|
2025-07-30 21:15:07 +08:00
|
|
|
|
return resultType;
|
2025-07-16 16:16:19 +08:00
|
|
|
|
}
|
2025-07-30 21:15:07 +08:00
|
|
|
|
throw new InvalidOperationException($"无法匹配类型 {typeName}");
|
2025-07-16 16:16:19 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-07-30 21:15:07 +08:00
|
|
|
|
|
2025-07-13 17:34:03 +08:00
|
|
|
|
|
2025-07-11 20:52:21 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取某个集合类型支持的索引参数类型
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="collectionType">集合类型</param>
|
|
|
|
|
|
/// <param name="indexType">索引</param>
|
|
|
|
|
|
/// <param name="resultType">获取到的类型</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static bool TryGetIndexerType(Type collectionType, out Type indexType, out Type resultType)
|
|
|
|
|
|
{
|
|
|
|
|
|
indexType = null!;
|
|
|
|
|
|
resultType = null!;
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否是数组
|
|
|
|
|
|
if (collectionType.IsArray)
|
|
|
|
|
|
{
|
|
|
|
|
|
indexType = typeof(int);
|
|
|
|
|
|
resultType = collectionType.GetElementType()!;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否实现 IDictionary<K, V>
|
|
|
|
|
|
var dictInterface = collectionType
|
|
|
|
|
|
.GetInterfaces()
|
|
|
|
|
|
.FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDictionary<,>));
|
|
|
|
|
|
|
|
|
|
|
|
if (dictInterface != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var args = dictInterface.GetGenericArguments();
|
|
|
|
|
|
indexType = args[0]; // Key
|
|
|
|
|
|
resultType = args[1]; // Value
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否实现 IList<T>
|
|
|
|
|
|
var listInterface = collectionType
|
|
|
|
|
|
.GetInterfaces()
|
|
|
|
|
|
.FirstOrDefault(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>));
|
|
|
|
|
|
|
|
|
|
|
|
if (listInterface != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
indexType = typeof(int);
|
|
|
|
|
|
resultType = listInterface.GetGenericArguments()[0];
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 检查是否有索引器属性
|
|
|
|
|
|
var indexer = collectionType
|
|
|
|
|
|
.GetDefaultMembers()
|
|
|
|
|
|
.OfType<PropertyInfo>()
|
|
|
|
|
|
.FirstOrDefault(p =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var args = p.GetIndexParameters();
|
|
|
|
|
|
return args.Length == 1;
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (indexer != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
var param = indexer.GetIndexParameters()[0];
|
|
|
|
|
|
indexType = param.ParameterType;
|
|
|
|
|
|
resultType = indexer.PropertyType;
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-07-09 21:49:26 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-07-11 20:52:21 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
case NullNode nullNode: // 返回null
|
|
|
|
|
|
case BooleanNode booleanNode: // 返回布尔
|
|
|
|
|
|
case NumberIntNode numberNode: // 数值
|
|
|
|
|
|
case StringNode stringNode: // 字符串
|
|
|
|
|
|
case CharNode charNode: // char
|
|
|
|
|
|
case IdentifierNode identifierNode: // 定义变量
|
|
|
|
|
|
case AssignmentNode assignmentNode: // 赋值行为
|
|
|
|
|
|
case BinaryOperationNode binOpNode: // 递归计算二元操作
|
|
|
|
|
|
case ObjectInstantiationNode objectInstantiationNode: // 创建对象
|
|
|
|
|
|
case FunctionCallNode callNode: // 调用方法
|
|
|
|
|
|
case MemberFunctionCallNode memberFunctionCallNode: // 对象方法调用
|
|
|
|
|
|
case MemberAccessNode memberAccessNode: // 对象成员访问
|
|
|
|
|
|
case CollectionIndexNode collectionIndexNode:
|
|
|
|
|
|
case ReturnNode returnNode: // 返回内容
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
|
|
|
|
|
*/
|
|
|
|
|
|
/* if (SymbolInfos.TryGetValue(varName, out var symbolInfo))
|
|
|
|
|
|
{
|
|
|
|
|
|
var state = symbolInfo.Type.IsAssignableFrom(type);
|
|
|
|
|
|
if (!state)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 错误:变量[{varName}]赋值异常,[{type.FullName}]无法转换为[{symbolInfo.Type.FullName}]
|
|
|
|
|
|
//SereinEnv.WriteLine(InfoType.ERROR, $"[{type.FullName}]无法转化为[{symbolInfo.Type.FullName}]。源代码:{assignmentNode.Code.Replace(Environment.NewLine,"")} [行{assignmentNode.Row}]");
|
|
|
|
|
|
SereinEnv.WriteLine(InfoType.ERROR, $"类型异常:无法赋值变量[{varName}],因为[{type.FullName}]无法转化为[{symbolInfo.Type.FullName}]。在[行{assignmentNode.Row}]:{assignmentNode.Code}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}*/
|