using Serein.Library; using Serein.Library.Utils; using Serein.Script.Node; using Serein.Script.Node.FlowControl; using Serein.Script.Symbol; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reactive; using System.Reflection; using System.Reflection.Emit; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; namespace Serein.Script { /// /// 脚本类型分析 /// public class SereinScriptTypeAnalysis { /// /// 符号表 /// public Dictionary NodeSymbolInfos { get; } = new Dictionary(); /// /// 记录方法节点是否需要进行异步调用 /// public Dictionary AsyncMethods { get; } = new Dictionary(); public void Reset() { NodeSymbolInfos.Clear(); // 清空符号表 AsyncMethods.Clear(); } public void LoadSymbol(Dictionary identifierNodes) { foreach(var kvp in identifierNodes) { var name = kvp.Key; var type = kvp.Value; var identifierNode = new IdentifierNode(name); NodeSymbolInfos[identifierNode] = type; } } public void Analysis(ProgramNode astNode) { //NodeSymbolInfos.Clear(); for (int i = 0; i < astNode.Statements.Count; i++) { var node = astNode.Statements[i]; Analysis(node); } var returnNodes = NodeSymbolInfos.Keys.Where(node => node is ReturnNode).ToArray(); 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 { var firstReturnType = NodeSymbolInfos[returnNodes[0]]; // 第一个返回值 foreach(var item in returnNodes) { if(NodeSymbolInfos[item] != firstReturnType) { throw new Exception("类型检查异常,存在不同分支返回值类型不一致"); } } NodeSymbolInfos[astNode] = NodeSymbolInfos[returnNodes[0]]; // 确定的返回值 } } /// /// 类型获取 /// /// /// /// /// private Type Analysis(ASTNode node) { switch (node) { case ProgramNode programNode: // 程序开始节点 NodeSymbolInfos[programNode] = typeof(void); return typeof(void); case ReturnNode returnNode: // 程序退出节点 Type AnalysisReturnNode(ReturnNode returnNode) { var resultType = Analysis(returnNode.Value); NodeSymbolInfos[returnNode.Value] = resultType; NodeSymbolInfos[returnNode] = resultType; return resultType; } return AnalysisReturnNode(returnNode); 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: // 变量定义 Type AnalysisIdentifierNode(IdentifierNode identifierNode) { 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; } return AnalysisIdentifierNode(identifierNode); case IfNode ifNode: // if语句结构 Type AnalysisIfNode(IfNode ifNode) { var conditionType = Analysis(ifNode.Condition); // 获取条件语句部分的返回类型 NodeSymbolInfos[ifNode.Condition] = conditionType; if (conditionType == typeof(bool?) || conditionType == typeof(bool)) { foreach (var item in ifNode.TrueBranch) { var itemType = Analysis(item); // 解析真分支的语句块 NodeSymbolInfos[item] = itemType; } foreach (var item in ifNode.FalseBranch) { var itemType = Analysis(item); // 解析假分支的语句块 NodeSymbolInfos[item] = itemType; } NodeSymbolInfos[ifNode] = typeof(void); return typeof(void); // if语句不产生类型 } else { throw new NotImplementedException("if...else...条件返回值不为布尔类型变量"); } } return AnalysisIfNode(ifNode); case WhileNode whileNode: // while语句结构 Type AnalysisWhileNode(WhileNode whileNode) { var conditionType = Analysis(whileNode.Condition); // 获取条件语句部分的返回类型 NodeSymbolInfos[whileNode.Condition] = conditionType; if (conditionType == typeof(bool?) || conditionType == typeof(bool)) { foreach (var item in whileNode.Body) { var itemType = Analysis(item); // 解析真分支的语句块 NodeSymbolInfos[item] = itemType; } NodeSymbolInfos[whileNode] = typeof(void); // while流程不产生类型 return typeof(void); // if语句不产生类型 } else { throw new NotImplementedException("if...else...条件返回值不为布尔类型变量"); } } return AnalysisWhileNode(whileNode); case AssignmentNode assignmentNode: // 对象赋值语句(let x;默认赋值null。默认类型object) Type AnalysisAssignmentNode(AssignmentNode assignmentNode) { var targetType = Analysis(assignmentNode.Target); var valueType = Analysis (assignmentNode.Value); if (!targetType.IsAssignableFrom(valueType)) throw new Exception($"赋值类型不匹配:需要 {targetType},实际为 {valueType}"); NodeSymbolInfos[assignmentNode.Value] = valueType; NodeSymbolInfos[assignmentNode.Target] = valueType; NodeSymbolInfos[assignmentNode] = typeof(void); // 赋值语句不产生类型 return targetType; } return AnalysisAssignmentNode(assignmentNode); case BinaryOperationNode binaryOperationNode: // 二元运算操作 Type AnalysisBinaryOperationNode(BinaryOperationNode binaryOperationNode) { var leftType = Analysis(binaryOperationNode.Left); // 递归判断左值类型 var rightType = Analysis(binaryOperationNode.Right); // 递归判断右值类型 var op = binaryOperationNode.Operator; var resultType = BinaryOperationEvaluator.EvaluateType(leftType, op, rightType); NodeSymbolInfos[binaryOperationNode.Left] = leftType; NodeSymbolInfos[binaryOperationNode.Right] = rightType; NodeSymbolInfos[binaryOperationNode] = resultType; return resultType; } return AnalysisBinaryOperationNode(binaryOperationNode); case CollectionIndexNode collectionIndexNode: // 集合类型操作,获取集合操作后返回的类型 Type AnalysisCollectionIndexNode(CollectionIndexNode collectionIndexNode) { var collectionType = Analysis(collectionIndexNode.Collection); // 分析集合类型(变量,对象成员) var indexExprType = Analysis(collectionIndexNode.Index); // 分析索引类型 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; } return AnalysisCollectionIndexNode(collectionIndexNode); 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); case ClassTypeDefinitionNode classTypeDefinitionNode: // 类型定义 Type AnalysisClassTypeDefinitionNode(ClassTypeDefinitionNode classTypeDefinitionNode) { 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; } NodeSymbolInfos[classTypeDefinitionNode] = classType; return classType; } return AnalysisClassTypeDefinitionNode(classTypeDefinitionNode); case TypeNode typeNode: Type AnalysisTypeNode(TypeNode typeNode) { // 类型搜寻优先级: 挂载类型 > 脚本中定义类型 > C#类型 Type resultType = GetTypeOfString(typeNode.TypeName); // 从自定义类型查询类型 NodeSymbolInfos[typeNode] = resultType; return resultType; } return AnalysisTypeNode(typeNode); case ObjectInstantiationNode objectInstantiationNode: // 类型实例化 Type AnalysisObjectInstantiationNode(ObjectInstantiationNode objectInstantiationNode) { Type resultType = Analysis(objectInstantiationNode.Type); foreach(var item in objectInstantiationNode.CtorAssignments) { Analysis(item); } NodeSymbolInfos[objectInstantiationNode] = resultType; return resultType; } return AnalysisObjectInstantiationNode(objectInstantiationNode); 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); /*case ExpressionNode expressionNode: // 类型表达式(链式调用) Type AnalysisObjectMemberExpressionNode(ExpressionNode expressionNode) { // 1. 对象成员获取 MemberAccessNode // 2. 对象方法调用 MemberFunctionCallNode // 3. 对象集合成员获取 CollectionIndexNode Type? resultType = Analysis(expressionNode.Value); NodeSymbolInfos[expressionNode.Value] = resultType; NodeSymbolInfos[expressionNode] = resultType; return resultType; } return AnalysisObjectMemberExpressionNode(expressionNode);*/ case MemberAccessNode memberAccessNode: // 对象成员访问 Type AnalysisMemberAccessNode(MemberAccessNode memberAccessNode) { var objectType = Analysis(memberAccessNode.Object); 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; } return AnalysisMemberAccessNode(memberAccessNode); case MemberAssignmentNode memberAssignmentNode: // 对象成员赋值 Type AnalysisMemberAssignmentNode(MemberAssignmentNode memberAssignmentNode) { var objectType = Analysis(memberAssignmentNode.Object); 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); } return typeof(void); // 对象成员赋值语句不产生类型 } return AnalysisMemberAssignmentNode(memberAssignmentNode); case MemberFunctionCallNode memberFunctionCallNode: // 对象方法调用 Type AnalysisMemberFunctionCallNode(MemberFunctionCallNode memberFunctionCallNode) { var objectType = Analysis(memberFunctionCallNode.Object); var types = memberFunctionCallNode.Arguments.Select(arg => Analysis(arg)).ToArray(); 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; } var isAsync = EmitHelper.IsGenericTask(methodInfo.ReturnType, out var taskResult); var methodReturnType = isAsync ? taskResult : methodInfo.ReturnType; AsyncMethods[memberFunctionCallNode] = isAsync; NodeSymbolInfos[memberFunctionCallNode.Object] = objectType; NodeSymbolInfos[memberFunctionCallNode] = methodReturnType; return methodReturnType; } return AnalysisMemberFunctionCallNode(memberFunctionCallNode); case FunctionCallNode functionCallNode: // 外部挂载的函数调用 Type AnalysisFunctionCallNode(FunctionCallNode functionCallNode) { if(!SereinScript.FunctionInfos.TryGetValue(functionCallNode.FunctionName, out var methodInfo)) { throw new Exception($"脚本没有挂载方法 {functionCallNode.FunctionName}"); } var types = functionCallNode.Arguments.Select(arg => Analysis(arg)).ToArray(); for (int index = 0; index < functionCallNode.Arguments.Count; index++) { ASTNode argNode = functionCallNode.Arguments[index]; Type argType = types[index]; NodeSymbolInfos[argNode] = argType; } var isAsync = EmitHelper.IsGenericTask(methodInfo.ReturnType, out var taskResult); var methodReturnType = isAsync ? taskResult : methodInfo.ReturnType; AsyncMethods[functionCallNode] = isAsync; NodeSymbolInfos[functionCallNode] = methodReturnType; return methodReturnType; } return AnalysisFunctionCallNode(functionCallNode); default: // 未定义的节点类型 break; } throw new NotImplementedException(); } /// /// 类型分析 /// /// /// 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; /* case ExpressionNode expressionNode: // 类型表达式(链式调用) Analysis(expressionNode.Value); break;*/ 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; } } private void ToILCompiler(ASTNode node) { 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; case CollectionAssignmentNode collectionAssignmentNode: break; case CollectionIndexNode collectionIndexNode: // 集合类型操作 break; case ClassTypeDefinitionNode classTypeDefinitionNode: // 类型定义 break; case TypeNode typeNode: // 类型 break; case ObjectInstantiationNode objectInstantiationNode: // 类型实例化 break; case CtorAssignmentNode ctorAssignmentNode: // 构造器赋值 break; case MemberAccessNode memberAccessNode: // 对象成员访问 break; case MemberAssignmentNode memberAssignmentNode: // 对象成员赋值 break; case MemberFunctionCallNode memberFunctionCallNode: // 对象方法调用 break; case FunctionCallNode functionCallNode: // 外部挂载的函数调用 break; default: // 未定义的节点类型 break; } } public static Type GetTypeOfString(string typeName) { Type? resultType = null; resultType = DynamicObjectHelper.GetCacheType(typeName); // 从自定义类型查询类型 if (resultType != null) { return resultType; } resultType = Type.GetType(typeName); // 从命名空间查询类型 if (resultType != null) { return resultType; } throw new InvalidOperationException($"无法匹配类型 {typeName}"); } /// /// 获取某个集合类型支持的索引参数类型 /// /// 集合类型 /// 索引 /// 获取到的类型 /// 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 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 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() .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; } } } /* 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}"); } }*/