Skip to content

Commit

Permalink
Merge branch 'indentationDown6' into indentationDown7
Browse files Browse the repository at this point in the history
  • Loading branch information
CyrusNajmabadi committed Mar 29, 2022
2 parents cde4150 + b587d50 commit 7259eda
Show file tree
Hide file tree
Showing 78 changed files with 694 additions and 346 deletions.
4 changes: 3 additions & 1 deletion docs/Language Feature Status.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ efforts behind them.
| [nameof accessing instance members](https://github.com/dotnet/roslyn/issues/40229) | main | [In Progress](https://github.com/dotnet/roslyn/pull/48754) | [YairHalberstadt ](https://github.com/YairHalberstadt) | [333fred](https://github.com/333fred), [AlekseyTs](https://github.com/AlekseyTs) | [333fred](https://github.com/333fred) |
| [Utf8 String Literals](https://github.com/dotnet/csharplang/issues/184) | [Utf8StringLiterals](https://github.com/dotnet/roslyn/tree/features/Utf8StringLiterals) | [In Progress](https://github.com/dotnet/roslyn/issues/58848) | [AlekseyTs](https://github.com/AlekseyTs) | [cston](https://github.com/cston), [RikkiGibson](https://github.com/RikkiGibson) | [MadsTorgersen](https://github.com/MadsTorgersen) |
| [ref fields](https://github.com/dotnet/csharplang/blob/main/proposals/low-level-struct-improvements.md) | [ref-fields](https://github.com/dotnet/roslyn/tree/features/ref-fields) | [In Progress](https://github.com/dotnet/roslyn/issues/59194) | [cston](https://github.com/cston) | [RikkiGibson](https://github.com/RikkiGibson), [AlekseyTs](https://github.com/AlekseyTs) | [jaredpar](https://github.com/jaredpar) |
| [checked operators](https://github.com/dotnet/csharplang/issues/4665) | [CheckedUserDefinedOperators](https://github.com/dotnet/roslyn/tree/features/CheckedUserDefinedOperators) | [In Progress](https://github.com/dotnet/roslyn/issues/59458) | [AlekseyTs](https://github.com/AlekseyTs) | [333fred](https://github.com/333fred), [chsienki](https://github.com/chsienki) | [AlekseyTs](https://github.com/AlekseyTs) |
| [Checked Operators](https://github.com/dotnet/csharplang/issues/4665) | [CheckedUserDefinedOperators](https://github.com/dotnet/roslyn/tree/features/CheckedUserDefinedOperators) | [In Progress](https://github.com/dotnet/roslyn/issues/59458) | [AlekseyTs](https://github.com/AlekseyTs) | [333fred](https://github.com/333fred), [chsienki](https://github.com/chsienki) | [AlekseyTs](https://github.com/AlekseyTs) |
| [auto-default structs](https://github.com/dotnet/csharplang/issues/5737) | main | [In Progress](https://github.com/dotnet/roslyn/issues/60167) | [RikkiGibson](https://github.com/RikkiGibson) | [cston](https://github.com/cston), [jcouv](https://github.com/jcouv) |
| [Unsigned Right Shift](https://github.com/dotnet/csharplang/issues/4682) | [UnsignedRightShift](https://github.com/dotnet/roslyn/tree/features/UnsignedRightShift) | [In Progress](https://github.com/dotnet/roslyn/issues/60433) | [AlekseyTs](https://github.com/AlekseyTs) | TBD | [AlekseyTs](https://github.com/AlekseyTs) |


# C# 10.0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Linq;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Operations;
using Roslyn.Utilities;
Expand All @@ -23,9 +24,55 @@ private AnalyzedPattern(IOperation target)
/// </summary>
internal sealed class Type : AnalyzedPattern
{
private static readonly SyntaxAnnotation s_annotation = new();

public static Type? TryCreate(BinaryExpressionSyntax binaryExpression, IIsTypeOperation operation)
{
Contract.ThrowIfNull(operation.SemanticModel);
if (binaryExpression.Right is not TypeSyntax typeSyntax)
{
return null;
}

// We are coming from a type pattern, which likes to bind to types, but converting to
// patters which like to bind to expressions. For example, given:
//
// if (T is C.X || T is Y) { }
//
// we would want to convert to:
//
// if (T is C.X or Y)
//
// In the first case the compiler will bind to types named C or Y that are in scope
// but in the second it will also bind to a fields, methods etc. which for 'Y' changes
// semantics, and for 'C.X' could be a compile error.
//
// So lets create a pattern syntax and make sure the result is the same
var dummyStatement = SyntaxFactory.ExpressionStatement(SyntaxFactory.AssignmentExpression(
SyntaxKind.SimpleAssignmentExpression,
SyntaxFactory.IdentifierName("_"),
SyntaxFactory.IsPatternExpression(
binaryExpression.Left,
SyntaxFactory.ConstantPattern(SyntaxFactory.ParenthesizedExpression(binaryExpression.Right.WithAdditionalAnnotations(s_annotation)))
)
));

if (operation.SemanticModel.TryGetSpeculativeSemanticModel(typeSyntax.SpanStart, dummyStatement, out var speculativeModel))
{
var originalInfo = operation.SemanticModel.GetTypeInfo(binaryExpression.Right);
var newInfo = speculativeModel.GetTypeInfo(dummyStatement.GetAnnotatedNodes(s_annotation).Single());
if (!originalInfo.Equals(newInfo))
{
return null;
}
}

return new Type(typeSyntax, operation.ValueOperand);
}

public readonly TypeSyntax TypeSyntax;

public Type(TypeSyntax type, IOperation target) : base(target)
private Type(TypeSyntax type, IOperation target) : base(target)
=> TypeSyntax = type;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ private enum ConstantResult
case IUnaryOperation { OperatorKind: UnaryOperatorKind.Not } op:
return Not.TryCreate(ParsePattern(op.Operand));

case IIsTypeOperation { Syntax: BinaryExpressionSyntax { Right: TypeSyntax type } } op:
return new Type(type, op.ValueOperand);
case IIsTypeOperation { Syntax: BinaryExpressionSyntax binaryExpression } op:
return Type.TryCreate(binaryExpression, op);

case IIsPatternOperation { Pattern: { Syntax: PatternSyntax pattern } } op:
return new Source(pattern, op.Value);
Expand Down
3 changes: 2 additions & 1 deletion src/Analyzers/CSharp/CodeFixes/CSharpCodeFixes.projitems
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<Compile Include="$(MSBuildThisFileDirectory)ConvertTypeOfToNameOf\CSharpConvertTypeOfToNameOfCodeFixProvider.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ConvertSwitchStatementToExpression\ConvertSwitchStatementToExpressionCodeFixProvider.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ConvertSwitchStatementToExpression\ConvertSwitchStatementToExpressionCodeFixProvider.Rewriter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)UsePatternCombinators\CSharpUsePatternCombinatorsCodeFixProvider.cs" />
<Compile Include="$(MSBuildThisFileDirectory)FileHeaders\CSharpFileHeaderCodeFixProvider.cs" />
<Compile Include="$(MSBuildThisFileDirectory)InlineDeclaration\CSharpInlineDeclarationCodeFixProvider.cs" />
<Compile Include="$(MSBuildThisFileDirectory)InvokeDelegateWithConditionalAccess\InvokeDelegateWithConditionalAccessCodeFixProvider.cs" />
Expand Down Expand Up @@ -80,4 +81,4 @@
<ItemGroup Condition="'$(DefaultLanguageSourceExtension)' != '' AND '$(BuildingInsideVisualStudio)' != 'true'">
<ExpectedCompile Include="$(MSBuildThisFileDirectory)**\*$(DefaultLanguageSourceExtension)" />
</ItemGroup>
</Project>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ private static PatternSyntax AsPatternSyntax(AnalyzedPattern pattern)
private static ExpressionSyntax AsExpressionSyntax(ExpressionSyntax expr, AnalyzedPattern p)
{
var semanticModel = p.Target.SemanticModel;
Debug.Assert(semanticModel != null);
RoslynDebug.Assert(semanticModel != null);
var type = semanticModel.GetTypeInfo(expr).Type;
if (type != null)
{
Expand Down Expand Up @@ -148,7 +148,9 @@ public MyCodeAction(string title, Func<CancellationToken, Task<Document>> create
{
}

#if !CODE_STYLE // 'CodeActionPriority' is not a public API, hence not supported in CodeStyle layer.
internal override CodeActionPriority Priority => CodeActionPriority.Low;
#endif
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,71 @@ void Method()
CheckStart(session.Session, expectValidSession: false);
}

[WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)]
[WorkItem(59178, "https://github.com/dotnet/roslyn/issues/59178")]
public void String_CompleteLiteral()
{
var code = @"class C
{
void Method()
{
var s = ""this"" + $$that"";
}
}";
using var session = CreateSessionDoubleQuote(code);
Assert.NotNull(session);
CheckStart(session.Session, expectValidSession: false);
}

[WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)]
[WorkItem(59178, "https://github.com/dotnet/roslyn/issues/59178")]
public void String_BeforeOtherString1()
{
var code = @"class C
{
void Method()
{
var s = $$ + "" + bar"";
}
}";
using var session = CreateSessionDoubleQuote(code);
Assert.NotNull(session);
CheckStart(session.Session);
}

[WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)]
[WorkItem(59178, "https://github.com/dotnet/roslyn/issues/59178")]
public void String_BeforeOtherString2()
{
var code = @"class C
{
void Method()
{
var s = $$ + ""; } "";
}
}";
using var session = CreateSessionDoubleQuote(code);
Assert.NotNull(session);
CheckStart(session.Session);
}

[WpfFact, Trait(Traits.Feature, Traits.Features.AutomaticCompletion)]
[WorkItem(59178, "https://github.com/dotnet/roslyn/issues/59178")]
public void String_DontCompleteVerbatim()
{
var code = @"class C
{
void Method()
{
var s = ""this"" + @$$that
and this"";
}
}";
using var session = CreateSessionDoubleQuote(code);
Assert.NotNull(session);
CheckStart(session.Session);
}

internal static Holder CreateSessionSingleQuote(string code)
{
return CreateSession(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -323,5 +323,14 @@ class C
}
}");
}

[WorkItem(60400, "https://github.com/dotnet/roslyn/issues/60400")]
[Fact, Trait(Traits.Feature, Traits.Features.KeywordHighlighting)]
public async Task TestTopLevelStatements()
{
await TestAsync(
@"[|await|] Task.Delay(1000);
{|Cursor:[|await|]|} Task.Run(() => { })");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -462,5 +462,13 @@ void M()
}
}");
}

[Fact, Trait(Traits.Feature, Traits.Features.KeywordHighlighting)]
public async Task TestInTopLevelStatements()
{
await TestAsync(
@"if (args.Length > 0) [|return|] 0;
{|Cursor:[|return|]|} 1;");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ public async Task TestMissingOnExpression(string expression)
[InlineData("i == default || i > default(int)", "i is default(int) or > (default(int))")]
[InlineData("!(o is C c)", "o is not C c")]
[InlineData("o is int ii && o is long jj", "o is int ii and long jj")]
[InlineData("o is string || o is Exception", "o is string or Exception")]
[InlineData("o is System.String || o is System.Exception", "o is System.String or System.Exception")]
[InlineData("!(o is C)", "o is not C")]
[InlineData("!(o is C _)", "o is not C _")]
[InlineData("i == (0x02 | 0x04) || i != 0", "i is (0x02 | 0x04) or not 0")]
Expand Down Expand Up @@ -477,6 +479,151 @@ void M(char c)
}
}
}
");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUsePatternCombinators)]
[WorkItem(57199, "https://github.com/dotnet/roslyn/issues/57199")]
public async Task TestMissingInNonConvertibleTypePattern1()
{
await TestMissingAsync(
@"
static class C
{
public struct S1 : I { }
public struct S2 : I { }
public interface I { }
}
class Test<T>
{
public readonly T C;
bool P => [|C is C.S1 || C is C.S2|];
}
");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUsePatternCombinators)]
[WorkItem(57199, "https://github.com/dotnet/roslyn/issues/57199")]
public async Task TestMissingInNonConvertibleTypePattern2()
{
await TestMissingAsync(
@"
class Goo
{
private class X { }
private class Y { }
private void M(object o)
{
var X = 1;
var Y = 2;
if [|(o is X || o is Y)|]
{
}
}
}
");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUsePatternCombinators)]
[WorkItem(57199, "https://github.com/dotnet/roslyn/issues/57199")]
public async Task TestMissingInNonConvertibleTypePattern3()
{
await TestMissingAsync(
@"
class Goo
{
private class X { }
private class Y { }
private void M(object o)
{
var X = 1;
var Y = 2;
if [|(o is global::Goo.X || o is Y)|]
{
}
}
}
");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUsePatternCombinators)]
[WorkItem(57199, "https://github.com/dotnet/roslyn/issues/57199")]
public async Task TestInConvertibleTypePattern()
{
await TestInRegularAndScriptAsync(
@"
static class C
{
public struct S1 : I { }
public struct S2 : I { }
public interface I { }
}
class Test<T>
{
bool P => [|C is C.S1 || C is C.S2|];
}
",

@"
static class C
{
public struct S1 : I { }
public struct S2 : I { }
public interface I { }
}
class Test<T>
{
bool P => C is C.S1 or C.S2;
}
");
}

[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsUsePatternCombinators)]
[WorkItem(57199, "https://github.com/dotnet/roslyn/issues/57199")]
public async Task TestInConvertibleTypePattern2()
{
await TestInRegularAndScriptAsync(
@"
public class Goo
{
private class X { }
private class Y { }
private void M(object o)
{
var X = 1;
var Y = 2;
var @int = 1;
var @long = 2;
if [|(o is int || o is long)|]
{
}
}
}
", @"
public class Goo
{
private class X { }
private class Y { }
private void M(object o)
{
var X = 1;
var Y = 2;
var @int = 1;
var @long = 2;
if (o is int or long)
{
}
}
}
");
}
}
Expand Down
Loading

0 comments on commit 7259eda

Please sign in to comment.