Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue/774 #802

Merged
merged 28 commits into from
Dec 23, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
15d7c54
Add override properties to handle event assignment for base members
GrahamTheCoder Dec 16, 2021
7bfb6ff
Initialize in test
GrahamTheCoder Dec 16, 2021
9570922
Comments
GrahamTheCoder Dec 16, 2021
ede09e9
Only generate property and modify InitializeComponent when written to…
GrahamTheCoder Dec 20, 2021
76699bc
Extract analysis code
GrahamTheCoder Dec 20, 2021
6b8894e
Use langversion 10
GrahamTheCoder Dec 20, 2021
1bea55d
Allow using C#10+ features
GrahamTheCoder Dec 20, 2021
cc562ee
Pull together analysis per event container
GrahamTheCoder Dec 20, 2021
cedb715
Assign property in constructor to wire up overridden events
GrahamTheCoder Dec 21, 2021
c534eb4
LangVersion 9 needed for vsix
GrahamTheCoder Dec 21, 2021
5e440b4
Deal with nulls
GrahamTheCoder Dec 22, 2021
ac6f8eb
Update dotnet.yml
GrahamTheCoder Dec 22, 2021
640940a
Update dotnet.yml
GrahamTheCoder Dec 22, 2021
3f3635e
Update dotnet.yml
GrahamTheCoder Dec 22, 2021
6537080
See if msbuild can build the test projects
GrahamTheCoder Dec 22, 2021
50b980d
Reference later version of MSBuild
GrahamTheCoder Dec 22, 2021
1ae21cc
Don't treat single InitializeComponent assignment as requiring a prop…
GrahamTheCoder Dec 22, 2021
9100a18
Only create delegating property if the conversion contains a write us…
GrahamTheCoder Dec 22, 2021
d05ae99
Generate delegates for all
GrahamTheCoder Dec 22, 2021
caf0352
Update source files to work with latest net framework
GrahamTheCoder Dec 22, 2021
cd6bdc7
Update characterization result
GrahamTheCoder Dec 22, 2021
5e8d37b
Revert "See if msbuild can build the test projects" (it can now)
GrahamTheCoder Dec 22, 2021
00af33a
Find if there are overriding classes in the compilation
GrahamTheCoder Dec 22, 2021
d3f74ac
Fix using statements
GrahamTheCoder Dec 22, 2021
9f834ad
Only do this once per compilation
GrahamTheCoder Dec 23, 2021
ce3b27d
Use the full metadata name in an equality comparer
GrahamTheCoder Dec 23, 2021
517bb5c
Changelog
GrahamTheCoder Dec 23, 2021
a78435c
Version 8.4.3
GrahamTheCoder Dec 23, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ on:

jobs:
build:
runs-on: windows-latest
runs-on: windows-2022
env:
BuildVersion: '8.4.2'
BuildVersion: '8.4.3'
BuildPlatform: Any CPU
BuildTarget: Release

Expand All @@ -33,7 +33,7 @@ jobs:
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.1
with:
vs-version: '[16.6,)'
vs-version: '[17.0,)'

- name: Dotnet deterministic Build
run: dotnet build DotNetBuildable.slnf /p:Platform=$env:BuildPlatform /p:Configuration=$env:BuildTarget /p:ContinuousIntegrationBuild=true
Expand Down
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,23 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
### Vsix


### VB -> C#


### C# -> VB


## [8.4.3] - 2021-12-23


### Vsix


### VB -> C#

