forked from nhabuiduc/TypescriptSyntaxPaste
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathClassToInterfaceReplacement.cs
More file actions
108 lines (90 loc) · 4.57 KB
/
ClassToInterfaceReplacement.cs
File metadata and controls
108 lines (90 loc) · 4.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/*
* Copyright (c) 2019-2021 João Pedro Martins Neves (shivayl) - All Rights Reserved.
*
* CSharpToTypescript is licensed under the GPLv3.0 license (GNU General Public License v3.0),
* located in the root of this project, under the name "LICENSE.md".
*
*/
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using System.Collections.Generic;
using System.Linq;
namespace CSharpToTypescript
{
public class ClassToInterfaceReplacement
{
public static CSharpSyntaxNode ReplaceClass(CSharpSyntaxNode syntaxNode)
{
IEnumerable<TypeDeclarationSyntax> allClassSyntaxes = syntaxNode.DescendantNodesAndSelf().OfType<ClassDeclarationSyntax>();
IEnumerable<TypeDeclarationSyntax> allStructSyntaxes = syntaxNode.DescendantNodesAndSelf().OfType<StructDeclarationSyntax>();
var newSyntaxNode = syntaxNode;
TypeDeclarationSyntax currentSyntax;
while ((currentSyntax = FindTypeDeclrationToReplace( newSyntaxNode )) != null)
{
newSyntaxNode = newSyntaxNode.ReplaceNode( currentSyntax, MakeInterface( currentSyntax ) );
}
return newSyntaxNode;
}
private static TypeDeclarationSyntax FindTypeDeclrationToReplace(CSharpSyntaxNode syntaxNode)
{
TypeDeclarationSyntax typeSyntax = syntaxNode.DescendantNodesAndSelf().OfType<ClassDeclarationSyntax>().FirstOrDefault();
if (typeSyntax != null) return typeSyntax;
typeSyntax = syntaxNode.DescendantNodesAndSelf().OfType<StructDeclarationSyntax>().FirstOrDefault();
if (typeSyntax != null) return typeSyntax;
return null;
}
private static InterfaceDeclarationSyntax MakeInterface(TypeDeclarationSyntax typeSyntax)
{
return SyntaxFactory.InterfaceDeclaration(
attributeLists: typeSyntax.AttributeLists,
modifiers: typeSyntax.Modifiers,
identifier: typeSyntax.Identifier,
typeParameterList: typeSyntax.TypeParameterList,
baseList: typeSyntax.BaseList,
constraintClauses: typeSyntax.ConstraintClauses,
members: MakeInterfaceSyntaxList( typeSyntax.Members ) ).NormalizeWhitespace();
}
private static SyntaxList<MemberDeclarationSyntax> MakeInterfaceSyntaxList(IEnumerable<MemberDeclarationSyntax> members)
{
var newMembers = ExtractInterfaceMembers( members ).ToArray();
var syntaxList = new SyntaxList<MemberDeclarationSyntax>();
syntaxList = syntaxList.AddRange( newMembers );
return syntaxList;
}
private static IEnumerable<MemberDeclarationSyntax> ExtractInterfaceMembers(IEnumerable<MemberDeclarationSyntax> members)
{
foreach (var member in members)
{
if (member is MethodDeclarationSyntax)
{
yield return MakeInterfaceMethod( (MethodDeclarationSyntax)member );
}
if (member is PropertyDeclarationSyntax)
{
yield return MakeInterfaceProperty( (PropertyDeclarationSyntax)member );
}
}
}
private static MethodDeclarationSyntax MakeInterfaceMethod(MethodDeclarationSyntax methodSyntax)
{
return methodSyntax.WithBody( null )
.WithModifiers( new SyntaxTokenList() )
.WithSemicolonToken( SyntaxFactory.Token( SyntaxKind.SemicolonToken ) );
}
private static PropertyDeclarationSyntax MakeInterfaceProperty(PropertyDeclarationSyntax propertySyntax)
{
var accessors = propertySyntax.AccessorList.Accessors.Select( f => MakeInterfaceAccessor( f ) );
var syntaxList = new SyntaxList<AccessorDeclarationSyntax>();
syntaxList = syntaxList.AddRange( accessors );
var accessorList = propertySyntax.AccessorList.WithAccessors( syntaxList );
return propertySyntax.WithModifiers( new SyntaxTokenList() ).WithAccessorList( accessorList );
}
private static AccessorDeclarationSyntax MakeInterfaceAccessor(AccessorDeclarationSyntax accessorSyntax)
{
return accessorSyntax.WithModifiers( new SyntaxTokenList() )
.WithBody( null )
.WithSemicolonToken( SyntaxFactory.Token( SyntaxKind.SemicolonToken ) );
}
}
}