Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
c0d6afc
Fix VisualStudioActiveDocumentTracker to handle frames without text b…
mavasani Dec 1, 2021
967883d
Add comment
mavasani Dec 2, 2021
05b7f37
Respond to changes in project context to support w/out navbar and mul…
dibarbet Dec 3, 2021
51113bf
Update Microsoft.CodeAnalysis.Analyzers to 3.3.3
Youssef1313 Dec 7, 2021
00c1668
Disable RS1034
Youssef1313 Dec 7, 2021
9666b7d
Update Roslyn.Diagnostics.Analyzers to latest stable
Youssef1313 Dec 7, 2021
8bf87bc
Revert Roslyn.Diagnostics.Analyzers back
Youssef1313 Dec 7, 2021
1a709f3
Simplify lazy initialization in RazorDocumentServiceProviderWrapper
sharwell Dec 1, 2021
2a9610b
Implement overloads of LazyInitialization.EnsureInitialized which sup…
sharwell Dec 7, 2021
ec459b7
Address feedback
Youssef1313 Dec 8, 2021
0a0c7b9
Clarify use of null as an initialized value
sharwell Dec 8, 2021
e91fd74
Fix generator caching in compiler server (#57177)
chsienki Dec 9, 2021
0615a77
Merge pull request #58063 from sharwell/lazy-init
sharwell Dec 9, 2021
f473056
OmniSharp options (#58208)
tmat Dec 9, 2021
9f82509
Merge pull request #58195 from dibarbet/lsp_proj_context
dibarbet Dec 9, 2021
2ee4427
Avoid calculating inferred delegate type unnecessarily in conversions…
cston Dec 9, 2021
39e010e
Merge pull request #58154 from Youssef1313/patch-24
sharwell Dec 9, 2021
f49697a
Update several ExpressionCompiler unit tests for inferred delegate ty…
cston Dec 9, 2021
f619079
Merge pull request #58049 from mavasani/ActiveDocTracker
mavasani Dec 9, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
<VisualStudioEditorNewPackagesVersion>17.0.487</VisualStudioEditorNewPackagesVersion>
<ILAsmPackageVersion>5.0.0-alpha1.19409.1</ILAsmPackageVersion>
<ILDAsmPackageVersion>5.0.0-preview.1.20112.8</ILDAsmPackageVersion>
<MicrosoftVisualStudioLanguageServerProtocolPackagesVersion>17.0.5133-g7b8c8bd49d</MicrosoftVisualStudioLanguageServerProtocolPackagesVersion>
<MicrosoftVisualStudioLanguageServerProtocolPackagesVersion>17.1.3</MicrosoftVisualStudioLanguageServerProtocolPackagesVersion>
<MicrosoftVisualStudioShellPackagesVersion>17.0.31723.112</MicrosoftVisualStudioShellPackagesVersion>
<RefOnlyMicrosoftBuildPackagesVersion>16.5.0</RefOnlyMicrosoftBuildPackagesVersion>
<!-- The version of Roslyn we build Source Generators against that are built in this
Expand Down Expand Up @@ -79,7 +79,7 @@
packages we will keep it untied to the RoslynDiagnosticsNugetPackageVersion we use for
other analyzers to ensure it stays on a release version.
-->
<MicrosoftCodeAnalysisAnalyzersVersion>3.3.2</MicrosoftCodeAnalysisAnalyzersVersion>
<MicrosoftCodeAnalysisAnalyzersVersion>3.3.3</MicrosoftCodeAnalysisAnalyzersVersion>
<MicrosoftCodeAnalysisBuildTasksVersion>2.0.0-rc2-61102-09</MicrosoftCodeAnalysisBuildTasksVersion>
<MicrosoftCodeAnalysisCSharpAnalyzerTestingXUnitVersion>$(MicrosoftCodeAnalysisTestingVersion)</MicrosoftCodeAnalysisCSharpAnalyzerTestingXUnitVersion>
<MicrosoftCodeAnalysisCSharpCodeFixTestingXUnitVersion>$(MicrosoftCodeAnalysisTestingVersion)</MicrosoftCodeAnalysisCSharpCodeFixTestingXUnitVersion>
Expand Down
4 changes: 4 additions & 0 deletions eng/config/globalconfigs/Common.globalconfig
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ dotnet_diagnostic.RS1022.severity = none
# RS1024: Compare symbols correctly
dotnet_diagnostic.RS1024.severity = refactoring

# RS1034: Prefer 'IsKind' for checking syntax kinds
# Hold on https://github.com/dotnet/roslyn/pull/51823#pullrequestreview-612747491
dotnet_diagnostic.RS1034.severity = none

dotnet_diagnostic.AD0001.severity = error

dotnet_diagnostic.RS0001.severity = warning
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1931,7 +1931,7 @@ internal void GenerateAnonymousFunctionConversionError(BindingDiagnosticBag diag
}

if (anonymousFunction.FunctionType is { } functionType &&
functionType.GetValue() is null)
functionType.GetInternalDelegateType() is null)
{
var discardedUseSiteInfo = CompoundUseSiteInfo<AssemblySymbol>.Discarded;
if (Conversions.IsValidFunctionTypeConversionTarget(targetType, ref discardedUseSiteInfo))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,9 @@ public static NullableFlowState GetNullableState(ArrayBuilder<TypeWithState> typ

if (result is FunctionTypeSymbol functionType)
{
inferredFromFunctionType = true;
return functionType.GetInternalDelegateType();
result = functionType.GetInternalDelegateType();
inferredFromFunctionType = result is { };
return result;
}

inferredFromFunctionType = false;
Expand Down Expand Up @@ -182,14 +183,18 @@ public static NullableFlowState GetNullableState(ArrayBuilder<TypeWithState> typ
case 0:
return null;
case 1:
return types[0];
return checkType(types[0]);
}

TypeSymbol? best = null;
int bestIndex = -1;
for (int i = 0; i < types.Count; i++)
{
TypeSymbol type = types[i];
TypeSymbol? type = checkType(types[i]);
if (type is null)
{
continue;
}
if (best is null)
{
best = type;
Expand Down Expand Up @@ -220,7 +225,11 @@ public static NullableFlowState GetNullableState(ArrayBuilder<TypeWithState> typ
// that every type *before* best was also worse.
for (int i = 0; i < bestIndex; i++)
{
TypeSymbol type = types[i];
TypeSymbol? type = checkType(types[i]);
if (type is null)
{
continue;
}
TypeSymbol? better = Better(best, type, conversions, ref useSiteInfo);
if (!best.Equals(better, TypeCompareKind.IgnoreNullableModifiersForReferenceTypes))
{
Expand All @@ -229,6 +238,11 @@ public static NullableFlowState GetNullableState(ArrayBuilder<TypeWithState> typ
}

return best;

static TypeSymbol? checkType(TypeSymbol type) =>
type is FunctionTypeSymbol functionType && functionType.GetInternalDelegateType() is null ?
null :
type;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2669,7 +2669,8 @@ private bool HasImplicitFunctionTypeConversion(FunctionTypeSymbol source, TypeSy
return HasImplicitFunctionTypeToFunctionTypeConversion(source, destinationFunctionType, ref useSiteInfo);
}

return IsValidFunctionTypeConversionTarget(destination, ref useSiteInfo);
return IsValidFunctionTypeConversionTarget(destination, ref useSiteInfo) &&
source.GetInternalDelegateType() is { };
}

internal bool IsValidFunctionTypeConversionTarget(TypeSymbol destination, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo)
Expand Down Expand Up @@ -2697,7 +2698,16 @@ internal bool IsValidFunctionTypeConversionTarget(TypeSymbol destination, ref Co
private bool HasImplicitFunctionTypeToFunctionTypeConversion(FunctionTypeSymbol sourceType, FunctionTypeSymbol destinationType, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo)
{
var sourceDelegate = sourceType.GetInternalDelegateType();
if (sourceDelegate is null)
{
return false;
}

var destinationDelegate = destinationType.GetInternalDelegateType();
if (destinationDelegate is null)
{
return false;
}

// https://github.com/dotnet/roslyn/issues/55909: We're relying on the variance of
// FunctionTypeSymbol.GetInternalDelegateType() which fails for synthesized
Expand Down Expand Up @@ -2848,13 +2858,14 @@ private bool HasAnyBaseInterfaceConversion(TypeSymbol derivedType, TypeSymbol ba
// * if the ith parameter of U is contravariant then either Si is exactly
// equal to Ti, or there is an implicit reference conversion from Ti to Si.

#nullable enable
private bool HasInterfaceVarianceConversion(TypeSymbol source, TypeSymbol destination, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo)
{
Debug.Assert((object)source != null);
Debug.Assert((object)destination != null);
NamedTypeSymbol s = source as NamedTypeSymbol;
NamedTypeSymbol d = destination as NamedTypeSymbol;
if ((object)s == null || (object)d == null)
NamedTypeSymbol? s = source as NamedTypeSymbol;
NamedTypeSymbol? d = destination as NamedTypeSymbol;
if (s is null || d is null)
{
return false;
}
Expand All @@ -2871,9 +2882,9 @@ private bool HasDelegateVarianceConversion(TypeSymbol source, TypeSymbol destina
{
Debug.Assert((object)source != null);
Debug.Assert((object)destination != null);
NamedTypeSymbol s = source as NamedTypeSymbol;
NamedTypeSymbol d = destination as NamedTypeSymbol;
if ((object)s == null || (object)d == null)
NamedTypeSymbol? s = source as NamedTypeSymbol;
NamedTypeSymbol? d = destination as NamedTypeSymbol;
if (s is null || d is null)
{
return false;
}
Expand Down Expand Up @@ -3150,7 +3161,6 @@ internal static bool HasImplicitPointerToVoidConversion(TypeSymbol source, TypeS
return source.IsPointerOrFunctionPointer() && destination is PointerTypeSymbol { PointedAtType: { SpecialType: SpecialType.System_Void } };
}

#nullable enable
internal bool HasImplicitPointerConversion(TypeSymbol? source, TypeSymbol? destination, ref CompoundUseSiteInfo<AssemblySymbol> useSiteInfo)
{
if (!(source is FunctionPointerTypeSymbol { Signature: { } sourceSig })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2664,9 +2664,12 @@ private static (TypeWithAnnotations Type, bool FromFunctionType) Fix(
if (containsFunctionTypes(lower) &&
(containsNonFunctionTypes(lower) || containsNonFunctionTypes(exact) || containsNonFunctionTypes(upper)))
{
lower = removeFunctionTypes(lower);
lower = removeTypes(lower, static type => isFunctionType(type, out _));
}

// Remove any function types with no delegate type.
lower = removeTypes(lower, static type => isFunctionType(type, out var functionType) && functionType.GetInternalDelegateType() is null);

// Optimization: if we have one exact bound then we need not add any
// inexact bounds; we're just going to remove them anyway.

Expand Down Expand Up @@ -2806,12 +2809,16 @@ static bool isExpressionType(TypeSymbol? type)
return false;
}

static HashSet<TypeWithAnnotations>? removeFunctionTypes(HashSet<TypeWithAnnotations> types)
static HashSet<TypeWithAnnotations>? removeTypes(HashSet<TypeWithAnnotations>? types, Func<TypeWithAnnotations, bool> predicate)
{
if (types is null)
{
return null;
}
HashSet<TypeWithAnnotations>? updated = null;
foreach (var type in types)
{
if (!isFunctionType(type, out _))
if (!predicate(type))
{
updated ??= new HashSet<TypeWithAnnotations>(TypeWithAnnotations.EqualsComparer.ConsiderEverythingComparer);
updated.Add(type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,12 @@ public static bool HasDynamicType(this BoundExpression node)

public static FunctionTypeSymbol? GetFunctionType(this BoundExpression expr)
{
var lazyType = expr switch
return expr switch
{
BoundMethodGroup methodGroup => methodGroup.FunctionType,
UnboundLambda unboundLambda => unboundLambda.FunctionType,
_ => null
};
return lazyType?.GetValue();
}

public static bool MethodGroupReceiverIsDynamic(this BoundMethodGroup node)
Expand Down
6 changes: 3 additions & 3 deletions src/Compilers/CSharp/Portable/BoundTree/BoundMethodGroup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ public BoundMethodGroup(
BoundMethodGroupFlags flags,
Binder binder,
bool hasErrors = false)
: this(syntax, typeArgumentsOpt, name, methods, lookupResult.SingleSymbolOrDefault, lookupResult.Error, flags, functionType: GetLazyFunctionType(binder, syntax), receiverOpt, lookupResult.Kind, hasErrors)
: this(syntax, typeArgumentsOpt, name, methods, lookupResult.SingleSymbolOrDefault, lookupResult.Error, flags, functionType: GetFunctionType(binder, syntax), receiverOpt, lookupResult.Kind, hasErrors)
{
FunctionType?.SetExpression(this);
}

private static FunctionTypeSymbol.Lazy? GetLazyFunctionType(Binder binder, SyntaxNode syntax)
private static FunctionTypeSymbol? GetFunctionType(Binder binder, SyntaxNode syntax)
{
return FunctionTypeSymbol.Lazy.CreateIfFeatureEnabled(syntax, binder, static (binder, expr) => binder.GetMethodGroupDelegateType((BoundMethodGroup)expr));
return FunctionTypeSymbol.CreateIfFeatureEnabled(syntax, binder, static (binder, expr) => binder.GetMethodGroupDelegateType((BoundMethodGroup)expr));
}

public MemberAccessExpressionSyntax? MemberAccessExpressionSyntax
Expand Down
4 changes: 2 additions & 2 deletions src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1704,7 +1704,7 @@
<Field Name="LookupSymbolOpt" Type="Symbol?"/>
<Field Name="LookupError" Type="DiagnosticInfo?"/>
<Field Name="Flags" Type="BoundMethodGroupFlags?"/>
<Field Name="FunctionType" Type="FunctionTypeSymbol.Lazy?" Null="allow"/>
<Field Name="FunctionType" Type="FunctionTypeSymbol?" Null="allow"/>
</Node>

<Node Name="BoundPropertyGroup" Base="BoundMethodOrPropertyGroup">
Expand Down Expand Up @@ -2117,7 +2117,7 @@
<!-- Type is not significant for this node type; always null -->
<Field Name="Type" Type="TypeSymbol?" Override="true" Null="always"/>
<Field Name="Data" Type="UnboundLambdaState" Null="disallow"/>
<Field Name="FunctionType" Type="FunctionTypeSymbol.Lazy?" Null="allow"/>
<Field Name="FunctionType" Type="FunctionTypeSymbol?" Null="allow"/>
<!-- Track dependencies while binding body, etc. -->
<Field Name="WithDependencies" Type="Boolean"/>
</Node>
Expand Down
6 changes: 3 additions & 3 deletions src/Compilers/CSharp/Portable/BoundTree/UnboundLambda.cs
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,8 @@ private static TypeWithAnnotations CalculateReturnType(
var bestType = returns[0].expr.GetTypeOrFunctionType();
if (bestType is FunctionTypeSymbol functionType)
{
inferredFromFunctionType = true;
bestType = functionType.GetInternalDelegateType();
inferredFromFunctionType = bestType is { };
}
else
{
Expand Down Expand Up @@ -390,15 +390,15 @@ public static UnboundLambda Create(
Debug.Assert(syntax.IsAnonymousFunction());
bool hasErrors = !types.IsDefault && types.Any(t => t.Type?.Kind == SymbolKind.ErrorType);

var functionType = FunctionTypeSymbol.Lazy.CreateIfFeatureEnabled(syntax, binder, static (binder, expr) => ((UnboundLambda)expr).Data.InferDelegateType());
var functionType = FunctionTypeSymbol.CreateIfFeatureEnabled(syntax, binder, static (binder, expr) => ((UnboundLambda)expr).Data.InferDelegateType());
var data = new PlainUnboundLambdaState(binder, returnRefKind, returnType, parameterAttributes, names, discardsOpt, types, refKinds, isAsync, isStatic, includeCache: true);
var lambda = new UnboundLambda(syntax, data, functionType, withDependencies, hasErrors: hasErrors);
data.SetUnboundLambda(lambda);
functionType?.SetExpression(lambda.WithNoCache());
return lambda;
}

private UnboundLambda(SyntaxNode syntax, UnboundLambdaState state, FunctionTypeSymbol.Lazy? functionType, bool withDependencies, NullableWalker.VariableState? nullableState, bool hasErrors) :
private UnboundLambda(SyntaxNode syntax, UnboundLambdaState state, FunctionTypeSymbol? functionType, bool withDependencies, NullableWalker.VariableState? nullableState, bool hasErrors) :
this(syntax, state, functionType, withDependencies, hasErrors)
{
this._nullableState = nullableState;
Expand Down
20 changes: 4 additions & 16 deletions src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,23 +140,11 @@ internal Conversions Conversions
private ImmutableHashSet<SyntaxTree>? _usageOfUsingsRecordedInTrees = ImmutableHashSet<SyntaxTree>.Empty;

/// <summary>
/// Nullable analysis data for methods, parameter default values, and attributes.
/// The key is a symbol for methods or parameters, and syntax for attributes.
/// The data is collected during testing only.
/// Optional data collected during testing only.
/// Used for instance for nullable analysis (<see cref="NullableWalker.NullableAnalysisData"/>)
/// and inferred delegate types (<see cref="InferredDelegateTypeData"/>).
/// </summary>
internal NullableData? NullableAnalysisData;

internal sealed class NullableData
{
internal readonly int MaxRecursionDepth;
internal readonly ConcurrentDictionary<object, NullableWalker.Data> Data;

internal NullableData(int maxRecursionDepth = -1)
{
MaxRecursionDepth = maxRecursionDepth;
Data = new ConcurrentDictionary<object, NullableWalker.Data>();
}
}
internal object? TestOnlyCompilationData;

internal ImmutableHashSet<SyntaxTree>? UsageOfUsingsRecordedInTrees => Volatile.Read(ref _usageOfUsingsRecordedInTrees);

Expand Down
30 changes: 25 additions & 5 deletions src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
Expand All @@ -24,6 +25,23 @@ namespace Microsoft.CodeAnalysis.CSharp
internal sealed partial class NullableWalker
: LocalDataFlowPass<NullableWalker.LocalState, NullableWalker.LocalFunctionState>
{
/// <summary>
/// Nullable analysis data for methods, parameter default values, and attributes
/// stored on the Compilation during testing only.
/// The key is a symbol for methods or parameters, and syntax for attributes.
/// </summary>
internal sealed class NullableAnalysisData
{
internal readonly int MaxRecursionDepth;
internal readonly ConcurrentDictionary<object, NullableWalker.Data> Data;

internal NullableAnalysisData(int maxRecursionDepth = -1)
{
MaxRecursionDepth = maxRecursionDepth;
Data = new ConcurrentDictionary<object, NullableWalker.Data>();
}
}

/// <summary>
/// Used to copy variable slots and types from the NullableWalker for the containing method
/// or lambda to the NullableWalker created for a nested lambda or local function.
Expand Down Expand Up @@ -428,7 +446,7 @@ public string GetDebuggerDisplay()
protected override void EnsureSufficientExecutionStack(int recursionDepth)
{
if (recursionDepth > StackGuard.MaxUncheckedRecursionDepth &&
compilation.NullableAnalysisData is { MaxRecursionDepth: var depth } &&
compilation.TestOnlyCompilationData is NullableAnalysisData { MaxRecursionDepth: var depth } &&
depth > 0 &&
recursionDepth > depth)
{
Expand Down Expand Up @@ -1511,7 +1529,7 @@ private static void Analyze(

private void RecordNullableAnalysisData(Symbol? symbol, bool requiredAnalysis)
{
if (compilation.NullableAnalysisData?.Data is { } state)
if (compilation.TestOnlyCompilationData is NullableAnalysisData { Data: { } state })
{
var key = (object?)symbol ?? methodMainNode.Syntax;
if (state.TryGetValue(key, out var result))
Expand Down Expand Up @@ -1690,9 +1708,11 @@ protected override int MakeSlot(BoundExpression node)
TypeSymbol? nodeType = node.Type;
var discardedUseSiteInfo = CompoundUseSiteInfo<AssemblySymbol>.Discarded;
var conversionsWithoutNullability = this.compilation.Conversions;
Debug.Assert(node.HasErrors || nodeType!.IsErrorType() ||
conversionsWithoutNullability.HasIdentityOrImplicitReferenceConversion(slotType, nodeType, ref discardedUseSiteInfo) ||
conversionsWithoutNullability.HasBoxingConversion(slotType, nodeType, ref discardedUseSiteInfo));
Debug.Assert(node.HasErrors ||
(nodeType is { } &&
(nodeType.IsErrorType() ||
conversionsWithoutNullability.HasIdentityOrImplicitReferenceConversion(slotType, nodeType, ref discardedUseSiteInfo) ||
conversionsWithoutNullability.HasBoxingConversion(slotType, nodeType, ref discardedUseSiteInfo))));
}
#endif
return result;
Expand Down
Loading