1919
2020namespace ICSharpCode . CodeConverter . CSharp
2121{
22+
2223 /// <summary>
2324 /// Declaration nodes, and nodes only used directly in that declaration (i.e. never within an expression)
2425 /// e.g. Class, Enum, TypeConstraint
@@ -33,18 +34,15 @@ internal class DeclarationNodeVisitor : VBasic.VisualBasicSyntaxVisitor<Task<CSh
3334 private readonly SyntaxGenerator _csSyntaxGenerator ;
3435 private readonly Compilation _compilation ;
3536 private readonly SemanticModel _semanticModel ;
36- private readonly MethodsWithHandles _methodsWithHandles = new MethodsWithHandles ( ) ;
3737 private readonly Dictionary < VBSyntax . StatementSyntax , MemberDeclarationSyntax [ ] > _additionalDeclarations = new Dictionary < VBSyntax . StatementSyntax , MemberDeclarationSyntax [ ] > ( ) ;
38- private readonly AdditionalInitializers _additionalInitializers ;
38+ private readonly TypeContext _typeContext = new TypeContext ( ) ;
3939 private readonly HoistedNodeState _additionalLocals = new HoistedNodeState ( ) ;
4040 private uint _failedMemberConversionMarkerCount ;
4141 private readonly HashSet < string > _extraUsingDirectives = new HashSet < string > ( ) ;
4242 private readonly VisualBasicEqualityComparison _visualBasicEqualityComparison ;
4343 private HashSet < string > _accessedThroughMyClass ;
4444 public CommentConvertingVisitorWrapper TriviaConvertingDeclarationVisitor { get ; }
4545 private readonly CommentConvertingVisitorWrapper _triviaConvertingExpressionVisitor ;
46-
47-
4846 private string _topAncestorNamespace ;
4947
5048 private CommonConversions CommonConversions { get ; }
@@ -62,8 +60,7 @@ public DeclarationNodeVisitor(Document document, Compilation compilation, Semant
6260 var expressionEvaluator = new ExpressionEvaluator ( semanticModel , _visualBasicEqualityComparison ) ;
6361 var typeConversionAnalyzer = new TypeConversionAnalyzer ( semanticModel , csCompilation , _extraUsingDirectives , _csSyntaxGenerator , expressionEvaluator ) ;
6462 CommonConversions = new CommonConversions ( document , semanticModel , typeConversionAnalyzer , csSyntaxGenerator , csCompilation ) ;
65- _additionalInitializers = new AdditionalInitializers ( ) ;
66- var expressionNodeVisitor = new ExpressionNodeVisitor ( semanticModel , _visualBasicEqualityComparison , _additionalLocals , csCompilation , _methodsWithHandles , CommonConversions , _extraUsingDirectives ) ;
63+ var expressionNodeVisitor = new ExpressionNodeVisitor ( semanticModel , _visualBasicEqualityComparison , _additionalLocals , csCompilation , _typeContext , CommonConversions , _extraUsingDirectives ) ;
6764 _triviaConvertingExpressionVisitor = expressionNodeVisitor . TriviaConvertingExpressionVisitor ;
6865 _createMethodBodyVisitorAsync = expressionNodeVisitor . CreateMethodBodyVisitor ;
6966 CommonConversions . TriviaConvertingExpressionVisitor = _triviaConvertingExpressionVisitor ;
@@ -196,15 +193,12 @@ private async Task<string> WithDeclarationCasing(VBSyntax.NamespaceBlockSyntax n
196193 private async Task < IEnumerable < MemberDeclarationSyntax > > ConvertMembers ( VBSyntax . TypeBlockSyntax parentType )
197194 {
198195 var members = parentType . Members ;
196+ var additionalInitializers = new AdditionalInitializers ( ) ;
197+ var methodsWithHandles = MethodsWithHandles . Create ( GetMethodWithHandles ( parentType ) ) ;
199198
200- //TODO: Store these per-type so nested classes aren't affected
201- _methodsWithHandles . Initialize ( GetMethodWithHandles ( parentType ) ) ;
202- _additionalInitializers . AdditionalInstanceInitializers . Clear ( ) ;
203- _additionalInitializers . AdditionalInstanceInitializers . Clear ( ) ;
199+ if ( methodsWithHandles . Any ( ) ) _extraUsingDirectives . Add ( "System.Runtime.CompilerServices" ) ; //For MethodImplOptions.Synchronized
204200
205- if ( _methodsWithHandles . Any ( ) ) _extraUsingDirectives . Add ( "System.Runtime.CompilerServices" ) ; //For MethodImplOptions.Synchronized
206-
207- var directlyConvertedMembers = await GetDirectlyConvertMembers ( ) ;
201+ IEnumerable < MemberDeclarationSyntax > directlyConvertedMembers = await GetDirectlyConvertedMembers ( additionalInitializers , methodsWithHandles ) ;
208202
209203 var namedTypeSymbol = _semanticModel . GetDeclaredSymbol ( parentType ) ;
210204 bool shouldAddTypeWideInitToThisPart = ShouldAddTypeWideInitToThisPart ( parentType , namedTypeSymbol ) ;
@@ -213,19 +207,24 @@ private async Task<IEnumerable<MemberDeclarationSyntax>> ConvertMembers(VBSyntax
213207 if ( shouldAddTypeWideInitToThisPart ) {
214208 if ( requiresInitializeComponent ) {
215209 // Constructor event handlers not required since they'll be inside InitializeComponent
216- directlyConvertedMembers = directlyConvertedMembers . Concat ( _methodsWithHandles . CreateDelegatingMethodsRequiredByInitializeComponent ( ) ) ;
210+ directlyConvertedMembers = directlyConvertedMembers . Concat ( methodsWithHandles . CreateDelegatingMethodsRequiredByInitializeComponent ( ) ) ;
217211 } else {
218- _additionalInitializers . AdditionalInstanceInitializers . AddRange ( _methodsWithHandles . GetConstructorEventHandlers ( ) ) ;
212+ additionalInitializers . AdditionalInstanceInitializers . AddRange ( methodsWithHandles . GetConstructorEventHandlers ( ) ) ;
219213 }
220214 }
221215
222- return _additionalInitializers . WithAdditionalInitializers ( namedTypeSymbol , directlyConvertedMembers . ToList ( ) , CommonConversions . ConvertIdentifier ( parentType . BlockStatement . Identifier ) , shouldAddTypeWideInitToThisPart , requiresInitializeComponent ) ;
216+ return additionalInitializers . WithAdditionalInitializers ( namedTypeSymbol , directlyConvertedMembers . ToList ( ) , CommonConversions . ConvertIdentifier ( parentType . BlockStatement . Identifier ) , shouldAddTypeWideInitToThisPart , requiresInitializeComponent ) ;
223217
224- async Task < IEnumerable < MemberDeclarationSyntax > > GetDirectlyConvertMembers ( )
218+ async Task < MemberDeclarationSyntax [ ] > GetDirectlyConvertedMembers ( AdditionalInitializers additionalInitializers , MethodsWithHandles methodsWithHandles )
225219 {
226- return await members . SelectManyAsync ( async member =>
227- new [ ] { await ConvertMember ( member ) } . Concat ( GetAdditionalDeclarations ( member ) ) ) ;
228-
220+ _typeContext . Push ( methodsWithHandles , additionalInitializers ) ;
221+ try {
222+ var convertedMembers = await members . SelectManyAsync ( async member =>
223+ new [ ] { await ConvertMember ( member ) } . Concat ( GetAdditionalDeclarations ( member ) ) ) ;
224+ return convertedMembers . ToArray ( ) ;
225+ } finally {
226+ _typeContext . Pop ( ) ;
227+ }
229228 }
230229 }
231230
@@ -515,14 +514,15 @@ private IEnumerable<MemberDeclarationSyntax> CreateWithEventsMembers(SyntaxToken
515514 . Where ( a => a . Initializer != null )
516515 . ToDictionary ( v => v . Identifier . Text , v => v . Initializer ) ;
517516 var fieldDecl = decl . RemoveNodes ( initializers . Values , SyntaxRemoveOptions . KeepNoTrivia ) ;
517+ var initializerState = _typeContext . Initializers ;
518518 var initializerCollection = convertedModifiers . Any ( m => m . IsKind ( Microsoft . CodeAnalysis . CSharp . SyntaxKind . StaticKeyword ) )
519- ? _additionalInitializers . AdditionalStaticInitializers
520- : _additionalInitializers . AdditionalInstanceInitializers ;
519+ ? initializerState . AdditionalStaticInitializers
520+ : initializerState . AdditionalInstanceInitializers ;
521521 foreach ( var initializer in initializers ) {
522522 initializerCollection . Add ( ( SyntaxFactory . IdentifierName ( initializer . Key ) , Microsoft . CodeAnalysis . CSharp . SyntaxKind . SimpleAssignmentExpression , initializer . Value . Value ) ) ;
523523 }
524524
525- var fieldDecls = _methodsWithHandles . GetDeclarationsForFieldBackedProperty ( fieldDecl ,
525+ var fieldDecls = _typeContext . MethodsWithHandles . GetDeclarationsForFieldBackedProperty ( fieldDecl ,
526526 convertedModifiers , SyntaxFactory . List ( attributes ) ) ;
527527 return fieldDecls ;
528528 }
@@ -897,7 +897,7 @@ public override async Task<CSharpSyntaxNode> VisitMethodBlock(VBSyntax.MethodBlo
897897
898898 if ( node . SubOrFunctionStatement . Identifier . Text == "InitializeComponent" && node . SubOrFunctionStatement . IsKind ( VBasic . SyntaxKind . SubStatement ) && declaredSymbol . ContainingType . IsDesignerGeneratedTypeWithInitializeComponent ( _compilation ) ) {
899899 var firstResumeLayout = convertedStatements . Statements . FirstOrDefault ( IsThisResumeLayoutInvocation ) ?? convertedStatements . Statements . Last ( ) ;
900- convertedStatements = convertedStatements . InsertNodesBefore ( firstResumeLayout , _methodsWithHandles . GetInitializeComponentClassEventHandlers ( ) ) ;
900+ convertedStatements = convertedStatements . InsertNodesBefore ( firstResumeLayout , _typeContext . MethodsWithHandles . GetInitializeComponentClassEventHandlers ( ) ) ;
901901 }
902902
903903 var body = WithImplicitReturnStatements ( node , convertedStatements , csReturnVariableOrNull ) ;
0 commit comments