Skip to content

Commit

Permalink
Merge pull request #41921 from dotnet/merges/release/dev16.5-to-relea…
Browse files Browse the repository at this point in the history
…se/dev16.5-vs-deps

Merge release/dev16.5 to release/dev16.5-vs-deps
  • Loading branch information
msftbot[bot] authored Feb 25, 2020
2 parents bb0c62e + f265123 commit 1baa0b3
Show file tree
Hide file tree
Showing 28 changed files with 502 additions and 133 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -450,12 +450,12 @@ private void AddAnonymousTypeName(INamedTypeSymbol symbol)
/// <returns></returns>
private bool CanUseTupleSyntax(INamedTypeSymbol tupleSymbol)
{
INamedTypeSymbol currentUnderlying = tupleSymbol.TupleUnderlyingType;
if (containsModopt(tupleSymbol))
{
return false;
}

INamedTypeSymbol currentUnderlying = GetTupleUnderlyingTypeOrSelf(tupleSymbol);
if (currentUnderlying.Arity <= 1)
{
return false;
Expand All @@ -473,12 +473,11 @@ private bool CanUseTupleSyntax(INamedTypeSymbol tupleSymbol)
return false;
}

currentUnderlying = tupleSymbol.TupleUnderlyingType;
currentUnderlying = GetTupleUnderlyingTypeOrSelf(tupleSymbol);
}

return true;


bool containsModopt(INamedTypeSymbol symbol)
{
NamedTypeSymbol underlyingTypeSymbol = (symbol as Symbols.PublicModel.NamedTypeSymbol)?.UnderlyingNamedTypeSymbol;
Expand All @@ -492,6 +491,11 @@ bool containsModopt(INamedTypeSymbol symbol)
}
}

private static INamedTypeSymbol GetTupleUnderlyingTypeOrSelf(INamedTypeSymbol type)
{
return type.TupleUnderlyingType ?? type;
}

