@@ -467,101 +467,104 @@ private async Task<List<MemberDeclarationSyntax>> GetMemberDeclarations(VBSyntax
467467 foreach ( var declarator in node . Declarators )
468468 {
469469 var splitDeclarations = await CommonConversions . SplitVariableDeclarations ( declarator , preferExplicitType : true ) ;
470- declarations . AddRange ( CreateFieldDeclarations ( splitDeclarations , isWithEvents , convertedModifiers , attributes ) ) ;
470+ declarations . AddRange ( CreateMemberDeclarations ( splitDeclarations . Variables , isWithEvents , convertedModifiers , attributes ) ) ;
471471 declarations . AddRange ( splitDeclarations . Methods . Cast < MemberDeclarationSyntax > ( ) ) ;
472472 }
473473
474474 return declarations ;
475475 }
476476
477- private IEnumerable < MemberDeclarationSyntax > CreateFieldDeclarations ( ( IReadOnlyCollection < VariableDeclarationSyntax > Variables , IReadOnlyCollection < CSharpSyntaxNode > Methods ) splitDeclarations ,
477+ private IEnumerable < MemberDeclarationSyntax > CreateMemberDeclarations ( IReadOnlyCollection < VariableDeclarationSyntax > splitDeclarationVariables ,
478478 bool isWithEvents , SyntaxTokenList convertedModifiers , List < AttributeListSyntax > attributes )
479479 {
480- foreach ( var decl in splitDeclarations . Variables )
480+ foreach ( var decl in splitDeclarationVariables )
481481 {
482482 if ( isWithEvents ) {
483- _extraUsingDirectives . Add ( "System.Runtime.CompilerServices" ) ;
484- var initializers = decl . Variables
485- . Where ( a => a . Initializer != null )
486- . ToDictionary ( v => v . Identifier . Text , v => v . Initializer ) ;
487- var fieldDecl = decl . RemoveNodes ( initializers . Values , SyntaxRemoveOptions . KeepNoTrivia ) ;
488- var initializerCollection = convertedModifiers . Any ( m => m . IsKind ( Microsoft . CodeAnalysis . CSharp . SyntaxKind . StaticKeyword ) )
489- ? _additionalInitializers . AdditionalStaticInitializers
490- : _additionalInitializers . AdditionalInstanceInitializers ;
491- foreach ( var initializer in initializers )
483+ var fieldDecls = CreateWithEventsMembers ( convertedModifiers , attributes , decl ) ;
484+ foreach ( var f in fieldDecls ) yield return f ;
485+ } else
486+ {
487+ if ( _additionalLocals . Count ( ) > 0 ) {
488+ foreach ( var additionalDecl in CreateAdditionalLocalMembers ( convertedModifiers , attributes , decl ) ) {
489+ yield return additionalDecl ;
490+ }
491+ } else
492492 {
493- initializerCollection . Add ( ( SyntaxFactory . IdentifierName ( initializer . Key ) , Microsoft . CodeAnalysis . CSharp . SyntaxKind . SimpleAssignmentExpression , initializer . Value . Value ) ) ;
493+ yield return SyntaxFactory . FieldDeclaration ( SyntaxFactory . List ( attributes ) , convertedModifiers , decl ) ;
494494 }
495495
496- var fieldDecls = _methodsWithHandles . GetDeclarationsForFieldBackedProperty ( fieldDecl ,
497- convertedModifiers , SyntaxFactory . List ( attributes ) ) ;
498- foreach ( var f in fieldDecls ) yield return f ;
496+
499497 }
500- else
501- {
502- FieldDeclarationSyntax baseFieldDeclarationSyntax ;
503- if ( _additionalLocals . Count ( ) > 0 )
504- {
505- if ( decl . Variables . Count > 1 )
506- {
507- // Currently no way to tell which _additionalLocals would apply to which initializer
508- throw new NotImplementedException (
509- "Fields with multiple declarations and initializers with ByRef parameters not currently supported" ) ;
510- }
498+ }
499+ }
511500
512- var v = decl . Variables . First ( ) ;
513- var invocations = v . Initializer . Value . DescendantNodesAndSelf ( ) . OfType < InvocationExpressionSyntax > ( ) . ToArray ( ) ;
514- if ( invocations . Length > 1 )
515- {
516- throw new NotImplementedException (
517- "Field initializers with nested method calls not currently supported" ) ;
518- }
501+ private IEnumerable < MemberDeclarationSyntax > CreateWithEventsMembers ( SyntaxTokenList convertedModifiers , List < AttributeListSyntax > attributes , VariableDeclarationSyntax decl )
502+ {
503+ _extraUsingDirectives . Add ( "System.Runtime.CompilerServices" ) ;
504+ var initializers = decl . Variables
505+ . Where ( a => a . Initializer != null )
506+ . ToDictionary ( v => v . Identifier . Text , v => v . Initializer ) ;
507+ var fieldDecl = decl . RemoveNodes ( initializers . Values , SyntaxRemoveOptions . KeepNoTrivia ) ;
508+ var initializerCollection = convertedModifiers . Any ( m => m . IsKind ( Microsoft . CodeAnalysis . CSharp . SyntaxKind . StaticKeyword ) )
509+ ? _additionalInitializers . AdditionalStaticInitializers
510+ : _additionalInitializers . AdditionalInstanceInitializers ;
511+ foreach ( var initializer in initializers ) {
512+ initializerCollection . Add ( ( SyntaxFactory . IdentifierName ( initializer . Key ) , Microsoft . CodeAnalysis . CSharp . SyntaxKind . SimpleAssignmentExpression , initializer . Value . Value ) ) ;
513+ }
519514
520- var invocationExpressionSyntax = invocations . First ( ) ;
521- var methodName = invocationExpressionSyntax . Expression
522- . ChildNodes ( ) . OfType < SimpleNameSyntax > ( ) . Last ( ) ;
523- var newMethodName = $ "{ methodName . Identifier . ValueText } _{ v . Identifier . ValueText } ";
524- var localVars = _additionalLocals . Select ( l => l . Value )
525- . Select ( al =>
526- SyntaxFactory . LocalDeclarationStatement (
527- CommonConversions . CreateVariableDeclarationAndAssignment ( al . Prefix , al . Initializer ) ) )
528- . Cast < StatementSyntax > ( ) . ToList ( ) ;
529- var newInitializer = v . Initializer . Value . ReplaceNodes (
530- v . Initializer . Value . GetAnnotatedNodes ( AdditionalLocals . Annotation ) , ( an , _ ) =>
531- {
532- // This should probably use a unique name like in MethodBodyVisitor - a collision is far less likely here
533- var id = ( ( IdentifierNameSyntax ) an ) . Identifier . ValueText ;
534- return SyntaxFactory . IdentifierName ( _additionalLocals [ id ] . Prefix ) ;
535- } ) ;
536- var body = SyntaxFactory . Block (
537- localVars . Concat ( SyntaxFactory . SingletonList ( SyntaxFactory . ReturnStatement ( newInitializer ) ) ) ) ;
538- var methodAttrs = SyntaxFactory . List < AttributeListSyntax > ( ) ;
539- // Method calls in initializers must be static in C# - Supporting this is #281
540- var modifiers = SyntaxFactory . TokenList ( SyntaxFactory . Token ( Microsoft . CodeAnalysis . CSharp . SyntaxKind . StaticKeyword ) ) ;
541- var typeConstraints = SyntaxFactory . List < TypeParameterConstraintClauseSyntax > ( ) ;
542- var parameterList = SyntaxFactory . ParameterList ( ) ;
543- var methodDecl = SyntaxFactory . MethodDeclaration ( methodAttrs , modifiers , decl . Type , null ,
544- SyntaxFactory . Identifier ( newMethodName ) , null , parameterList , typeConstraints , body , null ) ;
545- yield return methodDecl ;
546-
547- var newVar =
548- v . WithInitializer ( SyntaxFactory . EqualsValueClause (
549- SyntaxFactory . InvocationExpression ( SyntaxFactory . IdentifierName ( newMethodName ) ) ) ) ;
550- var newVarDecl =
551- SyntaxFactory . VariableDeclaration ( decl . Type , SyntaxFactory . SingletonSeparatedList ( newVar ) ) ;
552-
553- baseFieldDeclarationSyntax =
554- SyntaxFactory . FieldDeclaration ( SyntaxFactory . List ( attributes ) , convertedModifiers , newVarDecl ) ;
555- }
556- else
557- {
558- baseFieldDeclarationSyntax =
559- SyntaxFactory . FieldDeclaration ( SyntaxFactory . List ( attributes ) , convertedModifiers , decl ) ;
560- }
515+ var fieldDecls = _methodsWithHandles . GetDeclarationsForFieldBackedProperty ( fieldDecl ,
516+ convertedModifiers , SyntaxFactory . List ( attributes ) ) ;
517+ return fieldDecls ;
518+ }
561519
562- yield return baseFieldDeclarationSyntax ;
563- }
520+ private IEnumerable < MemberDeclarationSyntax > CreateAdditionalLocalMembers ( SyntaxTokenList convertedModifiers , List < AttributeListSyntax > attributes , VariableDeclarationSyntax decl )
521+ {
522+ if ( decl . Variables . Count > 1 ) {
523+ // Currently no way to tell which _additionalLocals would apply to which initializer
524+ throw new NotImplementedException (
525+ "Fields with multiple declarations and initializers with ByRef parameters not currently supported" ) ;
526+ }
527+
528+ var v = decl . Variables . First ( ) ;
529+ var invocations = v . Initializer . Value . DescendantNodesAndSelf ( ) . OfType < InvocationExpressionSyntax > ( ) . ToArray ( ) ;
530+ if ( invocations . Length > 1 ) {
531+ throw new NotImplementedException (
532+ "Field initializers with nested method calls not currently supported" ) ;
564533 }
534+
535+ var invocationExpressionSyntax = invocations . First ( ) ;
536+ var methodName = invocationExpressionSyntax . Expression
537+ . ChildNodes ( ) . OfType < SimpleNameSyntax > ( ) . Last ( ) ;
538+ var newMethodName = $ "{ methodName . Identifier . ValueText } _{ v . Identifier . ValueText } ";
539+ var localVars = _additionalLocals . Select ( l => l . Value )
540+ . Select ( al =>
541+ SyntaxFactory . LocalDeclarationStatement (
542+ CommonConversions . CreateVariableDeclarationAndAssignment ( al . Prefix , al . Initializer ) ) )
543+ . Cast < StatementSyntax > ( ) . ToList ( ) ;
544+ var newInitializer = v . Initializer . Value . ReplaceNodes (
545+ v . Initializer . Value . GetAnnotatedNodes ( AdditionalLocals . Annotation ) , ( an , _ ) => {
546+ // This should probably use a unique name like in MethodBodyVisitor - a collision is far less likely here
547+ var id = ( ( IdentifierNameSyntax ) an ) . Identifier . ValueText ;
548+ return SyntaxFactory . IdentifierName ( _additionalLocals [ id ] . Prefix ) ;
549+ } ) ;
550+ var body = SyntaxFactory . Block (
551+ localVars . Concat ( SyntaxFactory . SingletonList ( SyntaxFactory . ReturnStatement ( newInitializer ) ) ) ) ;
552+ var methodAttrs = SyntaxFactory . List < AttributeListSyntax > ( ) ;
553+ // Method calls in initializers must be static in C# - Supporting this is #281
554+ var modifiers = SyntaxFactory . TokenList ( SyntaxFactory . Token ( Microsoft . CodeAnalysis . CSharp . SyntaxKind . StaticKeyword ) ) ;
555+ var typeConstraints = SyntaxFactory . List < TypeParameterConstraintClauseSyntax > ( ) ;
556+ var parameterList = SyntaxFactory . ParameterList ( ) ;
557+ var methodDecl = SyntaxFactory . MethodDeclaration ( methodAttrs , modifiers , decl . Type , null ,
558+ SyntaxFactory . Identifier ( newMethodName ) , null , parameterList , typeConstraints , body , null ) ;
559+ yield return methodDecl ;
560+
561+ var newVar =
562+ v . WithInitializer ( SyntaxFactory . EqualsValueClause (
563+ SyntaxFactory . InvocationExpression ( SyntaxFactory . IdentifierName ( newMethodName ) ) ) ) ;
564+ var newVarDecl =
565+ SyntaxFactory . VariableDeclaration ( decl . Type , SyntaxFactory . SingletonSeparatedList ( newVar ) ) ;
566+
567+ yield return SyntaxFactory . FieldDeclaration ( SyntaxFactory . List ( attributes ) , convertedModifiers , newVarDecl ) ;
565568 }
566569
567570 private List < MethodWithHandles > GetMethodWithHandles ( VBSyntax . TypeBlockSyntax parentType )
0 commit comments