using FlutterCodeGenerator.Helper; using FlutterCodeGenerator.Map.Interface; using FlutterCodeGenerator.Model; using FlutterCodeGenerator.ModelTypes; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; namespace FlutterCodeGenerator.Map { internal class ServiceMap : IServiceMap { private List _userDefinedComplexReturnTypeList; private List _methodMapList; public string ServiceName { get; private set; } public List UsedComplexModelTypeList { get; } public bool HasMethod => _methodMapList.Count > 0; public ServiceMap(Type type, bool isFISLib) { ServiceName = type.Name[1..]; UsedComplexModelTypeList = new List(); GenerateDataCache.Instance.SetCurrentServiceMap(this); _methodMapList = new List(); var methodsList = type.GetMethods().ToList(); var eventList = type.GetEvents().ToList(); var eventMethodList = new List(); foreach (var eventType in eventList) { eventMethodList.Add(eventType.RemoveMethod); eventMethodList.Add(eventType.AddMethod); } methodsList = methodsList.Where(x => !eventMethodList.Contains(x)).ToList();//将Event的Method屏蔽 if (isFISLib) { methodsList = methodsList.Where(x => x.CustomAttributes.Any(y => y.AttributeType.FullName == "FISLib.FISAttribute" && y.ConstructorArguments.FirstOrDefault().ArgumentType == typeof(string) && (string)y.ConstructorArguments.FirstOrDefault().Value == "ForFlutter")).ToList(); } foreach (var method in methodsList) { var methodMap = new MethodMap(method); _methodMapList.Add(methodMap); } } public string GetServiceModelDartString() { var dartString = new StringBuilder(); var importServiceList = new List(); var alreadyGeneratedList = GenerateDataCache.Instance.AlreadyGeneratedList; foreach (var modelType in UsedComplexModelTypeList) { if (!alreadyGeneratedList.Any(x => x.Key.ParameterType.Name == modelType.ParameterType.Name && x.Key.ParameterType.Namespace == modelType.ParameterType.Namespace)) { alreadyGeneratedList.Add(modelType, ServiceName); dartString.AppendLine(modelType.GetDartString()); } else { var importService = alreadyGeneratedList.FirstOrDefault(x => x.Key.ParameterType.Name == modelType.ParameterType.Name && x.Key.ParameterType.Namespace == modelType.ParameterType.Namespace).Value; if (importService == null) { throw new Exception("Import Service is null"); } if (importService != ServiceName && !importServiceList.Contains(importService)) { importServiceList.Add(importService); } } } if (string.IsNullOrWhiteSpace(dartString.ToString())) { return null; } var serviceModelDartString = new StringBuilder(); foreach (var importService in importServiceList) { serviceModelDartString.AppendLine($"import '{LetterConverterHelper.FirstCharToLower(importService[0..^7])}.m.dart';"); } if (importServiceList.Count > 0) { serviceModelDartString.AppendLine(); } var dartStringInfo = dartString.ToString(); if (dartStringInfo.Contains("JsonRpcUtils")) { serviceModelDartString.AppendLine(CommonParameters.StringUtils); serviceModelDartString.AppendLine(); } if (dartStringInfo.Contains("jsonDecode")) { serviceModelDartString.AppendLine(CommonParameters.StringDartConvert); serviceModelDartString.AppendLine(); } if (dartStringInfo.Contains("FJsonConvert")) { serviceModelDartString.AppendLine(CommonParameters.StringJsonConvert); serviceModelDartString.AppendLine(); } serviceModelDartString.AppendLine(dartStringInfo); return serviceModelDartString.ToString(); } public string GetServiceDartString() { var serviceDartString = new StringBuilder(); var importServiceList = new List(); var alreadyGeneratedList = GenerateDataCache.Instance.AlreadyGeneratedList; foreach (var methodMap in _methodMapList) { GenerateDataCache.Instance.CurrentMethod = methodMap.MethodName; string importService = null; foreach (var modelType in methodMap.ParameterModelTypes) { if (modelType is ComplexModelType) { importService = alreadyGeneratedList.FirstOrDefault(x => x.Key.ParameterType.Name == modelType.ParameterType.Name && x.Key.ParameterType.Namespace == modelType.ParameterType.Namespace).Value; if (importService == null) { throw new Exception("Import Service is null"); } if (importService != ServiceName && !importServiceList.Contains(importService)) { importServiceList.Add(importService); } } } var returnModelType = methodMap.ReturnParameterModelType; if (returnModelType is ComplexModelType) { importService = alreadyGeneratedList.FirstOrDefault(x => x.Key.ParameterType.Name == returnModelType.ParameterType.Name && x.Key.ParameterType.Namespace == returnModelType.ParameterType.Namespace).Value; if (importService == null) { throw new Exception("Import Service is null"); } if (importService != ServiceName && !importServiceList.Contains(importService)) { importServiceList.Add(importService); } } else if (returnModelType is ListModelType listModelType) { var subReturnType = listModelType.GenericArgumentModelType; if (subReturnType is ComplexModelType) { importService = alreadyGeneratedList.FirstOrDefault(x => x.Key.ParameterType.Name == subReturnType.ParameterType.Name && x.Key.ParameterType.Namespace == subReturnType.ParameterType.Namespace).Value; if (importService == null) { throw new Exception("Import Service is null"); } if (importService != ServiceName && !importServiceList.Contains(importService)) { importServiceList.Add(importService); } } } else if (returnModelType is ArrayModelType arrayModelType) { var subReturnType = arrayModelType.Child; if (subReturnType is ComplexModelType) { importService = alreadyGeneratedList.FirstOrDefault(x => x.Key.ParameterType.Name == subReturnType.ParameterType.Name && x.Key.ParameterType.Namespace == subReturnType.ParameterType.Namespace).Value; if (importService == null) { throw new Exception("Import Service is null"); } if (importService != ServiceName && !importServiceList.Contains(importService)) { importServiceList.Add(importService); } } } else if (returnModelType is DictionaryModelType dictionaryModelType) { foreach (var subReturnType in dictionaryModelType.GenericArgumentModelTypeList) { if (subReturnType is ComplexModelType) { importService = alreadyGeneratedList.FirstOrDefault(x => x.Key.ParameterType.Name == subReturnType.ParameterType.Name && x.Key.ParameterType.Namespace == subReturnType.ParameterType.Namespace).Value; if (importService == null) { throw new Exception("Import Service is null"); } if (importService != ServiceName && !importServiceList.Contains(importService)) { importServiceList.Add(importService); } } } } } var complexReturnTypeNameList = GetUserDefinedComplexReturnTypeList(); foreach (var complexReturnTypeName in complexReturnTypeNameList) { string importService; if (complexReturnTypeName.Contains("<")) { var returnTypeName = complexReturnTypeName.Substring(0, complexReturnTypeName.IndexOf("<")); importService = alreadyGeneratedList.FirstOrDefault(x => x.Key.ParameterType.Name[0..^2] == returnTypeName).Value; } else { importService = alreadyGeneratedList.FirstOrDefault(x => x.Key.ParameterType.Name == complexReturnTypeName).Value; } if (importService != null && importService != ServiceName && !importServiceList.Contains(importService)) { importServiceList.Add(importService); } } foreach (var importService in importServiceList) { serviceDartString.AppendLine($"import '{LetterConverterHelper.FirstCharToLower(importService[0..^7])}.m.dart';"); } if (importServiceList.Count > 0) { serviceDartString.AppendLine(); } serviceDartString.AppendLine(); serviceDartString.AppendLine($"class {ServiceName} extends JsonRpcClientBase {{"); serviceDartString.AppendLine($"\t{ServiceName}("); serviceDartString.AppendLine("\t\tString host, {"); serviceDartString.AppendLine($"\t\tString serviceName = \"I{ServiceName}\","); serviceDartString.AppendLine("\t\tMap? headers,"); serviceDartString.AppendLine("\t\tint? timeout,"); serviceDartString.AppendLine("\t}) : super("); serviceDartString.AppendLine("\t\t\t\t\t\thost,"); serviceDartString.AppendLine("\t\t\t\t\t\tserviceName,"); serviceDartString.AppendLine("\t\t\t\t\t\theaders: headers,"); serviceDartString.AppendLine("\t\t\t\t\t\ttimeout: timeout,"); if (complexReturnTypeNameList.Count() == 0) { serviceDartString.AppendLine("\t\t\t\t);"); } else { serviceDartString.AppendLine("\t\t\t\t) {"); serviceDartString.AppendLine("\t\t/// 注册响应实体反序列化处理器"); foreach (var complexRetrunTypeName in complexReturnTypeNameList) { serviceDartString.AppendLine($"\t\tFJsonConvert.setDecoder((map) => {complexRetrunTypeName}.fromJson(map));"); } serviceDartString.AppendLine("\t}"); } serviceDartString.AppendLine(); foreach (var methodMap in _methodMapList) { GenerateDataCache.Instance.CurrentMethod = methodMap.MethodName; serviceDartString.AppendLine(methodMap.GetMethodDartString()); } serviceDartString.AppendLine("}"); return serviceDartString.ToString(); } public List GetUserDefinedComplexReturnTypeList() { _userDefinedComplexReturnTypeList = new List(); foreach (var method in _methodMapList) { GenerateDataCache.Instance.CurrentMethod = method.MethodName; var veturnParameterModelType = method.ReturnParameterModelType; AddUserDefinedComplexReturnType(veturnParameterModelType); } return _userDefinedComplexReturnTypeList; } private void AddUserDefinedComplexReturnType(ModelType modelType) { if (modelType is UserDefinedModelType) { if (!_userDefinedComplexReturnTypeList.Contains(modelType.GetFlutterTypeName())) { _userDefinedComplexReturnTypeList.Add(modelType.GetFlutterTypeName()); } } else if (modelType is UserDefinedDerivedModelType) { if (!_userDefinedComplexReturnTypeList.Contains(modelType.GetFlutterTypeName())) { _userDefinedComplexReturnTypeList.Add(modelType.GetFlutterTypeName()); } } else if (modelType is UserDefinedGenericModelType userDefinedGenericComplexModelType) { if (!_userDefinedComplexReturnTypeList.Contains(userDefinedGenericComplexModelType.GetFlutterTypeName())) { _userDefinedComplexReturnTypeList.Add(userDefinedGenericComplexModelType.GetFlutterTypeName()); } var argumentModelType = userDefinedGenericComplexModelType.GenericArgumentModelType; AddUserDefinedComplexReturnType(argumentModelType); } else if (modelType is ListModelType listModelType) { var argumentModelType = listModelType.GenericArgumentModelType; AddUserDefinedComplexReturnType(argumentModelType); } else if (modelType is DictionaryModelType dictionaryModelType) { foreach (var argumentModelType in dictionaryModelType.GenericArgumentModelTypeList) { AddUserDefinedComplexReturnType(argumentModelType); } } } } }