/// <summary> /// コンストラクタ /// </summary> /// <param name="node">対象Node</param> /// <param name="semanticModel">対象ソースのsemanticModel</param> /// <param name="parent">親IAnalyzeItem</param> /// <param name="container">イベントコンテナ</param> public ItemForEach(ForEachStatementSyntax node, SemanticModel semanticModel, IAnalyzeItem parent, EventContainer container) : base(parent, node, semanticModel, container) { ItemType = ItemTypes.MethodStatement; var oparetion = semanticModel.GetOperation(node) as IForEachLoopOperation; var localSymbol = oparetion.Locals.First(); // ローカルの型設定 IsVar = node.Type.IsVar; LocalTypes.AddRange(GetTypes(localSymbol.Type, semanticModel, node)); // ローカル設定 Local.Add(new Expression(localSymbol.Name, Expression.GetSymbolTypeName(localSymbol))); // コレクションの型設定 var conversionOperation = oparetion.Collection as IConversionOperation; if (!(conversionOperation is null)) { CollectionTypes.AddRange(GetTypes(conversionOperation.Operand.Type, semanticModel, node)); } //コレクション Collection.AddRange(OperationFactory.GetExpressionList(oparetion.Collection.Children.First(), container)); // 内部処理設定 var block = node.Statement as BlockSyntax; foreach (var statement in block.Statements) { Members.Add(ItemFactory.Create(statement, semanticModel, container, this)); } }
/// <summary> /// コンストラクタ /// </summary> /// <param name="node">対象Node</param> /// <param name="semanticModel">対象ソースのsemanticModel</param> /// <param name="parent">親IAnalyzeItem</param> /// <param name="container">イベントコンテナ</param> public ItemIf(IfStatementSyntax node, SemanticModel semanticModel, IAnalyzeItem parent, EventContainer container) : base(parent, node, semanticModel, container) { ItemType = ItemTypes.MethodStatement; var condition = semanticModel.GetOperation(node.Condition); Conditions.AddRange(OperationFactory.GetExpressionList(condition, container)); TrueBlock.AddRange(GetBlock(node.Statement, semanticModel)); FalseBlocks.AddRange(GetElseBlock(node.Else)); List <IAnalyzeItem> GetElseBlock(ElseClauseSyntax elseNode) { var result = new List <IAnalyzeItem>(); if (elseNode is null) { return(result); } result.Add(ItemFactory.Create(elseNode, semanticModel, container, parent)); // else ifの場合はさらに続ける if (elseNode.Statement is IfStatementSyntax ifNode) { result.AddRange(GetElseBlock(ifNode.Else)); } return(result); } }
/// <summary> /// コンストラクタ /// </summary> /// <param name="node">対象Node</param> /// <param name="semanticModel">対象ソースのsemanticModel</param> /// <param name="parent">親IAnalyzeItem</param> /// <param name="container">イベントコンテナ</param> public ItemSwitchCase(SwitchSectionSyntax node, SemanticModel semanticModel, IAnalyzeItem parent, EventContainer container) : base(parent, node, semanticModel, container) { ItemType = ItemTypes.MethodStatement; var operation = semanticModel.GetOperation(node) as ISwitchCaseOperation; // Caseラベル設定 foreach (var item in operation.Clauses.Where(item => !(item is IDefaultCaseClauseOperation))) { Labels.Add(OperationFactory.GetExpressionList(item.Children.First(), container)); } // defaultラベル設定 foreach (var item in operation.Clauses.Where(item => item is IDefaultCaseClauseOperation)) { Labels.Add(OperationFactory.GetExpressionList(item, container)); } // 内部処理設定 foreach (var statement in node.Statements) { var item = ItemFactory.Create(statement, semanticModel, container, this); if (!(item is null)) { Members.Add(ItemFactory.Create(statement, semanticModel, container, this)); } } }
/// <summary> /// TypeScript用スコープを返す /// </summary> /// <param name="item">C#解析結果</param> /// <returns>TypeScript用スコープ</returns> protected string GetScope(IAnalyzeItem item) { // class/interfaceのexport判定 if (item is IItemClass || item is IItemInterface) { if (item.Modifiers.Where(modifier => modifier != "private").Any()) { return("export "); } return(string.Empty); } // そのほかの要素 var resultItems = new List <string>(); foreach (var scope in item.Modifiers) { switch (scope) { case "private": case "protected": case "public": resultItems.Add(scope); break; } } var result = string.Join(" ", resultItems); if (resultItems.Any()) { result += " "; } return(result); }
/// <summary> /// コンストラクタ /// </summary> /// <param name="parent">親IAnalyzeItem</param> /// <param name="node">対象Node</param> /// <param name="semanticModel">対象ソースのsemanticModel</param> /// <param name="container">イベントコンテナ</param> protected AbstractItem(IAnalyzeItem parent, SyntaxNode node, SemanticModel semanticModel, EventContainer container) { // 親インスタンスを設定 Parent = parent; // 名前設定 Name = node.DescendantTokens(). Where(token => token.IsKind(SyntaxKind.IdentifierToken)). Select(token => semanticModel.GetDeclaredSymbol(token.Parent)). Where(symbol => symbol != null).FirstOrDefault()?.Name; // 識別子リスト設定 var modifiersObject = node.GetType().GetProperty("Modifiers")?.GetValue(node); if (modifiersObject is SyntaxTokenList modifiers) { Modifiers.AddRange(modifiers.Select(item => item.Text)); } // コメント設定 var targerComments = node.GetLeadingTrivia().ToString().Split("\n"). Select(item => item.TrimStart().Replace("\n", string.Empty, StringComparison.CurrentCulture)). Select(item => item.Replace("\r", string.Empty, StringComparison.CurrentCulture)). Where(item => !string.IsNullOrEmpty(item)); Comments.AddRange(targerComments); // イベントコンテナ eventContainer = container; }
/// <summary> /// エントリメソッド /// </summary> /// <param name="item">C#解析結果</param> /// <param name="config">設定情報</param> /// <param name="indent">インデント数</param> /// <param name="otherScripts">その他のスクリプト(内部クラスなど)</param> /// <returns>TypeScript変換結果</returns> public string Convert(IAnalyzeItem item, Config config, int indent, List <string> otherScripts) { if (item is IItemIf) { return(Convert(item as IItemIf, config, indent, otherScripts)); } else { return(Convert(item as IItemElseClause, config, indent, otherScripts)); } }
/// <summary> /// コメントをTypeScript用に変換する /// </summary> /// <param name="item">C#解析結果</param> /// <param name="indentSpace">インデント文字列</param> /// <returns>TypeScript用コメント</returns> protected string GetTypeScriptComments(IAnalyzeItem item, string indentSpace) { if (!item.Comments.Any()) { return(string.Empty); } // 1行コメント if (item.Comments.Count() == 1) { return($"{indentSpace}{item.Comments.First()}{Environment.NewLine}"); } // 複数コメント:コメント情報を一行にする var sb = new StringBuilder(); foreach (var itemComment in item.Comments) { sb.Append(itemComment.Replace("///", string.Empty, StringComparison.CurrentCulture).Trim()); } var src = sb.ToString(); var result = new StringBuilder(); result.AppendLine($"{indentSpace}/**"); // 正規表現でTypeScript用コメントを追加する foreach (var comment in comments) { var matches = Regex.Matches(src, comment.regx); if (matches.Count < 1) { continue; } foreach (Match macheItem in matches) { var matcheGroup = macheItem.Groups; if (matcheGroup.Count <= 1) { continue; } var replaceSentence = comment.replaceSentence; for (var i = 1; i < matcheGroup.Count; i++) { replaceSentence = replaceSentence.Replace($"${ i}", matcheGroup[i].Value, StringComparison.CurrentCulture); } result.AppendLine($"{indentSpace} * {replaceSentence}"); } } result.AppendLine($"{indentSpace} */"); return(result.ToString()); }
/// <summary> /// エントリメソッド /// </summary> /// <param name="item">C#解析結果</param> /// <param name="config">設定情報</param> /// <param name="indent">インデント数</param> /// <param name="otherScripts">その他のスクリプト(内部クラスなど)</param> /// <returns>TypeScript変換結果</returns> public string Convert(IAnalyzeItem item, Config config, int indent, List <string> otherScripts) { if (item is IItemSwitch) { return(Convert(item as IItemSwitch, config, indent, otherScripts)); } else { return(Convert(item as IItemSwitchCase, config, indent, otherScripts)); } }
/// <summary> /// コンストラクタ /// </summary> /// <param name="node">対象Node</param> /// <param name="semanticModel">対象ソースのsemanticModel</param> /// <param name="parent">親IAnalyzeItem</param> /// <param name="container">イベントコンテナ</param> public ItemEnum(EnumDeclarationSyntax node, SemanticModel semanticModel, IAnalyzeItem parent, EventContainer container) : base(parent, node, semanticModel, container) { ItemType = ItemTypes.Enum; // アイテムと初期値を取得 foreach (var member in node.Members) { var declaredSymbol = semanticModel.GetDeclaredSymbol(member) as IFieldSymbol; var name = declaredSymbol.Name; var value = declaredSymbol.ConstantValue; Items.Add(name, value?.ToString()); } }
/// <summary> /// C#解析結果からTS変換変換結果を返す /// </summary> /// <param name="csItem">C#解析結果</param> /// <param name="config">設定情報</param> /// <param name="indent">インデント数</param> /// <param name="otherScripts">その他のスクリプト(内部クラスなど)</param> /// <returns>TypeScript変換結果</returns> public static string Convert(IAnalyzeItem csItem, Config config, int indent, List <string> otherScripts) { // 対象リストからC#解析結果に該当するTS変換クラスを抽出 var query = table.Where(item => item.Key.IsInstanceOfType(csItem)); if (!query.Any()) { return(string.Empty); } // 該当したTS変換クラスのインスタンスからTS変換変換結果を返す return(query.First().Value().Convert(csItem, config, indent, otherScripts)); }
/// <summary> /// プロパティのset/get用Typescriptを返す /// </summary> /// <param name="accessorItem">set/get用のアイテム</param> /// <param name="config">設定情報</param> /// <param name="indent">インデント数</param> /// <param name="scope">スコープ名</param> /// <param name="propertyName">プロパティ名</param> /// <param name="propertyType">プロパティの型</param> /// <param name="refTarget">参照名(インスタンス参照の場合はthis)</param> /// <param name="otherScripts">その他のスクリプト(内部クラスなど)</param> /// <returns>set/get用Typescriptの文字列</returns> private string GetAccessorString(IAnalyzeItem accessorItem, Config config, int indent, string scope, string propertyName, string propertyType, string refTarget, List <string> otherScripts) { var indentSpace = GetIndentSpace(indent); var result = new StringBuilder(); var notExistsMember = true; if (accessorItem.Members.Any()) { notExistsMember = false; } // set/getの設定 var accessorItemName = accessorItem.Name.ToLower(CultureInfo.CurrentCulture); switch (accessorItemName) { case "set": result.AppendLine($"{indentSpace}{scope}set {propertyName}(value: {propertyType}) {{"); if (notExistsMember) { result.AppendLine($"{GetIndentSpace(indent + 1)}{refTarget}._{propertyName}_ = value;"); } break; case "get": result.AppendLine($"{indentSpace}{scope}get {propertyName}(): {propertyType} {{"); if (notExistsMember) { result.AppendLine($"{GetIndentSpace(indent + 1)}return {refTarget}._{propertyName}_;"); } break; default: return(result.ToString()); } // メンバー追加 foreach (var member in accessorItem.Members) { result.Append(ConvertUtility.Convert(member, config, indent + 1, otherScripts)); } result.AppendLine($"{indentSpace}}}"); return(result.ToString()); }
/// <summary> /// コンストラクタ /// </summary> /// <param name="node">対象Node</param> /// <param name="semanticModel">対象ソースのsemanticModel</param> /// <param name="parent">親IAnalyzeItem</param> /// <param name="container">イベントコンテナ</param> public ItemSwitch(SwitchStatementSyntax node, SemanticModel semanticModel, IAnalyzeItem parent, EventContainer container) : base(parent, node, semanticModel, container) { ItemType = ItemTypes.MethodStatement; var operation = semanticModel.GetOperation(node) as ISwitchOperation; // 条件設定 Conditions.AddRange(OperationFactory.GetExpressionList(operation.Value, container)); // Caseリスト設定 foreach (var item in operation.Cases) { Cases.Add(ItemFactory.Create(item.Syntax, semanticModel, container, this)); } }
/// <summary> /// コンストラクタ /// </summary> /// <param name="node">対象Node</param> /// <param name="semanticModel">対象ソースのsemanticModel</param> /// <param name="parent">親IAnalyzeItem</param> /// <param name="container">イベントコンテナ</param> public ItemDo(DoStatementSyntax node, SemanticModel semanticModel, IAnalyzeItem parent, EventContainer container) : base(parent, node, semanticModel, container) { ItemType = ItemTypes.MethodStatement; // 条件設定 var condition = semanticModel.GetOperation(node.Condition); Conditions.AddRange(OperationFactory.GetExpressionList(condition, container)); // 内部処理設定 var block = node.Statement as BlockSyntax; foreach (var statement in block.Statements) { Members.Add(ItemFactory.Create(statement, semanticModel, container, this)); } }
/// <summary> /// 初期化 /// </summary> /// <param name="node">対象Node</param> /// <param name="semanticModel">対象ソースのsemanticModel</param> /// <param name="parent">親IAnalyzeItem</param> public void Initialize(SyntaxNode node, SemanticModel semanticModel, IAnalyzeItem parent) { ItemType = ItemTypes.MethodStatement; var operation = semanticModel.GetOperation(node); // 戻り値設定 if (operation is IReturnOperation returnOperation) { if (returnOperation.ReturnedValue != null) { ReturnValue.AddRange(OperationFactory.GetExpressionList(returnOperation.ReturnedValue, eventContainer)); } return; } ReturnValue.AddRange(OperationFactory.GetExpressionList(operation, eventContainer)); }
/// <summary> /// コンストラクタ /// </summary> /// <param name="node">対象Node</param> /// <param name="semanticModel">対象ソースのsemanticModel</param> /// <param name="parent">親IAnalyzeItem</param> /// <param name="container">イベントコンテナ</param> public ItemField(FieldDeclarationSyntax node, SemanticModel semanticModel, IAnalyzeItem parent, EventContainer container) : base(parent, node, semanticModel, container) { ItemType = ItemTypes.Field; var declaredSymbol = semanticModel.GetDeclaredSymbol(node.Declaration.Variables.First()); // フィールドの型設定 var parts = ((IFieldSymbol)declaredSymbol).Type.ToDisplayParts(SymbolDisplayFormat.MinimallyQualifiedFormat); foreach (var part in parts) { // スペースの場合は型設定に含めない if (part.Kind == SymbolDisplayPartKind.Space) { continue; } var name = Expression.GetSymbolName(part, true); var type = Expression.GetSymbolTypeName(part.Symbol); if (part.Kind == SymbolDisplayPartKind.ClassName) { // 外部ファイル参照イベント発行 RaiseOtherFileReferenced(node, part.Symbol); } FieldTypes.Add(new Expression(name, type)); } // デフォルト設定 var constantValue = node.Declaration.Variables.FirstOrDefault(); if (constantValue?.Initializer == null) { return; } var initializer = semanticModel.GetOperation(constantValue.Initializer.Value); DefaultValues.AddRange(OperationFactory.GetExpressionList(initializer, container)); }
/// <summary> /// コンストラクタ /// </summary> /// <param name="node">対象Node</param> /// <param name="semanticModel">対象ソースのsemanticModel</param> /// <param name="parent">親IAnalyzeItem</param> /// <param name="container">イベントコンテナ</param> public ItemElseClause(ElseClauseSyntax node, SemanticModel semanticModel, IAnalyzeItem parent, EventContainer container) : base(parent, node, semanticModel, container) { ItemType = ItemTypes.MethodStatement; if (node.Statement is IfStatementSyntax ifNode) { var condition = semanticModel.GetOperation(ifNode.Condition); Conditions.AddRange(OperationFactory.GetExpressionList(condition, container)); var block = ifNode.Statement as BlockSyntax; foreach (var statement in block.Statements) { Block.Add(ItemFactory.Create(statement, semanticModel, container, this)); } } else { var block = node.Statement as BlockSyntax; foreach (var statement in block.Statements) { Block.Add(ItemFactory.Create(statement, semanticModel, container, this)); } } }
/// <summary> /// 初期化 /// </summary> /// <param name="node">対象Node</param> /// <param name="semanticModel">対象ソースのsemanticModel</param> /// <param name="parent">親IAnalyzeItem</param> private void Initialize(SyntaxNode node, SemanticModel semanticModel, IAnalyzeItem parent) { ItemType = ItemTypes.MethodStatement; // 処理内容を取得 IOperation operation = null; if (node is ExpressionStatementSyntax expressionStatement) { operation = semanticModel.GetOperation(expressionStatement.Expression); } else { operation = semanticModel.GetOperation(node); } // 式情報を取得 switch (operation) { case ISimpleAssignmentOperation param: LeftSideList.AddRange(OperationFactory.GetExpressionList(param.Target, eventContainer)); RightSideList.AddRange(OperationFactory.GetExpressionList(param.Value, eventContainer)); break; case IInvocationOperation param: RightSideList.AddRange(OperationFactory.GetExpressionList(param, eventContainer)); break; case IPropertyReferenceOperation param: RightSideList.AddRange(OperationFactory.GetExpressionList(param, eventContainer)); break; case ILocalReferenceOperation param: RightSideList.AddRange(OperationFactory.GetExpressionList(param, eventContainer)); break; case ILiteralOperation param: RightSideList.AddRange(OperationFactory.GetExpressionList(param, eventContainer)); break; case IFieldReferenceOperation param: RightSideList.AddRange(OperationFactory.GetExpressionList(param, eventContainer)); break; case IInstanceReferenceOperation param: RightSideList.AddRange(OperationFactory.GetExpressionList(param, eventContainer)); break; case ICompoundAssignmentOperation param: LeftSideList.AddRange(OperationFactory.GetExpressionList(param.Target, eventContainer)); RightSideList.AddRange(OperationFactory.GetExpressionList(param.Value, eventContainer)); break; case IIncrementOrDecrementOperation param: var target = OperationFactory.GetExpressionList(param.Target, eventContainer); if(param.IsPostfix){ RightSideList.AddRange(target); } switch (param.Kind) { case OperationKind.Increment: RightSideList.Add(new Expression("++", string.Empty)); break; case OperationKind.Decrement: RightSideList.Add(new Expression("--", string.Empty)); break; } if (!param.IsPostfix) { RightSideList.AddRange(target); } break; default: Console.Write($" [{operation.Kind} is none] "); break; } // 代入演算子 if(node is AssignmentExpressionSyntax assignmentExpression) { AssignmentOperator = assignmentExpression.OperatorToken.Text; } }
/// <summary> /// コンストラクタ /// </summary> /// <param name="node">対象Node</param> /// <param name="semanticModel">対象ソースのsemanticModel</param> /// <param name="parent">親IAnalyzeItem</param> /// <param name="container">イベントコンテナ</param> public ItemStatementExpression(SyntaxNode node, SemanticModel semanticModel, IAnalyzeItem parent, EventContainer container) : base(parent, node, semanticModel, container) { Initialize(node, semanticModel, parent); }
/// <summary> /// IAnalyzeItemインスタンス作成 /// </summary> /// <param name="node">対象Node</param> /// <param name="semanticModel">対象ソースのsemanticModel</param> /// <param name="container">イベントコンテナ</param> /// <param name="parent">親IAnalyzeItemインスタンス(デフォルトはnull)</param> /// <returns>IAnalyzeItemインスタンス</returns> public static IAnalyzeItem Create(SyntaxNode node, SemanticModel semanticModel, EventContainer container, IAnalyzeItem parent = null) { IAnalyzeItem result = null; // nodeの種類によって取得メソッドを実行 switch (node) { // クラス定義 case ClassDeclarationSyntax targetNode: result = new ItemClass(targetNode, semanticModel, parent, container); break; // インターフェース case InterfaceDeclarationSyntax targetNode: result = new ItemInterface(targetNode, semanticModel, parent, container); break; // クラス要素定義 case PropertyDeclarationSyntax targetNode: result = new ItemProperty(targetNode, semanticModel, parent, container); break; case FieldDeclarationSyntax targetNode: result = new ItemField(targetNode, semanticModel, parent, container); break; case MethodDeclarationSyntax targetNode: result = new ItemMethod(targetNode, semanticModel, parent, container); break; case ConstructorDeclarationSyntax targetNode: result = new ItemConstructor(targetNode, semanticModel, parent, container); break; case EnumDeclarationSyntax targetNode: result = new ItemEnum(targetNode, semanticModel, parent, container); break; // ラムダ式 case ArrowExpressionClauseSyntax targetNode: if (parent is ItemProperty) { result = new ItemAccessor(targetNode, semanticModel, parent, container); } else { var op = semanticModel.GetOperation(targetNode).Children.First(); switch (op) { case Microsoft.CodeAnalysis.Operations.IReturnOperation operation: result = new ItemReturn(op.Syntax, semanticModel, parent, container); break; case Microsoft.CodeAnalysis.Operations.IExpressionStatementOperation operation: result = new ItemStatementExpression(op.Syntax, semanticModel, parent, container); break; } } break; // ローカル定義 case LocalFunctionStatementSyntax targetNode: result = new ItemLocalFunction(targetNode, semanticModel, parent, container); break; case LocalDeclarationStatementSyntax targetNode: result = new ItemStatementLocalDeclaration(targetNode, semanticModel, parent, container); break; case ExpressionStatementSyntax targetNode: result = new ItemStatementExpression(targetNode, semanticModel, parent, container); break; case AccessorDeclarationSyntax targetNode: result = new ItemAccessor(targetNode, semanticModel, parent, container); break; // 分岐処理 case IfStatementSyntax targetNode: result = new ItemIf(targetNode, semanticModel, parent, container); break; case ElseClauseSyntax targetNode: result = new ItemElseClause(targetNode, semanticModel, parent, container); break; case SwitchStatementSyntax targetNode: result = new ItemSwitch(targetNode, semanticModel, parent, container); break; case SwitchSectionSyntax targetNode: result = new ItemSwitchCase(targetNode, semanticModel, parent, container); break; // ループ処理 case WhileStatementSyntax targetNode: result = new ItemWhile(targetNode, semanticModel, parent, container); break; case DoStatementSyntax targetNode: result = new ItemDo(targetNode, semanticModel, parent, container); break; case ForEachStatementSyntax targetNode: result = new ItemForEach(targetNode, semanticModel, parent, container); break; case ForStatementSyntax targetNode: result = new ItemFor(targetNode, semanticModel, parent, container); break; // その他 case ReturnStatementSyntax targetNode: result = new ItemReturn(targetNode, semanticModel, parent, container); break; case BreakStatementSyntax targetNode: result = new ItemBreak(targetNode, semanticModel, parent, container); break; case ContinueStatementSyntax targetNode: result = new ItemContinue(targetNode, semanticModel, parent, container); break; } return(result); }
/// <summary> /// エントリメソッド /// </summary> /// <param name="item">C#解析結果</param> /// <param name="config">設定情報</param> /// <param name="indent">インデント数</param> /// <param name="otherScripts">その他のスクリプト(内部クラスなど)</param> /// <returns>TypeScript変換結果</returns> public string Convert(IAnalyzeItem item, Config config, int indent, List <string> otherScripts) { return(Convert(item as IItemStatementExpression, config, indent, otherScripts)); }
/// <summary> /// エントリメソッド /// </summary> /// <param name="item">C#解析結果</param> /// <param name="indent">インデント数</param> /// <param name="otherScripts">その他のスクリプト(内部クラスなど)</param> /// <returns>TypeScript変換結果</returns> public string Convert(IAnalyzeItem item, Config config, int indent, List <string> otherScripts) { return(Convert(item as IItemConstructor, config, indent, otherScripts)); }
/// <summary> /// コンストラクタ /// </summary> /// <param name="node">対象Node</param> /// <param name="semanticModel">対象ソースのsemanticModel</param> /// <param name="parent">親IAnalyzeItem</param> /// <param name="container">イベントコンテナ</param> public ItemFor(ForStatementSyntax node, SemanticModel semanticModel, IAnalyzeItem parent, EventContainer container) : base(parent, node, semanticModel, container) { ItemType = ItemTypes.MethodStatement; // 宣言部 if (node.Declaration != null) { // 型設定 IsVar = node.Declaration.Type.IsVar; var declaredSymbol = semanticModel.GetDeclaredSymbol(node.Declaration.Variables.First()); var parts = ((ILocalSymbol)declaredSymbol).Type.ToDisplayParts(SymbolDisplayFormat.MinimallyQualifiedFormat); foreach (var part in parts) { // スペースの場合は型設定に含めない if (part.Kind == SymbolDisplayPartKind.Space) { continue; } var name = Expression.GetSymbolName(part, true); var type = Expression.GetSymbolTypeName(part.Symbol); if (part.Kind == SymbolDisplayPartKind.ClassName) { // 外部ファイル参照イベント発行 RaiseOtherFileReferenced(node, part.Symbol); } Types.Add(new Expression(name, type)); } // ローカル定義 foreach (var variable in node.Declaration.Variables) { var declaration = semanticModel.GetOperation(variable); Declarations.Add(OperationFactory.GetExpressionList(declaration, container)); } } else if (node.Initializers != null) { // 既存定義 foreach (var initializer in node.Initializers) { var declaration = semanticModel.GetOperation(initializer); Declarations.Add(OperationFactory.GetExpressionList(declaration, container)); } } // 計算部 foreach (var increment in node.Incrementors) { var incrementOperator = semanticModel.GetOperation(increment); Incrementors.Add(OperationFactory.GetExpressionList(incrementOperator, container)); } // 条件部 var condition = semanticModel.GetOperation(node.Condition); Conditions.AddRange(OperationFactory.GetExpressionList(condition, container)); // 内部処理設定 var block = node.Statement as BlockSyntax; foreach (var statement in block.Statements) { Members.Add(ItemFactory.Create(statement, semanticModel, container, this)); } }
/// <summary> /// コンストラクタ /// </summary> /// <param name="node">対象Node</param> /// <param name="semanticModel">対象ソースのsemanticModel</param> /// <param name="parent">親IAnalyzeItem</param> /// <param name="container">イベントコンテナ</param> public ItemAccessor(ArrowExpressionClauseSyntax node, SemanticModel semanticModel, IAnalyzeItem parent, EventContainer container) : base(parent, node, semanticModel, container) { ItemType = ItemTypes.Accessor; // メンバ var memberResult = ItemFactory.Create(node, semanticModel, container, this); Members.Add(memberResult); // キーワード if (memberResult is ItemReturn) { Name = "get"; } else { Name = "set"; } }
/// <summary> /// コンストラクタ /// </summary> /// <param name="node">対象Node</param> /// <param name="semanticModel">対象ソースのsemanticModel</param> /// <param name="parent">親IAnalyzeItem</param> /// <param name="container">イベントコンテナ</param> public ItemInterface(InterfaceDeclarationSyntax node, SemanticModel semanticModel, IAnalyzeItem parent, EventContainer container) : base(parent, node, semanticModel, container) { ItemType = ItemTypes.Interface; var declaredSymbol = semanticModel.GetDeclaredSymbol(node); // インターフェース設定 if (node.BaseList != null) { // インターフェース foreach (var interfaceInfo in declaredSymbol.AllInterfaces) { Interfaces.Add(getExpressionList(interfaceInfo)); // スーパーインタフェースのメンバーを追加する SetBaseMembers(interfaceInfo); } // 対象をList<IExpression>に格納する List <IExpression> getExpressionList(INamedTypeSymbol target) { var result = new List <IExpression>(); var displayParts = target.ToDisplayParts(SymbolDisplayFormat.MinimallyQualifiedFormat); foreach (var part in displayParts) { // スペースの場合は型設定に含めない if (part.Kind == SymbolDisplayPartKind.Space) { continue; } var name = Expression.GetSymbolName(part, true); var type = Expression.GetSymbolTypeName(part.Symbol); if (part.Symbol != null) { type = part.Symbol.GetType().Name; if (part.Kind == SymbolDisplayPartKind.ClassName || part.Kind == SymbolDisplayPartKind.InterfaceName) { // 外部ファイル参照イベント発行 RaiseOtherFileReferenced(node, part.Symbol); } } result.Add(new Expression(name, type)); } return(result); } } // ジェネリックタイプ if (declaredSymbol.TypeParameters.Any()) { var types = declaredSymbol.TypeParameters.Select(item => item.Name); GenericTypes.AddRange(types); } // メンバ foreach (var childSyntax in node.ChildNodes()) { var memberResult = ItemFactory.Create(childSyntax, semanticModel, container, this); if (memberResult != null) { Members.Add(memberResult); } } }
/// <summary> /// コンストラクタ /// </summary> /// <param name="node">対象Node</param> /// <param name="semanticModel">対象ソースのsemanticModel</param> /// <param name="parent">親IAnalyzeItem</param> /// <param name="container">イベントコンテナ</param> public ItemReturn(ReturnStatementSyntax node, SemanticModel semanticModel, IAnalyzeItem parent, EventContainer container) : base(parent, node, semanticModel, container) { Initialize(node, semanticModel, parent); }
/// <summary> /// エントリメソッド /// </summary> /// <param name="item">C#解析結果</param> /// <param name="config">設定情報</param> /// <param name="indent">インデント数</param> /// <param name="otherScripts">その他のスクリプト(内部クラスなど)</param> /// <returns>TypeScript変換結果</returns> public string Convert(IAnalyzeItem item, Config config, int indent, List <string> otherScripts) { return(Convert(item as IItemLocalFunction, config, indent, otherScripts)); }
/// <summary> /// コンストラクタ /// </summary> /// <param name="node">対象Node</param> /// <param name="semanticModel">対象ソースのsemanticModel</param> /// <param name="parent">親IAnalyzeItem</param> /// <param name="container">イベントコンテナ</param> public ItemProperty(PropertyDeclarationSyntax node, SemanticModel semanticModel, IAnalyzeItem parent, EventContainer container) : base(parent, node, semanticModel, container) { ItemType = ItemTypes.Property; var declaredSymbol = semanticModel.GetDeclaredSymbol(node); // プロパティの型設定 var parts = ((IPropertySymbol)declaredSymbol).Type.ToDisplayParts(SymbolDisplayFormat.MinimallyQualifiedFormat); foreach (var part in parts) { // スペースの場合は型設定に含めない if (part.Kind == SymbolDisplayPartKind.Space) { continue; } var name = Expression.GetSymbolName(part, true); var type = Expression.GetSymbolTypeName(part.Symbol); if (part.Kind == SymbolDisplayPartKind.ClassName) { // 外部ファイル参照イベント発行 RaiseOtherFileReferenced(node, part.Symbol); } PropertyTypes.Add(new Expression(name, type)); } // アクセサ設定 if (node.AccessorList is null) { AccessorList.Add(ItemFactory.Create(node.ExpressionBody, semanticModel, container, this)); } else { AccessorList.AddRange(node.AccessorList.Accessors.Select(accessor => ItemFactory.Create(accessor, semanticModel, container, this))); } // デフォルト設定 if (node.Initializer == null) { return; } var propertyInitializer = semanticModel.GetOperation(node.Initializer.Value); DefaultValues.AddRange(OperationFactory.GetExpressionList(propertyInitializer, container)); }
/// <summary> /// コンストラクタ /// </summary> /// <param name="node">対象Node</param> /// <param name="semanticModel">対象ソースのsemanticModel</param> /// <param name="parent">親IAnalyzeItem</param> /// <param name="container">イベントコンテナ</param> public ItemContinue(ContinueStatementSyntax node, SemanticModel semanticModel, IAnalyzeItem parent, EventContainer container) : base(parent, node, semanticModel, container) { ItemType = ItemTypes.MethodStatement; }
/// <summary> /// コンストラクタ /// </summary> /// <param name="node">対象Node</param> /// <param name="semanticModel">対象ソースのsemanticModel</param> /// <param name="parent">親IAnalyzeItem</param> /// <param name="container">イベントコンテナ</param> public ItemAccessor(AccessorDeclarationSyntax node, SemanticModel semanticModel, IAnalyzeItem parent, EventContainer container) : base(parent, node, semanticModel, container) { ItemType = ItemTypes.Accessor; // キーワード Name = node.Keyword.ValueText; var statement = node.ChildNodes(); if (!statement.Any()) { return; } // メンバ var firstStatement = statement.First(); if (firstStatement is ArrowExpressionClauseSyntax) { var memberResult = ItemFactory.Create(firstStatement, semanticModel, container, this); if (memberResult != null) { Members.Add(memberResult); } } else { var block = firstStatement as BlockSyntax; foreach (var childSyntax in block.Statements) { var memberResult = ItemFactory.Create(childSyntax, semanticModel, container, this); if (memberResult != null) { Members.Add(memberResult); } } } }