private static bool HasNonDefaultTupleElements(INamedTypeSymbol tupleSymbol)
{
return tupleSymbol.TupleElements.Any(e => !e.IsDefaultTupleElement());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;

namespace Microsoft.CodeAnalysis.CSharp.Symbols.PublicModel
{
Expand Down Expand Up @@ -162,14 +163,18 @@ ImmutableArray<IFieldSymbol> INamedTypeSymbol.TupleElements
}

/// <summary>
/// If this is a tuple type symbol, returns the symbol for its underlying type.
/// If this is a tuple type with element names, returns the symbol for the tuple type without names.
/// Otherwise, returns null.
/// </summary>
INamedTypeSymbol INamedTypeSymbol.TupleUnderlyingType
{
get
{
return UnderlyingNamedTypeSymbol.TupleUnderlyingType.GetPublicSymbol();
var type = UnderlyingNamedTypeSymbol;
var tupleUnderlyingType = type.TupleUnderlyingType;
return type.Equals(tupleUnderlyingType, TypeCompareKind.ConsiderEverything) ?
null :
tupleUnderlyingType.GetPublicSymbol();
}
}

Expand Down
173 changes: 157 additions & 16 deletions src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenTupleTest.cs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/Compilers/Core/Portable/Symbols/INamedTypeSymbol.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ public interface INamedTypeSymbol : ITypeSymbol
bool MightContainExtensionMethods { get; }

/// <summary>
/// If this is a tuple type symbol, returns the symbol for its underlying type (ie. without element names).
/// If this is a tuple type with element names, returns the symbol for the tuple type without names.
/// Otherwise, returns null.
/// The type argument corresponding to the type of the extension field (VT[8].Rest),
/// which is at the 8th (one based) position is always a symbol for another tuple,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
''' <param name="tupleSymbol"></param>
''' <returns></returns>
Private Shared Function CanUseTupleTypeName(tupleSymbol As INamedTypeSymbol) As Boolean
Dim currentUnderlying As INamedTypeSymbol = tupleSymbol.TupleUnderlyingType
Dim currentUnderlying As INamedTypeSymbol = GetTupleUnderlyingTypeOrSelf(tupleSymbol)

If currentUnderlying.Arity = 1 Then
Return False
Expand All @@ -344,12 +344,16 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return False
End If

currentUnderlying = tupleSymbol.TupleUnderlyingType
currentUnderlying = GetTupleUnderlyingTypeOrSelf(tupleSymbol)
End While

Return True
End Function

Private Shared Function GetTupleUnderlyingTypeOrSelf(tupleSymbol As INamedTypeSymbol) As INamedTypeSymbol
Return If(tupleSymbol.TupleUnderlyingType, tupleSymbol)
End Function

Private Shared Function HasNonDefaultTupleElements(tupleSymbol As INamedTypeSymbol) As Boolean
Return tupleSymbol.TupleElements.Any(Function(e) Not e.IsDefaultTupleElement)
End Function
Expand Down
106 changes: 106 additions & 0 deletions src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenTuples.vb
Original file line number Diff line number Diff line change
Expand Up @@ -22944,6 +22944,112 @@ End Class
CompileAndVerify(comp6, expectedOutput:="123")
End Sub

<Fact>
<WorkItem(41702, "https://github.com/dotnet/roslyn/issues/41702")>
Public Sub TupleUnderlyingType_FromCSharp()
Dim source =
"#pragma warning disable 169
class Program
{
static System.ValueTuple F0;
static (int, int) F1;
static (int A, int B) F2;
static (object, object, object, object, object, object, object, object) F3;
static (object, object B, object, object D, object, object F, object, object H) F4;
}"
Dim comp = CreateCSharpCompilation(source, referencedAssemblies:=TargetFrameworkUtil.GetReferences(TargetFramework.Standard))
comp.VerifyDiagnostics()
Dim containingType = comp.GlobalNamespace.GetTypeMembers("Program").Single()
VerifyTypeFromCSharp(DirectCast(DirectCast(containingType.GetMembers("F0").Single(), IFieldSymbol).Type, INamedTypeSymbol), TupleUnderlyingTypeValue.Nothing, "System.ValueTuple", "()")
VerifyTypeFromCSharp(DirectCast(DirectCast(containingType.GetMembers("F1").Single(), IFieldSymbol).Type, INamedTypeSymbol), TupleUnderlyingTypeValue.Nothing, "(System.Int32, System.Int32)", "(System.Int32, System.Int32)")
VerifyTypeFromCSharp(DirectCast(DirectCast(containingType.GetMembers("F2").Single(), IFieldSymbol).Type, INamedTypeSymbol), TupleUnderlyingTypeValue.Distinct, "(System.Int32 A, System.Int32 B)", "(A As System.Int32, B As System.Int32)")
VerifyTypeFromCSharp(DirectCast(DirectCast(containingType.GetMembers("F3").Single(), IFieldSymbol).Type, INamedTypeSymbol), TupleUnderlyingTypeValue.Nothing, "(System.Object, System.Object, System.Object, System.Object, System.Object, System.Object, System.Object, System.Object)", "(System.Object, System.Object, System.Object, System.Object, System.Object, System.Object, System.Object, System.Object)")
VerifyTypeFromCSharp(DirectCast(DirectCast(containingType.GetMembers("F4").Single(), IFieldSymbol).Type, INamedTypeSymbol), TupleUnderlyingTypeValue.Distinct, "(System.Object, System.Object B, System.Object, System.Object D, System.Object, System.Object F, System.Object, System.Object H)", "(System.Object, B As System.Object, System.Object, D As System.Object, System.Object, F As System.Object, System.Object, H As System.Object)")
End Sub

<Fact>
<WorkItem(41702, "https://github.com/dotnet/roslyn/issues/41702")>
Public Sub TupleUnderlyingType_FromVisualBasic()
Dim source =
"Class Program
Private F0 As System.ValueTuple
Private F1 As (Integer, Integer)
Private F2 As (A As Integer, B As Integer)
Private F3 As (Object, Object, Object, Object, Object, Object, Object, Object)
Private F4 As (Object, B As Object, Object, D As Object, Object, F As Object, Object, H As Object)
End Class"
Dim comp = CreateCompilation(source)
comp.AssertNoDiagnostics()
Dim containingType = comp.GlobalNamespace.GetTypeMembers("Program").Single()
VerifyTypeFromVisualBasic(DirectCast(DirectCast(containingType.GetMembers("F0").Single(), FieldSymbol).Type, NamedTypeSymbol), TupleUnderlyingTypeValue.Nothing, "System.ValueTuple", "System.ValueTuple")
VerifyTypeFromVisualBasic(DirectCast(DirectCast(containingType.GetMembers("F1").Single(), FieldSymbol).Type, NamedTypeSymbol), TupleUnderlyingTypeValue.Distinct, "(System.Int32, System.Int32)", "(System.Int32, System.Int32)")
VerifyTypeFromVisualBasic(DirectCast(DirectCast(containingType.GetMembers("F2").Single(), FieldSymbol).Type, NamedTypeSymbol), TupleUnderlyingTypeValue.Distinct, "(System.Int32 A, System.Int32 B)", "(A As System.Int32, B As System.Int32)")
VerifyTypeFromVisualBasic(DirectCast(DirectCast(containingType.GetMembers("F3").Single(), FieldSymbol).Type, NamedTypeSymbol), TupleUnderlyingTypeValue.Distinct, "(System.Object, System.Object, System.Object, System.Object, System.Object, System.Object, System.Object, System.Object)", "(System.Object, System.Object, System.Object, System.Object, System.Object, System.Object, System.Object, System.Object)")
VerifyTypeFromVisualBasic(DirectCast(DirectCast(containingType.GetMembers("F4").Single(), FieldSymbol).Type, NamedTypeSymbol), TupleUnderlyingTypeValue.Distinct, "(System.Object, System.Object B, System.Object, System.Object D, System.Object, System.Object F, System.Object, System.Object H)", "(System.Object, B As System.Object, System.Object, D As System.Object, System.Object, F As System.Object, System.Object, H As System.Object)")
End Sub

Private Enum TupleUnderlyingTypeValue
[Nothing]
Distinct
Same
End Enum

Private Shared Sub VerifyTypeFromCSharp(type As INamedTypeSymbol, expectedValue As TupleUnderlyingTypeValue, expectedCSharp As String, expectedVisualBasic As String)
VerifyDisplay(type, expectedCSharp, expectedVisualBasic)
VerifyPublicType(type, expectedValue)
VerifyPublicType(type.OriginalDefinition, TupleUnderlyingTypeValue.Nothing)
End Sub

Private Shared Sub VerifyTypeFromVisualBasic(type As NamedTypeSymbol, expectedValue As TupleUnderlyingTypeValue, expectedCSharp As String, expectedVisualBasic As String)
VerifyDisplay(type, expectedCSharp, expectedVisualBasic)
VerifyInternalType(type, expectedValue)
VerifyPublicType(type, expectedValue)
type = type.OriginalDefinition
VerifyInternalType(type, expectedValue)
VerifyPublicType(type, expectedValue)
End Sub

Private Shared Sub VerifyDisplay(type As INamedTypeSymbol, expectedCSharp As String, expectedVisualBasic As String)
Assert.Equal(expectedCSharp, CSharp.SymbolDisplay.ToDisplayString(type, SymbolDisplayFormat.TestFormat))
Assert.Equal(expectedVisualBasic, VisualBasic.SymbolDisplay.ToDisplayString(type, SymbolDisplayFormat.TestFormat))
End Sub

Private Shared Sub VerifyInternalType(type As NamedTypeSymbol, expectedValue As TupleUnderlyingTypeValue)
Dim underlyingType = type.TupleUnderlyingType

Select Case expectedValue
Case TupleUnderlyingTypeValue.Nothing
Assert.Null(underlyingType)

Case TupleUnderlyingTypeValue.Distinct
Assert.NotEqual(type, underlyingType)
Assert.False(type.Equals(underlyingType, TypeCompareKind.AllIgnoreOptions))
Assert.False(type.Equals(underlyingType, TypeCompareKind.ConsiderEverything))
VerifyPublicType(underlyingType, expectedValue:=TupleUnderlyingTypeValue.Nothing)

Case Else
Throw ExceptionUtilities.UnexpectedValue(expectedValue)
End Select
End Sub

Private Shared Sub VerifyPublicType(type As INamedTypeSymbol, expectedValue As TupleUnderlyingTypeValue)
Dim underlyingType = type.TupleUnderlyingType

Select Case expectedValue
Case TupleUnderlyingTypeValue.Nothing
Assert.Null(underlyingType)

Case TupleUnderlyingTypeValue.Distinct
Assert.NotEqual(type, underlyingType)
Assert.False(type.Equals(underlyingType, SymbolEqualityComparer.Default))
Assert.False(type.Equals(underlyingType, SymbolEqualityComparer.ConsiderEverything))
VerifyPublicType(underlyingType, expectedValue:=TupleUnderlyingTypeValue.Nothing)

Case Else
Throw ExceptionUtilities.UnexpectedValue(expectedValue)
End Select
End Sub

End Class

End Namespace
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ private protected override Task BaseVerifyWorkerAsync(
string expectedItemOrNull, string expectedDescriptionOrNull,
SourceCodeKind sourceCodeKind, bool usePreviousCharAsTrigger, bool checkForAbsence,
int? glyph, int? matchPriority, bool? hasSuggestionItem, string displayTextSuffix,
string inlineDescription = null, List<CompletionFilter> matchingFilters = null)
string inlineDescription = null, List<CompletionFilter> matchingFilters = null, CompletionItemFlags? flags = null)
{
return base.VerifyWorkerAsync(
code, position, expectedItemOrNull, expectedDescriptionOrNull,
sourceCodeKind, usePreviousCharAsTrigger, checkForAbsence,
glyph, matchPriority, hasSuggestionItem, displayTextSuffix,
inlineDescription, matchingFilters);
inlineDescription, matchingFilters, flags);
}

