提交 2c8f4d81 编写于 作者: J Jason Malinowski

Merge branch 'dotnet/dev15-rc' into master

......@@ -27,6 +27,11 @@ function Run-Build()
$debugDir = join-path $rootDir "Binaries\Debug"
$objDir = join-path $rootDir "Binaries\Obj"
# Temporarily forcing MSBuild 14.0 here to work around a bug in 15.0
# MSBuild bug: https://github.com/Microsoft/msbuild/issues/1183
# Roslyn tracking bug: https://github.com/dotnet/roslyn/issues/14451
$msbuild = "c:\Program Files (x86)\MSBuild\14.0\bin\MSBuild.exe"
# Create directories that may or may not exist to make the script execution below
# clean in either case.
mkdir $debugDir -errorAction SilentlyContinue | out-null
......@@ -38,10 +43,10 @@ function Run-Build()
write-host "Cleaning the Binaries"
rm -re -fo $debugDir
rm -re -fo $objDir
& msbuild /nologo /v:m /nodeReuse:false /t:clean $sln
& $msbuild /nologo /v:m /nodeReuse:false /t:clean $sln
write-host "Building the Solution"
& msbuild /nologo /v:m /nodeReuse:false /m /p:DebugDeterminism=true /p:BootstrapBuildPath=$script:buildDir '/p:Features="debug-determinism;pdb-path-determinism"' /p:UseRoslynAnalyzers=false $pathMapBuildOption $sln
& $msbuild /nologo /v:m /nodeReuse:false /m /p:DebugDeterminism=true /p:BootstrapBuildPath=$script:buildDir '/p:Features="debug-determinism;pdb-path-determinism"' /p:UseRoslynAnalyzers=false $pathMapBuildOption $sln
popd
}
......
......@@ -152,7 +152,7 @@ set TMP=%TEMP%
}
}
def triggerPhraseOnly = true
def triggerPhraseOnly = false
def triggerPhraseExtra = "determinism"
Utilities.setMachineAffinity(myJob, 'Windows_NT', 'latest-or-auto-dev15')
addRoslynJob(myJob, jobName, branchName, isPr, triggerPhraseExtra, triggerPhraseOnly)
......
......@@ -194,16 +194,7 @@ private static BoundExpression AddConditionSequencePoint(BoundExpression conditi
/// </remarks>
public override BoundStatement InstrumentForEachStatementCollectionVarDeclaration(BoundForEachStatement original, BoundStatement collectionVarDecl)
{
// NOTE: This is slightly different from Dev10. In Dev10, when you stop the debugger
// on the collection expression, you can see the (uninitialized) iteration variable.
// In Roslyn, you cannot because the iteration variable is re-declared in each iteration
// of the loop and is, therefore, not yet in scope.
if (original.Syntax is ForEachComponentStatementSyntax)
{
return InstrumentForEachStatementDeconstructionVariablesDeclaration(original, collectionVarDecl);
}
var forEachSyntax = (ForEachStatementSyntax)original.Syntax;
var forEachSyntax = (CommonForEachStatementSyntax)original.Syntax;
return new BoundSequencePoint(forEachSyntax.Expression,
base.InstrumentForEachStatementCollectionVarDeclaration(original, collectionVarDecl));
}
......
......@@ -179,7 +179,12 @@ public override BoundStatement InstrumentForEachStatementIterationVarDeclaration
{
return AddDynamicAnalysis(original, base.InstrumentForEachStatementIterationVarDeclaration(original, iterationVarDecl));
}
public override BoundStatement InstrumentForEachStatementDeconstructionVariablesDeclaration(BoundForEachStatement original, BoundStatement iterationVarDecl)
{
return AddDynamicAnalysis(original, base.InstrumentForEachStatementDeconstructionVariablesDeclaration(original, iterationVarDecl));
}
public override BoundStatement InstrumentIfStatement(BoundIfStatement original, BoundStatement rewritten)
{
return AddDynamicAnalysis(original, base.InstrumentIfStatement(original, rewritten));
......@@ -227,16 +232,25 @@ public override BoundStatement InstrumentPatternSwitchStatement(BoundPatternSwit
public override BoundStatement InstrumentPatternSwitchWhenClauseConditionalGotoBody(BoundExpression original, BoundStatement ifConditionGotoBody)
{
// TODO: Desired behavior for a switch when clause has not been specified.
// See also https://github.com/dotnet/roslyn/issues/14156
return base.InstrumentPatternSwitchWhenClauseConditionalGotoBody(original, ifConditionGotoBody);
ifConditionGotoBody = base.InstrumentPatternSwitchWhenClauseConditionalGotoBody(original, ifConditionGotoBody);
// Instrument the statement using a factory with the same syntax as the statement, so that the instrumentation appears to be part of the statement.
SyntheticBoundNodeFactory statementFactory = new SyntheticBoundNodeFactory(_method, original.Syntax, _methodBodyFactory.CompilationState, _diagnostics);
// Instrument using the span of the expression
return statementFactory.StatementList(AddAnalysisPoint(original.Syntax, statementFactory), ifConditionGotoBody);
}
public override BoundStatement InstrumentUsingTargetCapture(BoundUsingStatement original, BoundStatement usingTargetCapture)
{
return AddDynamicAnalysis(original, base.InstrumentUsingTargetCapture(original, usingTargetCapture));
}
public override BoundStatement InstrumentLocalDeconstructionDeclaration(BoundLocalDeconstructionDeclaration original, BoundStatement rewritten)
{
return AddDynamicAnalysis(original, base.InstrumentLocalDeconstructionDeclaration(original, rewritten));
}
private BoundStatement AddDynamicAnalysis(BoundStatement original, BoundStatement rewritten)
{
if (!original.WasCompilerGenerated)
......
......@@ -136,7 +136,7 @@ public virtual BoundStatement InstrumentWhileStatementConditionalGotoStart(Bound
public virtual BoundStatement InstrumentForEachStatementCollectionVarDeclaration(BoundForEachStatement original, BoundStatement collectionVarDecl)
{
Debug.Assert(!original.WasCompilerGenerated);
Debug.Assert(original.Syntax.Kind() == SyntaxKind.ForEachStatement);
Debug.Assert(original.Syntax is CommonForEachStatementSyntax);
return collectionVarDecl;
}
......
......@@ -41,9 +41,10 @@ private bool IsLambdaOrExpressionBodiedMember
{
return true;
}
var sourceMethod = method as SourceMethodSymbol;
return sourceMethod != null
&& sourceMethod.IsExpressionBodied;
return
(method as SourceMethodSymbol)?.IsExpressionBodied ??
(method as LocalFunctionSymbol)?.IsExpressionBodied ?? false;
}
}
}
......
......@@ -290,6 +290,8 @@ internal override TypeSymbol IteratorElementType
public bool IsUnsafe => (_declarationModifiers & DeclarationModifiers.Unsafe) != 0;
internal bool IsExpressionBodied => _syntax.Body == null && _syntax.ExpressionBody != null;
public override DllImportData GetDllImportData() => null;
internal override ImmutableArray<string> GetAppliedConditionalSymbols() => ImmutableArray<string>.Empty;
......
......@@ -122,5 +122,16 @@ internal override bool GenerateDebugInfo
{
get { return true; }
}
internal override bool IsExpressionBodied
{
get
{
var syntax = GetSyntax();
var hasBody = syntax.Body != null;
var hasExpressionBody = syntax.ExpressionBody != null;
return !hasBody && hasExpressionBody;
}
}
}
}
......@@ -124,6 +124,7 @@
<Compile Include="CodeGen\IndexerTests.cs" />
<Compile Include="CodeGen\CodeGenLockTests.cs" />
<Compile Include="CodeGen\ObjectAndCollectionInitializerTests.cs" />
<Compile Include="CodeGen\PropertyTests.cs" />
<Compile Include="CodeGen\SwitchTests.cs" />
<Compile Include="CodeGen\UnsafeTests.cs" />
<Compile Include="CodeGen\WinMdDelegateTests.cs" />
......
......@@ -817,6 +817,44 @@ .maxstack 3
IL_0012: stfld ""E1 C.e""
IL_0017: ret
}
");
}
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
[CompilerTrait(CompilerFeature.ExpressionBody)]
public void ExpressionBodedEvent()
{
var source = @"
class C
{
public int x;
public event System.Action E
{
add => x = 1;
remove => x = 0;
}
}";
var compilation = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll);
var verifier = CompileAndVerify(compilation);
verifier.VerifyIL("C.E.add", @"
{
// Code size 8 (0x8)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldc.i4.1
IL_0002: stfld ""int C.x""
IL_0007: ret
}
");
verifier.VerifyIL("C.E.remove", @"
{
// Code size 8 (0x8)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldc.i4.0
IL_0002: stfld ""int C.x""
IL_0007: ret
}
");
}
}
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.CodeGen
{
public class PropertyTests : EmitMetadataTestBase
{
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
[CompilerTrait(CompilerFeature.ExpressionBody)]
public void ExpressionBodedProperty()
{
var source = @"
class C
{
public int x;
public int X
{
set => x = value;
get => x;
}
}";
var compilation = CreateCompilationWithMscorlib(source, options: TestOptions.DebugDll);
var verifier = CompileAndVerify(compilation);
verifier.VerifyIL("C.X.get", @"
{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldarg.0
IL_0001: ldfld ""int C.x""
IL_0006: ret
}
");
verifier.VerifyIL("C.X.set", @"
{
// Code size 8 (0x8)
.maxstack 2
IL_0000: ldarg.0
IL_0001: ldarg.1
IL_0002: stfld ""int C.x""
IL_0007: ret
}
");
}
}
}
......@@ -424,6 +424,7 @@ class Student : Person { public double GPA; }
VerifySpans(reader, reader.Methods[1], sourceLines,
new SpanResult(13, 4, 26, 5, "static string Operate(Person p)"),
new SpanResult(17, 32, 17, 43, "s.GPA > 3.5"),
new SpanResult(18, 16, 18, 56, "return $\"Student {s.Name} ({s.GPA:N1})\""),
new SpanResult(20, 16, 20, 56, "return $\"Student {s.Name} ({s.GPA:N1})\""),
new SpanResult(22, 16, 22, 58, "return $\"Teacher {t.Name} of {t.Subject}\""),
......@@ -431,6 +432,113 @@ class Student : Person { public double GPA; }
new SpanResult(15, 16, 15, 17, "p"));
}
[Fact]
public void TestDeconstructionSpans()
{
string source = @"
using System;
public class C
{
public static void Main() // Method 1
{
var (x, y) = new C();
}
public void Deconstruct(out int x, out int y)
{
x = 1;
y = 2;
}
}
";
var c = CreateCompilationWithMscorlib(Parse(source + InstrumentationHelperSource, @"C:\myproject\doc1.cs"));
var peImage = c.EmitToArray(EmitOptions.Default.WithInstrumentationKinds(ImmutableArray.Create(InstrumentationKind.TestCoverage)));
var peReader = new PEReader(peImage);
var reader = DynamicAnalysisDataReader.TryCreateFromPE(peReader, "<DynamicAnalysisData>");
string[] sourceLines = source.Split('\n');
VerifySpans(reader, reader.Methods[0], sourceLines,
new SpanResult(5, 4, 8, 5, "public static void Main()"),
new SpanResult(7, 8, 7, 29, "var (x, y) = new C()"));
}
[Fact]
public void TestForeachSpans()
{
string source = @"
using System;
public class C
{
public static void Main() // Method 1
{
C[] a = null;
foreach
(var x
in a)
;
}
}
";
var c = CreateCompilationWithMscorlib(Parse(source + InstrumentationHelperSource, @"C:\myproject\doc1.cs"));
var peImage = c.EmitToArray(EmitOptions.Default.WithInstrumentationKinds(ImmutableArray.Create(InstrumentationKind.TestCoverage)));
var peReader = new PEReader(peImage);
var reader = DynamicAnalysisDataReader.TryCreateFromPE(peReader, "<DynamicAnalysisData>");
string[] sourceLines = source.Split('\n');
VerifySpans(reader, reader.Methods[0], sourceLines,
new SpanResult(5, 4, 12, 5, "public static void Main()"),
new SpanResult(7, 8, 7, 21, "C[] a = null"),
new SpanResult(11, 12, 11, 13, ";"),
new SpanResult(10, 15, 10, 16, "a")
);
}
[Fact]
public void TestForeachDeconstructionSpans()
{
string source = @"
using System;
public class C
{
public static void Main() // Method 1
{
C[] a = null;
foreach
(var (x, y)
in a)
;
}
public void Deconstruct(out int x, out int y)
{
x = 1;
y = 2;
}
}
";
var c = CreateCompilationWithMscorlib(Parse(source + InstrumentationHelperSource, @"C:\myproject\doc1.cs"));
var peImage = c.EmitToArray(EmitOptions.Default.WithInstrumentationKinds(ImmutableArray.Create(InstrumentationKind.TestCoverage)));
var peReader = new PEReader(peImage);
var reader = DynamicAnalysisDataReader.TryCreateFromPE(peReader, "<DynamicAnalysisData>");
string[] sourceLines = source.Split('\n');
VerifySpans(reader, reader.Methods[0], sourceLines,
new SpanResult(5, 4, 12, 5, "public static void Main()"),
new SpanResult(7, 8, 7, 21, "C[] a = null"),
new SpanResult(11, 12, 11, 13, ";"),
new SpanResult(10, 15, 10, 16, "a")
);
}
[Fact]
public void TestFieldInitializerSpans()
{
......
......@@ -1374,6 +1374,7 @@ File 1
Method 3
File 1
True
True
False
True
False
......@@ -1405,6 +1406,166 @@ File 1
verifier.VerifyDiagnostics(Diagnostic(ErrorCode.WRN_UnassignedInternalField, "Subject").WithArguments("Teacher.Subject", "null").WithLocation(37, 40));
}
[Fact]
public void DeconstructionStatementCoverage()
{
string source = @"
using System;
public class C
{
public static void Main() // Method 1
{
TestMain2();
Microsoft.CodeAnalysis.Runtime.Instrumentation.FlushPayload();
}
static void TestMain2() // Method 2
{
var (x, y) = new C();
}
static void TestMain3() // Method 3
{
var (x, y) = new C();
}
public C() // Method 4
{
}
public void Deconstruct(out int x, out int y) // Method 5
{
x = 1;
y = 2;
}
}
";
string expectedOutput = @"Flushing
Method 1
File 1
True
True
True
Method 2
File 1
True
True
Method 4
File 1
True
Method 5
File 1
True
True
True
Method 7
File 1
True
True
False
True
True
True
True
True
True
True
True
True
True
True
";
CompilationVerifier verifier = CompileAndVerify(source + InstrumentationHelperSource, expectedOutput: expectedOutput);
}
[Fact]
public void DeconstructionForeachStatementCoverage()
{
string source = @"
using System;
public class C
{
public static void Main() // Method 1
{
TestMain2(new C[] { new C() });
TestMain3(new C[] { });
Microsoft.CodeAnalysis.Runtime.Instrumentation.FlushPayload();
}
static void TestMain2(C[] a) // Method 2
{
foreach (
var (x, y)
in a)
;
}
static void TestMain3(C[] a) // Method 3
{
foreach (
var (x, y)
in a)
;
}
public C() // Method 4
{
}
public void Deconstruct(out int x, out int y) // Method 5
{
x = 1;
y = 2;
}
}
";
string expectedOutput = @"Flushing
Method 1
File 1
True
True
True
True
Method 2
File 1
True
True
True
Method 3
File 1
True
False
False
Method 4
File 1
True
Method 5
File 1
True
True
True
Method 7
File 1
True
True
False
True
True
True
True
True
True
True
True
True
True
True
";
CompilationVerifier verifier = CompileAndVerify(source + InstrumentationHelperSource, expectedOutput: expectedOutput);
}
[Fact]
public void LambdaCoverage()
{
......
......@@ -5110,6 +5110,128 @@ class C
</symbols>");
}
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
public void ExpressionBodiedConstructor()
{
var comp = CreateCompilationWithMscorlib45(@"
using System;
class C
{
public int X;
public C(Int32 x) => X = x;
}");
comp.VerifyDiagnostics();
comp.VerifyPdb(@"<symbols>
<methods>
<method containingType=""C"" name="".ctor"" parameterNames=""x"">
<customDebugInfo>
<using>
<namespace usingCount=""1"" />
</using>
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""7"" startColumn=""5"" endLine=""7"" endColumn=""22"" />
<entry offset=""0x6"" startLine=""7"" startColumn=""26"" endLine=""7"" endColumn=""31"" />
</sequencePoints>
<scope startOffset=""0x0"" endOffset=""0xe"">
<namespace name=""System"" />
</scope>
</method>
</methods>
</symbols>");
}
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
public void ExpressionBodiedDestructor()
{
var comp = CreateCompilationWithMscorlib45(@"
class C
{
public int X;
~C() => X = 0;
}");
comp.VerifyDiagnostics();
comp.VerifyPdb(@"<symbols>
<methods>
<method containingType=""C"" name=""Finalize"">
<customDebugInfo>
<using>
<namespace usingCount=""0"" />
</using>
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""5"" startColumn=""13"" endLine=""5"" endColumn=""18"" />
<entry offset=""0x9"" hidden=""true"" />
<entry offset=""0x10"" hidden=""true"" />
</sequencePoints>
</method>
</methods>
</symbols>");
}
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
public void ExpressionBodiedAccessor()
{
var comp = CreateCompilationWithMscorlib45(@"
class C
{
public int x;
public int X
{
get => x;
set => x = value;
}
public event System.Action E
{
add => x = 1;
remove => x = 0;
}
}");
comp.VerifyDiagnostics();
comp.VerifyPdb(@"<symbols>
<methods>
<method containingType=""C"" name=""get_X"">
<customDebugInfo>
<using>
<namespace usingCount=""0"" />
</using>
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""7"" startColumn=""16"" endLine=""7"" endColumn=""17"" />
</sequencePoints>
</method>
<method containingType=""C"" name=""set_X"" parameterNames=""value"">
<customDebugInfo>
<forward declaringType=""C"" methodName=""get_X"" />
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""8"" startColumn=""16"" endLine=""8"" endColumn=""25"" />
</sequencePoints>
</method>
<method containingType=""C"" name=""add_E"" parameterNames=""value"">
<customDebugInfo>
<forward declaringType=""C"" methodName=""get_X"" />
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""12"" startColumn=""16"" endLine=""12"" endColumn=""21"" />
</sequencePoints>
</method>
<method containingType=""C"" name=""remove_E"" parameterNames=""value"">
<customDebugInfo>
<forward declaringType=""C"" methodName=""get_X"" />
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""13"" startColumn=""19"" endLine=""13"" endColumn=""24"" />
</sequencePoints>
</method>
</methods>
</symbols>");
}
#endregion
#region Synthesized Methods
......@@ -5514,6 +5636,74 @@ static void M(object o)
</sequencePoints>
</method>
</methods>
</symbols>");
}
[WorkItem(14437, "https://github.com/dotnet/roslyn/issues/14437")]
[Fact]
public void LocalFunctionSequencePoints()
{
string source =
@"class Program
{
static int Main(string[] args)
{ // 4
int Local1(string[] a)
=>
a.Length; // 7
int Local2(string[] a)
{ // 9
return a.Length; // 10
} // 11
return Local1(args) + Local2(args); // 12
} // 13
}";
var c = CreateCompilationWithMscorlibAndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb(
@"<symbols>
<methods>
<method containingType=""Program"" name=""Main"" parameterNames=""args"">
<customDebugInfo>
<using>
<namespace usingCount=""0"" />
</using>
<encLocalSlotMap>
<slot kind=""21"" offset=""0"" />
</encLocalSlotMap>
<encLambdaMap>
<methodOrdinal>0</methodOrdinal>
<lambda offset=""99"" />
<lambda offset=""202"" />
</encLambdaMap>
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""4"" startColumn=""5"" endLine=""4"" endColumn=""6"" />
<entry offset=""0x3"" startLine=""12"" startColumn=""9"" endLine=""12"" endColumn=""44"" />
<entry offset=""0x13"" startLine=""13"" startColumn=""5"" endLine=""13"" endColumn=""6"" />
</sequencePoints>
</method>
<method containingType=""Program"" name=""&lt;Main&gt;g__Local10_0"" parameterNames=""a"">
<customDebugInfo>
<forward declaringType=""Program"" methodName=""Main"" parameterNames=""args"" />
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""7"" startColumn=""13"" endLine=""7"" endColumn=""21"" />
</sequencePoints>
</method>
<method containingType=""Program"" name=""&lt;Main&gt;g__Local20_1"" parameterNames=""a"">
<customDebugInfo>
<forward declaringType=""Program"" methodName=""Main"" parameterNames=""args"" />
<encLocalSlotMap>
<slot kind=""21"" offset=""202"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""9"" startColumn=""9"" endLine=""9"" endColumn=""10"" />
<entry offset=""0x1"" startLine=""10"" startColumn=""13"" endLine=""10"" endColumn=""29"" />
<entry offset=""0x7"" startLine=""11"" startColumn=""9"" endLine=""11"" endColumn=""10"" />
</sequencePoints>
</method>
</methods>
</symbols>");
}
}
......
......@@ -207,5 +207,60 @@ static void F()
"_\u1200_",
"\u1200"));
}
[Fact]
public void DeconstructionForeach()
{
var source =
@"class C
{
static void F(System.Collections.Generic.IEnumerable<(int a, int b)> ie)
{ //4,5
foreach ( //5,9
var (a, b) //6,13
in //7,13
ie) //8,13
{ //9,9
} //10,9
} //11,5
}";
var comp = CreateCompilationWithMscorlib(source, new[] { ValueTupleRef }, options: TestOptions.DebugDll);
comp.VerifyPdb(
string.Format(@"<symbols>
<methods>
<method containingType=""C"" name=""F"" parameterNames=""ie"">
<customDebugInfo>
<using>
<namespace usingCount=""0"" />
</using>
<encLocalSlotMap>
<slot kind=""5"" offset=""17"" />
<slot kind=""0"" offset=""59"" />
<slot kind=""0"" offset=""62"" />
<slot kind=""temp"" />
</encLocalSlotMap>
</customDebugInfo>
<sequencePoints>
<entry offset=""0x0"" startLine=""4"" startColumn=""5"" endLine=""4"" endColumn=""6"" />
<entry offset=""0x1"" startLine=""5"" startColumn=""9"" endLine=""5"" endColumn=""16"" />
<entry offset=""0x2"" startLine=""8"" startColumn=""13"" endLine=""8"" endColumn=""15"" />
<entry offset=""0x9"" hidden=""true"" />
<entry offset=""0xb"" startLine=""6"" startColumn=""13"" endLine=""6"" endColumn=""23"" />
<entry offset=""0x20"" startLine=""9"" startColumn=""9"" endLine=""9"" endColumn=""10"" />
<entry offset=""0x21"" startLine=""10"" startColumn=""9"" endLine=""10"" endColumn=""10"" />
<entry offset=""0x22"" startLine=""7"" startColumn=""13"" endLine=""7"" endColumn=""15"" />
<entry offset=""0x2c"" hidden=""true"" />
<entry offset=""0x37"" startLine=""11"" startColumn=""5"" endLine=""11"" endColumn=""6"" />
</sequencePoints>
<scope startOffset=""0x0"" endOffset=""0x38"">
<scope startOffset=""0xb"" endOffset=""0x22"">
<local name=""a"" il_index=""1"" il_start=""0xb"" il_end=""0x22"" attributes=""0"" />
<local name=""b"" il_index=""2"" il_start=""0xb"" il_end=""0x22"" attributes=""0"" />
</scope>
</scope>
</method>
</methods>
</symbols>"));
}
}
}
......@@ -1655,5 +1655,233 @@ public partial class C33 { }
Diagnostic("UniqueTextFileDiagnostic").WithArguments("Source3_File5.designer.cs").WithLocation(1, 1),
Diagnostic("NumberOfUniqueTextFileDescriptor").WithArguments("3").WithLocation(1, 1));
}
[Fact, WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")]
public void TestParametersAnalyzer_InConstructor()
{
string source = @"
public class C
{
public C(int a, int b)
{
}
}
";
var tree = CSharpSyntaxTree.ParseText(source, path: "Source.cs");
var compilation = CreateCompilationWithMscorlib45(new[] { tree });
compilation.VerifyDiagnostics();
var analyzers = new DiagnosticAnalyzer[] { new AnalyzerForParameters() };
compilation.VerifyAnalyzerDiagnostics(analyzers, null, null, true,
Diagnostic("Parameter_ID", "a").WithLocation(4, 18),
Diagnostic("Parameter_ID", "b").WithLocation(4, 25));
}
[Fact, WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")]
public void TestParametersAnalyzer_InRegularMethod()
{
string source = @"
public class C
{
void M1(string a, string b)
{
}
}
";
var tree = CSharpSyntaxTree.ParseText(source, path: "Source.cs");
var compilation = CreateCompilationWithMscorlib45(new[] { tree });
compilation.VerifyDiagnostics();
var analyzers = new DiagnosticAnalyzer[] { new AnalyzerForParameters() };
compilation.VerifyAnalyzerDiagnostics(analyzers, null, null, true,
Diagnostic("Parameter_ID", "a").WithLocation(4, 20),
Diagnostic("Parameter_ID", "b").WithLocation(4, 30));
}
[Fact, WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")]
public void TestParametersAnalyzer_InIndexers()
{
string source = @"
public class C
{
public int this[int index]
{
get { return 0; }
set { }
}
}
";
var tree = CSharpSyntaxTree.ParseText(source, path: "Source.cs");
var compilation = CreateCompilationWithMscorlib45(new[] { tree });
compilation.VerifyDiagnostics();
var analyzers = new DiagnosticAnalyzer[] { new AnalyzerForParameters() };
compilation.VerifyAnalyzerDiagnostics(analyzers, null, null, true,
Diagnostic("Parameter_ID", "index").WithLocation(4, 25));
}
[Fact(Skip = "https://github.com/dotnet/roslyn/issues/14061"), WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")]
public void TestParametersAnalyzer_Lambdas()
{
string source = @"
public class C
{
void M2()
{
System.Func<int, int, int> x = (int a, int b) => b;
}
}
";
var tree = CSharpSyntaxTree.ParseText(source, path: "Source.cs");
var compilation = CreateCompilationWithMscorlib45(new[] { tree });
compilation.VerifyDiagnostics();
var analyzers = new DiagnosticAnalyzer[] { new AnalyzerForParameters() };
compilation.VerifyAnalyzerDiagnostics(analyzers, null, null, true,
Diagnostic("Local_ID", "x").WithLocation(6, 36),
Diagnostic("Parameter_ID", "a").WithLocation(6, 45),
Diagnostic("Parameter_ID", "b").WithLocation(6, 52));
}
[Fact(Skip = "https://github.com/dotnet/roslyn/issues/14061"), WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")]
public void TestParametersAnalyzer_InAnonymousMethods()
{
string source = @"
public class C
{
void M3()
{
M4(delegate (int x, int y) { });
}
void M4(System.Action<int, int> a) { }
}
";
var tree = CSharpSyntaxTree.ParseText(source, path: "Source.cs");
var compilation = CreateCompilationWithMscorlib45(new[] { tree });
compilation.VerifyDiagnostics();
var analyzers = new DiagnosticAnalyzer[] { new AnalyzerForParameters() };
compilation.VerifyAnalyzerDiagnostics(analyzers, null, null, true,
Diagnostic("Parameter_ID", "a").WithLocation(9, 37),
Diagnostic("Parameter_ID", "x").WithLocation(6, 26),
Diagnostic("Parameter_ID", "y").WithLocation(6, 33));
}
[Fact, WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")]
public void TestParametersAnalyzer_InDelegateTypes()
{
string source = @"
public class C
{
delegate void D(int x, string y);
}
";
var tree = CSharpSyntaxTree.ParseText(source, path: "Source.cs");
var compilation = CreateCompilationWithMscorlib45(new[] { tree });
compilation.VerifyDiagnostics();
var analyzers = new DiagnosticAnalyzer[] { new AnalyzerForParameters() };
compilation.VerifyAnalyzerDiagnostics(analyzers, null, null, true,
Diagnostic("Parameter_ID", "x").WithLocation(4, 25),
Diagnostic("Parameter_ID", "y").WithLocation(4, 35));
}
[Fact, WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")]
public void TestParametersAnalyzer_InOperators()
{
string source = @"
public class C
{
public static implicit operator int (C c) { return 0; }
}
";
var tree = CSharpSyntaxTree.ParseText(source, path: "Source.cs");
var compilation = CreateCompilationWithMscorlib45(new[] { tree });
compilation.VerifyDiagnostics();
var analyzers = new DiagnosticAnalyzer[] { new AnalyzerForParameters() };
compilation.VerifyAnalyzerDiagnostics(analyzers, null, null, true,
Diagnostic("Parameter_ID", "c").WithLocation(4, 44));
}
[Fact, WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")]
public void TestParametersAnalyzer_InExplicitInterfaceImplementations()
{
string source = @"
interface I
{
void M(int a, int b);
}
public class C : I
{
void I.M(int c, int d) { }
}
";
var tree = CSharpSyntaxTree.ParseText(source, path: "Source.cs");
var compilation = CreateCompilationWithMscorlib45(new[] { tree });
compilation.VerifyDiagnostics();
var analyzers = new DiagnosticAnalyzer[] { new AnalyzerForParameters() };
compilation.VerifyAnalyzerDiagnostics(analyzers, null, null, true,
Diagnostic("Parameter_ID", "c").WithLocation(9, 18),
Diagnostic("Parameter_ID", "d").WithLocation(9, 25),
Diagnostic("Parameter_ID", "a").WithLocation(4, 16),
Diagnostic("Parameter_ID", "b").WithLocation(4, 23));
}
[Fact, WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")]
public void TestParametersAnalyzer_InExtensionMethods()
{
string source = @"
public static class C
{
static void M(this int x, int y) { }
}
";
var tree = CSharpSyntaxTree.ParseText(source, path: "Source.cs");
var compilation = CreateCompilationWithMscorlib45(new[] { tree });
compilation.VerifyDiagnostics();
var analyzers = new DiagnosticAnalyzer[] { new AnalyzerForParameters() };
compilation.VerifyAnalyzerDiagnostics(analyzers, null, null, true,
Diagnostic("Parameter_ID", "x").WithLocation(4, 28),
Diagnostic("Parameter_ID", "y").WithLocation(4, 35));
}
[Fact(Skip = "https://github.com/dotnet/roslyn/issues/14061"), WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")]
public void TestParametersAnalyzer_InLocalFunctions()
{
string source = @"
public class C
{
void M1()
{
M2(1, 2);
void M2(int a, int b)
{
}
}
}
";
var tree = CSharpSyntaxTree.ParseText(source, path: "Source.cs");
var compilation = CreateCompilationWithMscorlib45(new[] { tree });
compilation.VerifyDiagnostics();
var analyzers = new DiagnosticAnalyzer[] { new AnalyzerForParameters() };
compilation.VerifyAnalyzerDiagnostics(analyzers, null, null, true,
Diagnostic("Parameter_ID", "a").WithLocation(4, 18), // ctor
Diagnostic("Parameter_ID", "b").WithLocation(4, 25),
Diagnostic("Local_ID", "c").WithLocation(6, 13),
Diagnostic("Local_ID", "d").WithLocation(6, 20),
Diagnostic("Parameter_ID", "a").WithLocation(10, 20), // M1
Diagnostic("Parameter_ID", "b").WithLocation(10, 30),
Diagnostic("Local_ID", "c").WithLocation(12, 11),
Diagnostic("Local_ID", "x").WithLocation(18, 36), // M2
Diagnostic("Parameter_ID", "a").WithLocation(26, 37), // M4
Diagnostic("Parameter_ID", "index").WithLocation(28, 25)); // indexer
}
}
}
......@@ -701,6 +701,8 @@ public struct SymbolAnalysisContext
/// </summary>
public CancellationToken CancellationToken { get { return _cancellationToken; } }
internal Func<Diagnostic, bool> IsSupportedDiagnostic => _isSupportedDiagnostic;
public SymbolAnalysisContext(ISymbol symbol, Compilation compilation, AnalyzerOptions options, Action<Diagnostic> reportDiagnostic, Func<Diagnostic, bool> isSupportedDiagnostic, CancellationToken cancellationToken)
{
_symbol = symbol;
......
......@@ -608,6 +608,53 @@ public void RegisterSymbolAction(DiagnosticAnalyzer analyzer, Action<SymbolAnaly
SymbolAnalyzerAction analyzerAction = new SymbolAnalyzerAction(action, symbolKinds, analyzer);
this.GetOrCreateAnalyzerActions(analyzer).AddSymbolAction(analyzerAction);
_symbolActions = _symbolActions.Add(analyzerAction);
// The SymbolAnalyzerAction does not handle SymbolKind.Parameter because the compiler
// does not make CompilationEvents for them. As a workaround, handle them specially by
// registering further SymbolActions (for Methods) and utilize the results to construct
// the necessary SymbolAnalysisContexts.
if (symbolKinds.Contains(SymbolKind.Parameter))
{
RegisterSymbolAction(
analyzer,
context =>
{
ImmutableArray<IParameterSymbol> parameters;
switch (context.Symbol.Kind)
{
case SymbolKind.Method:
parameters = ((IMethodSymbol)context.Symbol).Parameters;
break;
case SymbolKind.Property:
parameters = ((IPropertySymbol)context.Symbol).Parameters;
break;
case SymbolKind.NamedType:
var namedType = (INamedTypeSymbol)context.Symbol;
var delegateInvokeMethod = namedType.DelegateInvokeMethod;
parameters = delegateInvokeMethod?.Parameters ?? ImmutableArray.Create<IParameterSymbol>();
break;
default:
throw new ArgumentException(nameof(context));
}
foreach (var parameter in parameters)
{
if (!parameter.IsImplicitlyDeclared)
{
action(new SymbolAnalysisContext(
parameter,
context.Compilation,
context.Options,
context.ReportDiagnostic,
context.IsSupportedDiagnostic,
context.CancellationToken));
}
}
},
ImmutableArray.Create(SymbolKind.Method, SymbolKind.Property, SymbolKind.NamedType));
}
}
public void RegisterCodeBlockStartAction<TLanguageKindEnum>(DiagnosticAnalyzer analyzer, Action<CodeBlockStartAnalysisContext<TLanguageKindEnum>> action) where TLanguageKindEnum : struct
......
......@@ -1375,6 +1375,14 @@ lUnsplitAndFinish:
Return Nothing
End Function
Public Overrides Function VisitRelaxationLambda(node As BoundRelaxationLambda) As BoundNode
Throw ExceptionUtilities.Unreachable
End Function
Public Overrides Function VisitConvertedTupleElements(node As BoundConvertedTupleElements) As BoundNode
Throw ExceptionUtilities.Unreachable
End Function
Public Overrides Function VisitUserDefinedConversion(node As BoundUserDefinedConversion) As BoundNode
VisitRvalue(node.UnderlyingExpression)
Return Nothing
......
......@@ -174,6 +174,7 @@
<Compile Include="Binding\TypesOfImportedNamespacesMembersBinder.vb" />
<Compile Include="Binding\UsingBlockBinder.vb" />
<Compile Include="Binding\UsingInfo.vb" />
<Compile Include="BoundTree\BoundConvertedTupleElements.vb" />
<Compile Include="BoundTree\BoundInterpolatedStringExpression.vb" />
<Compile Include="BoundTree\BoundMyClassReference.vb" />
<Compile Include="BoundTree\BoundMyBaseReference.vb" />
......
......@@ -995,7 +995,11 @@ DoneWithDiagnostics:
' The conversion has the lambda stored internally to not clutter the bound tree with synthesized nodes
' in the first pass. Later the node get's rewritten into a delegate creation with the lambda if needed.
Return New BoundConversion(tree, argument, convKind, False, isExplicit, boundLambdaOpt, relaxationReceiverPlaceholderOpt, targetType)
Return New BoundConversion(tree, argument, convKind, False, isExplicit, Nothing,
If(boundLambdaOpt Is Nothing,
Nothing,
New BoundRelaxationLambda(tree, boundLambdaOpt, relaxationReceiverPlaceholderOpt).MakeCompilerGenerated()),
targetType)
Else
Debug.Assert(diagnostics.HasAnyErrors())
End If
......@@ -1016,7 +1020,39 @@ DoneWithDiagnostics:
constantResult = Conversions.TryFoldNothingReferenceConversion(argument, convKind, targetType)
End If
Return New BoundConversion(tree, argument, convKind, CheckOverflow, isExplicit, constantResult, targetType)
Dim tupleElements As BoundConvertedTupleElements = CreateConversionForTupleElements(tree, sourceType, targetType, convKind, isExplicit)
Return New BoundConversion(tree, argument, convKind, CheckOverflow, isExplicit, constantResult, tupleElements, targetType)
End Function
Private Function CreateConversionForTupleElements(
tree As SyntaxNode,
sourceType As TypeSymbol,
targetType As TypeSymbol,
convKind As ConversionKind,
isExplicit As Boolean
) As BoundConvertedTupleElements
If (convKind And ConversionKind.Tuple) <> 0 Then
Dim ignore = DiagnosticBag.GetInstance()
Dim sourceElementTypes = sourceType.GetNullableUnderlyingTypeOrSelf().GetElementTypesOfTupleOrCompatible()
Dim targetElementTypes = targetType.GetNullableUnderlyingTypeOrSelf().GetElementTypesOfTupleOrCompatible()
Dim placeholders = ArrayBuilder(Of BoundRValuePlaceholder).GetInstance(sourceElementTypes.Length)
Dim converted = ArrayBuilder(Of BoundExpression).GetInstance(sourceElementTypes.Length)
For i As Integer = 0 To sourceElementTypes.Length - 1
Dim placeholder = New BoundRValuePlaceholder(tree, sourceElementTypes(i)).MakeCompilerGenerated()
placeholders.Add(placeholder)
converted.Add(ApplyConversion(tree, targetElementTypes(i), placeholder, isExplicit, ignore))
Next
ignore.Free()
Return New BoundConvertedTupleElements(tree, placeholders.ToImmutableAndFree(), converted.ToImmutableAndFree()).MakeCompilerGenerated()
End If
Return Nothing
End Function
Private Function CreateUserDefinedConversion(
......@@ -1434,7 +1470,11 @@ DoneWithDiagnostics:
End If
If conversionSemantics = SyntaxKind.CTypeKeyword Then
Return New BoundConversion(tree, boundLambda, convKind, False, isExplicit, relaxationLambdaOpt, targetType)
Return New BoundConversion(tree, boundLambda, convKind, False, isExplicit, Nothing,
If(relaxationLambdaOpt Is Nothing,
Nothing,
New BoundRelaxationLambda(tree, relaxationLambdaOpt, receiverPlaceholderOpt:=Nothing).MakeCompilerGenerated()),
targetType)
ElseIf conversionSemantics = SyntaxKind.DirectCastKeyword Then
Return New BoundDirectCast(tree, boundLambda, convKind, relaxationLambdaOpt, targetType)
ElseIf conversionSemantics = SyntaxKind.TryCastKeyword Then
......
......@@ -20,35 +20,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Me.New(syntax, operand, conversionKind, checked, explicitCastInCode, constantValueOpt:=Nothing, type:=type, hasErrors:=hasErrors)
End Sub
Public Sub New(
syntax As SyntaxNode,
operand As BoundExpression,
conversionKind As ConversionKind,
checked As Boolean,
explicitCastInCode As Boolean,
relaxationLambdaOpt As BoundLambda,
type As TypeSymbol,
Optional hasErrors As Boolean = False
)
Me.New(syntax, operand, conversionKind, checked, explicitCastInCode, constantValueOpt:=Nothing, constructorOpt:=Nothing,
relaxationLambdaOpt:=relaxationLambdaOpt, relaxationReceiverPlaceholderOpt:=Nothing, type:=type, hasErrors:=hasErrors)
End Sub
Public Sub New(
syntax As SyntaxNode,
operand As BoundExpression,
conversionKind As ConversionKind,
checked As Boolean,
explicitCastInCode As Boolean,
relaxationLambdaOpt As BoundLambda,
RelaxationReceiverPlaceholderOpt As BoundRValuePlaceholder,
type As TypeSymbol,
Optional hasErrors As Boolean = False
)
Me.New(syntax, operand, conversionKind, checked, explicitCastInCode, constantValueOpt:=Nothing, constructorOpt:=Nothing,
relaxationLambdaOpt:=relaxationLambdaOpt, relaxationReceiverPlaceholderOpt:=RelaxationReceiverPlaceholderOpt, type:=type, hasErrors:=hasErrors)
End Sub
Public Sub New(
syntax As SyntaxNode,
operand As BoundExpression,
......@@ -59,13 +30,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
type As TypeSymbol,
Optional hasErrors As Boolean = False
)
Me.New(syntax, operand, conversionKind, checked, explicitCastInCode, constantValueOpt:=constantValueOpt, constructorOpt:=Nothing, type:=type, hasErrors:=hasErrors)
End Sub
Public Sub New(syntax As SyntaxNode, operand As BoundExpression, conversionKind As ConversionKind, checked As Boolean, explicitCastInCode As Boolean, constantValueOpt As ConstantValue, constructorOpt As MethodSymbol, type As TypeSymbol, Optional hasErrors As Boolean = False)
Me.New(syntax, operand, conversionKind, checked, explicitCastInCode, constantValueOpt, constructorOpt,
relaxationLambdaOpt:=Nothing, relaxationReceiverPlaceholderOpt:=Nothing, type:=type, hasErrors:=hasErrors)
Me.New(syntax, operand, conversionKind, checked, explicitCastInCode, constantValueOpt:=constantValueOpt, extendedInfoOpt:=Nothing, type:=type, hasErrors:=hasErrors)
End Sub
#If DEBUG Then
......@@ -78,6 +43,24 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Else
Debug.Assert(((ConversionKind And VisualBasic.ConversionKind.UserDefined) <> 0) = (Operand.Kind = BoundKind.UserDefinedConversion))
If Conversions.IsIdentityConversion(ConversionKind) Then
Debug.Assert(ExtendedInfoOpt Is Nothing)
End If
If (ConversionKind And (ConversionKind.Lambda Or ConversionKind.AnonymousDelegate)) <> 0 Then
Debug.Assert(ExtendedInfoOpt Is Nothing OrElse ExtendedInfoOpt.Kind = BoundKind.RelaxationLambda)
Debug.Assert((ConversionKind And ConversionKind.AnonymousDelegate) <> 0 OrElse
TryCast(ExtendedInfoOpt, BoundRelaxationLambda)?.ReceiverPlaceholderOpt Is Nothing)
End If
If (ConversionKind And ConversionKind.Tuple) <> 0 Then
If ExtendedInfoOpt Is Nothing Then
Debug.Assert(Operand.Kind = BoundKind.ConvertedTupleLiteral OrElse Operand.HasErrors)
Else
Debug.Assert(ExtendedInfoOpt.Kind = BoundKind.ConvertedTupleElements)
End If
End If
If Operand.Kind = BoundKind.UserDefinedConversion Then
Dim udc = DirectCast(Operand, BoundUserDefinedConversion)
Debug.Assert(udc.UnderlyingExpression.Type.IsSameTypeIgnoringAll(Type))
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Namespace Microsoft.CodeAnalysis.VisualBasic
Partial Friend Class BoundConvertedTupleElements
#If DEBUG Then
Private Sub Validate()
Debug.Assert(ElementPlaceholders.Length = ConvertedElements.Length)
Debug.Assert(Not ElementPlaceholders.Contains(Nothing))
Debug.Assert(Not ConvertedElements.Contains(Nothing))
End Sub
#End If
End Class
End Namespace
\ No newline at end of file
......@@ -452,20 +452,24 @@
<Field Name="ExplicitCastInCode" Type="Boolean"/>
<Field Name="ConstantValueOpt" PropertyOverrides="true" Type="ConstantValue" Null="allow"/>
<!-- Constructor symbol may only be not-null for conversion from Nothing to a ValueType.
In this case we check if the ValueType has parameterless constructor and if it is accessible.
If we find such a constructor, we store the symbol in bound node to be used
in emit phase. If ConstructorOpt in Nothing, 'initobj' will be used for ValueType construction.
-->
<Field Name="ConstructorOpt" Type="MethodSymbol" Null="allow"/>
<Field Name="ExtendedInfoOpt" Type="BoundExtendedConversionInfo" Null="allow"/>
</Node>
<!-- If this is a lambda conversion which requires a stub, additional lambda
representing the stub is stored here -->
<Field Name="RelaxationLambdaOpt" Type="BoundLambda" Null="allow" />
<AbstractNode Name="BoundExtendedConversionInfo" Base="BoundNode"/>
<!-- Captures information about relaxation lambda necessary for a conversion -->
<Node Name="BoundRelaxationLambda" Base="BoundExtendedConversionInfo">
<Field Name="Lambda" Type="BoundLambda" Null="disallow" />
<!-- The placeholder of a captured receiver for the relaxation lambda -->
<Field Name="RelaxationReceiverPlaceholderOpt" Type="BoundRValuePlaceholder" Null="allow" />
<Field Name="ReceiverPlaceholderOpt" Type="BoundRValuePlaceholder" Null="allow" />
</Node>
<!-- Used when source is not a tuple literal -->
<Node Name="BoundConvertedTupleElements" Base="BoundExtendedConversionInfo" HasValidate="true">
<Field Name="ElementPlaceholders" Type="ImmutableArray(Of BoundRValuePlaceholder)" Null="disallow" />
<Field Name="ConvertedElements" Type="ImmutableArray(Of BoundExpression)" Null="disallow" />
</Node>
<!-- This node is created to represent a user-defined conversion operator call
It is used in place of BoundConversion.Operand and the initial operand of
the conversion is an argument (possibly converted) of the underlying call expression,
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Collections.Immutable
Imports System.Reflection.Metadata
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports PrimitiveTypeCode = Microsoft.Cci.PrimitiveTypeCode
......@@ -211,8 +212,18 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
' But first Pop off the Null reference cause we don't need it anymore.
_builder.EmitOpCode(ILOpCode.Pop)
Dim constructor = GetParameterlessValueTypeConstructor(DirectCast(typeTo, NamedTypeSymbol))
'TODO: used
EmitLoadDefaultValueOfTypeFromConstructorCall(conversion.ConstructorOpt, used:=True, syntaxNode:=conversion.Syntax)
If constructor Is Nothing OrElse constructor.IsDefaultValueTypeConstructor() Then
EmitInitObj(typeTo, used:=True, syntaxNode:=conversion.Syntax)
Else
' before we use constructor symbol we need to report use site error if any
Binder.ReportUseSiteError(_diagnostics, conversion.Syntax, constructor)
EmitNewObj(constructor, ImmutableArray(Of BoundExpression).Empty, used:=True, syntaxNode:=conversion.Syntax)
End If
_builder.EmitBranch(ILOpCode.Br_s, resultLabel)
_builder.MarkLabel(unboxLabel)
......@@ -230,6 +241,32 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
End Sub
''' <summary>
''' Returns parameterless value type constructor.
''' </summary>
Private Function GetParameterlessValueTypeConstructor(typeTo As NamedTypeSymbol) As MethodSymbol
Debug.Assert(typeTo.IsValueType AndAlso Not typeTo.IsTypeParameter)
' find valuetype parameterless constructor and check the accessibility
For Each constr In typeTo.InstanceConstructors
' NOTE: we intentionally skip constructors with all
' optional parameters; this matches Dev10 behavior
If constr.ParameterCount = 0 Then
' check 'constr'
If AccessCheck.IsSymbolAccessible(constr, _method.ContainingType, typeTo, useSiteDiagnostics:=Nothing) Then
Return constr
End If
' exit for each in any case
Return Nothing
End If
Next
' This point should not be reachable, because if there is no constructor in the
' loaded value type, we should have generated a synthesized constructor.
Throw ExceptionUtilities.Unreachable
End Function
Private Function IsUnboxingDirectCast(conversion As BoundDirectCast) As Boolean
Dim typeTo As TypeSymbol = conversion.Type
Dim typeFrom As TypeSymbol = conversion.Operand.Type
......
......@@ -1542,17 +1542,6 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
EmitLoadDefaultValueOfTypeFromNothingLiteral(type, used, syntaxNode)
End Sub
Private Sub EmitLoadDefaultValueOfTypeFromConstructorCall(constructor As MethodSymbol,
used As Boolean,
syntaxNode As SyntaxNode)
If constructor.IsDefaultValueTypeConstructor() Then
EmitInitObj(constructor.ContainingType, used, syntaxNode)
Else
EmitNewObj(constructor, ImmutableArray(Of BoundExpression).Empty, used, syntaxNode)
End If
End Sub
Private Sub EmitLoadDefaultValueOfTypeFromNothingLiteral(type As TypeSymbol, used As Boolean, syntaxNode As SyntaxNode)
EmitInitObj(type, used, syntaxNode)
End Sub
......
......@@ -363,8 +363,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Public Overrides Function VisitConversion(node As BoundConversion) As BoundNode
Dim rewritten = DirectCast(MyBase.VisitConversion(node), BoundConversion)
Dim operand As BoundExpression = rewritten.Operand
Debug.Assert(rewritten.RelaxationReceiverPlaceholderOpt Is Nothing)
Debug.Assert(rewritten.RelaxationLambdaOpt Is Nothing)
Debug.Assert(rewritten.ExtendedInfoOpt Is Nothing)
If Not NeedsSpill(operand) Then
Return rewritten
......@@ -379,9 +378,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
rewritten.Checked,
rewritten.ExplicitCastInCode,
rewritten.ConstantValueOpt,
rewritten.ConstructorOpt,
rewritten.RelaxationLambdaOpt,
rewritten.RelaxationReceiverPlaceholderOpt,
rewritten.ExtendedInfoOpt,
rewritten.Type))
End Function
......
......@@ -311,7 +311,7 @@ lSelect:
End If
If Me.IsInExpressionLambda AndAlso (node.ConversionKind And ConversionKind.Lambda) <> 0 Then
VisitLambdaConversion(node.Operand, node.RelaxationLambdaOpt)
VisitLambdaConversion(node.Operand, DirectCast(node.ExtendedInfoOpt, BoundRelaxationLambda)?.Lambda)
Else
MyBase.VisitConversion(node)
End If
......
......@@ -228,7 +228,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
If outConv IsNot Nothing Then
outConv = outConv.Update([call], outConv.ConversionKind, outConv.Checked, outConv.ExplicitCastInCode, outConv.ConstantValueOpt,
outConv.ConstructorOpt, outConv.RelaxationLambdaOpt, outConv.RelaxationReceiverPlaceholderOpt, outConv.Type)
outConv.ExtendedInfoOpt, outConv.Type)
End If
Dim newInOutConversionFlags As Byte = CByte(If(outConv IsNot Nothing, 2, 0) + If(innerConversionApplied, 1, 0))
......@@ -241,8 +241,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End If
Return conversion.Update(userDefinedConv, newConversionKind,
conversion.Checked, conversion.ExplicitCastInCode, conversion.ConstantValueOpt, conversion.ConstructorOpt,
conversion.RelaxationLambdaOpt, conversion.RelaxationReceiverPlaceholderOpt, toType)
conversion.Checked, conversion.ExplicitCastInCode, conversion.ConstantValueOpt,
conversion.ExtendedInfoOpt, toType)
End Function
End Class
......
......@@ -20,8 +20,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return Me.VisitInternal(node.Operand)
End If
Debug.Assert(node.RelaxationLambdaOpt Is Nothing)
Debug.Assert(node.RelaxationReceiverPlaceholderOpt Is Nothing)
Debug.Assert(node.ExtendedInfoOpt Is Nothing)
Return ConvertExpression(node.Operand, node.ConversionKind, node.Operand.Type, node.Type, node.Checked, node.ExplicitCastInCode, ConversionSemantics.[Default])
End Function
......
......@@ -356,7 +356,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Function
Public Overrides Function VisitConversion(conversion As BoundConversion) As BoundNode
Debug.Assert(conversion.RelaxationLambdaOpt Is Nothing AndAlso conversion.RelaxationReceiverPlaceholderOpt Is Nothing)
Debug.Assert(conversion.ExtendedInfoOpt Is Nothing)
Dim lambda As BoundLambda = TryCast(conversion.Operand, BoundLambda)
If lambda Is Nothing Then
......
......@@ -933,7 +933,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End Function
Public Overrides Function VisitConversion(conversion As BoundConversion) As BoundNode
Debug.Assert(conversion.RelaxationLambdaOpt Is Nothing AndAlso conversion.RelaxationReceiverPlaceholderOpt Is Nothing)
Debug.Assert(conversion.ExtendedInfoOpt Is Nothing)
Dim lambda As BoundLambda = TryCast(conversion.Operand, BoundLambda)
If lambda Is Nothing Then
......@@ -947,9 +947,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
conversion.Checked,
conversion.ExplicitCastInCode,
conversion.ConstantValueOpt,
conversion.ConstructorOpt,
conversion.RelaxationLambdaOpt,
conversion.RelaxationReceiverPlaceholderOpt,
conversion.ExtendedInfoOpt,
conversion.Type)
End If
Return result
......
......@@ -157,7 +157,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim cast = DirectCast(operand, BoundConversion)
Return cast.Update(ReplaceMyGroupCollectionPropertyGetWithUnderlyingField(cast.Operand),
cast.ConversionKind, cast.Checked, cast.ExplicitCastInCode, cast.ConstantValueOpt,
cast.ConstructorOpt, cast.RelaxationLambdaOpt, cast.RelaxationReceiverPlaceholderOpt,
cast.ExtendedInfoOpt,
cast.Type)
Case BoundKind.Call
......
......@@ -301,6 +301,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
WideningNumeric = [Widening] Or Numeric
NarrowingNumeric = [Narrowing] Or Numeric
''' <summary>
''' Can be combined with <see cref="ConversionKind.Tuple"/> to indicate that the underlying value conversion is a predefined tuple conversion
''' </summary>
Nullable = 1 << 4
WideningNullable = [Widening] Or Nullable
NarrowingNullable = [Narrowing] Or Nullable
......@@ -384,9 +387,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
InterpolatedString = [Widening] Or (1 << 25)
' Tuple conversions
''' <summary>
''' Can be combined with <see cref="ConversionKind.Nullable"/> to indicate that the underlying value conversion is a predefined tuple conversion
''' </summary>
Tuple = (1 << 26)
WideningTuple = [Widening] Or Tuple
NarrowingTuple = [Narrowing] Or Tuple
WideningNullableTuple = WideningNullable Or Tuple
NarrowingNullableTuple = NarrowingNullable Or Tuple
' Bits 28 - 31 are reserved for failure flags.
End Enum
......@@ -1225,8 +1233,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
If destination.IsNullableType Then
destination = destination.GetNullableUnderlyingType()
wideningConversion = ConversionKind.WideningNullable
narrowingConversion = ConversionKind.NarrowingNullable
wideningConversion = ConversionKind.WideningNullableTuple
narrowingConversion = ConversionKind.NarrowingNullableTuple
End If
' tuple literal converts to its inferred type
......@@ -1246,9 +1254,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' check arguments against flattened list of target element types
Dim result As ConversionKind = wideningConversion
' Note, as an optimization this local may accumulate flags other than ConversionKind.InvolvesNarrowingFromNumericConstant,
' but we are going to pay attention only to that bit at the end.
Dim involvesNarrowingFromNumericConstant As ConversionKind = Nothing
Dim allNarrowingIsFromNumericConstant = ConversionKind.InvolvesNarrowingFromNumericConstant
Dim maxDelegateRelaxationLevel = ConversionKind.DelegateRelaxationLevelNone
For i As Integer = 0 To arguments.Length - 1
Dim argument = arguments(i)
Dim targetElementType = targetElementTypes(i)
......@@ -1263,6 +1276,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return Nothing 'ConversionKind.NoConversion
End If
Dim elementDelegateRelaxationLevel = elementConversion And ConversionKind.DelegateRelaxationLevelMask
If elementDelegateRelaxationLevel > maxDelegateRelaxationLevel Then
maxDelegateRelaxationLevel = elementDelegateRelaxationLevel
End If
involvesNarrowingFromNumericConstant = involvesNarrowingFromNumericConstant Or elementConversion
If IsNarrowingConversion(elementConversion) Then
......@@ -1271,8 +1289,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End If
Next
Return result Or
(involvesNarrowingFromNumericConstant And allNarrowingIsFromNumericConstant And ConversionKind.InvolvesNarrowingFromNumericConstant)
Debug.Assert((allNarrowingIsFromNumericConstant And Not ConversionKind.InvolvesNarrowingFromNumericConstant) = 0)
Return result Or (involvesNarrowingFromNumericConstant And allNarrowingIsFromNumericConstant) Or maxDelegateRelaxationLevel
End Function
Private Shared Function ClassifyArrayInitialization(source As BoundArrayInitialization, targetElementType As TypeSymbol, binder As Binder, <[In], Out> ByRef useSiteDiagnostics As HashSet(Of DiagnosticInfo)) As ConversionKind
......@@ -1382,12 +1400,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return conv.Key And (Not ConversionKind.Identity) Or (ConversionKind.Widening Or ConversionKind.Lambda) Or conversionKindExpressionTree
ElseIf NoConversion(conv.Key) Then
Return conv.Key Or (ConversionKind.Lambda Or ConversionKind.FailedDueToQueryLambdaBodyMismatch) Or conversionKindExpressionTree
ElseIf conv.Value IsNot Nothing Then
Debug.Assert((conv.Key And ConversionKind.UserDefined) <> 0)
Return (conv.Key And (Not (ConversionKind.UserDefined Or ConversionKind.Nullable))) Or ConversionKind.Lambda Or conversionKindExpressionTree
Else
Debug.Assert((conv.Key And ConversionKind.UserDefined) = 0)
Return conv.Key Or ConversionKind.Lambda Or conversionKindExpressionTree
Debug.Assert(((conv.Key And ConversionKind.UserDefined) <> 0) = (conv.Value IsNot Nothing))
Return (conv.Key And (Not (ConversionKind.UserDefined Or ConversionKind.Nullable Or ConversionKind.Tuple))) Or ConversionKind.Lambda Or conversionKindExpressionTree
End If
End If
ElseIf invoke.ReturnType.IsSameTypeIgnoringAll(source.LambdaSymbol.ReturnType) Then
......@@ -3464,6 +3479,8 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End If
End If
Const preserveConversionKindFromUnderlyingPredefinedConversion As ConversionKind = ConversionKind.Tuple Or ConversionKind.DelegateRelaxationLevelMask
If srcIsNullable Then
Dim conv As ConversionKind
......@@ -3472,19 +3489,21 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
'From a type T? to a type S?
conv = ClassifyPredefinedConversion(srcUnderlying, dstUnderlying, useSiteDiagnostics)
Debug.Assert((conv And ConversionKind.VarianceConversionAmbiguity) = 0)
Debug.Assert((conv And ConversionKind.DelegateRelaxationLevelMask) = 0 OrElse (conv And ConversionKind.Tuple) <> 0)
If IsWideningConversion(conv) Then
'From a type T? to a type S?, where there is a widening conversion from the type T to the type S.
Return ConversionKind.WideningNullable
Return ConversionKind.WideningNullable Or (conv And preserveConversionKindFromUnderlyingPredefinedConversion)
ElseIf IsNarrowingConversion(conv) Then
'From a type T? to a type S?, where there is a narrowing conversion from the type T to the type S.
Return ConversionKind.NarrowingNullable
Return ConversionKind.NarrowingNullable Or (conv And preserveConversionKindFromUnderlyingPredefinedConversion)
End If
ElseIf IsInterfaceType(destination) Then
' !!! Note that the spec doesn't mention anything about variance, but
' !!! it appears to be taken into account by Dev10 compiler.
conv = ClassifyDirectCastConversion(srcUnderlying, destination, useSiteDiagnostics)
Debug.Assert((conv And ConversionKind.Tuple) = 0)
If IsWideningConversion(conv) Then
'From a type T? to an interface type that the type T implements.
......@@ -3497,9 +3516,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
ElseIf srcUnderlying.IsSameTypeIgnoringAll(destination) Then
'From a type T? to a type T.
Return ConversionKind.NarrowingNullable
ElseIf ConversionExists(ClassifyPredefinedConversion(srcUnderlying, destination, useSiteDiagnostics)) Then
'From a type S? to a type T, where there is a conversion from the type S to the type T.
Return ConversionKind.NarrowingNullable
Else
conv = ClassifyPredefinedConversion(srcUnderlying, destination, useSiteDiagnostics)
Debug.Assert((conv And ConversionKind.DelegateRelaxationLevelMask) = 0 OrElse (conv And ConversionKind.Tuple) <> 0)
If ConversionExists(conv) Then
'From a type S? to a type T, where there is a conversion from the type S to the type T.
Return ConversionKind.NarrowingNullable Or (conv And preserveConversionKindFromUnderlyingPredefinedConversion)
End If
End If
Else
......@@ -3513,13 +3537,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim conv = ClassifyPredefinedConversion(source, dstUnderlying, useSiteDiagnostics)
Debug.Assert((conv And ConversionKind.VarianceConversionAmbiguity) = 0)
Debug.Assert((conv And ConversionKind.DelegateRelaxationLevelMask) = 0 OrElse (conv And ConversionKind.Tuple) <> 0)
If IsWideningConversion(conv) Then
'From a type T to a type S?, where there is a widening conversion from the type T to the type S.
Return ConversionKind.WideningNullable
Return ConversionKind.WideningNullable Or (conv And preserveConversionKindFromUnderlyingPredefinedConversion)
ElseIf IsNarrowingConversion(conv) Then
'From a type T to a type S?, where there is a narrowing conversion from the type T to the type S.
Return ConversionKind.NarrowingNullable
Return ConversionKind.NarrowingNullable Or (conv And preserveConversionKindFromUnderlyingPredefinedConversion)
End If
End If
......@@ -3545,6 +3570,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' check arguments against flattened list of target element types
Dim result As ConversionKind = ConversionKind.WideningTuple
Dim maxDelegateRelaxationLevel = ConversionKind.DelegateRelaxationLevelNone
For i As Integer = 0 To sourceElementTypes.Length - 1
Dim argumentType = sourceElementTypes(i)
......@@ -3560,12 +3586,18 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return Nothing 'ConversionKind.NoConversion
End If
Debug.Assert((elementConversion And ConversionKind.InvolvesNarrowingFromNumericConstant) = 0)
Dim elementDelegateRelaxationLevel = elementConversion And ConversionKind.DelegateRelaxationLevelMask
If elementDelegateRelaxationLevel > maxDelegateRelaxationLevel Then
maxDelegateRelaxationLevel = elementDelegateRelaxationLevel
End If
If IsNarrowingConversion(elementConversion) Then
result = ConversionKind.NarrowingTuple
End If
Next
Return result
Return result Or maxDelegateRelaxationLevel
End Function
Public Shared Function ClassifyStringConversion(source As TypeSymbol, destination As TypeSymbol) As ConversionKind
......
......@@ -981,6 +981,162 @@ End Class
Diagnostic(OwningSymbolTestAnalyzer.ExpressionDescriptor.Id, "12").WithLocation(12, 36))
End Sub
<Fact, WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")>
Public Sub TestParametersAnalyzer_InRegularMethods()
Dim source = <compilation>
<file name="c.vb">
<![CDATA[
Class C
Public Sub M(a As Integer, b As String)
End Sub
End Class
]]>
</file>
</compilation>
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(source)
comp.VerifyDiagnostics()
comp.VerifyAnalyzerDiagnostics({New AnalyzerForParameters}, Nothing, Nothing, False,
Diagnostic("Parameter_ID", "a").WithLocation(2, 18),
Diagnostic("Parameter_ID", "b").WithLocation(2, 32))
End Sub
<Fact, WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")>
Public Sub TestParametersAnalyzer_InConstructors()
Dim source = <compilation>
<file name="c.vb">
<![CDATA[
Class C
Public Sub New(a As Integer, b As String)
End Sub
End Class
]]>
</file>
</compilation>
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(source)
comp.VerifyDiagnostics()
comp.VerifyAnalyzerDiagnostics({New AnalyzerForParameters}, Nothing, Nothing, False,
Diagnostic("Parameter_ID", "a").WithLocation(2, 20),
Diagnostic("Parameter_ID", "b").WithLocation(2, 34))
End Sub
<Fact, WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")>
Public Sub TestParametersAnalyzer_InIndexers()
Dim source = <compilation>
<file name="c.vb">
<![CDATA[
Class C
Default Public Property Item(a As Integer, b As Integer) As Integer
Get
Return 0
End Get
Set(ByVal Value As Integer)
End Set
End Property
End Class
]]>
</file>
</compilation>
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(source)
comp.VerifyDiagnostics()
comp.VerifyAnalyzerDiagnostics({New AnalyzerForParameters}, Nothing, Nothing, False,
Diagnostic("Parameter_ID", "a").WithLocation(2, 34),
Diagnostic("Parameter_ID", "b").WithLocation(2, 48),
Diagnostic("Parameter_ID", "Value").WithLocation(6, 19))
End Sub
<Fact(Skip:="https://github.com/dotnet/roslyn/issues/14062"), WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")>
Public Sub TestParametersAnalyzer_InDelegateTypes()
Dim source = <compilation>
<file name="c.vb">
<![CDATA[
Class C
Delegate Sub DelegateType(a As Integer, b As String)
End Class
]]>
</file>
</compilation>
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(source)
comp.VerifyDiagnostics()
comp.VerifyAnalyzerDiagnostics({New AnalyzerForParameters}, Nothing, Nothing, False,
Diagnostic("Parameter_ID", "a").WithLocation(2, 34),
Diagnostic("Parameter_ID", "b").WithLocation(2, 48))
End Sub
<Fact, WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")>
Public Sub TestParametersAnalyzer_InOperators()
Dim source = <compilation>
<file name="c.vb">
<![CDATA[
Class C
Public Shared Operator +(ByVal h1 As C, ByVal h2 As C)
Return New C()
End Operator
End Class
]]>
</file>
</compilation>
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(source)
comp.VerifyDiagnostics()
comp.VerifyAnalyzerDiagnostics({New AnalyzerForParameters}, Nothing, Nothing, False,
Diagnostic("Parameter_ID", "h1").WithLocation(2, 36),
Diagnostic("Parameter_ID", "h2").WithLocation(2, 51))
End Sub
<Fact, WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")>
Public Sub TestParametersAnalyzer_InInterfaceImplementations()
Dim source = <compilation>
<file name="c.vb">
<![CDATA[
Interface I
Sub M(a As Integer, b As String)
End Interface
Class C
Implements I
Public Sub M(a As Integer, b As String) Implements I.M
End Sub
End Class
]]>
</file>
</compilation>
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(source)
comp.VerifyDiagnostics()
comp.VerifyAnalyzerDiagnostics({New AnalyzerForParameters}, Nothing, Nothing, False,
Diagnostic("Parameter_ID", "a").WithLocation(2, 11),
Diagnostic("Parameter_ID", "b").WithLocation(2, 25),
Diagnostic("Parameter_ID", "a").WithLocation(7, 18),
Diagnostic("Parameter_ID", "b").WithLocation(7, 32))
End Sub
<Fact, WorkItem(8753, "https://github.com/dotnet/roslyn/issues/8753")>
Public Sub TestParametersAnalyzer_InParameterizedProperties()
Dim source = <compilation>
<file name="c.vb">
<![CDATA[
Class C
Public ReadOnly Property Test(a As Integer, b As String) As Integer
Get
Return 1
End Get
End Property
End Class
]]>
</file>
</compilation>
Dim comp = CreateCompilationWithMscorlibAndVBRuntime(source)
comp.VerifyDiagnostics()
comp.VerifyAnalyzerDiagnostics({New AnalyzerForParameters}, Nothing, Nothing, False,
Diagnostic("Parameter_ID", "a").WithLocation(2, 35),
Diagnostic("Parameter_ID", "b").WithLocation(2, 49))
End Sub
Private Shared Sub VerifyGeneratedCodeAnalyzerDiagnostics(compilation As Compilation, isGeneratedFileName As Func(Of String, Boolean), generatedCodeAnalysisFlagsOpt As GeneratedCodeAnalysisFlags?)
Dim expected = GetExpectedGeneratedCodeAnalyzerDiagnostics(compilation, isGeneratedFileName, generatedCodeAnalysisFlagsOpt)
VerifyGeneratedCodeAnalyzerDiagnostics(compilation, expected, generatedCodeAnalysisFlagsOpt)
......
......@@ -8904,6 +8904,23 @@ void foo()
await VerifyItemExistsAsync(markup, "Item3");
}
[WorkItem(14546, "https://github.com/dotnet/roslyn/issues/14546")]
[Fact, Trait(Traits.Feature, Traits.Features.Completion)]
public async Task TupleElementsCompletionOffMethodGroup()
{
var markup = @"
class C
{
void foo()
{
new object().ToString.$$
}
}" + TestResources.NetFX.ValueTuple.tuplelib_cs;
// should not crash
await VerifyItemExistsAsync(markup, "ToString");
}
[Fact]
[Trait(Traits.Feature, Traits.Features.Completion)]
[Test.Utilities.CompilerTrait(Test.Utilities.CompilerFeature.LocalFunctions)]
......
......@@ -511,4 +511,4 @@ void M()
");
}
}
}
\ No newline at end of file
}
......@@ -391,6 +391,21 @@ void Foo()
}");
}
[Fact]
public void ForEachDeconstructionStatementExpression()
{
TestSpan(
@"class C
{
void Foo()
{
foreach (var (x, y) in [|Foo().B$$ar()|])
{
}
}
}");
}
#region Lambdas
[Fact]
......@@ -2504,6 +2519,255 @@ void Foo()
}");
}
[Fact]
public void OnForEachDeconstructionKeyword1()
{
TestSpan(
@"class C
{
void Foo()
{
$$ [|foreach|] (var (x, y) in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionKeyword2()
{
TestSpan(
@"class C
{
void Foo()
{
[|fo$$reach|] (var (x, y) in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionKeyword3()
{
TestSpan(
@"class C
{
void Foo()
{
[|foreach|] $$
(var (x, y) in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionKeyword4()
{
TestSpan(
@"class C
{
void Foo()
{
[|foreach|]
$$ (var (x, y) in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionKeyword5()
{
TestSpan(
@"class C
{
void Foo()
{
[|foreach|] $$(var (x, y) in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionType1()
{
TestSpan(
@"class C
{
void Foo()
{
foreach ( $$
[|var (x, y)|] in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionType2()
{
TestSpan(
@"class C
{
void Foo()
{
foreach ([|v$$ar (x, y)|] in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionIdentifier()
{
TestSpan(
@"class C
{
void Foo()
{
foreach ([|var (v$$v, y)|] in expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionIn1()
{
TestSpan(
@"class C
{
void Foo()
{
foreach (var (x, y) [|i$$n|] expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionIn2()
{
TestSpan(
@"class C
{
void Foo()
{
foreach (var (x, y)
$$ [|in|] expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionIn3()
{
TestSpan(
@"class C
{
void Foo()
{
foreach (var (x, y)
[|in|] $$
expr().blah())
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionExpr1()
{
TestSpan(
@"class C
{
void Foo()
{
foreach (var (x, y) in [|expr($$).blah()|])
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionExpr2()
{
TestSpan(
@"class C
{
void Foo()
{
foreach (var (x, y) in [|expr().blah()|]
$$ )
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionExpr3()
{
TestSpan(
@"class C
{
void Foo()
{
foreach (var (x, y) in
$$ [|expr().blah()|]
)
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionStatement()
{
TestSpan(
@"class C
{
void Foo()
{
[|foreach|](var (x, y) in expr().blah()) $$
{
}
}
}");
}
[Fact]
public void OnForEachDeconstructionBlock1()
{
TestSpan(
@"class C
{
void Foo()
{
foreach (var (x, y) in expr().blah())
$$ [|{|]
}
}
}");
}
[Fact]
public void OnUsingWithDecl1()
{
......@@ -4127,6 +4391,273 @@ void Foo()
{
[|var (x, y) = $$(1, 2);|]
}
}");
}
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
public void OnAccessorExpressionBody1()
{
TestSpan(
@"class C
{
public int Id { get => [|12$$3|]; }
}");
}
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
public void OnAccessorExpressionBody2()
{
TestSpan(
@"class C
{
public int Id { get $$=> [|123|]; }
}");
}
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
public void OnAccessorExpressionBody3()
{
TestSpan(
@"class C
{
$$public int Id { get => [|123|]; }
}");
}
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
public void OnAccessorExpressionBody4()
{
TestSpan(
@"class C
{
public int Id { get => [|123|]; $$ }
}");
}
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
public void OnAccessorExpressionBody5()
{
TestSpan(
@"class C
{
$$ public event Action Foo { add => [|123|]; remove => 456; }
}");
}
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
public void OnAccessorExpressionBody6()
{
TestSpan(
@"class C
{
public event Action Foo { add => [|123|];$$ remove => 456; }
}");
}
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
public void OnAccessorExpressionBody7()
{
TestSpan(
@"class C
{
public event Action Foo { add => 123; $$remove => [|456|]; }
}");
}
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
public void OnAccessorExpressionBody8()
{
TestSpan(
@"class C
{
public event Action Foo { add => 123; remove => [|456|]; }$$
}");
}
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
public void OnCtorExpressionBody1()
{
TestSpan(
@"class C
{
$$ public C() => [|x = 1|];
}");
}
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
public void OnCtorExpressionBody2()
{
TestSpan(
@"class C
{
public C() => $$[|x = 1|];
}");
}
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
public void OnCtorExpressionBody3()
{
TestSpan(
@"class C
{
public C() => [|x =$$ 1|];
}");
}
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
public void OnCtorExpressionBody4()
{
TestSpan(
@"class C
{
public C() => [|x = 1|]$$;
}");
}
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
public void OnCtorExpressionBody5()
{
TestSpan(
@"class C
{
public C() => [|x = 1|];$$
}");
}
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
public void OnDtorExpressionBody1()
{
TestSpan(
@"class C
{
$$ public ~C() => [|x = 1|];
}");
}
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
public void OnDtorExpressionBody2()
{
TestSpan(
@"class C
{
public ~C() => $$[|x = 1|];
}");
}
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
public void OnDtorExpressionBody3()
{
TestSpan(
@"class C
{
public ~C() => [|x =$$ 1|];
}");
}
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
public void OnDtorExpressionBody4()
{
TestSpan(
@"class C
{
public ~C() => [|x = 1|]$$;
}");
}
[Fact, WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
public void OnDtorExpressionBody5()
{
TestSpan(
@"class C
{
public ~C() => [|x = 1|];$$
}");
}
[Fact, WorkItem(14437, "https://github.com/dotnet/roslyn/issues/14437")]
public void OnLocalFunctionDecl_1()
{
TestSpan(
@"class C
{
static void M()
{
$$ int Local(object[] a)
[|{|]
return a.Length;
}
}
}");
}
[Fact, WorkItem(14437, "https://github.com/dotnet/roslyn/issues/14437")]
public void OnLocalFunctionDecl_2()
{
TestSpan(
@"class C
{
static void M()
{
int Local(object[] a)$$
[|{|]
return a.Length;
}
}
}");
}
[Fact, WorkItem(14437, "https://github.com/dotnet/roslyn/issues/14437")]
public void OnLocalFunctionDecl_3()
{
TestSpan(
@"class C
{
static void M()
{
int Local(object[] a)
$$ [|{|]
return a.Length;
}
}
}");
}
[Fact, WorkItem(14437, "https://github.com/dotnet/roslyn/issues/14437")]
public void OnLocalFunctionDecl_4()
{
TestSpan(
@"class C
{
static void M()
{
$$ int Local(object[] a) => [|a.Length|];
}
}");
}
[Fact, WorkItem(14437, "https://github.com/dotnet/roslyn/issues/14437")]
public void OnLocalFunctionDecl_5()
{
TestSpan(
@"class C
{
static void M()
{
int Local(object$$[] a) => [|a.Length|];
}
}");
}
[Fact, WorkItem(14437, "https://github.com/dotnet/roslyn/issues/14437")]
public void OnLocalFunctionDecl_6()
{
TestSpan(
@"class C
{
static void M()
{
int Local(object[] a) => [|a.Length|];$$
}
}");
}
}
......
......@@ -18,6 +18,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics
{
[Export(typeof(ITaggerProvider))]
[ContentType(ContentTypeNames.RoslynContentType)]
[ContentType(ContentTypeNames.XamlContentType)]
[TagType(typeof(ClassificationTag))]
internal partial class DiagnosticsClassificationTaggerProvider : AbstractDiagnosticsTaggerProvider<ClassificationTag>
{
......
......@@ -20,6 +20,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics
{
[Export(typeof(ITaggerProvider))]
[ContentType(ContentTypeNames.RoslynContentType)]
[ContentType(ContentTypeNames.XamlContentType)]
[TagType(typeof(IErrorTag))]
internal partial class DiagnosticsSquiggleTaggerProvider : AbstractDiagnosticsAdornmentTaggerProvider<IErrorTag>
{
......
......@@ -20,6 +20,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics
{
[Export(typeof(ITaggerProvider))]
[ContentType(ContentTypeNames.RoslynContentType)]
[ContentType(ContentTypeNames.XamlContentType)]
[TagType(typeof(SuggestionTag))]
internal partial class DiagnosticsSuggestionTaggerProvider :
AbstractDiagnosticsAdornmentTaggerProvider<SuggestionTag>
......
......@@ -16,6 +16,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.Diagnostics
/// </summary>
[Export(typeof(IWpfTextViewCreationListener))]
[ContentType(ContentTypeNames.RoslynContentType)]
[ContentType(ContentTypeNames.XamlContentType)]
[TextViewRole(PredefinedTextViewRoles.Document)]
internal class SuggestionAdornmentManagerProvider :
AbstractAdornmentManagerProvider<SuggestionTag>
......
......@@ -18,7 +18,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.InlineRename
[Order(Before = PredefinedCommandHandlerNames.ChangeSignature)]
[Order(Before = PredefinedCommandHandlerNames.ExtractInterface)]
[Order(Before = PredefinedCommandHandlerNames.EncapsulateField)]
[ExportCommandHandler(PredefinedCommandHandlerNames.Rename, ContentTypeNames.RoslynContentType)]
[ExportCommandHandler(PredefinedCommandHandlerNames.Rename, ContentTypeNames.RoslynContentType, ContentTypeNames.XamlContentType)]
internal partial class RenameCommandHandler
{
private readonly InlineRenameService _renameService;
......
......@@ -12,6 +12,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.InlineRename
{
[Export(typeof(IWpfTextViewConnectionListener))]
[ContentType(ContentTypeNames.RoslynContentType)]
[ContentType(ContentTypeNames.XamlContentType)]
[TextViewRole(PredefinedTextViewRoles.Interactive)]
internal class DashboardAdornmentProvider : IWpfTextViewConnectionListener
{
......
......@@ -9,6 +9,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.InlineRename
{
[Export(typeof(ITaggerProvider))]
[ContentType(ContentTypeNames.RoslynContentType)]
[ContentType(ContentTypeNames.XamlContentType)]
[TagType(typeof(ITextMarkerTag))]
internal class RenameTaggerProvider : ITaggerProvider
{
......
......@@ -12,6 +12,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.Preview
[Export(typeof(ITaggerProvider))]
[TagType(typeof(ConflictTag))]
[ContentType(ContentTypeNames.RoslynContentType)]
[ContentType(ContentTypeNames.XamlContentType)]
[TextViewRole(TextViewRoles.PreviewRole)]
internal class PreviewConflictTaggerProvider
: AbstractPreviewTaggerProvider<ConflictTag>
......
......@@ -15,6 +15,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.Preview
[Export(typeof(ITaggerProvider))]
[TagType(typeof(NavigableHighlightTag))]
[ContentType(ContentTypeNames.RoslynContentType)]
[ContentType(ContentTypeNames.XamlContentType)]
[TextViewRole(TextViewRoles.PreviewRole)]
internal class PreviewReferenceHighlightingTaggerProvider
: AbstractPreviewTaggerProvider<NavigableHighlightTag>
......@@ -29,6 +30,7 @@ internal class PreviewReferenceHighlightingTaggerProvider
[Export(typeof(ITaggerProvider))]
[TagType(typeof(NavigableHighlightTag))]
[ContentType(ContentTypeNames.RoslynContentType)]
[ContentType(ContentTypeNames.XamlContentType)]
[TextViewRole(TextViewRoles.PreviewRole)]
internal class PreviewDefinitionHighlightingTaggerProvider
: AbstractPreviewTaggerProvider<NavigableHighlightTag>
......
......@@ -13,6 +13,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.Preview
[Export(typeof(ITaggerProvider))]
[TagType(typeof(PreviewWarningTag))]
[ContentType(ContentTypeNames.RoslynContentType)]
[ContentType(ContentTypeNames.XamlContentType)]
[TextViewRole(TextViewRoles.PreviewRole)]
internal class PreviewWarningTaggerProvider
: AbstractPreviewTaggerProvider<PreviewWarningTag>
......
......@@ -25,6 +25,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.ReferenceHighlighting
{
[Export(typeof(IViewTaggerProvider))]
[ContentType(ContentTypeNames.RoslynContentType)]
[ContentType(ContentTypeNames.XamlContentType)]
[TagType(typeof(NavigableHighlightTag))]
[TextViewRole(PredefinedTextViewRoles.Interactive)]
internal partial class ReferenceHighlightingViewTaggerProvider : AsynchronousViewTaggerProvider<NavigableHighlightTag>
......@@ -59,12 +60,12 @@ protected override ITaggerEventSource CreateEventSource(ITextView textView, ITex
protected override SnapshotPoint? GetCaretPoint(ITextView textViewOpt, ITextBuffer subjectBuffer)
{
return textViewOpt.Caret.Position.Point.GetPoint(b => b.ContentType.IsOfType(ContentTypeNames.RoslynContentType), PositionAffinity.Successor);
return textViewOpt.Caret.Position.Point.GetPoint(b => IsSupportedContentType(b.ContentType), PositionAffinity.Successor);
}
protected override IEnumerable<SnapshotSpan> GetSpansToTag(ITextView textViewOpt, ITextBuffer subjectBuffer)
{
return textViewOpt.BufferGraph.GetTextBuffers(b => b.ContentType.IsOfType(ContentTypeNames.RoslynContentType))
return textViewOpt.BufferGraph.GetTextBuffers(b => IsSupportedContentType(b.ContentType))
.Select(b => b.CurrentSnapshot.GetFullSpan())
.ToList();
}
......@@ -188,5 +189,12 @@ private static NavigableHighlightTag GetTag(HighlightSpan span)
return ReferenceHighlightTag.Instance;
}
}
private static bool IsSupportedContentType(IContentType contentType)
{
// This list should match the list of exported content types above
return contentType.IsOfType(ContentTypeNames.RoslynContentType) ||
contentType.IsOfType(ContentTypeNames.XamlContentType);
}
}
}
\ No newline at end of file
......@@ -8,7 +8,7 @@
namespace Microsoft.CodeAnalysis.Editor.Implementation.RenameTracking
{
[ExportCommandHandler(PredefinedCommandHandlerNames.RenameTrackingCancellation, ContentTypeNames.RoslynContentType)]
[ExportCommandHandler(PredefinedCommandHandlerNames.RenameTrackingCancellation, ContentTypeNames.RoslynContentType, ContentTypeNames.XamlContentType)]
[Order(After = PredefinedCommandHandlerNames.SignatureHelp)]
[Order(After = PredefinedCommandHandlerNames.IntelliSense)]
[Order(After = PredefinedCommandHandlerNames.AutomaticCompletion)]
......
......@@ -29,6 +29,7 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.RenameTracking
[TagType(typeof(RenameTrackingTag))]
[TagType(typeof(IErrorTag))]
[ContentType(ContentTypeNames.RoslynContentType)]
[ContentType(ContentTypeNames.XamlContentType)]
[TextViewRole(PredefinedTextViewRoles.Editable)]
internal sealed partial class RenameTrackingTaggerProvider : ITaggerProvider
{
......
......@@ -34,12 +34,14 @@ namespace Microsoft.CodeAnalysis.Editor.Implementation.Suggestions
[Export(typeof(ISuggestedActionsSourceProvider))]
[VisualStudio.Utilities.ContentType(ContentTypeNames.RoslynContentType)]
[VisualStudio.Utilities.ContentType(ContentTypeNames.XamlContentType)]
[VisualStudio.Utilities.Name("Roslyn Code Fix")]
[VisualStudio.Utilities.Order]
internal class SuggestedActionsSourceProvider : ISuggestedActionsSourceProvider
{
private static readonly Guid s_CSharpSourceGuid = new Guid("b967fea8-e2c3-4984-87d4-71a38f49e16a");
private static readonly Guid s_visualBasicSourceGuid = new Guid("4de30e93-3e0c-40c2-a4ba-1124da4539f6");
private static readonly Guid s_xamlSourceGuid = new Guid("a0572245-2eab-4c39-9f61-06a6d8c5ddda");
private const int InvalidSolutionVersion = -1;
......@@ -141,6 +143,9 @@ public bool TryGetTelemetryId(out Guid telemetryId)
case LanguageNames.VisualBasic:
telemetryId = s_visualBasicSourceGuid;
return true;
case "Xaml":
telemetryId = s_xamlSourceGuid;
return true;
default:
return false;
}
......
......@@ -16,6 +16,7 @@ namespace Microsoft.CodeAnalysis.Editor
{
[Export(typeof(IWpfTextViewConnectionListener))]
[ContentType(ContentTypeNames.RoslynContentType)]
[ContentType(ContentTypeNames.XamlContentType)]
[TextViewRole(PredefinedTextViewRoles.Interactive)]
[Export(typeof(ITextBufferAssociatedViewService))]
internal class TextBufferAssociatedViewService : IWpfTextViewConnectionListener, ITextBufferAssociatedViewService
......@@ -35,7 +36,7 @@ void IWpfTextViewConnectionListener.SubjectBuffersConnected(IWpfTextView textVie
lock (s_gate)
{
// only add roslyn type to tracking map
foreach (var buffer in subjectBuffers.Where(b => b.ContentType.IsOfType(ContentTypeNames.RoslynContentType)))
foreach (var buffer in subjectBuffers.Where(b => IsSupportedContentType(b.ContentType)))
{
HashSet<IWpfTextView> set;
if (!s_map.TryGetValue(buffer, out set))
......@@ -72,6 +73,13 @@ void IWpfTextViewConnectionListener.SubjectBuffersDisconnected(IWpfTextView text
}
}
private static bool IsSupportedContentType(IContentType contentType)
{
// This list should match the list of exported content types above
return contentType.IsOfType(ContentTypeNames.RoslynContentType) ||
contentType.IsOfType(ContentTypeNames.XamlContentType);
}
private static IList<IWpfTextView> GetTextViews(ITextBuffer textBuffer)
{
lock (s_gate)
......@@ -131,7 +139,7 @@ private void OnTextViewClose(object sender, EventArgs e)
lock (s_gate)
{
foreach (var buffer in view.BufferGraph.GetTextBuffers(b => b.ContentType.IsOfType(ContentTypeNames.RoslynContentType)))
foreach (var buffer in view.BufferGraph.GetTextBuffers(b => IsSupportedContentType(b.ContentType)))
{
HashSet<IWpfTextView> set;
if (s_map.TryGetValue(buffer, out set))
......
......@@ -149,19 +149,11 @@ private static int GetEndPosition(SyntaxNodeOrToken nodeOrToken)
switch (node.Kind())
{
case SyntaxKind.MethodDeclaration:
var methodDeclaration = (MethodDeclarationSyntax)node;
return (methodDeclaration.Body != null) ? CreateSpanForBlock(methodDeclaration.Body, position) : methodDeclaration.ExpressionBody?.Expression.Span;
case SyntaxKind.OperatorDeclaration:
var operatorDeclaration = (OperatorDeclarationSyntax)node;
return (operatorDeclaration.Body != null) ? CreateSpanForBlock(operatorDeclaration.Body, position) : operatorDeclaration.ExpressionBody?.Expression.Span;
case SyntaxKind.ConversionOperatorDeclaration:
var conversionDeclaration = (ConversionOperatorDeclarationSyntax)node;
return (conversionDeclaration.Body != null) ? CreateSpanForBlock(conversionDeclaration.Body, position) : conversionDeclaration.ExpressionBody?.Expression.Span;
case SyntaxKind.DestructorDeclaration:
return TryCreateSpanForNode(((DestructorDeclarationSyntax)node).Body, position);
var methodDeclaration = (BaseMethodDeclarationSyntax)node;
return (methodDeclaration.Body != null) ? CreateSpanForBlock(methodDeclaration.Body, position) : methodDeclaration.ExpressionBody?.Expression.Span;
case SyntaxKind.ConstructorDeclaration:
return CreateSpanForConstructorDeclaration((ConstructorDeclarationSyntax)node);
......@@ -204,18 +196,22 @@ private static int GetEndPosition(SyntaxNodeOrToken nodeOrToken)
case SyntaxKind.GetAccessorDeclaration:
case SyntaxKind.SetAccessorDeclaration:
var body = ((AccessorDeclarationSyntax)node).Body;
if (body == null)
{
return CreateSpan(node);
}
return TryCreateSpanForNode(body, position);
case SyntaxKind.AddAccessorDeclaration:
case SyntaxKind.RemoveAccessorDeclaration:
case SyntaxKind.UnknownAccessorDeclaration:
return TryCreateSpanForNode(((AccessorDeclarationSyntax)node).Body, position);
var accessor = (AccessorDeclarationSyntax)node;
if (accessor.ExpressionBody != null)
{
return CreateSpan(accessor.ExpressionBody.Expression);
}
else if (accessor.Body != null)
{
return TryCreateSpanForNode(accessor.Body, position);
}
else
{
return CreateSpan(node);
}
case SyntaxKind.PropertyDeclaration:
var property = (PropertyDeclarationSyntax)node;
......@@ -250,8 +246,10 @@ private static int GetEndPosition(SyntaxNodeOrToken nodeOrToken)
return CreateSpanForAccessors(indexer.AccessorList.Accessors, position);
case SyntaxKind.EventDeclaration:
var evnt = (EventDeclarationSyntax)node;
return evnt.AccessorList.Accessors.Select(a => TryCreateSpanForNode(a, position)).FirstOrDefault();
// event Action P { add [|{|] ... } remove { ... } }
// event Action P { [|add;|] [|remove;|] }
var @event = (EventDeclarationSyntax)node;
return CreateSpanForAccessors(@event.AccessorList.Accessors, position);
case SyntaxKind.BaseConstructorInitializer:
case SyntaxKind.ThisConstructorInitializer:
......@@ -293,6 +291,12 @@ private static int GetEndPosition(SyntaxNodeOrToken nodeOrToken)
var groupClause = (GroupClauseSyntax)node;
return TryCreateSpanForNode(groupClause.GroupExpression, position);
case SyntaxKind.LocalFunctionStatement:
var localFunction = (LocalFunctionStatementSyntax)node;
return (localFunction.Body != null) ?
TryCreateSpanForNode(localFunction.Body, position) :
TryCreateSpanForNode(localFunction.ExpressionBody.Expression, position);
default:
var expression = node as ExpressionSyntax;
if (expression != null)
......@@ -317,12 +321,18 @@ private static TextSpan CreateSpanForConstructorDeclaration(ConstructorDeclarati
return CreateSpanForConstructorInitializer(constructorSyntax.Initializer);
}
if (constructorSyntax.ExpressionBody != null)
{
return constructorSyntax.ExpressionBody.Expression.Span;
}
// static ctor doesn't have a default initializer:
if (constructorSyntax.Modifiers.Any(SyntaxKind.StaticKeyword))
{
return CreateSpan(constructorSyntax.Body.OpenBraceToken);
}
// the declaration is the span of the implicit initializer
return CreateSpan(constructorSyntax.Modifiers, constructorSyntax.Identifier, constructorSyntax.ParameterList.CloseParenToken);
}
......
......@@ -154,4 +154,4 @@ public MyCodeAction(string title, ImmutableArray<CodeAction> nestedActions)
}
}
}
}
\ No newline at end of file
}
......@@ -3,6 +3,10 @@ use vs
package name=Microsoft.CodeAnalysis.Compilers
version=$(Version)
vs.dependencies
vs.dependency id=Microsoft.Net.4.6.1.FullRedist
vs.dependency id=Microsoft.Net.4.6.1.FullRedist.Resource
folder InstallDir:\MSBuild\15.0\Bin
file source=$(OutputPath)\VBCSCompiler.exe vs.file.ngen=yes
file source=$(OutputPath)\csc.exe vs.file.ngen=yes
......
......@@ -16,6 +16,8 @@ vs.payloads
vs.dependencies
vs.dependency id=Microsoft.VisualStudio.MinShell
vs.dependency id=Microsoft.Net.4.6.1.FullRedist
vs.dependency id=Microsoft.Net.4.6.1.FullRedist.Resource
vs.dependency id=Microsoft.CodeAnalysis.VisualStudio.Setup
version=$(Version)
type=Required
......@@ -15,6 +15,8 @@ vs.payloads
vs.payload source=$(OutputPath)Roslyn.VisualStudio.InteractiveComponents.vsix
vs.dependencies
vs.dependency id=Microsoft.Net.4.6.1.FullRedist
vs.dependency id=Microsoft.Net.4.6.1.FullRedist.Resource
vs.dependency id=Microsoft.VisualStudio.MinShell
vs.dependency id=Microsoft.CodeAnalysis.VisualStudio.Setup
version=$(Version)
......
......@@ -15,4 +15,6 @@ vs.payloads
vs.payload source=$(OutputPath)Roslyn.VisualStudio.Setup.vsix
vs.dependencies
vs.dependency id=Microsoft.Net.4.6.1.FullRedist
vs.dependency id=Microsoft.Net.4.6.1.FullRedist.Resource
vs.dependency id=Microsoft.VisualStudio.MinShell
......@@ -15,6 +15,8 @@ vs.payloads
vs.payload source=$(OutputPath)Roslyn.VisualStudio.Setup.Next.vsix
vs.dependencies
vs.dependency id=Microsoft.Net.4.6.1.FullRedist
vs.dependency id=Microsoft.Net.4.6.1.FullRedist.Resource
vs.dependency id=Microsoft.VisualStudio.MinShell
vs.dependency id=Microsoft.CodeAnalysis.VisualStudio.Setup
version=$(Version)
......
......@@ -1067,5 +1067,29 @@ private void OnCompilationStart(CompilationStartAnalysisContext context)
});
}
}
[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
public class AnalyzerForParameters : DiagnosticAnalyzer
{
public static readonly DiagnosticDescriptor ParameterDescriptor = new DiagnosticDescriptor(
"Parameter_ID",
"Parameter_Title",
"Parameter_Message",
"Parameter_Category",
defaultSeverity: DiagnosticSeverity.Warning,
isEnabledByDefault: true);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(ParameterDescriptor);
public override void Initialize(AnalysisContext context)
{
context.RegisterSymbolAction(SymbolAction, SymbolKind.Parameter);
}
private void SymbolAction(SymbolAnalysisContext context)
{
context.ReportDiagnostic(Diagnostic.Create(ParameterDescriptor, context.Symbol.Locations[0]));
}
}
}
}
\ No newline at end of file
......@@ -75,7 +75,11 @@ public void VerifyAllAnalyzerMembersWereCalled()
public void VerifyAnalyzeSymbolCalledForAllSymbolKinds()
{
var expectedSymbolKinds = new[] { SymbolKind.Event, SymbolKind.Field, SymbolKind.Method, SymbolKind.NamedType, SymbolKind.Namespace, SymbolKind.Property };
var expectedSymbolKinds = new[]
{
SymbolKind.Event, SymbolKind.Field, SymbolKind.Method, SymbolKind.NamedType, SymbolKind.Namespace, SymbolKind.Parameter, SymbolKind.Property
};
var actualSymbolKinds = _callLog.Where(a => FilterByAbstractName(a, "Symbol")).Where(e => e.SymbolKind.HasValue).Select(e => e.SymbolKind.Value).Distinct();
AssertSequenceEqual(expectedSymbolKinds, actualSymbolKinds);
}
......
......@@ -13,6 +13,7 @@ namespace Microsoft.VisualStudio.LanguageServices.Implementation.Preview
[Export(typeof(IViewTaggerProvider))]
[TagType(typeof(HighlightTag))]
[ContentType(ContentTypeNames.RoslynContentType)]
[ContentType(ContentTypeNames.XamlContentType)]
internal class PreviewTaggerProvider : IViewTaggerProvider
{
public ITagger<T> CreateTagger<T>(ITextView textView, ITextBuffer buffer) where T : ITag
......
......@@ -152,7 +152,11 @@ internal abstract partial class AbstractProject : ForegroundThreadAffinitizedObj
if (visualStudioWorkspaceOpt != null)
{
this.EditAndContinueImplOpt = new VsENCRebuildableProjectImpl(this);
if (Language == LanguageNames.CSharp || Language == LanguageNames.VisualBasic)
{
this.EditAndContinueImplOpt = new VsENCRebuildableProjectImpl(this);
}
this.MetadataService = visualStudioWorkspaceOpt.Services.GetService<IMetadataService>();
}
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.Editor.Xaml.Features;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.Editor.Xaml.CodeFixes.AddMissingNamespace
{
internal interface IXamlAddMissingNamespaceService
{
Task<CodeAction> CreateMissingNamespaceFixAsync(Document document, TextSpan span, CancellationToken cancellationToken);
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Immutable;
using System.Composition;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.Editor.Xaml.Diagnostics;
using Microsoft.CodeAnalysis.Editor.Xaml.Features;
namespace Microsoft.CodeAnalysis.Editor.Xaml.CodeFixes.AddMissingNamespace
{
[ExportCodeFixProvider(StringConstants.XamlLanguageName, Name = PredefinedCodeFixProviderNames.AddUsingOrImport), Shared]
[ExtensionOrder(After = PredefinedCodeFixProviderNames.AddMissingReference)]
internal class XamlAddMissingNamespacePrefixCodeFixProvider : CodeFixProvider
{
private readonly IXamlAddMissingNamespaceService _missingNamespaceService;
[ImportingConstructor]
public XamlAddMissingNamespacePrefixCodeFixProvider(IXamlAddMissingNamespaceService missingNamespaceService)
{
_missingNamespaceService = missingNamespaceService;
}
public sealed override ImmutableArray<string> FixableDiagnosticIds
{
get { return ImmutableArray.Create(XamlDiagnosticIds.MissingNamespaceId); }
}
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
{
var changeAction = await _missingNamespaceService.CreateMissingNamespaceFixAsync(context.Document, context.Span, context.CancellationToken).ConfigureAwait(false);
if (changeAction == null)
{
return;
}
context.RegisterCodeFix(
changeAction,
context.Diagnostics);
}
}
}
......@@ -4,7 +4,6 @@ namespace Microsoft.CodeAnalysis.Editor.Xaml.Diagnostics
{
internal static class XamlDiagnosticIds
{
public const string UnnecessaryNamespacesId = "XAML0001";
public const string MissingNamespaceId = "XAML0002";
public const string UnnecessaryNamespacesId = "XAML1103";
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Diagnostics;
using Microsoft.CodeAnalysis.Text;
namespace Microsoft.CodeAnalysis.Editor.Xaml.Features
{
[DebuggerDisplay("{GetDebuggerDisplay(),nq}")]
internal struct DocumentSpan
{
public Document Document { get; }
......@@ -14,5 +16,10 @@ public DocumentSpan(Document document, TextSpan textSpan) : this()
this.Document = document;
this.TextSpan = textSpan;
}
private string GetDebuggerDisplay()
{
return $"{Document.Name} [{TextSpan.Start}...{TextSpan.End}]";
}
}
}
......@@ -66,8 +66,6 @@ public async Task<IInlineRenameLocationSet> FindRenameLocationsAsync(OptionSet o
{
var references = new List<InlineRenameLocation>();
references.Add(new InlineRenameLocation(_document, _renameInfo.TriggerSpan));
IList<DocumentSpan> renameLocations = await _renameInfo.FindRenameLocationsAsync(
renameInStrings: optionSet.GetOption(RenameOptions.RenameInStrings),
renameInComments: optionSet.GetOption(RenameOptions.RenameInComments),
......
......@@ -8,11 +8,6 @@ namespace Microsoft.CodeAnalysis.Editor.Xaml
{
public static class XamlStaticTypeDefinitions
{
[Export]
[Name(ContentTypeNames.XamlContentType)]
[BaseDefinition(ContentTypeNames.RoslynContentType)]
public static readonly ContentTypeDefinition XamlContentTypeDefinition;
// Associate .xaml as the Xaml content type.
[Export]
[FileExtension(StringConstants.XamlFileExtension)]
......
......@@ -52,8 +52,6 @@
<InternalsVisibleToVisualStudio Include="Microsoft.VisualStudio.DesignTools.XamlLanguageService" />
</ItemGroup>
<ItemGroup>
<Compile Include="CodeFixes\AddMissingNamespace\IXamlAddMissingNamespaceService.cs" />
<Compile Include="CodeFixes\AddMissingNamespace\XamlAddMissingNamespacePrefixCodeFixProvider.cs" />
<Compile Include="CodeFixes\RemoveUnnecessaryUsings\XamlRemoveUnnecessaryUsingsCodeFixProvider.cs" />
<Compile Include="Diagnostics\Analyzers\IXamlDocumentAnalyzerService.cs" />
<Compile Include="Diagnostics\Analyzers\XamlDocumentDiagnosticAnalyzer.cs" />
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections;
using System.Collections.Generic;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.Options;
......@@ -72,4 +73,4 @@ public static IEnumerable<Option<CodeStyleOption<bool>>> GetCodeStyleOptions()
yield return PreferExpressionBodiedAccessors;
}
}
}
\ No newline at end of file
}
......@@ -12,8 +12,9 @@ public class CodeStyleOptions
/// but with none enforcement, so that the user is not prompted about their usage.
/// </remarks>
internal static readonly CodeStyleOption<bool> TrueWithNoneEnforcement = new CodeStyleOption<bool>(value: true, notification: NotificationOption.None);
internal static readonly CodeStyleOption<bool> TrueWithSuggestionEnforcement = new CodeStyleOption<bool>(value: true, notification: NotificationOption.Suggestion);
internal static readonly CodeStyleOption<bool> FalseWithNoneEnforcement = new CodeStyleOption<bool>(value: false, notification: NotificationOption.None);
internal static readonly CodeStyleOption<bool> TrueWithSuggestionEnforcement = new CodeStyleOption<bool>(value: true, notification: NotificationOption.Suggestion);
internal static readonly CodeStyleOption<bool> FalseWithSuggestionEnforcement = new CodeStyleOption<bool>(value: false, notification: NotificationOption.Suggestion);
/// <summary>
/// This option says if we should simplify away the <see langword="this"/>. or <see langword="Me"/>. in field access expressions.
......@@ -76,4 +77,4 @@ public class CodeStyleOptions
storageLocations: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.PreferInlinedVariableDeclaration"));
}
}
\ No newline at end of file
}
......@@ -81,7 +81,7 @@ internal abstract class AbstractRecommendationService : IRecommendationService
protected static ImmutableArray<ISymbol> SuppressDefaultTupleElements(
INamespaceOrTypeSymbol container, ImmutableArray<ISymbol> symbols)
{
if (!container.IsType)
if (container?.IsType != true)
{
return symbols;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册