未验证 提交 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()
......@@ -14,6 +14,12 @@ 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
......@@ -69,3 +75,12 @@ jobs:
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,8 +607,18 @@ 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)
{
case BoundKind.Conversion:
{
var operandConversion = (BoundConversion)operandOpt;
return isSupportedConversion(operandConversion.Conversion, operandConversion.Operand);
}
case BoundKind.ConvertedTupleLiteral:
{
var arguments = ((BoundConvertedTupleLiteral)operandOpt).Arguments;
var conversions = conversion.UnderlyingConversions;
......@@ -614,7 +633,11 @@ bool isSupportedConversion(Conversion conversion, BoundExpression operandOpt)
}
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);
slot = GetOrCreateObjectCreationPlaceholderSlot(node);
if (slot > 0)
{
var constructor = (node as BoundObjectCreationExpression)?.Constructor;
bool isDefaultValueTypeConstructor = constructor?.IsDefaultValueTypeConstructor() == true;
if (!type.IsValueType || isTrackableStructType)
{
slot = GetOrCreateObjectCreationPlaceholderSlot(node);
if (slot > 0 && isTrackableStructType)
if (EmptyStructTypeCache.IsTrackableStructType(type))
{
this.State[slot] = NullableFlowState.NotNull;
var tupleType = constructor?.ContainingType as TupleTypeSymbol;
......@@ -1428,7 +1467,6 @@ public override BoundNode VisitObjectCreationExpression(BoundObjectCreationExpre
isDefaultValue: isDefaultValueTypeConstructor);
}
}
}
else if (type.IsNullableType())
{
if (isDefaultValueTypeConstructor)
......@@ -1447,6 +1485,7 @@ public override BoundNode VisitObjectCreationExpression(BoundObjectCreationExpre
}
}
}
}
if (initializerOpt != null)
{
......@@ -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;
......
......@@ -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")>
......
......@@ -56,6 +56,11 @@ public bool IsExperimentEnabled(string experimentName)
if (_isCachedFlightEnabledInfo != null)
{
try
{
// 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)
{
var enabled = _featureFlags.IsFeatureEnabled(experimentName, defaultValue: false);
if (enabled)
......@@ -63,6 +68,7 @@ public bool IsExperimentEnabled(string experimentName)
return enabled;
}
}
}
catch
{
// featureFlags can throw if given name is in incorrect format which can happen for us
......
......@@ -259,7 +259,7 @@ private class TestService : ServiceHubServiceBase
{
Event = new ManualResetEvent(false);
Rpc.StartListening();
StartService();
}
public readonly ManualResetEvent Event;
......
......@@ -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);
}
......@@ -64,18 +94,13 @@ public int GetHashCode(ImmutableArray<ITypeSymbol> obj)
}
}
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.
先完成此消息的编辑!
想要评论请 注册