Skip to content

Commit

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

Merge release/dev16.8 to release/dev16.8-vs-deps
  • Loading branch information
msftbot[bot] authored Dec 4, 2020
2 parents 6559f38 + dedcd58 commit 9ed4b77
Show file tree
Hide file tree
Showing 13 changed files with 198 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ The minimal required version of .NET Framework is 4.7.2.

## Developing with Visual Studio 2019

1. [Visual Studio 2019 16.8p2](https://visualstudio.microsoft.com/downloads/)
1. [Visual Studio 2019 16.8](https://visualstudio.microsoft.com/downloads/)
- Ensure C#, VB, MSBuild, .NET Core and Visual Studio Extensibility are included in the selected work loads
- Ensure Visual Studio is on Version "16.8 Preview 3" or greater
- Ensure Visual Studio is on Version "16.8" or greater
- Ensure "Use previews of the .NET Core SDK" is checked in Tools -> Options -> Environment -> Preview Features
- Restart Visual Studio
1. [.NET Core SDK 5.0 Release Candidate 2](https://dotnet.microsoft.com/download/dotnet-core/5.0) [Windows x64 installer](https://dotnet.microsoft.com/download/dotnet/thank-you/sdk-5.0.100-rc.2-windows-x64-installer)
1. [.NET Core SDK 5.0](https://dotnet.microsoft.com/download/dotnet-core/5.0) [Windows x64 installer](https://dotnet.microsoft.com/download/dotnet/thank-you/sdk-5.0.100-windows-x64-installer)
1. [PowerShell 5.0 or newer](https://docs.microsoft.com/en-us/powershell/scripting/setup/installing-windows-powershell). If you are on Windows 10, you are fine; you'll only need to upgrade if you're on earlier versions of Windows. The download link is under the ["Upgrading existing Windows PowerShell"](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-windows-powershell?view=powershell-6#upgrading-existing-windows-powershell) heading.
1. Run Restore.cmd
1. Open Roslyn.sln
Expand Down
1 change: 1 addition & 0 deletions eng/build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,7 @@ function Prepare-TempDir() {
$env:TMP=$TempDir

Copy-Item (Join-Path $RepoRoot "src\Workspaces\MSBuildTest\Resources\.editorconfig") $TempDir
Copy-Item (Join-Path $RepoRoot "src\Workspaces\MSBuildTest\Resources\global.json") $TempDir
Copy-Item (Join-Path $RepoRoot "src\Workspaces\MSBuildTest\Resources\Directory.Build.props") $TempDir
Copy-Item (Join-Path $RepoRoot "src\Workspaces\MSBuildTest\Resources\Directory.Build.targets") $TempDir
Copy-Item (Join-Path $RepoRoot "src\Workspaces\MSBuildTest\Resources\Directory.Build.rsp") $TempDir
Expand Down
24 changes: 0 additions & 24 deletions eng/targets/Imports.targets
Original file line number Diff line number Diff line change
Expand Up @@ -175,30 +175,6 @@
</ItemGroup>
</Target>

<!--
Work around missing code fix references causing VBCSCompiler.exe to reject compilations.
https://github.com/dotnet/roslyn/issues/46684
-->
<Target Name="ExcludeCodeFixes"
BeforeTargets="CoreCompile"
Condition="'$(UseRoslynAnalyzers)' != 'false' AND '$(BuildingProject)' == 'true'">
<!--
Disable analyzers that only provide code fixes.
-->
<ItemGroup>
<Analyzer Remove="@(Analyzer)"
Condition="'%(Filename)' == 'Microsoft.CodeAnalysis.CSharp.CodeStyle.Fixes'
OR '%(Filename)' == 'Microsoft.VisualStudio.Threading.Analyzers.CodeFixes'"/>
</ItemGroup>

<!--
Explicitly reference Humanizer prior to https://github.com/dotnet/roslyn/pull/47297
-->
<ItemGroup>
<Analyzer Include="$(NuGetPackageRoot)\humanizer.core\$(HumanizerCoreVersion)\lib\netstandard1.0\Humanizer.dll" />
</ItemGroup>
</Target>

<ItemGroup>
<PackageDownload Include="Humanizer.Core" Version="[$(HumanizerCoreVersion)]" />
</ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions global.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"sdk": {
"version": "5.0.100-rc.2.20479.15",
"version": "5.0.100",
"allowPrerelease": true,
"rollForward": "major"
},
"tools": {
"dotnet": "5.0.100-rc.2.20479.15",
"dotnet": "5.0.100",
"vs": {
"version": "16.8"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ internal interface ILocalDataFlowState : ILocalState
/// <summary>
/// A mapping from local variables to the index of their slot in a flow analysis local state.
/// </summary>
protected readonly PooledDictionary<VariableIdentifier, int> _variableSlot = PooledDictionary<VariableIdentifier, int>.GetInstance();
protected PooledDictionary<VariableIdentifier, int> _variableSlot = PooledDictionary<VariableIdentifier, int>.GetInstance();

/// <summary>
/// A mapping from the local variable slot to the symbol for the local variable itself. This
Expand Down
111 changes: 110 additions & 1 deletion src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ public VisitArgumentResult(VisitResult visitResult, Optional<LocalState> stateFo
/// <summary>
/// The inferred type at the point of declaration of var locals and parameters.
/// </summary>
private readonly PooledDictionary<Symbol, TypeWithAnnotations> _variableTypes = SpecializedSymbolCollections.GetPooledSymbolDictionaryInstance<Symbol, TypeWithAnnotations>();
private PooledDictionary<Symbol, TypeWithAnnotations> _variableTypes = SpecializedSymbolCollections.GetPooledSymbolDictionaryInstance<Symbol, TypeWithAnnotations>();

/// <summary>
/// Binder for symbol being analyzed.
Expand Down Expand Up @@ -192,6 +192,11 @@ public VisitArgumentResult(VisitResult visitResult, Optional<LocalState> stateFo
/// </summary>
private readonly bool _isSpeculative;

/// <summary>
/// Is a method that contains only blocks, expression statements, and lambdas.
/// </summary>
private readonly bool _isSimpleMethod;

/// <summary>
/// True if this walker was created using an initial state.
/// </summary>
Expand Down Expand Up @@ -394,6 +399,7 @@ private NullableWalker(
_returnTypesOpt = returnTypesOpt;
_snapshotBuilderOpt = snapshotBuilderOpt;
_isSpeculative = isSpeculative;
_isSimpleMethod = IsSimpleMethodVisitor.IsSimpleMethod(node);

if (initialState != null)
{
Expand All @@ -418,6 +424,68 @@ private NullableWalker(
}
}

internal sealed class IsSimpleMethodVisitor : BoundTreeWalkerWithStackGuard
{
private bool _hasComplexity;

internal static bool IsSimpleMethod(BoundNode? node)
{
if (node is BoundConstructorMethodBody constructorBody && constructorBody.Initializer is { })
{
return false;
}
if (node is BoundMethodBodyBase methodBody)
{
var blockBody = methodBody.BlockBody;
var expressionBody = methodBody.ExpressionBody;
node = blockBody;
if (node is { })
{
if (expressionBody is { }) return false;
}
else
{
node = expressionBody;
}
}
var visitor = new IsSimpleMethodVisitor();
try
{
visitor.Visit(node);
return !visitor._hasComplexity;
}
catch (CancelledByStackGuardException)
{
return false;
}
}

public override BoundNode? Visit(BoundNode? node)
{
if (node is null)
{
return null;
}
if (_hasComplexity)
{
return node;
}
if (node is BoundExpression)
{
return base.Visit(node);
}
switch (node.Kind)
{
case BoundKind.Block:
case BoundKind.ExpressionStatement:
case BoundKind.ReturnStatement:
return base.Visit(node);
}
_hasComplexity = true;
return node;
}
}

public string GetDebuggerDisplay()
{
if (this.IsConditionalState)
Expand Down Expand Up @@ -2535,6 +2603,37 @@ private void AnalyzeLocalFunctionOrLambda(
var oldState = this.State;
this.State = state;

var oldVariableSlot = _variableSlot;
var oldVariableTypes = _variableTypes;
var oldVariableBySlot = variableBySlot;
var oldNextVariableSlot = nextVariableSlot;

// As an optimization, if the entire method is simple enough,
// we'll reset the set of variable slots and types after analyzing the nested function,
// to avoid accumulating entries in the outer function for variables that are
// local to the nested function. (Of course, this will drop slots associated
// with variables in the outer function that were first used in the nested function,
// such as a field access on a captured local, but the state associated with
// any such entries are dropped, so the slots can be dropped as well.)
// We don't optimize more complicated methods (methods that contain labels,
// branches, try blocks, local functions) because we track additional state for
// those nodes that might be invalidated if we drop the associated slots or types.
if (_isSimpleMethod)
{
_variableSlot = PooledDictionary<VariableIdentifier, int>.GetInstance();
foreach (var pair in oldVariableSlot)
{
_variableSlot.Add(pair.Key, pair.Value);
}
_variableTypes = SpecializedSymbolCollections.GetPooledSymbolDictionaryInstance<Symbol, TypeWithAnnotations>();
foreach (var pair in oldVariableTypes)
{
_variableTypes.Add(pair.Key, pair.Value);
}
variableBySlot = new VariableIdentifier[oldVariableBySlot.Length];
Array.Copy(oldVariableBySlot, variableBySlot, oldVariableBySlot.Length);
}

var previousSlot = _snapshotBuilderOpt?.EnterNewWalker(lambdaOrFunctionSymbol) ?? -1;

var oldPending = SavePending();
Expand Down Expand Up @@ -2576,6 +2675,16 @@ private void AnalyzeLocalFunctionOrLambda(

_snapshotBuilderOpt?.ExitWalker(this.SaveSharedState(), previousSlot);

if (_isSimpleMethod)
{
nextVariableSlot = oldNextVariableSlot;
variableBySlot = oldVariableBySlot;
_variableTypes.Free();
_variableTypes = oldVariableTypes;
_variableSlot.Free();
_variableSlot = oldVariableSlot;
}

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

using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Roslyn.Test.Utilities;
using System.Linq;
Expand Down Expand Up @@ -373,5 +374,75 @@ public void ArrayInitializationAnonymousTypes()
var comp = CreateCompilation(source);
comp.VerifyEmitDiagnostics();
}

[Fact]
[WorkItem(49745, "https://github.com/dotnet/roslyn/issues/49745")]
public void NullableStateLambdas()
{
const int nFunctions = 10000;

var builder = new StringBuilder();
builder.AppendLine("#nullable enable");
builder.AppendLine("class Program");
builder.AppendLine("{");
builder.AppendLine(" static void F1(System.Func<object, object> f) { }");
builder.AppendLine(" static void F2(object arg)");
builder.AppendLine(" {");
for (int i = 0; i < nFunctions; i++)
{
builder.AppendLine($" F1(arg{i} => arg{i});");
}
builder.AppendLine(" }");
builder.AppendLine("}");

var source = builder.ToString();
var comp = CreateCompilation(source);
comp.VerifyDiagnostics();

CheckIsSimpleMethod(comp, "F2", true);
}

[Theory]
[InlineData("class Program { static object F() => null; }", "F", true)]
[InlineData("class Program { static void F() { } }", "F", true)]
[InlineData("class Program { static void F() { { } { } { } } }", "F", true)]
[InlineData("class Program { static void F() { ;;; } }", "F", false)]
[InlineData("class Program { static void F2(System.Action a) { } static void F() { F2(() => { }); } }", "F", true)]
[InlineData("class Program { static void F() { void Local() { } } }", "F", false)]
[InlineData("class Program { static void F() { System.Action a = () => { }; } }", "F", false)]
[InlineData("class Program { static void F() { if (true) { } } }", "F", false)]
[InlineData("class Program { static void F() { while (true) { } } }", "F", false)]
[InlineData("class Program { static void F() { try { } finally { } } }", "F", false)]
[InlineData("class Program { static void F() { label: F(); } }", "F", false)]
[WorkItem(49745, "https://github.com/dotnet/roslyn/issues/49745")]
public void NullableState_IsSimpleMethod(string source, string methodName, bool expectedResult)
{
var comp = CreateCompilation(source);
var diagnostics = comp.GetDiagnostics().Where(d => d.Severity == DiagnosticSeverity.Error);
diagnostics.Verify();
CheckIsSimpleMethod(comp, methodName, expectedResult);
}

private static void CheckIsSimpleMethod(CSharpCompilation comp, string methodName, bool expectedResult)
{
var tree = comp.SyntaxTrees[0];
var model = (CSharpSemanticModel)comp.GetSemanticModel(tree);
var methodDeclaration = tree.GetCompilationUnitRoot().DescendantNodes().OfType<MethodDeclarationSyntax>().Single(m => m.Identifier.ToString() == methodName);
var methodBody = methodDeclaration.Body;
BoundBlock block;
if (methodBody is { })
{
var binder = model.GetEnclosingBinder(methodBody.SpanStart);
block = binder.BindEmbeddedBlock(methodBody, new DiagnosticBag());
}
else
{
var expressionBody = methodDeclaration.ExpressionBody;
var binder = model.GetEnclosingBinder(expressionBody.SpanStart);
block = binder.BindExpressionBodyAsBlock(expressionBody, new DiagnosticBag());
}
var actualResult = NullableWalker.IsSimpleMethodVisitor.IsSimpleMethod(block);
Assert.Equal(expectedResult, actualResult);
}
}
}
2 changes: 1 addition & 1 deletion src/Interactive/HostProcess/InteractiveHost64.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<PropertyGroup>
<Prefer32Bit>false</Prefer32Bit>
<OutputType>Exe</OutputType>
<TargetFrameworks>net472;net5.0-windows</TargetFrameworks>
<TargetFrameworks>net472;net5.0-windows7.0</TargetFrameworks>
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
<UseWindowsForms>true</UseWindowsForms>

Expand Down
2 changes: 1 addition & 1 deletion src/Interactive/HostTest/InteractiveHost.UnitTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
</CopyPublishedOutputProjectReference>

<CopyPublishedOutputProjectReference Include="..\HostProcess\InteractiveHost64.csproj">
<SetTargetFramework>TargetFramework=net5.0-windows</SetTargetFramework>
<SetTargetFramework>TargetFramework=net5.0-windows7.0</SetTargetFramework>
<OutputItemType>InteractiveHostFiles_Core</OutputItemType>
</CopyPublishedOutputProjectReference>
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,8 @@ private static Process StartNewVisualStudioProcess(string installationPath, int
// influences.
processStartInfo.Environment.Remove("DOTNET_MULTILEVEL_LOOKUP");
processStartInfo.Environment.Remove("DOTNET_INSTALL_DIR");
processStartInfo.Environment.Remove("DotNetRoot");
processStartInfo.Environment.Remove("DotNetTool");

// The first element of the path in CI is a .dotnet used for the Roslyn build. Make sure to remove that.
if (processStartInfo.Environment.TryGetValue("BUILD_SOURCESDIRECTORY", out var sourcesDirectory))
Expand Down
2 changes: 1 addition & 1 deletion src/VisualStudio/Setup/Roslyn.VisualStudio.Setup.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@
<ProjectReference Include="..\..\Interactive\HostProcess\InteractiveHost64.csproj">
<Name>InteractiveHost.Core64</Name>

<SetTargetFramework>TargetFramework=net5.0-windows</SetTargetFramework>
<SetTargetFramework>TargetFramework=net5.0-windows7.0</SetTargetFramework>
<SkipGetTargetFrameworkProperties>true</SkipGetTargetFrameworkProperties>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<PropertyGroup>
<OutputType>Library</OutputType>
<RootNamespace>Microsoft.CodeAnalysis.UnitTests</RootNamespace>
<TargetFrameworks>net5.0-windows;netcoreapp3.1;net472</TargetFrameworks>
<TargetFrameworks>net5.0-windows7.0;netcoreapp3.1;net472</TargetFrameworks>
<UseWpf>true</UseWpf>
<IsShipping>false</IsShipping>
<ExcludeFromSourceBuild>true</ExcludeFromSourceBuild>
Expand Down
4 changes: 4 additions & 0 deletions src/Workspaces/MSBuildTest/Resources/global.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
// this file is empty to ensure we get the "standard" behavior as if
// no global.json was specified in the first place
}

0 comments on commit 9ed4b77

Please sign in to comment.