private protected override async Task VerifyWorkerAsync(
Expand All @@ -52,7 +52,7 @@ private protected override async Task VerifyWorkerAsync(
SourceCodeKind sourceCodeKind, bool usePreviousCharAsTrigger,
bool checkForAbsence, int? glyph, int? matchPriority,
bool? hasSuggestionItem, string displayTextSuffix, string inlineDescription = null,
List<CompletionFilter> matchingFilters = null)
List<CompletionFilter> matchingFilters = null, CompletionItemFlags? flags = null)
{
await VerifyAtPositionAsync(code, position, usePreviousCharAsTrigger, expectedItemOrNull, expectedDescriptionOrNull, sourceCodeKind, checkForAbsence, glyph, matchPriority, hasSuggestionItem, displayTextSuffix, inlineDescription, matchingFilters);
await VerifyInFrontOfCommentAsync(code, position, usePreviousCharAsTrigger, expectedItemOrNull, expectedDescriptionOrNull, sourceCodeKind, checkForAbsence, glyph, matchPriority, hasSuggestionItem, displayTextSuffix, inlineDescription, matchingFilters);
Expand Down Expand Up @@ -87,7 +87,7 @@ private Task VerifyInFrontOfCommentAsync(
code, position, expectedItemOrNull, expectedDescriptionOrNull,
sourceCodeKind, usePreviousCharAsTrigger, checkForAbsence, glyph,
matchPriority, hasSuggestionItem, displayTextSuffix, inlineDescription,
matchingFilters);
matchingFilters, flags: null);
}

