/// <summary> /// クラス情報の取得 /// </summary> /// <param name="item">C#解析結果</param> /// <returns>クラス情報</returns> /// <remarks>ジェネリックス、継承の文字列取得</remarks> private string GetClassInfo(IItemClass item) { var result = new StringBuilder(); // ジェネリックスクラス if (item.GenericTypes.Any()) { result.Append("<"); result.Append(string.Join(", ", item.GenericTypes.Select(typeItem => GetTypeScriptType(typeItem)))); result.Append(">"); } // スーパークラスあり if (item.SuperClass.Any()) { result.Append($" extends {ExpressionsToString(item.SuperClass)}"); } // インターフェイスあり if (item.Interfaces.Any()) { var interfaceList = new List <string>(); foreach (var targetItemList in item.Interfaces) { // インターフェース名追加 interfaceList.Add(ExpressionsToString(targetItemList)); } result.Append(" implements "); result.Append(string.Join(", ", interfaceList.Select(typeItem => GetTypeScriptType(typeItem)))); } return(result.ToString()); }
/// <summary> /// クラスタイプの取得 /// </summary> /// <param name="item">C#解析結果</param> /// <returns>クラスタイプ</returns> private ClassType GetClassType(IItemClass item) { if (item.Parent is IItemClass) { return(ClassType.Inner); } return(ClassType.Normal); }
/// <summary> /// 変換メソッド /// </summary> /// <param name="item">C#解析結果</param> /// <param name="indent">インデント数</param> /// <returns>TypeScript変換結果</returns> private string Convert(IItemClass item, Config config, int indent, List <string> otherScripts) { var result = new StringBuilder(); var classType = GetClassType(item); // 内部クラスの場合はインデント固定 if (classType == ClassType.Inner) { indent = 1; } var indentSpace = GetIndentSpace(indent); // クラスコメント result.Append(GetTypeScriptComments(item, indentSpace)); // クラス定義 result.Append(indentSpace); switch (classType) { case ClassType.Normal: result.Append($"{GetScope(item)}class {item.Name}{GetClassInfo(item)}"); break; case ClassType.Inner: result.Append($"export class {item.Name}{GetClassInfo(item)}"); break; } result.AppendLine(" {"); // メンバー追加 var members = item.Members; if (config.Mode.Value == OutputMode.Mode.WithoutMethod) { members = members.Where(member => member is IItemField || member is IItemProperty || member is IItemClass || member is IItemInterface).ToList(); } foreach (var member in members) { result.Append(ConvertUtility.Convert(member, config, indent + 1, otherScripts)); } result.AppendLine($"{indentSpace}}}"); // 内部クラスの場合はotherScriptsに格納 if (classType == ClassType.Inner) { otherScripts.Add($"export namespace {GetParentClessName(item)} {{"); otherScripts.Add($"{result.ToString()}}}"); otherScripts.Add($""); // 親クラスのメンバーに含めない result.Clear(); } return(result.ToString()); }
/// <summary> /// 親クラスのパスを取得する /// </summary> /// <param name="item">内部クラスのインスタンス</param> /// <returns>親クラスのパス</returns> protected string GetParentClessName(IItemClass item) { var result = new List <string>(); // 親クラスをさかのぼりながら格納する var parent = item?.Parent as IItemClass; while (parent != null) { result.Add(parent.Name); parent = parent.Parent as IItemClass; } return(string.Join(".", result)); }
/// <summary> /// 対象インスタンスの取得 /// </summary> /// <param name="itemClass">対象のアイテムクラス</param> /// <returns>対象インスタンスリスト</returns> private List <IItemMethod> GetTargetInstances(IItemClass itemClass) { return(itemClass.Members.Where(member => member is IItemMethod). Select(member => member as IItemMethod).ToList()); }
/// <summary> /// 変換メソッド メイン処理(class) /// </summary> /// <param name="parentInstanse">親インスタンス</param> /// <param name="item">C#解析結果</param> /// <param name="config">設定情報</param> /// <param name="indent">インデント数</param> /// <param name="otherScripts">その他のスクリプト(内部クラスなど)</param> /// <returns>TypeScript変換結果</returns> private string ConvertMain(IItemClass parentInstanse, IItemMethod item, Config config, int indent, List <string> otherScripts) { // 親インスタンスがnullの場合はそのまま終了 if (parentInstanse is null) { return(string.Empty); } var result = new StringBuilder(); var indentSpace = GetIndentSpace(indent); // メソッド名 string BaseMethodName = item.Name; // クラス情報(親インスタンス)を取得 var className = parentInstanse.Name; var targetIndex = 1; var targetItems = parentInstanse.Members.Where(member => member is IItemMethod && member.Name == BaseMethodName) .Select(member => (index: targetIndex++, item: member as IItemMethod)).ToList(); var isOverload = targetItems.Count() > 1; var returnType = ExpressionsToString(item.MethodTypes); var isReturn = returnType != "void"; // 複数コンストラクタの存在確認 var indexValue = string.Empty; if (isOverload) { // インデックスの設定 foreach (var targetItem in targetItems) { if (targetItem.item == item) { indexValue = $"{targetItem.index}"; } } } // コメント result.Append(GetTypeScriptComments(item, indentSpace)); // パラメータ取得 var args = new List <string>(); foreach (var arg in item.Args) { args.Add($"{arg.name}: {ExpressionsToString(arg.expressions)}"); } // 定義 var scope = GetScope(item); if (isOverload) { scope = "private "; } if (item.Modifiers.Contains("static")) { scope += "static "; } result.Append($"{indentSpace}{scope}{BaseMethodName}{indexValue}"); // ジェネリックスクラス if (item.GenericTypes.Any()) { result.Append("<"); result.Append(string.Join(", ", item.GenericTypes.Select(typeItem => GetTypeScriptType(typeItem)))); result.Append(">"); } result.Append("("); result.Append(string.Join(", ", args)); result.Append($"): {returnType}"); result.AppendLine(" {"); // メンバー追加 foreach (var member in item.Members) { result.Append(ConvertUtility.Convert(member, config, indent + 1, otherScripts)); } result.AppendLine($"{indentSpace}}}"); // 複数メソッドで最終メソッドの場合は総括メソッドを作成する if (isOverload && targetItems.Last().item == item) { // 総合メソッド内処理用文字列 var methodResult = new StringBuilder(); // パラメータ数のリスト取得 var paramCounts = targetItems.Select(member => member.item.Args.Count); var existsNoneParam = paramCounts.Min() <= 0; var maxParamCount = paramCounts.Max(); // 戻り値の取得 var retrunTypes = targetItems. Select(returnTypeItem => ExpressionsToString(returnTypeItem.item.MethodTypes)). Distinct(); var isMultiReturnType = retrunTypes.Count() > 1; // パラメータリストを生成 var methodArgs = new Dictionary <int, List <string> >(); for (var index = 1; index <= maxParamCount; index++) { methodArgs.Add(index, new List <string>()); } // メソッドパラメータの格納とメソッド内処理の作成 foreach (var targetItem in targetItems) { // 1メソッドのパラメータ取得 var argIndex = 1; var ifConditions = new List <string>(); var callMethodParams = new List <string>(); foreach (var arg in targetItem.item.Args) { var expressionsValue = ExpressionsToString(arg.expressions); // メソッドパラメータに追加 if (!methodArgs[argIndex].Contains(expressionsValue)) { methodArgs[argIndex].Add(expressionsValue); } // メソッド内条件 ifConditions.Add(GetCondition(argIndex, expressionsValue)); // 呼び出しメソッドのパラメータ callMethodParams.Add($"param{argIndex}"); argIndex++; } // メソッド内条件の追加 while (argIndex <= maxParamCount) { ifConditions.Add(GetCondition(argIndex, "undefined")); argIndex++; } // メソッド内処理の追加 var methodSpace = GetIndentSpace(indent + 1); methodResult.AppendLine($"{methodSpace}if ({string.Join(" && ", ifConditions)}) {{"); methodResult.Append($"{GetIndentSpace(indent + 2)}"); if (isMultiReturnType) { methodResult.Append($"return "); } methodResult.Append($"this.{BaseMethodName}{targetItem.index}"); methodResult.Append("("); methodResult.Append(string.Join(", ", callMethodParams)); methodResult.AppendLine(");"); if (!isMultiReturnType) { methodResult.AppendLine($"{GetIndentSpace(indent + 2)}return;"); } methodResult.AppendLine($"{methodSpace}}}"); } // 総合メソッドの作成 result.Append($"{indentSpace}{GetScope(item)}{BaseMethodName}("); // パラメータ設定 for (var index = 1; index <= maxParamCount; index++) { if (index > 1) { result.Append(", "); } result.Append($"param{index}"); if (existsNoneParam) { result.Append("?"); } result.Append($": {string.Join(" | ", methodArgs[index])}"); } // 戻り値 var methodType = string.Join(" | ", retrunTypes); //if(isMultiReturnType) //{ // methodType = "any"; //} result.Append($"): {methodType}"); result.AppendLine(" {"); result.Append(methodResult.ToString()); result.AppendLine($"{GetIndentSpace(indent + 1)}throw new Error('Error');"); result.AppendLine($"{indentSpace}}}"); } return(result.ToString()); }