* Convert extension methods on ByRef reference types to static invocations [#785](https://github.com/icsharpcode/CodeConverter/issues/785)
* Wire up events for WithEvents fields in an ancestor class [#774](https://github.com/icsharpcode/CodeConverter/issues/774)
* Only create delegating property for WithEvents fields if there is a *known* write usage or descendant class [Due to feedback on #615](https://github.com/icsharpcode/CodeConverter/issues/615#issuecomment-993151917)

### C# -> VB

Expand Down
6 changes: 3 additions & 3 deletions CodeConverter/CSharp/AdditionalInitializers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,12 @@ public AdditionalInitializers(VBSyntax.TypeBlockSyntax typeSyntax, INamedTypeSym
HasInstanceConstructorsOutsideThisPart = instanceConstructors.Any(c => c.DeclaringSyntaxReferences.Any(
reference => !typeSyntax.OverlapsWith(reference)
)) || !instanceConstructors.Any() && !isBestPartToAddParameterlessConstructor;
RequiresInitializeComponent = namedTypeSybol.IsDesignerGeneratedTypeWithInitializeComponent(vbCompilation);
DesignerGeneratedInitializeComponentOrNull = namedTypeSybol.GetDesignerGeneratedInitializeComponentOrNull(vbCompilation);
}

public bool HasInstanceConstructorsOutsideThisPart { get; }
public bool IsBestPartToAddTypeInit { get; }
public bool RequiresInitializeComponent { get; }
public IMethodSymbol DesignerGeneratedInitializeComponentOrNull { get; }

public List<Assignment> AdditionalStaticInitializers { get; } = new List<Assignment>();
public List<Assignment> AdditionalInstanceInitializers { get; } = new List<Assignment>();
Expand All @@ -41,7 +41,7 @@ public IReadOnlyCollection<MemberDeclarationSyntax> WithAdditionalInitializers(L
.Where(cds => !cds.Initializer.IsKind(SyntaxKind.ThisConstructorInitializer))
.SplitOn(cds => cds.IsInStaticCsContext());

convertedMembers = WithAdditionalInitializers(convertedMembers, parentTypeName, AdditionalInstanceInitializers, SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword)), rootInstanceConstructors, _shouldAddInstanceConstructor, RequiresInitializeComponent);
convertedMembers = WithAdditionalInitializers(convertedMembers, parentTypeName, AdditionalInstanceInitializers, SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword)), rootInstanceConstructors, _shouldAddInstanceConstructor, DesignerGeneratedInitializeComponentOrNull != null);

convertedMembers = WithAdditionalInitializers(convertedMembers, parentTypeName,
AdditionalStaticInitializers, SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.StaticKeyword)), rootStaticConstructors, _shouldAddStaticConstructor, false);
Expand Down
43 changes: 23 additions & 20 deletions CodeConverter/CSharp/CommonConversions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ internal class CommonConversions
private static readonly Type ExtensionAttributeType = typeof(ExtensionAttribute);
private static readonly Type OutAttributeType = typeof(OutAttribute);
public Document Document { get; }
private readonly SemanticModel _semanticModel;
public SemanticModel SemanticModel { get; }
public SyntaxGenerator CsSyntaxGenerator { get; }
public Compilation Compilation { get; }
public VisualBasicEqualityComparison VisualBasicEqualityComparison { get; }

private readonly CSharpCompilation _csCompilation;
Expand All @@ -51,12 +52,14 @@ internal class CommonConversions

