@@ -29,15 +29,14 @@ internal class DeclarationNodeVisitor : VBasic.VisualBasicSyntaxVisitor<Task<CSh
2929 private static readonly Type DllImportType = typeof ( DllImportAttribute ) ;
3030 private static readonly Type CharSetType = typeof ( CharSet ) ;
3131 private static readonly SyntaxToken SemicolonToken = SyntaxFactory . Token ( Microsoft . CodeAnalysis . CSharp . SyntaxKind . SemicolonToken ) ;
32- private static readonly TypeSyntax VarType = SyntaxFactory . ParseTypeName ( "var" ) ;
3332 private readonly CSharpCompilation _csCompilation ;
3433 private readonly SyntaxGenerator _csSyntaxGenerator ;
3534 private readonly Compilation _compilation ;
3635 private readonly SemanticModel _semanticModel ;
3736 private readonly MethodsWithHandles _methodsWithHandles = new MethodsWithHandles ( ) ;
3837 private readonly Dictionary < VBSyntax . StatementSyntax , MemberDeclarationSyntax [ ] > _additionalDeclarations = new Dictionary < VBSyntax . StatementSyntax , MemberDeclarationSyntax [ ] > ( ) ;
3938 private readonly AdditionalInitializers _additionalInitializers ;
40- private readonly AdditionalLocals _additionalLocals = new AdditionalLocals ( ) ;
39+ private readonly HoistedNodeState _additionalLocals = new HoistedNodeState ( ) ;
4140 private uint _failedMemberConversionMarkerCount ;
4241 private readonly HashSet < string > _extraUsingDirectives = new HashSet < string > ( ) ;
4342 private readonly VisualBasicEqualityComparison _visualBasicEqualityComparison ;
@@ -490,7 +489,7 @@ private IEnumerable<MemberDeclarationSyntax> CreateMemberDeclarations(IReadOnlyC
490489 foreach ( var f in fieldDecls ) yield return f ;
491490 } else
492491 {
493- if ( _additionalLocals . Count ( ) > 0 ) {
492+ if ( _additionalLocals . GetDeclarations ( ) . Count ( ) > 0 ) {
494493 foreach ( var additionalDecl in CreateAdditionalLocalMembers ( convertedModifiers , attributes , decl ) ) {
495494 yield return additionalDecl ;
496495 }
@@ -547,26 +546,19 @@ private IEnumerable<MemberDeclarationSyntax> CreateAdditionalLocalMembers(Syntax
547546 var methodName = invocationExpressionSyntax . Expression
548547 . ChildNodes ( ) . OfType < SimpleNameSyntax > ( ) . Last ( ) ;
549548 var newMethodName = $ "{ methodName . Identifier . ValueText } _{ v . Identifier . ValueText } ";
550- var localVars = _additionalLocals . Select ( l => l . Value )
551- . Select ( al =>
552- SyntaxFactory . LocalDeclarationStatement (
553- CommonConversions . CreateVariableDeclarationAndAssignment ( al . Prefix , al . Initializer ) ) )
554- . Cast < StatementSyntax > ( ) . ToList ( ) ;
555- var newInitializer = v . Initializer . Value . ReplaceNodes (
556- v . Initializer . Value . GetAnnotatedNodes ( AdditionalLocals . Annotation ) , ( an , _ ) => {
557- // This should probably use a unique name like in MethodBodyVisitor - a collision is far less likely here
558- var id = ( ( IdentifierNameSyntax ) an ) . Identifier . ValueText ;
559- return SyntaxFactory . IdentifierName ( _additionalLocals [ id ] . Prefix ) ;
560- } ) ;
561- var body = SyntaxFactory . Block (
562- localVars . Concat ( SyntaxFactory . SingletonList ( SyntaxFactory . ReturnStatement ( newInitializer ) ) ) ) ;
563- var methodAttrs = SyntaxFactory . List < AttributeListSyntax > ( ) ;
549+ var declarationInfo = _additionalLocals . GetDeclarations ( ) ;
550+
551+ var localVars = declarationInfo
552+ . Select ( al => CommonConversions . CreateLocalVariableDeclarationAndAssignment ( al . Prefix , al . Initializer ) )
553+ . ToArray < StatementSyntax > ( ) ;
554+
555+ // This should probably use a unique name like in MethodBodyVisitor - a collision is far less likely here
556+ var newNames = declarationInfo . ToDictionary ( l => l . Id , l => l . Prefix ) ;
557+ var newInitializer = HoistedNodeState . ReplaceNames ( v . Initializer . Value , newNames ) ;
558+
559+ var body = SyntaxFactory . Block ( localVars . Concat ( SyntaxFactory . ReturnStatement ( newInitializer ) . Yield ( ) ) ) ;
564560 // Method calls in initializers must be static in C# - Supporting this is #281
565- var modifiers = SyntaxFactory . TokenList ( SyntaxFactory . Token ( Microsoft . CodeAnalysis . CSharp . SyntaxKind . StaticKeyword ) ) ;
566- var typeConstraints = SyntaxFactory . List < TypeParameterConstraintClauseSyntax > ( ) ;
567- var parameterList = SyntaxFactory . ParameterList ( ) ;
568- var methodDecl = SyntaxFactory . MethodDeclaration ( methodAttrs , modifiers , decl . Type , null ,
569- SyntaxFactory . Identifier ( newMethodName ) , null , parameterList , typeConstraints , body , null ) ;
561+ var methodDecl = CreateParameterlessMethod ( newMethodName , decl . Type , body ) ;
570562 yield return methodDecl ;
571563
572564 var newVar =
@@ -578,6 +570,17 @@ private IEnumerable<MemberDeclarationSyntax> CreateAdditionalLocalMembers(Syntax
578570 yield return SyntaxFactory . FieldDeclaration ( SyntaxFactory . List ( attributes ) , convertedModifiers , newVarDecl ) ;
579571 }
580572
573+ private static MethodDeclarationSyntax CreateParameterlessMethod ( string newMethodName , TypeSyntax type , BlockSyntax body )
574+ {
575+ var modifiers = SyntaxFactory . TokenList ( SyntaxFactory . Token ( Microsoft . CodeAnalysis . CSharp . SyntaxKind . StaticKeyword ) ) ;
576+ var typeConstraints = SyntaxFactory . List < TypeParameterConstraintClauseSyntax > ( ) ;
577+ var parameterList = SyntaxFactory . ParameterList ( ) ;
578+ var methodAttrs = SyntaxFactory . List < AttributeListSyntax > ( ) ;
579+ var methodDecl = SyntaxFactory . MethodDeclaration ( methodAttrs , modifiers , type , null ,
580+ SyntaxFactory . Identifier ( newMethodName ) , null , parameterList , typeConstraints , body , null ) ;
581+ return methodDecl ;
582+ }
583+
581584 private List < MethodWithHandles > GetMethodWithHandles ( VBSyntax . TypeBlockSyntax parentType )
582585 {
583586 if ( parentType == null || ! ( this . _semanticModel . GetDeclaredSymbol ( ( global ::Microsoft . CodeAnalysis . SyntaxNode ) parentType ) is ITypeSymbol containingType ) ) return new List < MethodWithHandles > ( ) ;
@@ -1077,7 +1080,7 @@ public override async Task<CSharpSyntaxNode> VisitEventBlock(VBSyntax.EventBlock
10771080 var attributes = await block . AttributeLists . SelectManyAsync ( CommonConversions . ConvertAttribute ) ;
10781081 var modifiers = CommonConversions . ConvertModifiers ( block , block . Modifiers , GetMemberContext ( node ) ) ;
10791082
1080- var rawType = ( TypeSyntax ) await ( block . AsClause ? . Type ) . AcceptAsync ( _triviaConvertingExpressionVisitor ) ?? VarType ;
1083+ var rawType = ( TypeSyntax ) await ( block . AsClause ? . Type ) . AcceptAsync ( _triviaConvertingExpressionVisitor ) ?? ValidSyntaxFactory . VarType ;
10811084
10821085 var convertedAccessors = await node . Accessors . SelectAsync ( async a => await a . AcceptAsync ( TriviaConvertingDeclarationVisitor ) ) ;
10831086 _additionalDeclarations . Add ( node , convertedAccessors . OfType < MemberDeclarationSyntax > ( ) . ToArray ( ) ) ;
0 commit comments