88using CS = Microsoft . CodeAnalysis . CSharp ;
99using ICSharpCode . CodeConverter . Shared ;
1010using System ;
11+ using Microsoft . CodeAnalysis . CSharp . Syntax ;
12+ using Microsoft . CodeAnalysis . CSharp ;
1113
1214namespace ICSharpCode . CodeConverter . CSharp
1315{
@@ -57,15 +59,26 @@ public IReadOnlyCollection<AdditionalAssignment> GetPostAssignments()
5759 return _hoistedNodesPerScope . Peek ( ) . OfType < AdditionalAssignment > ( ) . ToArray ( ) ;
5860 }
5961
60- public IReadOnlyCollection < HoistedStatement > GetStatements ( )
62+ public IReadOnlyCollection < HoistedLocalFunction > GetStatements ( )
6163 {
62- return _hoistedNodesPerScope . Peek ( ) . OfType < HoistedStatement > ( ) . ToArray ( ) ;
64+ return _hoistedNodesPerScope . Peek ( ) . OfType < HoistedLocalFunction > ( ) . ToArray ( ) ;
6365 }
6466
65- public async Task < SyntaxList < CS . Syntax . StatementSyntax > > CreateLocals ( VBasic . VisualBasicSyntaxNode vbNode , IEnumerable < CS . Syntax . StatementSyntax > csNodes , HashSet < string > generatedNames , SemanticModel semanticModel )
67+ public SyntaxList < StatementSyntax > CreateStatements ( VBasic . VisualBasicSyntaxNode vbNode , IEnumerable < StatementSyntax > statements , HashSet < string > generatedNames , SemanticModel semanticModel )
6668 {
67- var preDeclarations = new List < CS . Syntax . StatementSyntax > ( ) ;
68- var postAssignments = new List < CS . Syntax . StatementSyntax > ( ) ;
69+ var localFunctions = GetStatements ( ) ;
70+ var newNames = localFunctions . ToDictionary ( f => f . Id , f =>
71+ NameGenerator . GetUniqueVariableNameInScope ( semanticModel , generatedNames , vbNode , f . Prefix )
72+ ) ;
73+ statements = ReplaceNames ( statements , newNames ) ;
74+ var functions = localFunctions . Select ( f => f . LocalFunction ( newNames [ f . Id ] ) ) ;
75+ return SyntaxFactory . List ( functions . Concat ( statements ) ) ;
76+ }
77+
78+ public async Task < SyntaxList < StatementSyntax > > CreateLocals ( VBasic . VisualBasicSyntaxNode vbNode , IEnumerable < StatementSyntax > csNodes , HashSet < string > generatedNames , SemanticModel semanticModel )
79+ {
80+ var preDeclarations = new List < StatementSyntax > ( ) ;
81+ var postAssignments = new List < StatementSyntax > ( ) ;
6982
7083 var additionalDeclarationInfo = GetDeclarations ( ) ;
7184 var newNames = additionalDeclarationInfo . ToDictionary ( l => l . Id , l =>
@@ -82,9 +95,26 @@ public IReadOnlyCollection<HoistedStatement> GetStatements()
8295 postAssignments . Add ( CS . SyntaxFactory . ExpressionStatement ( assign ) ) ;
8396 }
8497
85- var statementsWithUpdatedIds = AdditionalDeclaration . ReplaceNames ( preDeclarations . Concat ( csNodes ) . Concat ( postAssignments ) , newNames ) ;
98+ var statementsWithUpdatedIds = ReplaceNames ( preDeclarations . Concat ( csNodes ) . Concat ( postAssignments ) , newNames ) ;
8699
87100 return CS . SyntaxFactory . List ( statementsWithUpdatedIds ) ;
88101 }
102+
103+ public static IEnumerable < StatementSyntax > ReplaceNames ( IEnumerable < StatementSyntax > csNodes , Dictionary < string , string > newNames )
104+ {
105+ csNodes = csNodes . Select ( csNode => ReplaceNames ( csNode , newNames ) ) . ToList ( ) ;
106+ return csNodes ;
107+ }
108+
109+ public static T ReplaceNames < T > ( T csNode , Dictionary < string , string > newNames ) where T : SyntaxNode
110+ {
111+ return csNode . ReplaceNodes ( csNode . GetAnnotatedNodes ( Annotation ) , ( _ , withReplaced ) => {
112+ var idns = ( IdentifierNameSyntax ) withReplaced ;
113+ if ( newNames . TryGetValue ( idns . Identifier . ValueText , out var newName ) ) {
114+ return idns . WithoutAnnotations ( Annotation ) . WithIdentifier ( CS . SyntaxFactory . Identifier ( newName ) ) ;
115+ }
116+ return idns ;
117+ } ) ;
118+ }
89119 }
90120}
0 commit comments