未验证 提交 c4f9f252 编写于 作者: M msftbot[bot] 提交者: GitHub

Merge pull request #39452 from dotnet/merges/master-to-release/dev16.5-preview1

Merge master to release/dev16.5-preview1
......@@ -176,6 +176,7 @@ IAsyncEnumerator<T> GetAsyncEnumerator(CancellationToken token)
if (initialThreadId == /*managedThreadId*/ && state == StateMachineStates.FinishedStateMachine)
{
state = InitialState; // -3
builder = AsyncIteratorMethodBuilder.Create();
disposeMode = false;
result = this;
}
......
......@@ -157,7 +157,7 @@ protected virtual NullableWalker.SnapshotManager GetSnapshotManager()
internal ImmutableDictionary<Symbol, Symbol> GetRemappedSymbols()
{
EnsureNullabilityAnalysisPerformedIfNecessary();
Debug.Assert(_lazyRemappedSymbols is object || !Compilation.NullableSemanticAnalysisEnabled);
Debug.Assert(_lazyRemappedSymbols is object || this is AttributeSemanticModel || !Compilation.NullableSemanticAnalysisEnabled);
return _lazyRemappedSymbols;
}
......
// 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;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.CSharp.Symbols;
......@@ -71,6 +71,7 @@ protected override BoundStatement GenerateSetResultCall()
// if (this.combinedTokens != null) { this.combinedTokens.Dispose(); this.combinedTokens = null; } // for enumerables only
// this.promiseOfValueOrEnd.SetResult(false);
// this.builder.Complete();
// return;
// _exprReturnLabelTrue:
// this.promiseOfValueOrEnd.SetResult(true);
......@@ -86,6 +87,7 @@ protected override BoundStatement GenerateSetResultCall()
builder.AddRange(
// this.promiseOfValueOrEnd.SetResult(false);
generateSetResultOnPromise(false),
GenerateCompleteOnBuilder(),
F.Return(),
F.Label(_exprReturnLabelTrue),
// this.promiseOfValueOrEnd.SetResult(true);
......@@ -102,6 +104,17 @@ BoundExpressionStatement generateSetResultOnPromise(bool result)
}
}
private BoundExpressionStatement GenerateCompleteOnBuilder()
{
// Produce:
// this.builder.Complete();
return F.ExpressionStatement(
F.Call(
F.Field(F.This(), _asyncMethodBuilderField),
_asyncMethodBuilderMemberCollection.SetResult, // AsyncIteratorMethodBuilder.Complete is the corresponding method to AsyncTaskMethodBuilder.SetResult
ImmutableArray<BoundExpression>.Empty));
}
private void AddDisposeCombinedTokensIfNeeded(ArrayBuilder<BoundStatement> builder)
{
// if (this.combinedTokens != null) { this.combinedTokens.Dispose(); this.combinedTokens = null; } // for enumerables only
......@@ -131,6 +144,9 @@ protected override BoundStatement GenerateSetExceptionCall(LocalSymbol exception
_asyncIteratorInfo.SetExceptionMethod,
F.Local(exceptionLocal))));
// this.builder.Complete();
builder.Add(GenerateCompleteOnBuilder());
return F.Block(builder.ToImmutableAndFree());
}
......
......@@ -133,7 +133,7 @@ internal static bool TryCreate(SyntheticBoundNodeFactory F, MethodSymbol method,
createBuilderMethod: createBuilderMethod,
taskProperty: null,
setException: null, // unused
setResult: WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__Complete,
setResult: WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__Complete, // AsyncIteratorMethodBuilder.Complete is the corresponding method to AsyncTaskMethodBuilder.SetResult
awaitOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__AwaitOnCompleted,
awaitUnsafeOnCompleted: WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__AwaitUnsafeOnCompleted,
start: WellKnownMember.System_Runtime_CompilerServices_AsyncIteratorMethodBuilder__MoveNext_T,
......
......@@ -28,12 +28,12 @@ internal class AsyncMethodToStateMachineRewriter : MethodToStateMachineRewriter
/// <see cref="AsyncVoidMethodBuilder"/>, <see cref="AsyncTaskMethodBuilder"/>, or <see cref="AsyncTaskMethodBuilder{TResult}"/> depending on the
/// return type of the async method.
/// </summary>
private readonly FieldSymbol _asyncMethodBuilderField;
protected readonly FieldSymbol _asyncMethodBuilderField;
/// <summary>
/// A collection of well-known members for the current async method builder.
/// </summary>
private readonly AsyncMethodBuilderMemberCollection _asyncMethodBuilderMemberCollection;
protected readonly AsyncMethodBuilderMemberCollection _asyncMethodBuilderMemberCollection;
/// <summary>
/// The exprReturnLabel is used to label the return handling code at the end of the async state-machine
......
......@@ -148,7 +148,7 @@ protected override void GenerateConstructor()
// {
// this.state = state;
// this.initialThreadId = {managedThreadId};
// this.builder = System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Create();
// this.builder = System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Create();
// }
Debug.Assert(stateMachineType.Constructor is IteratorConstructor);
......@@ -164,23 +164,25 @@ protected override void GenerateConstructor()
bodyBuilder.Add(F.Assignment(F.InstanceField(initialThreadIdField), managedThreadId));
}
// this.builder = System.Runtime.CompilerServices.AsyncVoidMethodBuilder.Create();
AsyncMethodBuilderMemberCollection methodScopeAsyncMethodBuilderMemberCollection;
bool found = AsyncMethodBuilderMemberCollection.TryCreate(F, method, typeMap: null, out methodScopeAsyncMethodBuilderMemberCollection);
Debug.Assert(found);
bodyBuilder.Add(
F.Assignment(
F.InstanceField(_builderField),
F.StaticCall(
null,
methodScopeAsyncMethodBuilderMemberCollection.CreateBuilder)));
// this.builder = System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Create();
bodyBuilder.Add(GenerateCreateAndAssignBuilder());
bodyBuilder.Add(F.Return());
F.CloseMethod(F.Block(bodyBuilder.ToImmutableAndFree()));
bodyBuilder = null;
}
private BoundExpressionStatement GenerateCreateAndAssignBuilder()
{
// Produce:
// this.builder = System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Create();
return F.Assignment(
F.InstanceField(_builderField),
F.StaticCall(
null,
_asyncMethodBuilderMemberCollection.CreateBuilder));
}
protected override void InitializeStateMachine(ArrayBuilder<BoundStatement> bodyBuilder, NamedTypeSymbol frameType, LocalSymbol stateMachineLocal)
{
// var stateMachineLocal = new {StateMachineType}({initialState})
......@@ -632,10 +634,23 @@ private void GenerateIAsyncEnumerableImplementation_GetAsyncEnumerator()
GenerateIteratorGetEnumerator(IAsyncEnumerableOfElementType_GetEnumerator, ref managedThreadId, initialState: StateMachineStates.InitialAsyncIteratorStateMachine);
}
protected override BoundStatement GetExtraResetForIteratorGetEnumerator()
protected override void GenerateResetInstance(ArrayBuilder<BoundStatement> builder, int initialState)
{
// disposeMode = false;
return F.Assignment(F.InstanceField(_disposeModeField), F.Literal(false));
// this.state = {initialState};
// this.builder = System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Create();
// this.disposeMode = false;
builder.Add(
// this.state = {initialState};
F.Assignment(F.Field(F.This(), stateField), F.Literal(initialState)));
builder.Add(
// this.builder = System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Create();
GenerateCreateAndAssignBuilder());
builder.Add(
// disposeMode = false;
F.Assignment(F.InstanceField(_disposeModeField), F.Literal(false)));
}
protected override void GenerateMoveNext(SynthesizedImplementationMethod moveNextMethod)
......
......@@ -402,20 +402,12 @@ protected SynthesizedImplementationMethod GenerateIteratorGetEnumerator(MethodSy
managedThreadId = MakeCurrentThreadId();
var thenBuilder = ArrayBuilder<BoundStatement>.GetInstance(4);
thenBuilder.Add(
// this.state = {initialState};
F.Assignment(F.Field(F.This(), stateField), F.Literal(initialState)));
GenerateResetInstance(thenBuilder, initialState);
thenBuilder.Add(
// result = this;
F.Assignment(F.Local(resultVariable), F.This()));
var extraReset = GetExtraResetForIteratorGetEnumerator();
if (extraReset != null)
{
thenBuilder.Add(extraReset);
}
if (method.IsStatic || method.ThisParameter.Type.IsReferenceType)
{
// if this is a reference type, no need to copy it since it is not assignable
......@@ -473,6 +465,16 @@ protected SynthesizedImplementationMethod GenerateIteratorGetEnumerator(MethodSy
return getEnumerator;
}
/// <summary>
/// Generate logic to reset the current instance (rather than creating a new instance)
/// </summary>
protected virtual void GenerateResetInstance(ArrayBuilder<BoundStatement> builder, int initialState)
{
builder.Add(
// this.state = {initialState};
F.Assignment(F.Field(F.This(), stateField), F.Literal(initialState)));
}
protected virtual BoundStatement InitializeParameterField(MethodSymbol getEnumeratorMethod, ParameterSymbol parameter, BoundExpression resultParameter, BoundExpression parameterProxy)
{
Debug.Assert(!method.IsIterator || !method.IsAsync); // an override handles async-iterators
......@@ -481,12 +483,6 @@ protected virtual BoundStatement InitializeParameterField(MethodSymbol getEnumer
return F.Assignment(resultParameter, parameterProxy);
}
/// <summary>
/// Async-iterator methods use a GetAsyncEnumerator method just like the GetEnumerator of iterator methods.
/// But they need to do a bit more work (to reset the dispose mode).
/// </summary>
protected virtual BoundStatement GetExtraResetForIteratorGetEnumerator() => null;
/// <summary>
/// Returns true if either Thread.ManagedThreadId or Environment.CurrentManagedThreadId are available
/// </summary>
......
......@@ -3597,7 +3597,6 @@ class D<T>
var root = syntaxTree.GetRoot();
var model = comp.GetSemanticModel(syntaxTree);
var lambda = root.DescendantNodes().OfType<LambdaExpressionSyntax>().First();
var lambdaSymbol = model.GetSymbolInfo(lambda).Symbol;
var localFunction = lambda.DescendantNodes().OfType<LocalFunctionStatementSyntax>().First();
......@@ -3607,5 +3606,39 @@ class D<T>
var typeParameters = localFunctionSymbol.TypeParameters[0];
Assert.Same(localFunctionSymbol, typeParameters.ContainingSymbol);
}
[Fact]
public void SpeculativeModel_InAttribute()
{
var source = @"
using System;
[AttributeUsage(AttributeTargets.ReturnValue)]
class Attr : Attribute
{
public Attr(string Test) {}
}
class Test
{
const string Constant = ""Test"";
[return: Attr(""Test"")]
void M() {}
}
";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
var syntaxTree = comp.SyntaxTrees[0];
var root = syntaxTree.GetRoot();
var model = comp.GetSemanticModel(syntaxTree);
var attributeUsage = root.DescendantNodes().OfType<AttributeSyntax>().ElementAt(1);
var newAttributeUsage = SyntaxFactory.Attribute(SyntaxFactory.ParseName("Attr"), SyntaxFactory.ParseAttributeArgumentList("(Constant)"));
Assert.True(model.TryGetSpeculativeSemanticModel(attributeUsage.SpanStart, newAttributeUsage, out var specModel));
Assert.NotNull(specModel);
var symbolInfo = specModel.GetSymbolInfo(newAttributeUsage.ArgumentList.Arguments[0].Expression);
Assert.Equal(SpecialType.System_String, ((IFieldSymbol)symbolInfo.Symbol).Type.SpecialType);
}
}
}
......@@ -51,6 +51,53 @@ internal override (DiagnosticAnalyzer, CodeFixProvider) CreateDiagnosticProvider
private static readonly ParseOptions CSharp7_1 = CSharpParseOptions.Default.WithLanguageVersion(LanguageVersion.CSharp7_1);
private const string NullableAttributesCode = @"
namespace System.Diagnostics.CodeAnalysis
{
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
internal sealed class AllowNullAttribute : Attribute { }
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
internal sealed class DisallowNullAttribute : Attribute { }
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
internal sealed class MaybeNullAttribute : Attribute { }
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, Inherited = false)]
internal sealed class NotNullAttribute : Attribute { }
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
internal sealed class MaybeNullWhenAttribute : Attribute
{
public MaybeNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
public bool ReturnValue { get; }
}
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
internal sealed class NotNullWhenAttribute : Attribute
{
public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue;
public bool ReturnValue { get; }
}
[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Property | AttributeTargets.ReturnValue, AllowMultiple = true, Inherited = false)]
internal sealed class NotNullIfNotNullAttribute : Attribute
{
public NotNullIfNotNullAttribute(string parameterName) => ParameterName = parameterName;
public string ParameterName { get; }
}
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
internal sealed class DoesNotReturnAttribute : Attribute { }
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
internal sealed class DoesNotReturnIfAttribute : Attribute
{
public DoesNotReturnIfAttribute(bool parameterValue) => ParameterValue = parameterValue;
public bool ParameterValue { get; }
}
}";
internal async Task TestWithAllCodeStyleOptionsOffAsync(
string initialMarkup, string expectedMarkup,
int index = 0, ParseOptions parseOptions = null)
......@@ -8133,5 +8180,58 @@ public class Test : ITest
public string P => throw new System.NotImplementedException();
}");
}
[Fact, Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)]
public async Task GenericInterfaceNotNull1()
{
await TestInRegularAndScriptAsync(
@$"#nullable enable
using System.Diagnostics.CodeAnalysis;
{NullableAttributesCode}
interface IFoo<T>
{{
[return: NotNull]
T Bar([DisallowNull] T bar);
[return: MaybeNull]
T Baz([AllowNull] T bar);
}}
class A : [|IFoo<int>|]
{{
}}",
@$"#nullable enable
using System.Diagnostics.CodeAnalysis;
{NullableAttributesCode}
interface IFoo<T>
{{
[return: NotNull]
T Bar([DisallowNull] T bar);
[return: MaybeNull]
T Baz([AllowNull] T bar);
}}
class A : [|IFoo<int>|]
{{
[return: NotNull]
public int Bar([DisallowNull] int bar)
{{
throw new System.NotImplementedException();
}}
[return: MaybeNull]
public int Baz([AllowNull] int bar)
{{
throw new System.NotImplementedException();
}}
}}");
}
}
}
......@@ -186,5 +186,20 @@ public static ImmutableArray<IAssemblySymbol> GetReferencedAssemblySymbols(this
public static INamedTypeSymbol? SystemIDisposableType(this Compilation compilation)
=> compilation.GetTypeByMetadataName(typeof(IDisposable).FullName);
public static INamedTypeSymbol? NotNullAttribute(this Compilation compilation)
=> compilation.GetTypeByMetadataName(typeof(NotNullAttribute).FullName);
public static INamedTypeSymbol? MaybeNullAttribute(this Compilation compilation)
=> compilation.GetTypeByMetadataName(typeof(MaybeNullAttribute).FullName);
public static INamedTypeSymbol? MaybeNullWhenAttribute(this Compilation compilation)
=> compilation.GetTypeByMetadataName(typeof(MaybeNullWhenAttribute).FullName);
public static INamedTypeSymbol? AllowNullAttribute(this Compilation compilation)
=> compilation.GetTypeByMetadataName(typeof(AllowNullAttribute).FullName);
public static INamedTypeSymbol? DisallowNullAttribute(this Compilation compilation)
=> compilation.GetTypeByMetadataName(typeof(DisallowNullAttribute).FullName);
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册