public CommonConversions(Document document, SemanticModel semanticModel,
TypeConversionAnalyzer typeConversionAnalyzer, SyntaxGenerator csSyntaxGenerator,
Compilation compilation,
CSharpCompilation csCompilation, ITypeContext typeContext, VisualBasicEqualityComparison visualBasicEqualityComparison)
{
TypeConversionAnalyzer = typeConversionAnalyzer;
Document = document;
_semanticModel = semanticModel;
SemanticModel = semanticModel;
CsSyntaxGenerator = csSyntaxGenerator;
Compilation = compilation;
_csCompilation = csCompilation;
_typeContext = typeContext;
VisualBasicEqualityComparison = visualBasicEqualityComparison;
Expand All @@ -68,15 +71,15 @@ public CommonConversions(Document document, SemanticModel semanticModel,
{
var vbInitValue = GetInitializerToConvert(declarator);
var initializerOrMethodDecl = await vbInitValue.AcceptAsync<CSharpSyntaxNode>(TriviaConvertingExpressionVisitor);
var vbInitializerTypeInfo = vbInitValue != null ? _semanticModel.GetTypeInfo(vbInitValue) : default(TypeInfo?);
var vbInitializerTypeInfo = vbInitValue != null ? SemanticModel.GetTypeInfo(vbInitValue) : default(TypeInfo?);
var vbInitializerType = vbInitValue != null ? vbInitializerTypeInfo.Value.Type : default(ITypeSymbol);

bool requireExplicitTypeForAll = declarator.Names.Count > 1;
IMethodSymbol initSymbol = null;
if (vbInitValue != null) {
TypeInfo expType = vbInitializerTypeInfo.Value;
preferExplicitType |= ShouldPreferExplicitType(vbInitValue, expType.ConvertedType, out bool vbInitIsNothingLiteral);
initSymbol = _semanticModel.GetSymbolInfo(vbInitValue).Symbol as IMethodSymbol;
initSymbol = SemanticModel.GetSymbolInfo(vbInitValue).Symbol as IMethodSymbol;
bool isAnonymousFunction = initSymbol?.IsAnonymousFunction() == true;
requireExplicitTypeForAll |= vbInitIsNothingLiteral || isAnonymousFunction;
}
Expand All @@ -86,7 +89,7 @@ public CommonConversions(Document document, SemanticModel semanticModel,

foreach (var name in declarator.Names) {

var declaredSymbol = _semanticModel.GetDeclaredSymbol(name);
var declaredSymbol = SemanticModel.GetDeclaredSymbol(name);
if (symbolsToSkip?.Contains(declaredSymbol) == true) continue;
var declaredSymbolType = declaredSymbol.GetSymbolType();
var equalsValueClauseSyntax = await ConvertEqualsValueClauseSyntaxAsync(declarator, name, vbInitValue, declaredSymbolType, declaredSymbol, initializerOrMethodDecl);
Expand Down Expand Up @@ -115,9 +118,9 @@ public bool ShouldPreferExplicitType(VBSyntax.ExpressionSyntax exp,
ITypeSymbol expConvertedType,
out bool isNothingLiteral)
{
var op = _semanticModel.GetExpressionOperation(exp);
var op = SemanticModel.GetExpressionOperation(exp);
exp = op.Syntax as VBSyntax.ExpressionSyntax;
var vbInitConstantValue = _semanticModel.GetConstantValue(exp);
var vbInitConstantValue = SemanticModel.GetConstantValue(exp);
isNothingLiteral = vbInitConstantValue.HasValue && vbInitConstantValue.Value == null || exp is VBSyntax.LiteralExpressionSyntax les && les.IsKind(SyntaxKind.NothingLiteralExpression);
bool shouldPreferExplicitType = expConvertedType != null && (expConvertedType.HasCsKeyword() || !expConvertedType.Equals(op.Type));
return shouldPreferExplicitType;
Expand All @@ -143,7 +146,7 @@ public bool ShouldPreferExplicitType(VBSyntax.ExpressionSyntax exp,
? TypeConversionAnalyzer.AddExplicitConversion(vbInitValue, adjustedInitializerExpr, isConst: declaredConst)
: adjustedInitializerExpr;

if (isField && !declaredSymbol.IsStatic && !_semanticModel.IsDefinitelyStatic(vbName, vbInitValue)) {
if (isField && !declaredSymbol.IsStatic && !SemanticModel.IsDefinitelyStatic(vbName, vbInitValue)) {
if (!_typeContext.Initializers.HasInstanceConstructorsOutsideThisPart) {
var lhs = SyntaxFactory.IdentifierName(ConvertIdentifier(vbName.Identifier, sourceTriviaMapKind: SourceTriviaMapKind.None));
_typeContext.Initializers.AdditionalInstanceInitializers.Add((lhs, CSSyntaxKind.SimpleAssignmentExpression, adjustedInitializerExpr));
Expand All @@ -157,7 +160,7 @@ public bool ShouldPreferExplicitType(VBSyntax.ExpressionSyntax exp,
equalsValueClauseSyntax = SyntaxFactory.EqualsValueClause(convertedInitializer);
}
}
else if (isField || declaredSymbol != null && _semanticModel.IsDefinitelyAssignedBeforeRead(declaredSymbol, vbName))
else if (isField || declaredSymbol != null && SemanticModel.IsDefinitelyAssignedBeforeRead(declaredSymbol, vbName))
{
equalsValueClauseSyntax = null;
}
Expand Down Expand Up @@ -270,8 +273,8 @@ public SyntaxToken ConvertIdentifier(SyntaxToken id, bool isAttribute = false, S
{
string text = id.ValueText;

if (id.SyntaxTree == _semanticModel.SyntaxTree) {
var idSymbol = _semanticModel.GetSymbolInfo(id.Parent).Symbol ?? _semanticModel.GetDeclaredSymbol(id.Parent);
if (id.SyntaxTree == SemanticModel.SyntaxTree) {
var idSymbol = SemanticModel.GetSymbolInfo(id.Parent).Symbol ?? SemanticModel.GetDeclaredSymbol(id.Parent);
if (idSymbol != null && !String.IsNullOrWhiteSpace(idSymbol.Name)) {
text = WithDeclarationName(id, idSymbol, text);
var normalizedText = text.WithHalfWidthLatinCharacters();
Expand All @@ -287,8 +290,8 @@ public SyntaxToken ConvertIdentifier(SyntaxToken id, bool isAttribute = false, S
text = propertyFieldSymbol.AssociatedSymbol.Name;
} else if (normalizedText.EndsWith("Event", StringComparison.OrdinalIgnoreCase) && idSymbol is IFieldSymbol eventFieldSymbol && eventFieldSymbol.AssociatedSymbol?.IsKind(SymbolKind.Event) == true) {
text = eventFieldSymbol.AssociatedSymbol.Name;
} else if (WinformsConversions.MustInlinePropertyWithEventsAccess(id.Parent, idSymbol)) {
// For C# Winforms designer, we need to use direct field access - see other usage of MustInlinePropertyWithEventsAccess
} else if (WinformsConversions.MayNeedToInlinePropertyAccess(id.Parent, idSymbol) && _typeContext.HandledEventsAnalysis.ShouldGeneratePropertyFor(idSymbol.Name)) {
// For C# Winforms designer, we need to use direct field access - see other usage of MayNeedToInlinePropertyAccess
text = "_" + text;
}
}
Expand Down Expand Up @@ -350,7 +353,7 @@ public static SyntaxToken CsEscapedIdentifier(string text)
public SyntaxTokenList ConvertModifiers(SyntaxNode node, IReadOnlyCollection<SyntaxToken> modifiers,
TokenContext context = TokenContext.Global, bool isVariableOrConst = false, params CSSyntaxKind[] extraCsModifierKinds)
{
ISymbol declaredSymbol = _semanticModel.GetDeclaredSymbol(node);
ISymbol declaredSymbol = SemanticModel.GetDeclaredSymbol(node);
var declaredAccessibility = declaredSymbol?.DeclaredAccessibility ?? Accessibility.NotApplicable;
modifiers = modifiers.Where(m =>
!m.IsKind(SyntaxKind.OverloadsKeyword) || RequiresNewKeyword(declaredSymbol) != false).ToList();
Expand Down Expand Up @@ -506,7 +509,7 @@ private async Task<IEnumerable<ExpressionSyntax>> ConvertArrayBoundsAsync(Separa

private async Task<ExpressionSyntax> IncreaseArrayUpperBoundExpressionAsync(VBSyntax.ExpressionSyntax expr)
{
var op = _semanticModel.GetOperation(expr);
var op = SemanticModel.GetOperation(expr);
var constant = op.ConstantValue;
if (constant.HasValue && constant.Value is int)
return SyntaxFactory.LiteralExpression(CSSyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal((int)constant.Value + 1));
Expand Down Expand Up @@ -588,7 +591,7 @@ private async Task<ExpressionSyntax> GetParameterizedSetterArgAsync(IOperation o
public CSSyntax.IdentifierNameSyntax GetRetVariableNameOrNull(VBSyntax.MethodBlockBaseSyntax node)
{
if (!node.MustReturn()) return null;
if (_semanticModel.GetDeclaredSymbol(node) is IMethodSymbol ms && ms.ReturnsVoidOrAsyncTask()) {
if (SemanticModel.GetDeclaredSymbol(node) is IMethodSymbol ms && ms.ReturnsVoidOrAsyncTask()) {
return null;
}

Expand All @@ -598,7 +601,7 @@ public CSSyntax.IdentifierNameSyntax GetRetVariableNameOrNull(VBSyntax.MethodBlo
if (!node.Statements.IsEmpty()) {
string methodName = GetMethodBlockBaseIdentifierForImplicitReturn(node).ValueText ?? "";
Func<ISymbol, bool> equalsMethodName = s => s.IsKind(SymbolKind.Local) && s.Name.Equals(methodName, StringComparison.OrdinalIgnoreCase);
var flow = _semanticModel.AnalyzeDataFlow(node.Statements.First(), node.Statements.Last());
var flow = SemanticModel.AnalyzeDataFlow(node.Statements.First(), node.Statements.Last());

if (flow.Succeeded) {
assignsToMethodNameVariable = flow.ReadInside.Any(equalsMethodName) || flow.WrittenInside.Any(equalsMethodName);
Expand Down Expand Up @@ -646,19 +649,19 @@ public bool HasOutAttribute(VBSyntax.AttributeListSyntax a)

public bool IsExtensionAttribute(VBSyntax.AttributeSyntax a)
{
return _semanticModel.GetTypeInfo(a).ConvertedType?.GetFullMetadataName()
return SemanticModel.GetTypeInfo(a).ConvertedType?.GetFullMetadataName()
?.Equals(ExtensionAttributeType.FullName) == true;
}

public bool IsOutAttribute(VBSyntax.AttributeSyntax a)
{
return _semanticModel.GetTypeInfo(a).ConvertedType?.GetFullMetadataName()
return SemanticModel.GetTypeInfo(a).ConvertedType?.GetFullMetadataName()
?.Equals(OutAttributeType.FullName) == true;
}

public ISymbol GetDeclaredCsOriginalSymbolOrNull(VBasic.VisualBasicSyntaxNode node)
{
var declaredSymbol = _semanticModel.GetDeclaredSymbol(node);
var declaredSymbol = SemanticModel.GetDeclaredSymbol(node);
return declaredSymbol != null ? GetCsOriginalSymbolOrNull(declaredSymbol) : null;
}

Expand Down
Loading