private Task VerifyInFrontOfCommentAsync(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,17 @@ private protected override async Task VerifyWorkerAsync(
string expectedItemOrNull, string expectedDescriptionOrNull,
SourceCodeKind sourceCodeKind, bool usePreviousCharAsTrigger, bool checkForAbsence,
int? glyph, int? matchPriority, bool? hasSuggestionItem, string displayTextSuffix,
string inlineDescription = null, List<CompletionFilter> matchingFilters = null)
string inlineDescription = null, List<CompletionFilter> matchingFilters = null, CompletionItemFlags? flags = null)
{
await VerifyAtPositionAsync(
code, position, usePreviousCharAsTrigger, expectedItemOrNull, expectedDescriptionOrNull, sourceCodeKind,
checkForAbsence, glyph, matchPriority, hasSuggestionItem, displayTextSuffix, inlineDescription,
matchingFilters);
matchingFilters, flags);

await VerifyAtEndOfFileAsync(
code, position, usePreviousCharAsTrigger, expectedItemOrNull, expectedDescriptionOrNull, sourceCodeKind,
checkForAbsence, glyph, matchPriority, hasSuggestionItem, displayTextSuffix, inlineDescription,
matchingFilters);
matchingFilters, flags);

// Items cannot be partially written if we're checking for their absence,
// or if we're verifying that the list will show up (without specifying an actual item)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ private protected override Task VerifyWorkerAsync(
string code, int position, string expectedItemOrNull, string expectedDescriptionOrNull,
SourceCodeKind sourceCodeKind, bool usePreviousCharAsTrigger, bool checkForAbsence,
int? glyph, int? matchPriority, bool? hasSuggestionItem, string displayTextSuffix,
string inlineDescription = null, List<CompletionFilter> matchingFilters = null)
string inlineDescription = null, List<CompletionFilter> matchingFilters = null, CompletionItemFlags? flags = null)
{
return BaseVerifyWorkerAsync(
code, position, expectedItemOrNull, expectedDescriptionOrNull,
sourceCodeKind, usePreviousCharAsTrigger, checkForAbsence,
glyph, matchPriority, hasSuggestionItem, displayTextSuffix,
inlineDescription, matchingFilters);
inlineDescription, matchingFilters, flags);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ private protected override Task VerifyWorkerAsync(
string code, int position, string expectedItemOrNull, string expectedDescriptionOrNull,
SourceCodeKind sourceCodeKind, bool usePreviousCharAsTrigger, bool checkForAbsence,
int? glyph, int? matchPriority, bool? hasSuggestionItem, string displayTextSuffix,
string inlineDescription = null, List<CompletionFilter> matchingFilters = null)
string inlineDescription = null, List<CompletionFilter> matchingFilters = null, CompletionItemFlags? flags = null)
{
return BaseVerifyWorkerAsync(
code, position, expectedItemOrNull, expectedDescriptionOrNull,
sourceCodeKind, usePreviousCharAsTrigger, checkForAbsence,
glyph, matchPriority, hasSuggestionItem, displayTextSuffix,
inlineDescription, matchingFilters);
inlineDescription, matchingFilters, flags);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ private protected override Task VerifyWorkerAsync(
string code, int position, string expectedItemOrNull, string expectedDescriptionOrNull,
SourceCodeKind sourceCodeKind, bool usePreviousCharAsTrigger, bool checkForAbsence,
int? glyph, int? matchPriority, bool? hasSuggestionItem, string displayTextSuffix,
string inlineDescription, List<CompletionFilter> matchingFilters)
string inlineDescription, List<CompletionFilter> matchingFilters, CompletionItemFlags? flags = null)
{
return base.VerifyWorkerAsync(code, position,
expectedItemOrNull, expectedDescriptionOrNull,
SourceCodeKind.Regular, usePreviousCharAsTrigger, checkForAbsence,
glyph, matchPriority, hasSuggestionItem, displayTextSuffix,
inlineDescription, matchingFilters);
inlineDescription, matchingFilters, flags);
}

[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
Expand Down
Loading

0 comments on commit 1baa0b3

Please sign in to comment.