Skip to content

Commit 21f074d

Browse files
Refactor to make space for PreResumeLayout calls
1 parent 2231b65 commit 21f074d

9 files changed

Lines changed: 162 additions & 61 deletions

File tree

ICSharpCode.CodeConverter/CSharp/CommonConversions.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,12 @@ public SyntaxToken ConvertIdentifier(SyntaxToken id, bool isAttribute = false)
340340

341341
public static bool MustInlinePropertyWithEventsAccess(SyntaxNode anyNodePossiblyWithinMethod, ISymbol potentialPropertySymbol)
342342
{
343-
return anyNodePossiblyWithinMethod.GetAncestor<MethodBlockSyntax>()?.SubOrFunctionStatement.Identifier.Text == "InitializeComponent" && potentialPropertySymbol is IPropertySymbol prop && prop.IsWithEvents;
343+
return InMethodCalledInitializeComponent(anyNodePossiblyWithinMethod) && potentialPropertySymbol is IPropertySymbol prop && prop.IsWithEvents;
344+
}
345+
346+
public static bool InMethodCalledInitializeComponent(SyntaxNode anyNodePossiblyWithinMethod)
347+
{
348+
return anyNodePossiblyWithinMethod.GetAncestor<MethodBlockSyntax>()?.SubOrFunctionStatement.Identifier.Text == "InitializeComponent";
344349
}
345350

346351
private static SyntaxToken CsEscapedIdentifier(string text)

ICSharpCode.CodeConverter/CSharp/MethodBodyVisitor.cs

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class MethodBodyVisitor : VBasic.VisualBasicSyntaxVisitor<SyntaxList<StatementSy
2828
private readonly VBasic.VisualBasicSyntaxVisitor<CSharpSyntaxNode> _nodesVisitor;
2929
private readonly Stack<string> _withBlockTempVariableNames;
3030
private readonly HashSet<string> _extraUsingDirectives;
31-
private readonly ILookup<string, MethodWithHandles> _handledMethodsFromPropertyWithEventName;
31+
private readonly MethodsWithHandles _methodsWithHandles;
3232
private readonly HashSet<string> _generatedNames = new HashSet<string>();
3333

