未验证 提交 c9c3d05c 编写于 作者: D dotnet-automerge-bot 提交者: GitHub

Merge pull request #34077 from dotnet/merges/master-to-master-vs-deps

Merge master to master-vs-deps
......@@ -2,9 +2,9 @@
<Dependencies>
<ProductDependencies></ProductDependencies>
<ToolsetDependencies>
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="1.0.0-beta.19157.23">
<Dependency Name="Microsoft.DotNet.Arcade.Sdk" Version="1.0.0-beta.19161.14">
<Uri>https://github.com/dotnet/arcade</Uri>
<Sha>a0d951e12a53401c3da812b581e39feb4a5bb4ab</Sha>
<Sha>2ca74c76adc84f0459b4a0352034db463d0b910f</Sha>
</Dependency>
</ToolsetDependencies>
</Dependencies>
......@@ -208,7 +208,11 @@ function BuildSolution() {
$projects = Join-Path $RepoRoot $solution
$enableAnalyzers = !$skipAnalyzers
$toolsetBuildProj = InitializeToolset
$quietRestore = !$ci
# Have to disable quiet restore during bootstrap builds to work around
# an arcade bug
# https://github.com/dotnet/arcade/issues/2220
$quietRestore = !($ci -or ($bootstrapDir -ne ""))
$testTargetFrameworks = if ($testCoreClr) { "netcoreapp2.1" } else { "" }
$ibcSourceBranchName = GetIbcSourceBranchName
$ibcDropId = if ($officialIbcDropId -ne "default") { $officialIbcDropId } else { "" }
......
......@@ -11,7 +11,6 @@
</PropertyGroup>
<Import Project="$(MSBuildThisFileDirectory)DefaultVersions.props" Condition="Exists('$(MSBuildThisFileDirectory)DefaultVersions.props')" />
<Import Project="$(MSBuildThisFileDirectory)Versions.props" Condition="Exists('$(MSBuildThisFileDirectory)Versions.props')" />
<Import Project="$(NuGetPackageRoot)microsoft.dotnet.build.tasks.feed\$(MicrosoftDotNetBuildTasksFeedVersion)\build\Microsoft.DotNet.Build.Tasks.Feed.targets" />
......
......@@ -42,7 +42,7 @@ try {
}
Write-Host "Generating dependency graph..."
$darc = Invoke-Expression "& `"$darcExe`" $options"
Invoke-Expression "& `"$darcExe`" $options"
CheckExitCode "Generating dependency graph"
$graph = Get-Content $graphVizFilePath
......
parameters:
# Optional: dependencies of the job
dependsOn: ''
# Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool
pool: {}
# Optional: Include toolset dependencies in the generated graph files
includeToolset: false
jobs:
- job: Generate_Graph_Files
dependsOn: ${{ parameters.dependsOn }}
displayName: Generate Graph Files
pool: ${{ parameters.pool }}
variables:
# Publish-Build-Assets provides: MaestroAccessToken, BotAccount-dotnet-maestro-bot-PAT
# DotNet-AllOrgs-Darc-Pats provides: dn-bot-devdiv-dnceng-rw-code-pat
- group: Publish-Build-Assets
- group: DotNet-AllOrgs-Darc-Pats
- name: _GraphArguments
value: -gitHubPat $(BotAccount-dotnet-maestro-bot-PAT)
-azdoPat $(dn-bot-devdiv-dnceng-rw-code-pat)
-barToken $(MaestroAccessToken)
-outputFolder '$(Build.StagingDirectory)/GraphFiles/'
- ${{ if ne(parameters.includeToolset, 'false') }}:
- name: _GraphArguments
value: ${{ variables._GraphArguments }} -includeToolset
steps:
- task: PowerShell@2
displayName: Generate Graph Files
inputs:
filePath: eng\common\generate-graph-files.ps1
arguments: $(_GraphArguments)
continueOnError: true
- task: PublishBuildArtifacts@1
displayName: Publish Graph to Artifacts
inputs:
PathtoPublish: '$(Build.StagingDirectory)/GraphFiles'
PublishLocation: Container
ArtifactName: GraphFiles
continueOnError: true
condition: always()
......@@ -13,7 +13,13 @@ parameters:
# Optional: Enable publishing to the build asset registry
enablePublishBuildAssets: false
graphFileGeneration:
# Optional: Enable generating the graph files at the end of the build
enabled: false
# Optional: Include toolset dependencies in the generated graph files
includeToolset: false
# Optional: Include PublishTestResults task
enablePublishTestResults: false
......@@ -68,4 +74,13 @@ jobs:
vmImage: vs2017-win2016
runAsPublic: ${{ parameters.runAsPublic }}
enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }}
- ${{ if and(eq(parameters.graphFileGeneration.enabled, true), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}:
- template: ../job/generate-graph-files.yml
parameters:
continueOnError: ${{ parameters.continueOnError }}
includeToolset: ${{ parameters.graphFileGeneration.includeToolset }}
dependsOn:
- Asset_Registry_Publish
pool:
vmImage: vs2017-win2016
......@@ -7,6 +7,6 @@
"xcopy-msbuild": "15.9.0-alpha"
},
"msbuild-sdks": {
"Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19157.23"
"Microsoft.DotNet.Arcade.Sdk": "1.0.0-beta.19161.14"
}
}
......@@ -30,7 +30,8 @@ private void VisitSwitchBlock(BoundSwitchStatement node)
{
foreach (var label in section.SwitchLabels)
{
if (reachableLabels.Contains(label.Label) || label.HasErrors)
if (reachableLabels.Contains(label.Label) || label.HasErrors ||
label == node.DefaultLabel && node.Expression.ConstantValue == null && IsTraditionalSwitch(node))
{
SetState(initialState.Clone());
}
......
......@@ -53,16 +53,20 @@ internal sealed class VariableState
/// Contains a result type which tells us whether the expression may be null,
/// and an l-value type which tells us whether we can assign null to the expression.
/// </summary>
[DebuggerDisplay("{GetDebuggerDisplay(), nq}")]
private readonly struct VisitResult
{
public readonly TypeWithState RValueType;
public readonly TypeSymbolWithAnnotations LValueType;
public VisitResult(TypeWithState resultType, TypeSymbolWithAnnotations lValueType)
public VisitResult(TypeWithState rValueType, TypeSymbolWithAnnotations lValueType)
{
RValueType = resultType;
RValueType = rValueType;
LValueType = lValueType;
}
private string GetDebuggerDisplay() =>
$"RValueType={RValueType.GetDebuggerDisplay()}, LValueType={LValueType.GetDebuggerDisplay()}";
}
/// <summary>
......@@ -135,7 +139,7 @@ private TypeWithState ResultType
get => _visitResult.RValueType;
set
{
SetResult(resultType: value, lvalueType: value.ToTypeSymbolWithAnnotations());
SetResult(rvalueType: value, lvalueType: value.ToTypeSymbolWithAnnotations());
}
}
......@@ -152,7 +156,7 @@ private TypeSymbolWithAnnotations LvalueResultType
get => _visitResult.LValueType;
set
{
SetResult(resultType: value.ToTypeWithState(), lvalueType: value);
SetResult(rvalueType: value.ToTypeWithState(), lvalueType: value);
}
}
......@@ -164,9 +168,9 @@ private void UseLvalueOnly()
LvalueResultType = LvalueResultType;
}
private void SetResult(TypeWithState resultType, TypeSymbolWithAnnotations lvalueType)
private void SetResult(TypeWithState rvalueType, TypeSymbolWithAnnotations lvalueType)
{
_visitResult = new VisitResult(resultType, lvalueType);
_visitResult = new VisitResult(rvalueType, lvalueType);
}
/// <summary>
......@@ -534,8 +538,12 @@ protected override int MakeSlot(BoundExpression node)
}
break;
case ConversionKind.Identity:
case ConversionKind.ImplicitReference:
case ConversionKind.ExplicitReference:
case ConversionKind.ImplicitTupleLiteral:
case ConversionKind.ExplicitTupleLiteral:
case ConversionKind.ImplicitTuple:
case ConversionKind.ExplicitTuple:
if (isSupportedConversion(conv.Conversion, conv.Operand))
{
return MakeSlot(conv.Operand);
......@@ -548,6 +556,7 @@ protected override int MakeSlot(BoundExpression node)
case BoundKind.ObjectCreationExpression:
case BoundKind.DynamicObjectCreationExpression:
case BoundKind.AnonymousObjectCreationExpression:
case BoundKind.NewT:
case BoundKind.TupleLiteral:
case BoundKind.ConvertedTupleLiteral:
return getPlaceholderSlot(node);
......@@ -573,7 +582,7 @@ int getPlaceholderSlot(BoundExpression expr)
return -1;
}
MethodSymbol getTopLevelMethod(MethodSymbol method)
static MethodSymbol getTopLevelMethod(MethodSymbol method)
{
while ((object)method != null)
{
......@@ -589,7 +598,7 @@ MethodSymbol getTopLevelMethod(MethodSymbol method)
// Returns true if the nullable state from the operand of the conversion
// can be used as is, and we can create a slot from the conversion.
bool isSupportedConversion(Conversion conversion, BoundExpression operandOpt)
static bool isSupportedConversion(Conversion conversion, BoundExpression operandOpt)
{
// https://github.com/dotnet/roslyn/issues/32599: Allow implicit and explicit
// conversions where the nullable state of the operand remains valid.
......@@ -598,23 +607,37 @@ bool isSupportedConversion(Conversion conversion, BoundExpression operandOpt)
case ConversionKind.Identity:
case ConversionKind.DefaultOrNullLiteral:
case ConversionKind.ImplicitReference:
case ConversionKind.ExplicitReference:
return true;
case ConversionKind.ImplicitTupleLiteral:
case ConversionKind.ExplicitTupleLiteral:
switch (operandOpt?.Kind)
{
var arguments = ((BoundConvertedTupleLiteral)operandOpt).Arguments;
var conversions = conversion.UnderlyingConversions;
for (int i = 0; i < arguments.Length; i++)
{
// https://github.com/dotnet/roslyn/issues/32600: Copy nullable
// state of tuple elements independently.
if (!isSupportedConversion(conversions[i], (arguments[i] as BoundConversion)?.Operand))
case BoundKind.Conversion:
{
return false;
var operandConversion = (BoundConversion)operandOpt;
return isSupportedConversion(operandConversion.Conversion, operandConversion.Operand);
}
}
return true;
case BoundKind.ConvertedTupleLiteral:
{
var arguments = ((BoundConvertedTupleLiteral)operandOpt).Arguments;
var conversions = conversion.UnderlyingConversions;
for (int i = 0; i < arguments.Length; i++)
{
// https://github.com/dotnet/roslyn/issues/32600: Copy nullable
// state of tuple elements independently.
if (!isSupportedConversion(conversions[i], (arguments[i] as BoundConversion)?.Operand))
{
return false;
}
}
return true;
}
default:
return false;
}
case ConversionKind.ImplicitTuple:
case ConversionKind.ExplicitTuple:
// https://github.com/dotnet/roslyn/issues/32600: Copy nullable
// state of tuple elements independently.
return conversion.UnderlyingConversions.All(c => isSupportedConversion(c, null));
......@@ -852,12 +875,12 @@ private void ReportNullabilityMismatchInAssignment(SyntaxNode syntaxNode, object
// https://github.com/dotnet/roslyn/issues/33428: Can the areEquivalentTypes check be removed
// if InheritNullableStateOfMember asserts the member is valid for target and value?
if (areEquivalentTypes(targetType, valueType)) // https://github.com/dotnet/roslyn/issues/29968 Allow assignment to base type.
if (areEquivalentTypes(targetType, valueType))
{
// https://github.com/dotnet/roslyn/issues/31395: We should copy all tracked state from `value` regardless of
// BoundNode type but we'll need to handle cycles (see NullableReferenceTypesTests.Members_FieldCycle_07).
// For now, we copy a limited set of BoundNode types that shouldn't contain cycles.
if ((targetType.IsReferenceType && (value.Kind == BoundKind.ObjectCreationExpression || value.Kind == BoundKind.AnonymousObjectCreationExpression || value.Kind == BoundKind.DynamicObjectCreationExpression || targetType.TypeSymbol.IsAnonymousType)) ||
if ((targetType.IsReferenceType && (isSupportedReferenceTypeValue(value) || targetType.TypeSymbol.IsAnonymousType)) ||
targetType.IsNullableType())
{
// Nullable<T> is handled here rather than in InheritNullableStateOfTrackableStruct since that
......@@ -875,8 +898,24 @@ private void ReportNullabilityMismatchInAssignment(SyntaxNode syntaxNode, object
}
}
bool areEquivalentTypes(TypeSymbolWithAnnotations target, TypeWithState assignedValue) =>
static bool areEquivalentTypes(TypeSymbolWithAnnotations target, TypeWithState assignedValue) =>
target.TypeSymbol.Equals(assignedValue.Type, TypeCompareKind.AllIgnoreOptions);
// https://github.com/dotnet/roslyn/issues/31395: See comment above.
static bool isSupportedReferenceTypeValue(BoundExpression value)
{
switch (value.Kind)
{
case BoundKind.Conversion:
return isSupportedReferenceTypeValue(((BoundConversion)value).Operand);
case BoundKind.ObjectCreationExpression:
case BoundKind.AnonymousObjectCreationExpression:
case BoundKind.DynamicObjectCreationExpression:
return true;
default:
return false;
}
}
}
private void ReportNonSafetyDiagnostic(SyntaxNode syntax)
......@@ -1291,7 +1330,6 @@ public override BoundNode VisitLocalDeclaration(BoundLocalDeclaration node)
return null;
}
bool inferredType = node.DeclaredType.InferredType;
TypeSymbolWithAnnotations type = local.Type;
TypeWithState valueType;
if (local.IsRef)
......@@ -1300,8 +1338,8 @@ public override BoundNode VisitLocalDeclaration(BoundLocalDeclaration node)
}
else
{
bool inferredType = node.DeclaredType.InferredType;
valueType = VisitOptionalImplicitConversion(initializer, targetTypeOpt: inferredType ? default : type, useLegacyWarnings: true, AssignmentKind.Assignment);
if (inferredType)
{
if (valueType.HasNullType)
......@@ -1395,7 +1433,9 @@ public override BoundNode VisitObjectCreationExpression(BoundObjectCreationExpre
ImmutableArray<VisitResult> argumentResults,
BoundExpression initializerOpt)
{
Debug.Assert(node.Kind == BoundKind.ObjectCreationExpression || node.Kind == BoundKind.DynamicObjectCreationExpression);
Debug.Assert(node.Kind == BoundKind.ObjectCreationExpression ||
node.Kind == BoundKind.DynamicObjectCreationExpression ||
node.Kind == BoundKind.NewT);
var argumentTypes = argumentResults.SelectAsArray(ar => ar.RValueType);
int slot = -1;
......@@ -1403,14 +1443,13 @@ public override BoundNode VisitObjectCreationExpression(BoundObjectCreationExpre
NullableFlowState resultState = NullableFlowState.NotNull;
if ((object)type != null)
{
bool isTrackableStructType = EmptyStructTypeCache.IsTrackableStructType(type);
var constructor = (node as BoundObjectCreationExpression)?.Constructor;
bool isDefaultValueTypeConstructor = constructor?.IsDefaultValueTypeConstructor() == true;
if (!type.IsValueType || isTrackableStructType)
slot = GetOrCreateObjectCreationPlaceholderSlot(node);
if (slot > 0)
{
slot = GetOrCreateObjectCreationPlaceholderSlot(node);
if (slot > 0 && isTrackableStructType)
var constructor = (node as BoundObjectCreationExpression)?.Constructor;
bool isDefaultValueTypeConstructor = constructor?.IsDefaultValueTypeConstructor() == true;
if (EmptyStructTypeCache.IsTrackableStructType(type))
{
this.State[slot] = NullableFlowState.NotNull;
var tupleType = constructor?.ContainingType as TupleTypeSymbol;
......@@ -1428,21 +1467,21 @@ public override BoundNode VisitObjectCreationExpression(BoundObjectCreationExpre
isDefaultValue: isDefaultValueTypeConstructor);
}
}
}
else if (type.IsNullableType())
{
if (isDefaultValueTypeConstructor)
{
// a nullable value type created with its default constructor is by definition null
resultState = NullableFlowState.MaybeNull;
}
else if (constructor.ParameterCount == 1)
else if (type.IsNullableType())
{
// if we deal with one-parameter ctor that takes underlying, then Value state is inferred from the argument.
var parameterType = constructor.ParameterTypes[0];
if (AreNullableAndUnderlyingTypes(type, parameterType.TypeSymbol, out TypeSymbolWithAnnotations underlyingType))
if (isDefaultValueTypeConstructor)
{
TrackNullableStateOfNullableValue(node, arguments[0], type, underlyingType);
// a nullable value type created with its default constructor is by definition null
resultState = NullableFlowState.MaybeNull;
}
else if (constructor.ParameterCount == 1)
{
// if we deal with one-parameter ctor that takes underlying, then Value state is inferred from the argument.
var parameterType = constructor.ParameterTypes[0];
if (AreNullableAndUnderlyingTypes(type, parameterType.TypeSymbol, out TypeSymbolWithAnnotations underlyingType))
{
TrackNullableStateOfNullableValue(node, arguments[0], type, underlyingType);
}
}
}
}
......@@ -1706,13 +1745,11 @@ private ArrayTypeSymbol VisitArrayInitializer(BoundArrayCreation node)
node, returnTypesOpt: null, initialState: null, callbackOpt: null);
int n = returns.Count;
var expressions = ArrayBuilder<BoundExpression>.GetInstance();
var resultTypes = ArrayBuilder<TypeSymbolWithAnnotations>.GetInstance(n);
var placeholdersBuilder = ArrayBuilder<BoundExpression>.GetInstance(n);
for (int i = 0; i < n; i++)
{
var (returnExpr, resultType) = returns[i];
expressions.Add(returnExpr);
resultTypes.Add(resultType);
placeholdersBuilder.Add(CreatePlaceholderIfNecessary(returnExpr, resultType));
}
......@@ -1745,7 +1782,6 @@ private ArrayTypeSymbol VisitArrayInitializer(BoundArrayCreation node)
}
resultTypes.Free();
expressions.Free();
walker.Free();
return inferredType;
......@@ -2325,6 +2361,7 @@ public override BoundNode VisitConditionalOperator(BoundConditionalOperator node
{
(consequence, consequenceConversion, consequenceResult) = visitConditionalOperand(consequenceState, node.Consequence);
Unsplit();
consequenceState = this.State;
(alternative, alternativeConversion, alternativeResult) = visitConditionalOperand(alternativeState, node.Alternative);
Unsplit();
Join(ref this.State, ref consequenceState);
......@@ -2361,32 +2398,22 @@ public override BoundNode VisitConditionalOperator(BoundConditionalOperator node
if (!isConstantFalse)
{
convertedConsequenceResult = ApplyConversion(
convertedConsequenceResult = convertResult(
node.Consequence,
consequence,
consequenceConversion,
resultTypeWithAnnotations,
consequenceResult.ToTypeWithState(),
checkConversion: true,
fromExplicitCast: false,
useLegacyWarnings: false,
AssignmentKind.Assignment,
reportTopLevelWarnings: false).ToTypeSymbolWithAnnotations();
consequenceResult);
}
if (!isConstantTrue)
{
convertedAlternativeResult = ApplyConversion(
convertedAlternativeResult = convertResult(
node.Alternative,
alternative,
alternativeConversion,
resultTypeWithAnnotations,
alternativeResult.ToTypeWithState(),
checkConversion: true,
fromExplicitCast: false,
useLegacyWarnings: false,
AssignmentKind.Assignment,
reportTopLevelWarnings: false).ToTypeSymbolWithAnnotations();
alternativeResult);
}
if (!convertedAlternativeResult.HasType)
......@@ -2465,6 +2492,26 @@ NullableAnnotation getNullableAnnotation(BoundExpression expr, TypeSymbolWithAnn
return (operand, conversion, resultWithAnnotation);
}
TypeSymbolWithAnnotations convertResult(
BoundExpression node,
BoundExpression operand,
Conversion conversion,
TypeSymbolWithAnnotations targetType,
TypeSymbolWithAnnotations operandType)
{
return ApplyConversion(
node,
operand,
conversion,
targetType,
operandType.ToTypeWithState(),
checkConversion: true,
fromExplicitCast: false,
useLegacyWarnings: false,
AssignmentKind.Assignment,
reportTopLevelWarnings: false).ToTypeSymbolWithAnnotations();
}
}
/// <summary>
......@@ -4667,7 +4714,6 @@ public override BoundNode VisitCompoundAssignmentOperator(BoundCompoundAssignmen
TypeSymbolWithAnnotations leftLValueType = LvalueResultType;
TypeWithState leftResultType = ResultType;
TypeWithState resultType;
Debug.Assert(!IsConditionalState);
TypeWithState leftOnRightType = GetAdjustedResult(leftResultType, MakeSlot(node.Left));
......@@ -4694,6 +4740,7 @@ public override BoundNode VisitCompoundAssignmentOperator(BoundCompoundAssignmen
leftOnRightType = default;
}
TypeWithState resultType;
TypeWithState rightType = VisitRvalueWithState(node.Right);
if ((object)node.Operator.ReturnType != null)
{
......@@ -5459,9 +5506,7 @@ public override BoundNode VisitImplicitReceiver(BoundImplicitReceiver node)
public override BoundNode VisitAnonymousPropertyDeclaration(BoundAnonymousPropertyDeclaration node)
{
var result = base.VisitAnonymousPropertyDeclaration(node);
SetNotNullResult(node);
return result;
throw ExceptionUtilities.Unreachable;
}
public override BoundNode VisitNoPiaObjectCreationExpression(BoundNoPiaObjectCreationExpression node)
......@@ -5473,9 +5518,8 @@ public override BoundNode VisitNoPiaObjectCreationExpression(BoundNoPiaObjectCre
public override BoundNode VisitNewT(BoundNewT node)
{
var result = base.VisitNewT(node);
ResultType = new TypeWithState(node.Type, NullableFlowState.NotNull);
return result;
VisitObjectOrDynamicObjectCreation(node, ImmutableArray<BoundExpression>.Empty, ImmutableArray<VisitResult>.Empty, node.InitializerExpressionOpt);
return null;
}
public override BoundNode VisitArrayInitialization(BoundArrayInitialization node)
......
......@@ -10,8 +10,8 @@ namespace Microsoft.CodeAnalysis.CSharp.Symbols
[DebuggerDisplay("{GetDebuggerDisplay(), nq}")]
internal readonly struct TypeWithState
{
public TypeSymbol Type { get; }
public NullableFlowState State { get; }
public readonly TypeSymbol Type;
public readonly NullableFlowState State;
public bool HasNullType => Type is null;
public bool MayBeNull => State == NullableFlowState.MaybeNull;
public bool IsNotNull => State == NullableFlowState.NotNull;
......
......@@ -19,7 +19,6 @@ public class NullableReferenceTypesTests : CSharpTestBase
{
private const string Tuple2NonNullable =
@"
namespace System
{
#nullable enable
......@@ -42,9 +41,7 @@ public override string ToString()
return """";
}
}
}
";
}";
private const string TupleRestNonNullable =
@"
......@@ -21318,6 +21315,75 @@ static void F(bool b)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(6, 9));
}
[Fact]
public void ConditionalOperator_16()
{
var source =
@"class Program
{
static bool F(object? x)
{
return true;
}
static void F1(bool b, bool c, object x1, object? y1)
{
if (b ? c && F(x1 = y1) : true) // 1
{
x1.ToString(); // 2
}
}
static void F2(bool b, bool c, object x2, object? y2)
{
if (b ? true : c && F(x2 = y2)) // 3
{
x2.ToString(); // 4
}
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (9,29): warning CS8600: Converting null literal or possible null value to non-nullable type.
// if (b ? c && F(x1 = y1) : true) // 1
Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "y1").WithLocation(9, 29),
// (11,13): warning CS8602: Possible dereference of a null reference.
// x1.ToString(); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x1").WithLocation(11, 13),
// (16,36): warning CS8600: Converting null literal or possible null value to non-nullable type.
// if (b ? true : c && F(x2 = y2)) // 3
Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "y2").WithLocation(16, 36),
// (18,13): warning CS8602: Possible dereference of a null reference.
// x2.ToString(); // 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x2").WithLocation(18, 13));
}
[Fact]
public void ConditionalOperator_17()
{
var source =
@"class Program
{
static void F(bool x, bool y, bool z, bool? w)
{
object o;
o = x ? y && z : w; // 1
o = true ? y && z : w;
o = false ? w : y && z;
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
// Should there be a warning for // 1 only?
comp.VerifyDiagnostics(
// (6,13): warning CS8600: Converting null literal or possible null value to non-nullable type.
// o = x ? y && z : w; // 1
Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "x ? y && z : w").WithLocation(6, 13),
// (7,13): warning CS8600: Converting null literal or possible null value to non-nullable type.
// o = true ? y && z : w;
Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "true ? y && z : w").WithLocation(7, 13),
// (8,13): warning CS8600: Converting null literal or possible null value to non-nullable type.
// o = false ? w : y && z;
Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "false ? w : y && z").WithLocation(8, 13));
}
[Fact]
public void ConditionalOperator_TopLevelNullability()
{
......@@ -34490,6 +34556,27 @@ class Awaiter : System.Runtime.CompilerServices.INotifyCompletion
);
}
[Fact]
public void Await_03()
{
var source =
@"using System.Threading.Tasks;
class Program
{
async void M(Task? x, Task? y)
{
if (y == null) return;
await x; // 1
await y;
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (7,15): warning CS8602: Possible dereference of a null reference.
// await x; // 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(7, 15));
}
[Fact]
public void Await_ProduceResultTypeFromTask()
{
......@@ -39174,6 +39261,55 @@ static void Main()
Diagnostic(ErrorCode.WRN_NullReferenceAssignment, "RefReturn()").WithLocation(15, 32));
}
[Fact]
[WorkItem(27317, "https://github.com/dotnet/roslyn/pull/27317")]
public void RefOutSuppressionInference()
{
var src = @"
class C
{
void M<T>(ref T t) { }
void M2<T>(out T t) => throw null!;
void M3<T>(in T t) { }
T M4<T>(in T t) => t;
void M3()
{
string? s1 = null;
M(ref s1!);
s1.ToString();
string? s2 = null;
M2(out s2!);
s2.ToString();
string? s3 = null;
M3(s3!);
s3.ToString(); // warn
string? s4 = null;
M3(in s4!);
s4.ToString(); // warn
string? s5 = null;
s5 = M4(s5!);
s5.ToString();
string? s6 = null;
s6 = M4(in s6!);
s6.ToString();
}
}";
var comp = CreateCompilation(src, options: WithNonNullTypesTrue(TestOptions.DebugDll));
comp.VerifyDiagnostics(
// (21,9): warning CS8602: Possible dereference of a null reference.
// s3.ToString(); // warn
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s3").WithLocation(21, 9),
// (25,9): warning CS8602: Possible dereference of a null reference.
// s4.ToString(); // warn
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s4").WithLocation(25, 9));
}
[Fact]
[WorkItem(27522, "https://github.com/dotnet/roslyn/issues/27522")]
[WorkItem(29903, "https://github.com/dotnet/roslyn/issues/29903")]
......@@ -43531,8 +43667,6 @@ static void F2()
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
// https://github.com/dotnet/roslyn/issues/29968 Allow conversion to base
// type to avoid the warning for `u2.y.F.ToString();`.
comp.VerifyDiagnostics(
// (12,22): warning CS8619: Nullability of reference types in value of type '(A?, A)' doesn't match target type '(A, A?)'.
// (A, A?) t1 = (null, new A() { F = 1 }); // 1
......@@ -43545,10 +43679,7 @@ static void F2()
Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "(null, new B() { F = 2 })").WithArguments("(A?, A)", "(A, A?)").WithLocation(20, 22),
// (22,9): warning CS8602: Possible dereference of a null reference.
// u2.x.ToString(); // 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "u2.x").WithLocation(22, 9),
// (24,9): warning CS8602: Possible dereference of a null reference.
// u2.y.F.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "u2.y.F").WithLocation(24, 9));
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "u2.x").WithLocation(22, 9));
comp.VerifyTypes();
}
......@@ -43642,25 +43773,27 @@ static void F(string x, string? y)
t.Item2.ToString(); // 2
u.Item1.ToString();
u.Item2.ToString(); // 3
v.Item1.ToString(); // 4
v.Item2.ToString(); // 5
v.Item1.ToString();
v.Item2.ToString(); // 4
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
// https://github.com/dotnet/roslyn/issues/32599: Support explicit conversions (see // 5).
comp.VerifyDiagnostics(
// (5,30): warning CS8619: Nullability of reference types in value of type '(object x, string? y)' doesn't match target type '(object, string)'.
// (object, string) t = ((object, string))(x, y)/*T:(object! x, string? y)*/; // 1
Diagnostic(ErrorCode.WRN_NullabilityMismatchInAssignment, "((object, string))(x, y)").WithArguments("(object x, string? y)", "(object, string)").WithLocation(5, 30),
// (5,52): warning CS8600: Converting null literal or possible null value to non-nullable type.
// (object, string) t = ((object, string))(x, y)/*T:(string? x, string? y)*/; // 1
// (object, string) t = ((object, string))(x, y)/*T:(object! x, string? y)*/; // 1
Diagnostic(ErrorCode.WRN_ConvertingNullableToNonNullable, "y").WithLocation(5, 52),
// (9,9): warning CS8602: Possible dereference of a null reference.
// t.Item2.ToString(); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t.Item2").WithLocation(9, 9),
// (11,9): warning CS8602: Possible dereference of a null reference.
// u.Item2.ToString(); // 3
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "u.Item2").WithLocation(11, 9),
// (12,9): warning CS8602: Possible dereference of a null reference.
// v.Item1.ToString(); // 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "v.Item1").WithLocation(12, 9));
// (13,9): warning CS8602: Possible dereference of a null reference.
// v.Item2.ToString(); // 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "v.Item2").WithLocation(13, 9));
comp.VerifyTypes();
}
......@@ -50914,8 +51047,7 @@ static void F()
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "c.E").WithLocation(9, 9));
}
// https://github.com/dotnet/roslyn/issues/29977: Support assignment of derived type instances.
[Fact(Skip = "https://github.com/dotnet/roslyn/issues/29977")]
[Fact]
[WorkItem(29977, "https://github.com/dotnet/roslyn/issues/29977")]
public void Members_ObjectInitializer_DerivedType()
{
......@@ -50935,31 +51067,27 @@ static void Main()
{
A a;
a = new B() { F = new A(), G = new object() };
a.F.ToString(); // 1
a.F.ToString();
a = new A();
a.F.ToString(); // 2
a.F.ToString(); // 1
a = new B() { F = new B() { F = new A() } };
a.F.ToString(); // 3
a.F.F.ToString(); // 3
a.F.ToString();
a.F.F.ToString();
a = new B() { G = new object() };
a.F.ToString(); // 4
a.F.ToString(); // 2
}
}";
var comp = CreateCompilation(new[] { source }, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (18,9): warning CS8602: Possible dereference of a null reference.
// a.F.ToString(); // 2
// a.F.ToString(); // 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "a.F").WithLocation(18, 9),
// (20,9): warning CS8602: Possible dereference of a null reference.
// a.F.ToString(); // 3
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "a.F").WithLocation(20, 9),
// (23,9): warning CS8602: Possible dereference of a null reference.
// a.F.ToString(); // 4
// a.F.ToString(); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "a.F").WithLocation(23, 9));
}
// https://github.com/dotnet/roslyn/issues/29977: Support assignment of derived type instances.
[Fact(Skip = "https://github.com/dotnet/roslyn/issues/29977")]
[Fact]
[WorkItem(29977, "https://github.com/dotnet/roslyn/issues/29977")]
public void Members_Assignment()
{
......@@ -50998,11 +51126,417 @@ static void Main()
// (17,9): warning CS8602: Possible dereference of a null reference.
// a.F.ToString(); // 1
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "a.F").WithLocation(17, 9),
// (20,9): warning CS8602: Possible dereference of a null reference.
// a.F.ToString(); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "a.F").WithLocation(20, 9),
// (23,9): warning CS8602: Possible dereference of a null reference.
// a.F.ToString(); // 3
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "a.F").WithLocation(23, 9),
// (24,9): warning CS8602: Possible dereference of a null reference.
// a.F.F.ToString(); // 3
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "a.F.F").WithLocation(24, 9),
// (27,9): warning CS8602: Possible dereference of a null reference.
// a.F.ToString(); // 4
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "a.F").WithLocation(27, 9));
}
[Fact]
[WorkItem(29977, "https://github.com/dotnet/roslyn/issues/29977")]
public void Conversions_ReferenceConversions_01()
{
var source =
@"class A
{
internal object? FA;
}
class B : A
{
internal object FB = new object();
}
class Program
{
static void F()
{
A a = new B() { FA = 1 };
a.FA.ToString();
a = new B() { FA = 2, FB = null }; // 1
((B)a).FA.ToString();
((B)a).FB.ToString(); // 2
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (15,36): warning CS8625: Cannot convert null literal to non-nullable reference type.
// a = new B() { FA = 2, FB = null }; // 1
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(15, 36),
// (17,9): warning CS8602: Possible dereference of a null reference.
// ((B)a).FB.ToString(); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "((B)a).FB").WithLocation(17, 9));
}
[Fact]
[WorkItem(29977, "https://github.com/dotnet/roslyn/issues/29977")]
public void Conversions_ReferenceConversions_02()
{
var source =
@"class A
{
internal object? FA;
}
class B : A
{
internal object FB = new object();
}
class Program
{
static void F()
{
B b = new B() { FA = 1 };
A a = b;
a.FA.ToString();
a = new B() { FB = null }; // 1
b = (B)a;
b.FB.ToString(); // 2
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
// https://github.com/dotnet/roslyn/issues/31395: Nullability of class members should be copied on assignment.
comp.VerifyDiagnostics(
// (15,9): warning CS8602: Possible dereference of a null reference.
// a.FA.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "a.FA").WithLocation(15, 9),
// (16,28): warning CS8625: Cannot convert null literal to non-nullable reference type.
// a = new B() { FB = null }; // 1
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(16, 28));
}
[Fact]
[WorkItem(29977, "https://github.com/dotnet/roslyn/issues/29977")]
public void Conversions_ReferenceConversions_03()
{
var source =
@"interface IA
{
object? PA { get; set; }
}
interface IB : IA
{
object PB { get; set; }
}
class Program
{
static void F(IB b)
{
b.PA = 1;
b.PB = null; // 1
((IA)b).PA.ToString();
((IB)(object)b).PB.ToString(); // 2
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (14,16): warning CS8625: Cannot convert null literal to non-nullable reference type.
// b.PB = null; // 1
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(14, 16),
// (16,9): warning CS8602: Possible dereference of a null reference.
// ((IB)(object)b).PB.ToString(); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "((IB)(object)b).PB").WithLocation(16, 9));
}
[Fact]
[WorkItem(29977, "https://github.com/dotnet/roslyn/issues/29977")]
public void Conversions_ReferenceConversions_04()
{
var source =
@"interface IA
{
object? PA { get; set; }
}
interface IB : IA
{
object PB { get; set; }
}
class Program
{
static void F(IB b)
{
b.PA = 1;
b.PB = null; // 1
object o = b;
b = o; // 2
b.PA.ToString();
b = (IB)o;
b.PB.ToString(); // 3
((IB)o).PA.ToString();
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
// https://github.com/dotnet/roslyn/issues/31395: Nullability of class members should be copied on assignment.
comp.VerifyDiagnostics(
// (14,16): warning CS8625: Cannot convert null literal to non-nullable reference type.
// b.PB = null; // 1
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(14, 16),
// (16,13): error CS0266: Cannot implicitly convert type 'object' to 'IB'. An explicit conversion exists (are you missing a cast?)
// b = o; // 2
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "o").WithArguments("object", "IB").WithLocation(16, 13),
// (17,9): warning CS8602: Possible dereference of a null reference.
// b.PA.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "b.PA").WithLocation(17, 9),
// (20,9): warning CS8602: Possible dereference of a null reference.
// ((IB)o).PA.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "((IB)o).PA").WithLocation(20, 9));
}
[Fact]
[WorkItem(29977, "https://github.com/dotnet/roslyn/issues/29977")]
public void Conversions_ReferenceConversions_05()
{
var source =
@"#pragma warning disable 0649
class C
{
internal object? F;
}
class Program
{
static void F(object x, object? y)
{
if (((C)x).F != null)
((C)x).F.ToString();
if (((C?)y)?.F != null)
((C)y).F.ToString();
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics();
}
[Fact]
[WorkItem(29977, "https://github.com/dotnet/roslyn/issues/29977")]
public void Conversions_ReferenceConversions_06()
{
var source =
@"class C
{
internal object F() => null!;
}
class Program
{
static void F(object? x)
{
if (((C?)x)?.F() != null)
((C)x).F().ToString();
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics();
}
[Fact]
[WorkItem(29977, "https://github.com/dotnet/roslyn/issues/29977")]
public void Conversions_ReferenceConversions_07()
{
var source =
@"interface I
{
object? P { get; }
}
class Program
{
static void F(object x, object? y)
{
if (((I)x).P != null)
((I)x).P.ToString();
if (((I?)y)?.P != null)
((I)y).P.ToString();
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics();
}
[Fact]
[WorkItem(29977, "https://github.com/dotnet/roslyn/issues/29977")]
public void Conversions_ReferenceConversions_08()
{
var source =
@"interface I
{
object F();
}
class Program
{
static void F(object? x)
{
if (((I?)x)?.F() != null)
((I)x).F().ToString();
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics();
}
[Fact]
[WorkItem(29977, "https://github.com/dotnet/roslyn/issues/29977")]
public void Conversions_ReferenceConversions_09()
{
var source =
@"class A
{
internal bool? F;
}
class B : A
{
}
class Program
{
static void M(bool b1, bool b2)
{
A a;
if (b1 ? b2 && (a = new B() { F = true }).F.Value : false)
{
}
if (true ? b2 && (a = new B() { F = false }).F.Value : false)
{
}
if (false ? false : b2 && (a = new B() { F = b1 }).F.Value)
{
}
if (false ? b2 && (a = new B() { F = null }).F.Value : true)
{
}
_ = (a = new B() { F = null }).F.Value; // 1
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (25,13): warning CS8629: Nullable value type may be null.
// _ = (a = new B() { F = null }).F.Value; // 1
Diagnostic(ErrorCode.WRN_NullableValueTypeMayBeNull, "(a = new B() { F = null }).F").WithLocation(25, 13));
}
[Fact]
[WorkItem(29977, "https://github.com/dotnet/roslyn/issues/29977")]
public void Conversions_TupleConversions_01()
{
var source =
@"class A
{
internal object? FA;
}
class B : A
{
internal object FB = new object();
}
class Program
{
static void F()
{
(B, object) t = (new B() { FA = 1 }, new B() { FB = null }); // 1
t.Item1.FA.ToString();
((A)t.Item1).FA.ToString();
((B)t.Item2).FB.ToString(); // 2
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (13,61): warning CS8625: Cannot convert null literal to non-nullable reference type.
// (B, object) t = (new B() { FA = 1 }, new B() { FB = null }); // 1
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(13, 61),
// (16,9): warning CS8602: Possible dereference of a null reference.
// ((B)t.Item2).FB.ToString(); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "((B)t.Item2).FB").WithLocation(16, 9));
}
[Fact]
[WorkItem(29977, "https://github.com/dotnet/roslyn/issues/29977")]
public void Conversions_TupleConversions_02()
{
var source =
@"class A
{
internal object? FA;
}
class B : A
{
internal object FB = new object();
}
class Program
{
static void F()
{
(B, object) t = (new B() { FA = 1 }, new B() { FB = null }); // 1
(((A, A))t).Item1.FA.ToString();
(((B, B))t).Item2.FB.ToString(); // 2
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (13,61): warning CS8625: Cannot convert null literal to non-nullable reference type.
// (B, object) t = (new B() { FA = 1 }, new B() { FB = null }); // 1
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(13, 61),
// (15,9): warning CS8602: Possible dereference of a null reference.
// (((B, B))t).Item2.FB.ToString(); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "(((B, B))t).Item2.FB").WithLocation(15, 9));
}
[Fact]
[WorkItem(29977, "https://github.com/dotnet/roslyn/issues/29977")]
public void Conversions_TupleConversions_03()
{
var source =
@"class A
{
internal object? FA;
}
class B : A
{
internal object FB = new object();
}
class Program
{
static void F()
{
B b = new B() { FA = 1, FB = null }; // 1
(B, (A, A)) t;
t = (b, (b, b));
t.Item1.FB.ToString(); // 2
t.Item2.Item1.FA.ToString();
t = ((B, (A, A)))(b, (b, b));
t.Item1.FB.ToString(); // 3
t.Item2.Item1.FA.ToString();
(A, (B, B)) u;
u = t; // 4
u.Item1.FA.ToString();
u.Item2.Item2.FB.ToString(); // 5
u = ((A, (B, B)))t;
u.Item1.FA.ToString();
u.Item2.Item2.FB.ToString(); // 6
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
// https://github.com/dotnet/roslyn/issues/31395: Nullability of class members should be copied on assignment.
comp.VerifyDiagnostics(
// (13,38): warning CS8625: Cannot convert null literal to non-nullable reference type.
// B b = new B() { FA = 1, FB = null }; // 1
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(13, 38),
// (17,9): warning CS8602: Possible dereference of a null reference.
// t.Item2.Item1.FA.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t.Item2.Item1.FA").WithLocation(17, 9),
// (20,9): warning CS8602: Possible dereference of a null reference.
// t.Item2.Item1.FA.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "t.Item2.Item1.FA").WithLocation(20, 9),
// (22,13): error CS0266: Cannot implicitly convert type '(B, (A, A))' to '(A, (B, B))'. An explicit conversion exists (are you missing a cast?)
// u = t; // 4
Diagnostic(ErrorCode.ERR_NoImplicitConvCast, "t").WithArguments("(B, (A, A))", "(A, (B, B))").WithLocation(22, 13),
// (23,9): warning CS8602: Possible dereference of a null reference.
// u.Item1.FA.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "u.Item1.FA").WithLocation(23, 9),
// (26,9): warning CS8602: Possible dereference of a null reference.
// u.Item1.FA.ToString();
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "u.Item1.FA").WithLocation(26, 9));
}
[Fact]
public void Members_FieldCycle_01()
{
......@@ -51266,6 +51800,39 @@ static void M(S s)
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "s.P.F").WithLocation(19, 9));
}
[Fact]
public void Members_StaticField_Struct()
{
var source =
@"struct S<T> where T : class
{
internal T F;
internal T? G;
internal static S<T> Instance = new S<T>();
}
class Program
{
static void F<T>() where T : class, new()
{
S<T>.Instance.F = null; // 1
S<T>.Instance.G = new T();
S<T>.Instance.F.ToString(); // 2
S<T>.Instance.G.ToString();
}
}";
var comp = CreateCompilation(source, options: WithNonNullTypesTrue());
comp.VerifyDiagnostics(
// (5,26): error CS0523: Struct member 'S<T>.Instance' of type 'S<T>' causes a cycle in the struct layout
// internal static S<T> Instance = new S<T>();
Diagnostic(ErrorCode.ERR_StructLayoutCycle, "Instance").WithArguments("S<T>.Instance", "S<T>").WithLocation(5, 26),
// (11,27): warning CS8625: Cannot convert null literal to non-nullable reference or unconstrained type parameter.
// S<T>.Instance.F = null; // 1
Diagnostic(ErrorCode.WRN_NullAsNonNullable, "null").WithLocation(11, 27),
// (13,9): warning CS8602: Possible dereference of a null reference.
// S<T>.Instance.F.ToString(); // 2
Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "S<T>.Instance.F").WithLocation(13, 9));
}
[Fact]
public void Members_DefaultConstructor_Class()
{
......@@ -55708,9 +56275,9 @@ class C {
// (4,2): error CS8652: The feature 'nullable reference types' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// #nullable enable
Diagnostic(ErrorCode.ERR_FeatureInPreview, "nullable").WithArguments("nullable reference types").WithLocation(4, 2),
// (5,2): error CS8652: The feature 'nullable reference types' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// (4,2): error CS8652: The feature 'nullable reference types' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// #nullable enable
Diagnostic(ErrorCode.ERR_FeatureInPreview, "nullable").WithArguments("nullable reference types").WithLocation(5, 2),
Diagnostic(ErrorCode.ERR_FeatureInPreview, "nullable").WithArguments("nullable reference types").WithLocation(4, 2),
// (6,20): error CS8652: The feature 'object generic type constraint' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// where T1 : object
Diagnostic(ErrorCode.ERR_FeatureInPreview, "object").WithArguments("object generic type constraint").WithLocation(6, 20),
......@@ -55718,13 +56285,16 @@ class C {
// (string?, string) t1;
Diagnostic(ErrorCode.ERR_FeatureInPreview, "?").WithArguments("nullable reference types").WithLocation(7, 16),
// (7,20): error CS8652: The feature 'object generic type constraint' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// where T1 : object
Diagnostic(ErrorCode.ERR_FeatureInPreview, "object").WithArguments("object generic type constraint").WithLocation(7, 20),
// (7,20): error CS8652: The feature 'object generic type constraint' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// where T2 : object
Diagnostic(ErrorCode.ERR_FeatureInPreview, "object").WithArguments("object generic type constraint").WithLocation(7, 20),
// (8,20): error CS8652: The feature 'object generic type constraint' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// where T3 : object
// where T2 : object
Diagnostic(ErrorCode.ERR_FeatureInPreview, "object").WithArguments("object generic type constraint").WithLocation(8, 20),
// (8,20): error CS8652: The feature 'object generic type constraint' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// where T1 : object
// where T3 : object
Diagnostic(ErrorCode.ERR_FeatureInPreview, "object").WithArguments("object generic type constraint").WithLocation(8, 20),
// (8,33): error CS8652: The feature 'nullable reference types' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// Type t2 = typeof((string?, string));
......@@ -55732,9 +56302,6 @@ class C {
// (9,20): error CS8652: The feature 'object generic type constraint' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// where T4 : object
Diagnostic(ErrorCode.ERR_FeatureInPreview, "object").WithArguments("object generic type constraint").WithLocation(9, 20),
// (9,20): error CS8652: The feature 'object generic type constraint' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// where T2 : object
Diagnostic(ErrorCode.ERR_FeatureInPreview, "object").WithArguments("object generic type constraint").WithLocation(9, 20),
// (10,20): error CS8652: The feature 'object generic type constraint' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
// where T5 : object
Diagnostic(ErrorCode.ERR_FeatureInPreview, "object").WithArguments("object generic type constraint").WithLocation(10, 20),
......@@ -82714,7 +83281,7 @@ static IB<T> CreateB<T>(T t)
static void F1<T>(T x1)
{
if (x1 == null) return;
var y1 = CreateB(x1);
var y1 = CreateB(x1);
y1.A.ToString(); // 1
y1.B.ToString(); // 2
}
......@@ -82729,21 +83296,21 @@ static void F1<T>(T x1)
static void F3<T>() where T : class, new()
{
T? x3 = new T();
var y3 = CreateB(x3);
var y3 = CreateB(x3);
y3.A.ToString();
y3.B.ToString();
}
static void F4<T>() where T : struct
{
T? x4 = null;
var y4 = CreateB(x4);
var y4 = CreateB(x4);
_ = y4.A.Value; // 6
_ = y4.B.Value; // 7
}
static void F5<T>() where T : struct
{
T? x5 = new T();
var y5 = CreateB(x5);
var y5 = CreateB(x5);
_ = y5.A.Value; // 8
_ = y5.B.Value; // 9
}
......@@ -82852,7 +83419,7 @@ static void F1<T>(T x1)
if (x1 == null) return;
T y1 = default; // 1
var ix1 = CreateB(x1);
var iy1 = CreateB(y1);
var iy1 = CreateB(y1);
ix1.A(y1);
ix1.B(y1);
iy1.A(x1);
......@@ -82863,7 +83430,7 @@ static void F2<T>() where T : class, new()
T x2 = null; // 2
T? y2 = new T();
var ix2 = CreateB(x2);
var iy2 = CreateB(y2);
var iy2 = CreateB(y2);
ix2.A(y2);
ix2.B(y2);
iy2.A(x2); // 3
......@@ -82874,7 +83441,7 @@ static void F2<T>() where T : class, new()
T? x3 = null;
T? y3 = new T();
var ix3 = CreateB(x3);
var iy3 = CreateB(y3);
var iy3 = CreateB(y3);
ix3.A(y3);
ix3.B(y3);
iy3.A(x3);
......@@ -2918,6 +2918,35 @@ public static void Main()
);
}
[Fact]
[WorkItem(33783, "https://github.com/dotnet/roslyn/issues/33783")]
public void UnreachableDefaultInBoolSwitch()
{
var text = @"
public class TestClass
{
public static void Main()
{
bool b = false;
switch (b)
{
case true:
break;
case false:
break;
default:
break; //1
}
}
}";
CreateCompilation(text, parseOptions: TestOptions.Regular6).VerifyDiagnostics();
CreateCompilation(text, parseOptions: TestOptions.Regular7_3).VerifyDiagnostics();
CreateCompilation(text).VerifyDiagnostics(
// (14,17): warning CS0162: Unreachable code detected
// break; //1
Diagnostic(ErrorCode.WRN_UnreachableCode, "break").WithLocation(14, 17));
}
#endregion
}
}
......@@ -3112,6 +3112,64 @@ End Class
End Using
End Sub
<Fact>
<Trait(Traits.Feature, Traits.Features.Rename)>
<WorkItem(16576, "https://github.com/dotnet/roslyn/issues/16576")>
Public Sub RenameParameterizedPropertyResolvedConflict()
Using result = RenameEngineResult.Create(_outputHelper,
<Workspace>
<Project Language="Visual Basic" CommonReferences="true">
<Document><![CDATA[
Public Class C
Public ReadOnly Property P(a As Object) As Int32
Get
Return 2
End Get
End Property
Public ReadOnly Property [|$$P2|](a As String) As Int32
Get
Return {|Conflict0:P|}("")
End Get
End Property
End Class
]]>
</Document>
</Project>
</Workspace>, renameTo:="P")
result.AssertLabeledSpansAre("Conflict0", replacement:="Return P(CObj(""""))", type:=RelatedLocationType.ResolvedNonReferenceConflict)
End Using
End Sub
<Fact>
<Trait(Traits.Feature, Traits.Features.Rename)>
<WorkItem(16576, "https://github.com/dotnet/roslyn/issues/16576")>
Public Sub RenameParameterizedPropertyUnresolvedConflict()
Using result = RenameEngineResult.Create(_outputHelper,
<Workspace>
<Project Language="Visual Basic" CommonReferences="true">
<Document><![CDATA[
Public Class C
Public ReadOnly Property {|Conflict:P|}(a As String) As Int32
Get
Return 2
End Get
End Property
Public ReadOnly Property [|$$P2|](a As String) As Int32
Get
Return 3
End Get
End Property
End Class
]]>
</Document>
</Project>
</Workspace>, renameTo:="P")
result.AssertLabeledSpansAre("Conflict", type:=RelatedLocationType.UnresolvedConflict)
End Using
End Sub
<Fact>
<Trait(Traits.Feature, Traits.Features.Rename)>
<WorkItem(10469, "https://github.com/dotnet/roslyn/issues/10469")>
......
......@@ -57,10 +57,16 @@ public bool IsExperimentEnabled(string experimentName)
{
try
{
var enabled = _featureFlags.IsFeatureEnabled(experimentName, defaultValue: false);
if (enabled)
// check whether "." exist in the experimentName since it is requirement for featureflag service.
// we do this since RPS complains about resource file being loaded for invalid name exception
// we are not testing all rules but just simple "." check
if (experimentName.IndexOf(".") > 0)
{
return enabled;
var enabled = _featureFlags.IsFeatureEnabled(experimentName, defaultValue: false);
if (enabled)
{
return enabled;
}
}
}
catch
......
......@@ -259,7 +259,7 @@ private class TestService : ServiceHubServiceBase
{
Event = new ManualResetEvent(false);
Rpc.StartListening();
StartService();
}
public readonly ManualResetEvent Event;
......
......@@ -40,7 +40,7 @@ internal static partial class ConflictResolver
/// <param name="originalText">The original name of the identifier.</param>
/// <param name="replacementText">The new name of the identifier</param>
/// <param name="optionSet">The option for rename</param>
/// <param name="hasConflict">Called after renaming references. Can be used by callers to
/// <param name="hasConflict">Called after renaming references. Can be used by callers to
/// indicate if the new symbols that the reference binds to should be considered to be ok or
/// are in conflict. 'true' means they are conflicts. 'false' means they are not conflicts.
/// 'null' means that the default conflict check should be used.</param>
......@@ -181,14 +181,31 @@ private static bool IsRenameValid(ConflictResolution conflictResolution, ISymbol
{
try
{
var project = conflictResolution.NewSolution.GetProject(renamedSymbol.ContainingAssembly, cancellationToken);
if (renamedSymbol.ContainingSymbol.IsKind(SymbolKind.NamedType))
{
var otherThingsNamedTheSame = renamedSymbol.ContainingType.GetMembers(renamedSymbol.Name)
.Where(s => !s.Equals(renamedSymbol) &&
string.Equals(s.MetadataName, renamedSymbol.MetadataName, StringComparison.Ordinal) &&
(s.Kind != SymbolKind.Method || renamedSymbol.Kind != SymbolKind.Method));
string.Equals(s.MetadataName, renamedSymbol.MetadataName, StringComparison.Ordinal));
AddConflictingSymbolLocations(otherThingsNamedTheSame, conflictResolution, reverseMappedLocations);
IEnumerable<ISymbol> otherThingsNamedTheSameExcludeMethodAndParameterizedProperty;
// Possibly overloaded symbols are excluded here and handled elsewhere
var semanticFactsService = project.LanguageServices.GetService<ISemanticFactsService>();
if (semanticFactsService.SupportsParameterizedProperties)
{
otherThingsNamedTheSameExcludeMethodAndParameterizedProperty = otherThingsNamedTheSame
.Where(s=> !s.MatchesKind(SymbolKind.Method, SymbolKind.Property) ||
!renamedSymbol.MatchesKind(SymbolKind.Method, SymbolKind.Property));
}
else
{
otherThingsNamedTheSameExcludeMethodAndParameterizedProperty = otherThingsNamedTheSame
.Where(s => s.Kind != SymbolKind.Method || renamedSymbol.Kind != SymbolKind.Method);
}
AddConflictingSymbolLocations(otherThingsNamedTheSameExcludeMethodAndParameterizedProperty, conflictResolution, reverseMappedLocations);
}
......@@ -220,8 +237,6 @@ private static bool IsRenameValid(ConflictResolution conflictResolution, ISymbol
// Some types of symbols (namespaces, cref stuff, etc) might not have ContainingAssemblies
if (renamedSymbol.ContainingAssembly != null)
{
var project = conflictResolution.NewSolution.GetProject(renamedSymbol.ContainingAssembly, cancellationToken);
// There also might be language specific rules we need to include
var languageRenameService = project.LanguageServices.GetService<IRenameRewriterLanguageService>();
var languageConflicts = await languageRenameService.ComputeDeclarationConflictsAsync(
......
// 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.Linq;
......@@ -17,24 +18,53 @@ public static ImmutableArray<Location> GetMembersWithConflictingSignatures(IMeth
.OfType<IMethodSymbol>()
.Where(m => !m.Equals(renamedMethod) && m.Arity == renamedMethod.Arity);
var signatureToConflictingMember = new Dictionary<ImmutableArray<ITypeSymbol>, IMethodSymbol>(ConflictingSignatureComparer.Instance);
return GetConflictLocations(renamedMethod, potentiallyConfictingMethods, isMethod:true,
(method) => GetAllSignatures((method as IMethodSymbol).Parameters, trimOptionalParameters));
}
public static ImmutableArray<Location> GetMembersWithConflictingSignatures(IPropertySymbol renamedProperty, bool trimOptionalParameters)
{
var potentiallyConfictingProperties =
renamedProperty.ContainingType.GetMembers(renamedProperty.Name)
.OfType<IPropertySymbol>()
.Where(m => !m.Equals(renamedProperty) && m.Parameters.Count() == renamedProperty.Parameters.Count());
return GetConflictLocations(renamedProperty, potentiallyConfictingProperties, isMethod: false,
(property)=>GetAllSignatures((property as IPropertySymbol).Parameters, trimOptionalParameters));
}
private static ImmutableArray<Location> GetConflictLocations(ISymbol renamedMember,
IEnumerable<ISymbol> potentiallyConfictingMembers,
bool isMethod,
Func<ISymbol, ImmutableArray<ImmutableArray<ITypeSymbol>>> getAllSignatures)
{
var signatureToConflictingMember = new Dictionary<ImmutableArray<ITypeSymbol>, ISymbol>(ConflictingSignatureComparer.Instance);
foreach (var method in potentiallyConfictingMethods)
foreach (var member in potentiallyConfictingMembers)
{
foreach (var signature in GetAllSignatures(method, trimOptionalParameters))
foreach (var signature in getAllSignatures(member))
{
signatureToConflictingMember[signature] = method;
signatureToConflictingMember[signature] = member;
}
}
var builder = ArrayBuilder<Location>.GetInstance();
foreach (var signature in GetAllSignatures(renamedMethod, trimOptionalParameters))
foreach (var signature in getAllSignatures(renamedMember))
{
if (signatureToConflictingMember.TryGetValue(signature, out var conflictingSymbol))
{
if (!(conflictingSymbol.PartialDefinitionPart != null && conflictingSymbol.PartialDefinitionPart == renamedMethod) &&
!(conflictingSymbol.PartialImplementationPart != null && conflictingSymbol.PartialImplementationPart == renamedMethod))
if (isMethod)
{
var conflictingMethod = conflictingSymbol as IMethodSymbol;
var renamedMethod = renamedMember as IMethodSymbol;
if (!(conflictingMethod.PartialDefinitionPart != null && conflictingMethod.PartialDefinitionPart == renamedMethod) &&
!(conflictingMethod.PartialImplementationPart != null && conflictingMethod.PartialImplementationPart == renamedMethod))
{
builder.AddRange(conflictingSymbol.Locations);
}
}
else
{
builder.AddRange(conflictingSymbol.Locations);
}
......@@ -57,25 +87,20 @@ public bool Equals(ImmutableArray<ITypeSymbol> x, ImmutableArray<ITypeSymbol> y)
public int GetHashCode(ImmutableArray<ITypeSymbol> obj)
{
// This is a very simple GetHashCode implementation. Doing something "fancier" here
// isn't really worth it, since to compute a proper hash we'd end up walking all the
// ITypeSymbols anyways.
// This is a very simple GetHashCode implementation. Doing something "fancier" here
// isn't really worth it, since to compute a proper hash we'd end up walking all the
// ITypeSymbols anyways.
return obj.Length;
}
}
private static ImmutableArray<ImmutableArray<ITypeSymbol>> GetAllSignatures(IMethodSymbol method, bool trimOptionalParameters)
private static ImmutableArray<ImmutableArray<ITypeSymbol>> GetAllSignatures(ImmutableArray<IParameterSymbol> parameters, bool trimOptionalParameters)
{
var resultBuilder = ArrayBuilder<ImmutableArray<ITypeSymbol>>.GetInstance();
var signatureBuilder = ArrayBuilder<ITypeSymbol>.GetInstance();
if (method.MethodKind == MethodKind.Conversion)
{
signatureBuilder.Add(method.ReturnType);
}
foreach (var parameter in method.Parameters)
foreach (var parameter in parameters)
{
// In VB, a method effectively creates multiple signatures which are produced by
// chopping off each of the optional parameters on the end, last to first, per 4.1.1 of
......
......@@ -42,5 +42,14 @@
<Compile Include="..\ServiceHub\Shared\ServiceHubServiceBase.cs">
<Link>Shared\ServiceHubServiceBase.cs</Link>
</Compile>
<Compile Include="..\ServiceHub\Shared\Extensions.cs">
<Link>Shared\Extensions.cs</Link>
</Compile>
<Compile Include="..\ServiceHub\Shared\ClientDirectStream.cs">
<Link>Shared\ClientDirectStream.cs</Link>
</Compile>
<Compile Include="..\ServiceHub\Shared\ServerDirectStream.cs">
<Link>Shared\ServerDirectStream.cs</Link>
</Compile>
</ItemGroup>
</Project>
\ No newline at end of file
// 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 Microsoft.VisualStudio.Telemetry;
namespace Microsoft.VisualStudio.Telemetry
{
internal interface IFaultUtility
{
void AddProcessDump(int pid);
void AddFile(string fullpathname);
}
}
namespace Microsoft.CodeAnalysis.ErrorReporting
{
/// <summary>
/// dummy types just to make linked file work
/// </summary>
internal class WatsonReporter
{
public static void Report(string description, Exception exception)
{
// do nothing
}
public static void Report(string description, Exception exception, Func<IFaultUtility, int> callback)
{
// do nothing
}
}
}
......@@ -11,7 +11,7 @@ internal partial class CodeAnalysisService : ServiceHubServiceBase
public CodeAnalysisService(Stream stream, IServiceProvider serviceProvider) :
base(serviceProvider, stream)
{
Rpc.StartListening();
StartService();
}
}
}
......@@ -61,8 +61,8 @@ public SymbolSearchService(CodeAnalysisService codeAnalysisService)
public async Task<IList<PackageWithTypeResult>> FindPackagesWithTypeAsync(
string source, string name, int arity, CancellationToken cancellationToken)
{
var result = await codeAnalysisService.Rpc.InvokeAsync<IList<PackageWithTypeResult>>(
nameof(FindPackagesWithTypeAsync), source, name, arity).ConfigureAwait(false);
var result = await codeAnalysisService.InvokeAsync<IList<PackageWithTypeResult>>(
nameof(FindPackagesWithTypeAsync), new object[] { source, name, arity }, cancellationToken).ConfigureAwait(false);
return result;
}
......@@ -70,8 +70,8 @@ public SymbolSearchService(CodeAnalysisService codeAnalysisService)
public async Task<IList<PackageWithAssemblyResult>> FindPackagesWithAssemblyAsync(
string source, string assemblyName, CancellationToken cancellationToken)
{
var result = await codeAnalysisService.Rpc.InvokeAsync<IList<PackageWithAssemblyResult>>(
nameof(FindPackagesWithAssemblyAsync), source, assemblyName).ConfigureAwait(false);
var result = await codeAnalysisService.InvokeAsync<IList<PackageWithAssemblyResult>>(
nameof(FindPackagesWithAssemblyAsync), new object[] { source, assemblyName }, cancellationToken).ConfigureAwait(false);
return result;
}
......@@ -79,8 +79,8 @@ public SymbolSearchService(CodeAnalysisService codeAnalysisService)
public async Task<IList<ReferenceAssemblyWithTypeResult>> FindReferenceAssembliesWithTypeAsync(
string name, int arity, CancellationToken cancellationToken)
{
var result = await codeAnalysisService.Rpc.InvokeAsync<IList<ReferenceAssemblyWithTypeResult>>(
nameof(FindReferenceAssembliesWithTypeAsync), name, arity).ConfigureAwait(false);
var result = await codeAnalysisService.InvokeAsync<IList<ReferenceAssemblyWithTypeResult>>(
nameof(FindReferenceAssembliesWithTypeAsync), new object[] { name, arity }, cancellationToken).ConfigureAwait(false);
return result;
}
......
......@@ -168,10 +168,10 @@ public FindLiteralReferencesProgressCallback(CodeAnalysisService service)
}
public Task ReportProgressAsync(int current, int maximum)
=> _service.Rpc.InvokeAsync(nameof(ReportProgressAsync), current, maximum);
=> _service.InvokeAsync(nameof(ReportProgressAsync), new object[] { current, maximum }, CancellationToken.None);
public Task OnReferenceFoundAsync(Document document, TextSpan span)
=> _service.Rpc.InvokeAsync(nameof(OnReferenceFoundAsync), document.Id, span);
=> _service.InvokeAsync(nameof(OnReferenceFoundAsync), new object[] { document.Id, span }, CancellationToken.None);
}
private class FindReferencesProgressCallback : IStreamingFindReferencesProgress
......@@ -184,30 +184,29 @@ public FindReferencesProgressCallback(CodeAnalysisService service)
}
public Task OnStartedAsync()
=> _service.Rpc.InvokeAsync(nameof(OnStartedAsync));
=> _service.InvokeAsync(nameof(OnStartedAsync), CancellationToken.None);
public Task OnCompletedAsync()
=> _service.Rpc.InvokeAsync(nameof(OnCompletedAsync));
=> _service.InvokeAsync(nameof(OnCompletedAsync), CancellationToken.None);
public Task ReportProgressAsync(int current, int maximum)
=> _service.Rpc.InvokeAsync(nameof(ReportProgressAsync), current, maximum);
=> _service.InvokeAsync(nameof(ReportProgressAsync), new object[] { current, maximum }, CancellationToken.None);
public Task OnFindInDocumentStartedAsync(Document document)
=> _service.Rpc.InvokeAsync(nameof(OnFindInDocumentStartedAsync), document.Id);
=> _service.InvokeAsync(nameof(OnFindInDocumentStartedAsync), new object[] { document.Id }, CancellationToken.None);
public Task OnFindInDocumentCompletedAsync(Document document)
=> _service.Rpc.InvokeAsync(nameof(OnFindInDocumentCompletedAsync), document.Id);
=> _service.InvokeAsync(nameof(OnFindInDocumentCompletedAsync), new object[] { document.Id }, CancellationToken.None);
public Task OnDefinitionFoundAsync(SymbolAndProjectId definition)
=> _service.Rpc.InvokeAsync(nameof(OnDefinitionFoundAsync),
SerializableSymbolAndProjectId.Dehydrate(definition));
=> _service.InvokeAsync(nameof(OnDefinitionFoundAsync), new object[] { SerializableSymbolAndProjectId.Dehydrate(definition) }, CancellationToken.None);
public Task OnReferenceFoundAsync(
SymbolAndProjectId definition, ReferenceLocation reference)
{
return _service.Rpc.InvokeAsync(nameof(OnReferenceFoundAsync),
SerializableSymbolAndProjectId.Dehydrate(definition),
SerializableReferenceLocation.Dehydrate(reference));
return _service.InvokeAsync(nameof(OnReferenceFoundAsync),
new object[] { SerializableSymbolAndProjectId.Dehydrate(definition), SerializableReferenceLocation.Dehydrate(reference) },
CancellationToken.None);
}
}
}
......
......@@ -57,7 +57,7 @@ static RemoteHostService()
base(serviceProvider, stream)
{
// this service provide a way for client to make sure remote host is alive
Rpc.StartListening();
StartService();
}
public string Connect(string host, int uiCultureLCID, int cultureLCID, string serializedSession, CancellationToken cancellationToken)
......
......@@ -21,7 +21,7 @@ public RemoteSymbolSearchUpdateEngine(Stream stream, IServiceProvider servicePro
_updateEngine = new SymbolSearchUpdateEngine(
logService: this, progressService: this);
Rpc.StartListening();
StartService();
}
public Task UpdateContinuouslyAsync(string sourceName, string localSettingsDirectory)
......@@ -68,22 +68,22 @@ public Task<IList<ReferenceAssemblyWithTypeResult>> FindReferenceAssembliesWithT
#region Messages to forward from here to VS
public Task LogExceptionAsync(string exception, string text)
=> this.Rpc.InvokeAsync(nameof(LogExceptionAsync), exception, text);
=> this.InvokeAsync(nameof(LogExceptionAsync), new object[] { exception, text }, CancellationToken.None);
public Task LogInfoAsync(string text)
=> this.Rpc.InvokeAsync(nameof(LogInfoAsync), text);
=> this.InvokeAsync(nameof(LogInfoAsync), new object[] { text }, CancellationToken.None);
public Task OnDownloadFullDatabaseStartedAsync(string title)
=> this.Rpc.InvokeAsync(nameof(OnDownloadFullDatabaseStartedAsync), title);
=> this.InvokeAsync(nameof(OnDownloadFullDatabaseStartedAsync), new object[] { title }, CancellationToken.None);
public Task OnDownloadFullDatabaseSucceededAsync()
=> this.Rpc.InvokeAsync(nameof(OnDownloadFullDatabaseSucceededAsync));
=> this.InvokeAsync(nameof(OnDownloadFullDatabaseSucceededAsync), CancellationToken.None);
public Task OnDownloadFullDatabaseCanceledAsync()
=> this.Rpc.InvokeAsync(nameof(OnDownloadFullDatabaseCanceledAsync));
=> this.InvokeAsync(nameof(OnDownloadFullDatabaseCanceledAsync), CancellationToken.None);
public Task OnDownloadFullDatabaseFailedAsync(string message)
=> this.Rpc.InvokeAsync(nameof(OnDownloadFullDatabaseFailedAsync), message);
=> this.InvokeAsync(nameof(OnDownloadFullDatabaseFailedAsync), new object[] { message }, CancellationToken.None);
#endregion
}
......
......@@ -38,7 +38,7 @@ public override async Task<IList<(Checksum, object)>> RequestAssetsAsync(int sco
{
return await _owner.RunServiceAsync(cancellationToken =>
{
return _owner.Rpc.InvokeAsync(WellKnownServiceHubServices.AssetService_RequestAssetAsync,
return _owner.InvokeAsync(WellKnownServiceHubServices.AssetService_RequestAssetAsync,
new object[] { scopeId, checksums.ToArray() },
(s, c) => ReadAssets(s, scopeId, checksums, serializerService, c), cancellationToken);
}, callerCancellation).ConfigureAwait(false);
......@@ -52,8 +52,7 @@ public override async Task<IList<(Checksum, object)>> RequestAssetsAsync(int sco
private bool ReportUnlessCanceled(Exception ex, CancellationToken cancellationToken)
{
if (!cancellationToken.IsCancellationRequested &&
((IDisposableObservable)_owner.Rpc).IsDisposed)
if (!cancellationToken.IsCancellationRequested && _owner.IsDisposed)
{
// kill OOP if snapshot service got disconnected due to this exception.
FailFast.OnFatalException(ex);
......
......@@ -19,7 +19,7 @@ internal partial class SnapshotService : ServiceHubServiceBase
{
_source = new JsonRpcAssetSource(this);
Rpc.StartListening();
StartService();
}
}
}
// 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.Diagnostics;
using System.IO;
using System.Reflection;
......@@ -20,14 +21,17 @@ internal abstract class ServiceHubServiceBase : IDisposable
private static int s_instanceId;
private readonly CancellationTokenSource _shutdownCancellationSource;
private readonly JsonRpc _rpc;
protected readonly int InstanceId;
protected readonly JsonRpc Rpc;
protected readonly TraceSource Logger;
protected readonly AssetStorage AssetStorage;
protected readonly CancellationToken ShutdownCancellationToken;
[Obsolete("don't use RPC directly but use it through StartService and InvokeAsync", error: true)]
protected readonly JsonRpc Rpc;
/// <summary>
/// PinnedSolutionInfo.ScopeId. scope id of the solution. caller and callee share this id which one
/// can use to find matching caller and callee while exchanging data
......@@ -62,9 +66,14 @@ protected ServiceHubServiceBase(IServiceProvider serviceProvider, Stream stream)
// due to this issue - https://github.com/dotnet/roslyn/issues/16900#issuecomment-277378950
// all sub type must explicitly start JsonRpc once everything is
// setup
Rpc = new JsonRpc(new JsonRpcMessageHandler(stream, stream), this);
Rpc.JsonSerializer.Converters.Add(AggregateJsonConverter.Instance);
Rpc.Disconnected += OnRpcDisconnected;
_rpc = new JsonRpc(new JsonRpcMessageHandler(stream, stream), this);
_rpc.JsonSerializer.Converters.Add(AggregateJsonConverter.Instance);
_rpc.Disconnected += OnRpcDisconnected;
// we do this since we want to mark Rpc as obsolete but want to set its value for
// partner teams until they move. we can't use Rpc directly since we will get
// obsolete error and we can't suppress it since it is an error
this.GetType().GetField("Rpc", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(this, _rpc);
}
protected string DebugInstanceString => $"{GetType()} ({InstanceId})";
......@@ -82,6 +91,37 @@ protected RoslynServices RoslynServices
}
}
protected bool IsDisposed => ((IDisposableObservable)_rpc).IsDisposed;
protected void StartService()
{
_rpc.StartListening();
}
protected Task<TResult> InvokeAsync<TResult>(
string targetName, IReadOnlyList<object> arguments, CancellationToken cancellationToken)
{
return _rpc.InvokeWithCancellationAsync<TResult>(targetName, arguments, cancellationToken);
}
protected Task<TResult> InvokeAsync<TResult>(
string targetName, IReadOnlyList<object> arguments,
Func<Stream, CancellationToken, TResult> funcWithDirectStream, CancellationToken cancellationToken)
{
return Extensions.InvokeAsync(_rpc, targetName, arguments, funcWithDirectStream, cancellationToken);
}
protected Task InvokeAsync(string targetName, CancellationToken cancellationToken)
{
return InvokeAsync(targetName, SpecializedCollections.EmptyReadOnlyList<object>(), cancellationToken);
}
protected Task InvokeAsync(
string targetName, IReadOnlyList<object> arguments, CancellationToken cancellationToken)
{
return _rpc.InvokeWithCancellationAsync(targetName, arguments, cancellationToken);
}
protected Task<Solution> GetSolutionAsync(CancellationToken cancellationToken)
{
Contract.ThrowIfNull(_solutionInfo);
......@@ -123,7 +163,7 @@ public void Dispose()
}
_disposed = true;
Rpc.Dispose();
_rpc.Dispose();
_shutdownCancellationSource.Dispose();
Dispose(disposing: true);
......
......@@ -731,6 +731,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.Rename
.Select(Function(loc) reverseMappedLocations(loc)))
ElseIf renamedSymbol.Kind = SymbolKind.Property Then
conflicts.AddRange(
DeclarationConflictHelpers.GetMembersWithConflictingSignatures(DirectCast(renamedSymbol, IPropertySymbol), trimOptionalParameters:=True) _
.Select(Function(loc) reverseMappedLocations(loc)))
ConflictResolver.AddConflictingParametersOfProperties(
referencedSymbols.Select(Function(s) s.Symbol).Concat(renameSymbol).Where(Function(sym) sym.Kind = SymbolKind.Property),
renamedSymbol.Name,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册