Skip to content

Commit

Permalink
Correctly handle type promoted module symbols [icsharpcode#375]
Browse files Browse the repository at this point in the history
  • Loading branch information
mrmonday committed Nov 13, 2019
1 parent fc2f6db commit 9aa841e
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 23 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ All notable changes to the code converter will be documented here.
* Convert types in ternary expressions (#363)
* Support for converting dot net standard VB projects (#398)
* Avoid compilation error for duplicate cases (#374)
* Correctly handle type promoted module symbols (#375)

### C# -> VB
* Convert property accessors with visiblity modifiers (#92)
Expand Down
26 changes: 3 additions & 23 deletions ICSharpCode.CodeConverter/CSharp/ExpressionNodeVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,10 @@ public override async Task<CSharpSyntaxNode> VisitMemberAccessExpression(VBasic.
}
}
if (left == null && nodeSymbol?.IsStatic == true) {
var typeInfo = _semanticModel.GetTypeInfo(node.Expression);
var type = nodeSymbol.ContainingType;
var expressionSymbolInfo = _semanticModel.GetSymbolInfo(node.Expression);
if (typeInfo.Type != null && !expressionSymbolInfo.Symbol.IsType()) {
left = CommonConversions.GetTypeSyntax(typeInfo.Type);
if (type != null && !expressionSymbolInfo.Symbol.IsType()) {
left = CommonConversions.GetTypeSyntax(type);
}
}
if (left == null) {
Expand All @@ -296,9 +296,6 @@ public override async Task<CSharpSyntaxNode> VisitMemberAccessExpression(VBasic.
: (ExpressionSyntax)SyntaxFactory.MemberBindingExpression(simpleNameSyntax);
}
left = _withBlockLhs.Peek();
} else if (TryGetTypePromotedModuleSymbol(node, out var promotedModuleSymbol)) {
left = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, left,
SyntaxFactory.IdentifierName(promotedModuleSymbol.Name));
}

if (node.Expression.IsKind(VBasic.SyntaxKind.GlobalName)) {
Expand Down Expand Up @@ -990,23 +987,6 @@ private ExpressionSyntax GetConvertMethodForKeywordOrNull(SyntaxNode type)
return convertedType != null && _convertMethodsLookupByReturnType.Value.TryGetValue(convertedType, out var convertMethodName)
? SyntaxFactory.ParseExpression(convertMethodName) : null;
}

/// <remarks>https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/declared-elements/type-promotion</remarks>
private bool TryGetTypePromotedModuleSymbol(VBasic.Syntax.MemberAccessExpressionSyntax node, out INamedTypeSymbol moduleSymbol)
{
if (_semanticModel.GetSymbolInfo(node.Expression).ExtractBestMatch() is INamespaceSymbol
expressionSymbol &&
_semanticModel.GetSymbolInfo(node.Name).ExtractBestMatch()?.ContainingSymbol is INamedTypeSymbol
nameContainingSymbol &&
nameContainingSymbol.ContainingSymbol.Equals(expressionSymbol)) {
moduleSymbol = nameContainingSymbol;
return true;
}

moduleSymbol = null;
return false;
}

private static bool IsSubPartOfConditionalAccess(VBasic.Syntax.MemberAccessExpressionSyntax node)
{
var firstPossiblyConditionalAncestor = node.Parent;
Expand Down
18 changes: 18 additions & 0 deletions Tests/CSharp/ExpressionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2236,6 +2236,24 @@ End Sub
}");
}

[Fact]
public async Task GlobalNameIssue375()
{
await TestConversionVisualBasicToCSharpWithoutComments(@"Module Module1
Sub Main()
Dim x = Microsoft.VisualBasic.Timer
End Sub
End Module", @"using Microsoft.VisualBasic;
internal static partial class Module1
{
public static void Main()
{
double x = DateAndTime.Timer;
}
}");
}

[Fact]
public async Task TernaryConversionIssue363()
{
Expand Down

0 comments on commit 9aa841e

Please sign in to comment.