3434
public bool IsIterator { get; set; }
@@ -41,7 +41,7 @@ class MethodBodyVisitor : VBasic.VisualBasicSyntaxVisitor<SyntaxList<StatementSy
4141
public MethodBodyVisitor(VBasic.VisualBasicSyntaxNode methodNode, SemanticModel semanticModel,
4242
VBasic.VisualBasicSyntaxVisitor<CSharpSyntaxNode> nodesVisitor, CommonConversions commonConversions,
4343
Stack<string> withBlockTempVariableNames, HashSet<string> extraUsingDirectives,
44-
AdditionalLocals additionalLocals, ILookup<string, MethodWithHandles> handledMethodsFromPropertyWithEventName,
44+
AdditionalLocals additionalLocals, MethodsWithHandles methodsWithHandles,
4545
TriviaConverter triviaConverter)
4646
{
4747
_methodNode = methodNode;
@@ -50,7 +50,7 @@ public MethodBodyVisitor(VBasic.VisualBasicSyntaxNode methodNode, SemanticModel
5050
CommonConversions = commonConversions;
5151
_withBlockTempVariableNames = withBlockTempVariableNames;
5252
_extraUsingDirectives = extraUsingDirectives;
53-
_handledMethodsFromPropertyWithEventName = handledMethodsFromPropertyWithEventName;
53+
_methodsWithHandles = methodsWithHandles;
5454
var byRefParameterVisitor = new ByRefParameterVisitor(this, additionalLocals, semanticModel, _generatedNames);
5555
CommentConvertingVisitor = new CommentConvertingMethodBodyVisitor(byRefParameterVisitor, triviaConverter);
5656
}
@@ -116,12 +116,17 @@ private static SyntaxKind ConvertAddRemoveHandlerToCSharpSyntaxKind(VBSyntax.Add
116116

117117
public override SyntaxList<StatementSyntax> VisitExpressionStatement(VBSyntax.ExpressionStatementSyntax node)
118118
{
119-
var invoke = node.Expression as VBSyntax.InvocationExpressionSyntax;
120-
if (invoke != null &&
121-
invoke.Expression is VBSyntax.MemberAccessExpressionSyntax expr &&
122-
expr.Expression is VBSyntax.MyBaseExpressionSyntax &&
123-
expr.Name.Identifier.ValueText.Equals("Finalize", StringComparison.OrdinalIgnoreCase)) {
124-
return new SyntaxList<StatementSyntax>();
119+
if (node.Expression is VBSyntax.InvocationExpressionSyntax invoke && invoke.Expression is VBSyntax.MemberAccessExpressionSyntax access) {
120+
if (access.Expression is VBSyntax.MyBaseExpressionSyntax && access.Name.Identifier.ValueText.Equals("Finalize", StringComparison.OrdinalIgnoreCase)) {
121+
return new SyntaxList<StatementSyntax>();
122+
} else if (CommonConversions.InMethodCalledInitializeComponent(node) &&
123+
access.Name.Identifier.ValueText.Equals("ResumeLayout",
124+
StringComparison.OrdinalIgnoreCase)) {
125+
var eventSubscriptionStatements = _methodsWithHandles.GetPreResumeLayoutEventHandlers();
126+
if (eventSubscriptionStatements.Any()) {
127+
return SyntaxFactory.List(eventSubscriptionStatements.Concat(SingleStatement((ExpressionSyntax)node.Expression.Accept(_nodesVisitor))));
128+
}
129+
}
125130
}
126131

127132
return SingleStatement((ExpressionSyntax)node.Expression.Accept(_nodesVisitor));
@@ -152,22 +157,10 @@ _methodNode is VBSyntax.MethodBlockSyntax mb &&
152157
return postAssignment.Insert(0, SyntaxFactory.ExpressionStatement(assignment));
153158
}
154159

155-
/// <summary>
156-
/// Make winforms designer work: https://github.com/icsharpcode/CodeConverter/issues/321
157-
/// </summary>
158160
private SyntaxList<StatementSyntax> GetPostAssignmentStatements(VBSyntax.AssignmentStatementSyntax node)
159161
{
160162
var potentialPropertySymbol = _semanticModel.GetSymbolInfo(node.Left).ExtractBestMatch();
161-
if (CommonConversions.MustInlinePropertyWithEventsAccess(node, potentialPropertySymbol)) {
162-
var fieldName = SyntaxFactory.IdentifierName("_" + potentialPropertySymbol.Name);
163-
var handledMethods = _handledMethodsFromPropertyWithEventName[potentialPropertySymbol.Name].ToArray();
164-
if (handledMethods.Any()) {
165-
var postAssignmentStatements = handledMethods.SelectMany(h => h.GetPostInitializationStatements(potentialPropertySymbol.Name, fieldName));
166-
return SyntaxFactory.List(postAssignmentStatements);
167-
}
168-
}
169-
170-
return SyntaxFactory.List<StatementSyntax>();
163+
return _methodsWithHandles.GetPostAssignmentStatements(node, potentialPropertySymbol);
171164
}
172165

173166
public override SyntaxList<StatementSyntax> VisitEraseStatement(VBSyntax.EraseStatementSyntax node)

ICSharpCode.CodeConverter/CSharp/MethodWithHandles.cs

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,19 @@ namespace ICSharpCode.CodeConverter.CSharp
1010
{
1111
public class MethodWithHandles
1212
{
13+
private IdentifierNameSyntax _methodId;
1314
public SyntaxToken MethodCSharpId { get; }
14-
public List<(SyntaxToken, SyntaxToken)> HandledEventCSharpIds { get; }
15+
public List<(SyntaxToken EventContainerName, SyntaxToken EventSymbolName)> HandledPropertyEventCSharpIds { get; }
16+
public List<(SyntaxToken EventContainerName, SyntaxToken EventSymbolName)> HandledClassEventCSharpIds { get; }
1517

16-
public MethodWithHandles(SyntaxToken methodCSharpId, List<(SyntaxToken EventContainerName, SyntaxToken EventSymbolName)> handledEventCSharpIds)
18+
public MethodWithHandles(SyntaxToken methodCSharpId,
19+
List<(SyntaxToken EventContainerName, SyntaxToken EventSymbolName)> handledPropertyEventCSharpIds,
20+
List<(SyntaxToken, SyntaxToken)> handledClassEventCSharpIds)
1721
{
1822
MethodCSharpId = methodCSharpId;
19-
HandledEventCSharpIds = handledEventCSharpIds;
23+
HandledPropertyEventCSharpIds = handledPropertyEventCSharpIds;
24+
HandledClassEventCSharpIds = handledClassEventCSharpIds;
25+
_methodId = SyntaxFactory.IdentifierName(MethodCSharpId);
2026
}
2127

2228
public static IEnumerable<MemberDeclarationSyntax> GetDeclarationsForFieldBackedProperty(
@@ -89,22 +95,32 @@ public IEnumerable<StatementSyntax> GetPostInitializationStatements(string prope
8995
return CreateHandlesUpdater(propertyIdentifier, fieldIdSyntax, SyntaxKind.AddAssignmentExpression);
9096
}
9197

92-
private IEnumerable<ExpressionStatementSyntax> CreateHandlesUpdater(string propertyIdentifier,
98+
private IEnumerable<StatementSyntax> CreateHandlesUpdater(string propertyIdentifier,
9399
IdentifierNameSyntax fieldIdSyntax, SyntaxKind assignmentExpressionKind)
94100
{
95-
var methodId = SyntaxFactory.IdentifierName(MethodCSharpId);
96-
return HandledEventCSharpIds
97-
.Where(h => h.Item1.Text == propertyIdentifier)
98-
.Select(e =>
99-
{
100-
var handledFieldMember = SyntaxFactory.MemberAccessExpression(
101-
SyntaxKind.SimpleMemberAccessExpression,
102-
fieldIdSyntax, SyntaxFactory.IdentifierName(e.Item2));
103-
return SyntaxFactory.ExpressionStatement(
104-
SyntaxFactory.AssignmentExpression(assignmentExpressionKind,
105-
handledFieldMember,
106-
methodId));
107-
});
101+
return HandledPropertyEventCSharpIds
102+
.Where(h => h.EventContainerName.Text == propertyIdentifier)
103+
.Select(e => CreateHandlesUpdater(fieldIdSyntax, e, assignmentExpressionKind));
104+
}
105+
106+
private StatementSyntax CreateHandlesUpdater(IdentifierNameSyntax eventSource,
107+
(SyntaxToken EventContainerName, SyntaxToken EventSymbolName) e,
108+
SyntaxKind assignmentExpressionKind)
109+
{
110+
var handledFieldMember = SyntaxFactory.MemberAccessExpression(
111+
SyntaxKind.SimpleMemberAccessExpression,
112+
eventSource, SyntaxFactory.IdentifierName(e.EventSymbolName));
113+
return SyntaxFactory.ExpressionStatement(
114+
SyntaxFactory.AssignmentExpression(assignmentExpressionKind,
115+
handledFieldMember,
116+
_methodId));
117+
}
118+
119+
120+
public IEnumerable<StatementSyntax> GetPreResumeLayoutEventHandlers()
121+
{
122+
return HandledClassEventCSharpIds.Select(e =>
123+
CreateHandlesUpdater(SyntaxFactory.IdentifierName(e.EventContainerName), e, SyntaxKind.AddAssignmentExpression));
108124
}
109125

110126

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using Microsoft.CodeAnalysis;
5+
using Microsoft.CodeAnalysis.CSharp;
6+
using Microsoft.CodeAnalysis.CSharp.Syntax;
7+
8+
namespace ICSharpCode.CodeConverter.CSharp
9+
{
10+
internal class MethodsWithHandles
11+
{
12+
private readonly List<MethodWithHandles> _methodWithHandleses;
13+
private readonly ILookup<string, MethodWithHandles> _handledMethodsFromPropertyWithEventName;
14+
15+
public MethodsWithHandles(List<MethodWithHandles> methodWithHandleses)
16+
{
17+
_methodWithHandleses = methodWithHandleses;
18+
_handledMethodsFromPropertyWithEventName = methodWithHandleses
19+
.SelectMany(m => m.HandledPropertyEventCSharpIds.Select(h => (EventPropertyName: h.Item1.Text, MethodWithHandles: m)))
20+
.ToLookup(m => m.EventPropertyName, m => m.MethodWithHandles);
21+
}
22+
23+
public bool Any()
24+
{
25+
return _methodWithHandleses.Any();
26+
}
27+
28+
public IEnumerable<MemberDeclarationSyntax> GetDeclarationsForFieldBackedProperty(VariableDeclarationSyntax fieldDecl, SyntaxTokenList convertedModifiers, SyntaxList<AttributeListSyntax> list)
29+
{
30+
return MethodWithHandles.GetDeclarationsForFieldBackedProperty(fieldDecl, convertedModifiers, list,
31+
_methodWithHandleses);
32+
}
33+
34+
35+
/// <summary>
36+
/// Make winforms designer work: https://github.com/icsharpcode/CodeConverter/issues/321
37+
/// </summary>
38+
public SyntaxList<StatementSyntax> GetPostAssignmentStatements(Microsoft.CodeAnalysis.VisualBasic.Syntax.AssignmentStatementSyntax node, ISymbol potentialPropertySymbol)
39+
{
40+
if (CommonConversions.MustInlinePropertyWithEventsAccess(node, potentialPropertySymbol))
41+
{
42+
var fieldName = SyntaxFactory.IdentifierName("_" + potentialPropertySymbol.Name);
43+
var handledMethods = _handledMethodsFromPropertyWithEventName[potentialPropertySymbol.Name].ToArray();
44+
if (handledMethods.Any())
45+
{
46+
var postAssignmentStatements = handledMethods.SelectMany(h =>
47+
h.GetPostInitializationStatements(potentialPropertySymbol.Name, fieldName));
48+
return SyntaxFactory.List(postAssignmentStatements);
49+
}
50+
}
51+
52+
return SyntaxFactory.List<StatementSyntax>();
53+
}
54+
55+
public SyntaxList<StatementSyntax> GetPreResumeLayoutEventHandlers()
56+
{
57+
var handledMethods = _methodWithHandleses.SelectMany(m => m.GetPreResumeLayoutEventHandlers()).ToArray();
58+
return SyntaxFactory.List(handledMethods);
59+
}
60+
}
61+
}

0 commit comments

Comments
 (0)