未验证 提交 8a0c1f46 编写于 作者: J Jason Malinowski 提交者: GitHub

Merge pull request #46529 from jasonmalinowski/null-annotate-symbolkey

Null annotate SymbolKey and a bit more of the compiler
......@@ -250,7 +250,7 @@ public LanguageVersion LanguageVersion
get;
}
protected override INamedTypeSymbol CommonCreateErrorTypeSymbol(INamespaceOrTypeSymbol container, string name, int arity)
protected override INamedTypeSymbol CommonCreateErrorTypeSymbol(INamespaceOrTypeSymbol? container, string name, int arity)
{
return new ExtendedErrorTypeSymbol(
container.EnsureCSharpSymbolOrNull(nameof(container)),
......
......@@ -213,7 +213,7 @@ public SemanticModel GetSemanticModel(SyntaxTree syntaxTree, bool ignoreAccessib
/// Returns a new INamedTypeSymbol representing an error type with the given name and arity
/// in the given optional container.
/// </summary>
public INamedTypeSymbol CreateErrorTypeSymbol(INamespaceOrTypeSymbol container, string name, int arity)
public INamedTypeSymbol CreateErrorTypeSymbol(INamespaceOrTypeSymbol? container, string name, int arity)
{
if (name == null)
{
......@@ -228,7 +228,7 @@ public INamedTypeSymbol CreateErrorTypeSymbol(INamespaceOrTypeSymbol container,
return CommonCreateErrorTypeSymbol(container, name, arity);
}
protected abstract INamedTypeSymbol CommonCreateErrorTypeSymbol(INamespaceOrTypeSymbol container, string name, int arity);
protected abstract INamedTypeSymbol CommonCreateErrorTypeSymbol(INamespaceOrTypeSymbol? container, string name, int arity);
/// <summary>
/// Returns a new INamespaceSymbol representing an error (missing) namespace with the given name.
......
......@@ -6,6 +6,7 @@
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis.Symbols;
using Microsoft.CodeAnalysis.Text;
......@@ -29,6 +30,7 @@ internal Location()
/// <summary>
/// Returns true if the location represents a specific location in a source code file.
/// </summary>
[MemberNotNullWhen(true, nameof(SourceTree))]
public bool IsInSource { get { return SourceTree != null; } }
/// <summary>
......
......@@ -2,14 +2,15 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
// This was copied from https://github.com/dotnet/coreclr/blob/60f1e6265bd1039f023a82e0643b524d6aaf7845/src/System.Private.CoreLib/shared/System/Diagnostics/CodeAnalysis/NullableAttributes.cs
// This was copied from https://github.com/dotnet/runtime/blob/39b9607807f29e48cae4652cd74735182b31182e/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/NullableAttributes.cs
// and updated to have the scope of the attributes be internal.
#if !NETCOREAPP
#nullable enable
namespace System.Diagnostics.CodeAnalysis
{
#if !NETCOREAPP
/// <summary>Specifies that null is allowed as an input even if the corresponding type disallows it.</summary>
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.Property, Inherited = false)]
internal sealed class AllowNullAttribute : Attribute { }
......@@ -86,6 +87,67 @@ internal sealed class DoesNotReturnIfAttribute : Attribute
/// <summary>Gets the condition parameter value.</summary>
public bool ParameterValue { get; }
}
}
#endif
\ No newline at end of file
#endif
#if !NETCOREAPP || NETCOREAPP3_1
/// <summary>Specifies that the method or property will ensure that the listed field and property members have not-null values.</summary>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
internal sealed class MemberNotNullAttribute : Attribute
{
/// <summary>Initializes the attribute with a field or property member.</summary>
/// <param name="member">
/// The field or property member that is promised to be not-null.
/// </param>
public MemberNotNullAttribute(string member) => Members = new[] { member };
/// <summary>Initializes the attribute with the list of field and property members.</summary>
/// <param name="members">
/// The list of field and property members that are promised to be not-null.
/// </param>
public MemberNotNullAttribute(params string[] members) => Members = members;
/// <summary>Gets field or property member names.</summary>
public string[] Members { get; }
}
/// <summary>Specifies that the method or property will ensure that the listed field and property members have not-null values when returning with the specified return value condition.</summary>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
internal sealed class MemberNotNullWhenAttribute : Attribute
{
/// <summary>Initializes the attribute with the specified return value condition and a field or property member.</summary>
/// <param name="returnValue">
/// The return value condition. If the method returns this value, the associated parameter will not be null.
/// </param>
/// <param name="member">
/// The field or property member that is promised to be not-null.
/// </param>
public MemberNotNullWhenAttribute(bool returnValue, string member)
{
ReturnValue = returnValue;
Members = new[] { member };
}
/// <summary>Initializes the attribute with the specified return value condition and list of field and property members.</summary>
/// <param name="returnValue">
/// The return value condition. If the method returns this value, the associated parameter will not be null.
/// </param>
/// <param name="members">
/// The list of field and property members that are promised to be not-null.
/// </param>
public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
{
ReturnValue = returnValue;
Members = members;
}
/// <summary>Gets the return value condition.</summary>
public bool ReturnValue { get; }
/// <summary>Gets field or property member names.</summary>
public string[] Members { get; }
}
#endif
}
......@@ -14,6 +14,7 @@
using Microsoft.CodeAnalysis.Editor.Host;
using Microsoft.CodeAnalysis.Editor.Implementation.IntelliSense.QuickInfo;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.VisualStudio.Text.Adornments;
using Roslyn.Utilities;
......@@ -179,7 +180,7 @@ internal static class Helpers
SymbolKeyResolution resolvedSymbolKey;
try
{
resolvedSymbolKey = SymbolKey.ResolveString(navigationTarget, document.Project.GetCompilationAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None), cancellationToken: CancellationToken.None);
resolvedSymbolKey = SymbolKey.ResolveString(navigationTarget, document.Project.GetRequiredCompilationAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None), cancellationToken: CancellationToken.None);
}
catch
{
......
......@@ -8,6 +8,7 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.ExtractMethod
{
......@@ -72,7 +73,8 @@ public static SyntaxToken GetTokenWithAnnotation(this SemanticDocument document,
public static T ResolveType<T>(this SemanticModel semanticModel, T symbol) where T : class, ITypeSymbol
{
// Can be cleaned up when https://github.com/dotnet/roslyn/issues/38061 is resolved
var typeSymbol = (T)symbol.GetSymbolKey().Resolve(semanticModel.Compilation).GetAnySymbol();
var typeSymbol = (T?)symbol.GetSymbolKey().Resolve(semanticModel.Compilation).GetAnySymbol();
Contract.ThrowIfNull(typeSymbol);
return (T)typeSymbol.WithNullableAnnotation(symbol.NullableAnnotation);
}
......
......@@ -319,7 +319,7 @@ private void InitializeWorkspace(Project project)
return null;
}
var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
var compilation = await project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false);
var resolutionResult = symbolId.Resolve(compilation, ignoreAssemblyKey: true, cancellationToken: cancellationToken);
if (resolutionResult.Symbol == null)
{
......
......@@ -148,10 +148,10 @@ private async Task<Solution> ProcessResultAsync(CodeFixContext context, Diagnost
propertyDocument = solution.GetRequiredDocument(propertyDocument.Id);
Debug.Assert(fieldDocument.Project == propertyDocument.Project);
compilation = await fieldDocument.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);
compilation = await fieldDocument.Project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false);
fieldSymbol = (IFieldSymbol)fieldSymbol.GetSymbolKey(cancellationToken).Resolve(compilation, cancellationToken: cancellationToken).Symbol;
propertySymbol = (IPropertySymbol)propertySymbol.GetSymbolKey(cancellationToken).Resolve(compilation, cancellationToken: cancellationToken).Symbol;
fieldSymbol = (IFieldSymbol?)fieldSymbol.GetSymbolKey(cancellationToken).Resolve(compilation, cancellationToken: cancellationToken).Symbol;
propertySymbol = (IPropertySymbol?)propertySymbol.GetSymbolKey(cancellationToken).Resolve(compilation, cancellationToken: cancellationToken).Symbol;
Contract.ThrowIfTrue(fieldSymbol == null || propertySymbol == null);
declarator = (TVariableDeclarator)await fieldSymbol.DeclaringSyntaxReferences[0].GetSyntaxAsync(cancellationToken).ConfigureAwait(false);
......
......@@ -471,7 +471,7 @@ private async Task DebugVerifyNoErrorsAsync(MutableConflictResolution conflictRe
if (_nonConflictSymbols == null)
return null;
var compilation = await currentProject.GetCompilationAsync(_cancellationToken).ConfigureAwait(false);
var compilation = await currentProject.GetRequiredCompilationAsync(_cancellationToken).ConfigureAwait(false);
return ImmutableHashSet.CreateRange(
_nonConflictSymbols.Select(s => s.GetSymbolKey().Resolve(compilation).GetAnySymbol()).WhereNotNull());
}
......
......@@ -2,6 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System.Linq;
using System.Threading;
using Microsoft.CodeAnalysis.Shared.Utilities;
......@@ -15,14 +18,14 @@ public static void Create(IAliasSymbol symbol, SymbolKeyWriter visitor)
{
visitor.WriteString(symbol.Name);
visitor.WriteSymbolKey(symbol.Target);
visitor.WriteString(FirstOrDefault(symbol.DeclaringSyntaxReferences)?.SyntaxTree.FilePath ?? "");
visitor.WriteString(symbol.DeclaringSyntaxReferences.FirstOrDefault()?.SyntaxTree.FilePath ?? "");
}
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
var name = reader.ReadString();
var name = reader.ReadString()!;
var targetResolution = reader.ReadSymbolKey(out var targetFailureReason);
var filePath = reader.ReadString();
var filePath = reader.ReadString()!;
if (targetFailureReason != null)
{
......@@ -78,7 +81,7 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string fai
{
if (child.IsNode)
{
var result = Resolve(semanticModel, child.AsNode(), name, target, cancellationToken);
var result = Resolve(semanticModel, child.AsNode()!, name, target, cancellationToken);
if (result.HasValue)
{
return result;
......
......@@ -2,7 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System.Diagnostics;
using System.Linq;
using Microsoft.CodeAnalysis.Shared.Extensions;
namespace Microsoft.CodeAnalysis
......@@ -28,13 +31,13 @@ public static void Create(ISymbol symbol, SymbolKeyWriter visitor)
// the anonymous-function, then use that anonymous-functoin to get at
// the synthesized anonymous delegate.
visitor.WriteBoolean(symbol.IsAnonymousDelegateType());
visitor.WriteLocation(FirstOrDefault(symbol.Locations));
visitor.WriteLocation(symbol.Locations.First());
}
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
var isAnonymousDelegateType = reader.ReadBoolean();
var location = reader.ReadLocation(out var locationFailureReason);
var location = reader.ReadLocation(out var locationFailureReason)!;
if (locationFailureReason != null)
{
......@@ -59,9 +62,9 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string fai
// If this was a key for an anonymous delegate type, then go find the
// associated delegate for this lambda and return that instead of the
// lambda function symbol itself.
if (isAnonymousDelegateType)
if (isAnonymousDelegateType && symbol != null)
{
var anonymousDelegate = (symbol as IMethodSymbol).AssociatedAnonymousDelegate;
var anonymousDelegate = ((IMethodSymbol)symbol).AssociatedAnonymousDelegate;
symbol = anonymousDelegate;
}
......
......@@ -2,9 +2,12 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
namespace Microsoft.CodeAnalysis
{
......@@ -20,7 +23,7 @@ public static void Create(INamedTypeSymbol symbol, SymbolKeyWriter visitor)
var propertyTypes = properties.SelectAsArray(p => p.Type);
var propertyNames = properties.SelectAsArray(p => p.Name);
var propertyIsReadOnly = properties.SelectAsArray(p => p.SetMethod == null);
var propertyLocations = properties.SelectAsArray(p => FirstOrDefault(p.Locations));
var propertyLocations = properties.SelectAsArray(p => p.Locations.FirstOrDefault());
visitor.WriteSymbolKeyArray(propertyTypes);
visitor.WriteStringArray(propertyNames);
......@@ -28,12 +31,14 @@ public static void Create(INamedTypeSymbol symbol, SymbolKeyWriter visitor)
visitor.WriteLocationArray(propertyLocations);
}
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
using var propertyTypes = reader.ReadSymbolKeyArray<ITypeSymbol>(out var propertyTypesFailureReason);
using var propertyNames = reader.ReadStringArray();
#pragma warning disable IDE0007 // Use implicit type
using PooledArrayBuilder<string> propertyNames = reader.ReadStringArray()!;
#pragma warning restore IDE0007 // Use implicit type
using var propertyIsReadOnly = reader.ReadBooleanArray();
using var propertyLocations = reader.ReadLocationArray(out var propertyLocationsFailureReason);
var propertyLocations = ReadPropertyLocations(reader, out var propertyLocationsFailureReason);
if (propertyTypesFailureReason != null)
{
......@@ -49,22 +54,30 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string fai
if (!propertyTypes.IsDefault)
{
try
{
var anonymousType = reader.Compilation.CreateAnonymousTypeSymbol(
propertyTypes.ToImmutable(), propertyNames.ToImmutable(),
propertyIsReadOnly.ToImmutable(), propertyLocations.ToImmutable());
failureReason = null;
return new SymbolKeyResolution(anonymousType);
}
catch (ArgumentException)
{
}
var anonymousType = reader.Compilation.CreateAnonymousTypeSymbol(
propertyTypes.ToImmutable(), propertyNames.ToImmutable(),
propertyIsReadOnly.ToImmutable(), propertyLocations);
failureReason = null;
return new SymbolKeyResolution(anonymousType);
}
failureReason = null;
return new SymbolKeyResolution(reader.Compilation.ObjectType);
}
private static ImmutableArray<Location> ReadPropertyLocations(SymbolKeyReader reader, out string? failureReason)
{
using var propertyLocations = reader.ReadLocationArray(out failureReason);
if (failureReason != null)
return default;
// Compiler API requires that all the locations are non-null, or that there is a default
// immutable array passed in.
if (propertyLocations.Builder.All(loc => loc == null))
return default;
return propertyLocations.ToImmutable()!;
}
}
}
}
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
namespace Microsoft.CodeAnalysis
{
internal partial struct SymbolKey
......@@ -14,7 +16,7 @@ public static void Create(IArrayTypeSymbol symbol, SymbolKeyWriter visitor)
visitor.WriteInteger(symbol.Rank);
}
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
var elementTypeResolution = reader.ReadSymbolKey(out var elementTypeFailureReason);
var rank = reader.ReadInteger();
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using Microsoft.CodeAnalysis.Shared.Extensions;
namespace Microsoft.CodeAnalysis
......@@ -17,7 +19,7 @@ public static void Create(IAssemblySymbol symbol, SymbolKeyWriter visitor)
visitor.WriteString(symbol.Identity.Name);
}
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
var assemblyName = reader.ReadString();
var compilation = reader.Compilation;
......
......@@ -120,9 +120,11 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? fa
{
var cancellationToken = reader.CancellationToken;
var name = reader.ReadString();
var name = reader.ReadString()!;
var kind = (SymbolKind)reader.ReadInteger();
var locations = reader.ReadLocationArray(out var locationsFailureReason);
#pragma warning disable IDE0007 // Use implicit type
PooledArrayBuilder<Location> locations = reader.ReadLocationArray(out var locationsFailureReason)!;
#pragma warning restore IDE0007 // Use implicit type
var ordinal = reader.ReadInteger();
if (locationsFailureReason != null)
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
namespace Microsoft.CodeAnalysis
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
namespace Microsoft.CodeAnalysis
{
internal partial struct SymbolKey
......@@ -14,7 +16,7 @@ public static void Create(SymbolKeyWriter _)
// per compilation.
}
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
failureReason = null;
return new SymbolKeyResolution(reader.Compilation.DynamicType);
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.PooledObjects;
using Roslyn.Utilities;
......@@ -60,10 +62,9 @@ private static ImmutableArray<string> GetContainingNamespaceNamesInReverse(IName
return builder.ToImmutable();
}
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
var name = reader.ReadString();
var name = reader.ReadString()!;
var containingSymbolResolution = ResolveContainer(reader, out var containingSymbolFailureReason);
var arity = reader.ReadInteger();
var isConstructed = reader.ReadBoolean();
......@@ -94,7 +95,7 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string fai
foreach (var container in containingSymbolResolution.OfType<INamespaceOrTypeSymbol>())
{
var originalType = reader.Compilation.CreateErrorTypeSymbol(container, name, arity);
var errorType = isConstructed ? originalType.Construct(typeArgumentsArray) : originalType;
var errorType = typeArgumentsArray != null ? originalType.Construct(typeArgumentsArray) : originalType;
result.AddIfNotNull(errorType);
}
......@@ -105,7 +106,7 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string fai
return CreateResolution(result, $"({nameof(ErrorTypeSymbolKey)} failed)", out failureReason);
}
private static SymbolKeyResolution ResolveContainer(SymbolKeyReader reader, out string failureReason)
private static SymbolKeyResolution ResolveContainer(SymbolKeyReader reader, out string? failureReason)
{
var type = reader.ReadInteger();
......@@ -114,7 +115,9 @@ private static SymbolKeyResolution ResolveContainer(SymbolKeyReader reader, out
if (type == 1)
{
using var namespaceNames = reader.ReadStringArray();
#pragma warning disable IDE0007 // Use implicit type
using PooledArrayBuilder<string> namespaceNames = reader.ReadStringArray()!;
#pragma warning restore IDE0007 // Use implicit type
var currentNamespace = reader.Compilation.GlobalNamespace;
// have to walk the namespaces in reverse because that's how we encoded them.
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
namespace Microsoft.CodeAnalysis
{
internal partial struct SymbolKey
......@@ -14,7 +16,7 @@ public static void Create(IEventSymbol symbol, SymbolKeyWriter visitor)
visitor.WriteSymbolKey(symbol.ContainingType);
}
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
var metadataName = reader.ReadString();
var containingTypeResolution = reader.ReadSymbolKey(out var containingTypeFailureReason);
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
namespace Microsoft.CodeAnalysis
{
internal partial struct SymbolKey
......@@ -14,7 +16,7 @@ public static void Create(IFieldSymbol symbol, SymbolKeyWriter visitor)
visitor.WriteSymbolKey(symbol.ContainingType);
}
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
var metadataName = reader.ReadString();
var containingTypeResolution = reader.ReadSymbolKey(out var containingTypeFailureReason);
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
namespace Microsoft.CodeAnalysis
{
internal partial struct SymbolKey
......@@ -16,7 +18,7 @@ public static void Create(IFunctionPointerTypeSymbol symbol, SymbolKeyWriter vis
visitor.WriteParameterTypesArray(symbol.Signature.Parameters);
}
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
var returnRefKind = reader.ReadRefKind();
var returnType = reader.ReadSymbolKey(out var returnTypeFailureReason);
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System.Diagnostics;
namespace Microsoft.CodeAnalysis
......@@ -18,7 +20,7 @@ public static void Create(IMethodSymbol symbol, SymbolKeyWriter visitor)
visitor.WriteSymbolKey(symbol.ReceiverType);
}
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
var reducedFromResolution = reader.ReadSymbolKey(out var reducedFromFailureReason);
if (reducedFromFailureReason != null)
......@@ -58,7 +60,7 @@ public static void Create(IMethodSymbol symbol, SymbolKeyWriter visitor)
visitor.WriteSymbolKeyArray(symbol.TypeArguments);
}
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
var constructedFrom = reader.ReadSymbolKey(out var constructedFromFailureReason);
if (constructedFromFailureReason != null)
......@@ -132,9 +134,9 @@ public static void Create(IMethodSymbol symbol, SymbolKeyWriter visitor)
visitor.PopMethod(symbol);
}
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
var metadataName = reader.ReadString();
var metadataName = reader.ReadString()!;
var containingType = reader.ReadSymbolKey(out var containingTypeFailureReason);
var arity = reader.ReadInteger();
......@@ -151,7 +153,7 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string fai
// point.
var beforeParametersPosition = reader.Position;
using var methods = GetMembersOfNamedType<IMethodSymbol>(containingType, metadataNameOpt: null);
using var methods = GetMembersOfNamedType<IMethodSymbol>(containingType, metadataName: null);
using var result = PooledArrayBuilder<IMethodSymbol>.GetInstance();
foreach (var candidate in methods)
......@@ -176,7 +178,7 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string fai
// Push an null-method to our stack so that any method-type-parameters
// can at least be read (if not resolved) properly.
reader.PushMethod(methodOpt: null);
reader.PushMethod(method: null);
// read out the values. We don't actually need to use them, but we have
// to effectively read past them in the string.
......@@ -186,7 +188,7 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string fai
_ = reader.ReadSymbolKey(out _);
}
reader.PopMethod(methodOpt: null);
reader.PopMethod(method: null);
}
if (containingTypeFailureReason != null)
......@@ -198,7 +200,7 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string fai
return CreateResolution(result, $"({nameof(MethodSymbolKey)} '{metadataName}' not found)", out failureReason);
}
private static IMethodSymbol Resolve(
private static IMethodSymbol? Resolve(
SymbolKeyReader reader, string metadataName, int arity, bool isPartialMethodImplementationPart,
PooledArrayBuilder<RefKind> parameterRefKinds, int beforeParametersPosition,
IMethodSymbol method)
......@@ -233,11 +235,11 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string fai
return null;
}
private static IMethodSymbol Resolve(
private static IMethodSymbol? Resolve(
SymbolKeyReader reader, bool isPartialMethodImplementationPart, IMethodSymbol method)
{
using var originalParameterTypes = reader.ReadSymbolKeyArray<ITypeSymbol>(out _);
var returnType = (ITypeSymbol)reader.ReadSymbolKey(out _).GetAnySymbol();
var returnType = (ITypeSymbol?)reader.ReadSymbolKey(out _).GetAnySymbol();
if (reader.ParameterTypesMatch(method.OriginalDefinition.Parameters, originalParameterTypes))
{
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
namespace Microsoft.CodeAnalysis
{
internal partial struct SymbolKey
......@@ -11,7 +13,7 @@ private static class ModuleSymbolKey
public static void Create(IModuleSymbol symbol, SymbolKeyWriter visitor)
=> visitor.WriteSymbolKey(symbol.ContainingSymbol);
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
var containingSymbolResolution = reader.ReadSymbolKey(out var containingSymbolFailureReason);
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Collections.Immutable;
......@@ -28,9 +30,9 @@ public static void Create(INamedTypeSymbol symbol, SymbolKeyWriter visitor)
}
}
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
var metadataName = reader.ReadString();
var metadataName = reader.ReadString()!;
var containingSymbolResolution = reader.ReadSymbolKey(out var containingSymbolFailureReason);
var arity = reader.ReadInteger();
var isUnboundGenericType = reader.ReadBoolean();
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Diagnostics;
......@@ -52,9 +54,9 @@ public static void Create(INamespaceSymbol symbol, SymbolKeyWriter visitor)
}
}
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
var metadataName = reader.ReadString();
var metadataName = reader.ReadString()!;
var isCompilationGlobalNamespace = reader.ReadBoolean();
var containingSymbolResolution = reader.ReadSymbolKey(out var containingSymbolFailureReason);
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System.Collections.Immutable;
namespace Microsoft.CodeAnalysis
......@@ -16,9 +18,9 @@ public static void Create(IParameterSymbol symbol, SymbolKeyWriter visitor)
visitor.WriteSymbolKey(symbol.ContainingSymbol);
}
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
var metadataName = reader.ReadString();
var metadataName = reader.ReadString()!;
var containingSymbolResolution = reader.ReadSymbolKey(out var containingSymbolFailureReason);
if (containingSymbolFailureReason != null)
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
namespace Microsoft.CodeAnalysis
{
internal partial struct SymbolKey
......@@ -11,7 +13,7 @@ private static class PointerTypeSymbolKey
public static void Create(IPointerTypeSymbol symbol, SymbolKeyWriter visitor)
=> visitor.WriteSymbolKey(symbol.PointedAtType);
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
var pointedAtTypeResolution = reader.ReadSymbolKey(out var pointedAtTypeFailureReason);
......
......@@ -2,8 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis.PooledObjects;
namespace Microsoft.CodeAnalysis
......@@ -21,7 +24,7 @@ private PooledArrayBuilder(ArrayBuilder<T> builder)
public int Count => Builder.Count;
public T this[int index] => Builder[index];
public void AddIfNotNull(T value)
public void AddIfNotNull([AllowNull] T value)
{
if (value != null)
{
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
namespace Microsoft.CodeAnalysis
{
internal partial struct SymbolKey
......@@ -17,7 +19,7 @@ public static void Create(IPropertySymbol symbol, SymbolKeyWriter visitor)
visitor.WriteParameterTypesArray(symbol.OriginalDefinition.Parameters);
}
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
var metadataName = reader.ReadString();
var containingTypeResolution = reader.ReadSymbolKey(out var containingTypeFailureReason);
......@@ -43,7 +45,7 @@ public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string fai
return default;
}
using var properties = GetMembersOfNamedType<IPropertySymbol>(containingTypeResolution, metadataNameOpt: null);
using var properties = GetMembersOfNamedType<IPropertySymbol>(containingTypeResolution, metadataName: null);
using var result = PooledArrayBuilder<IPropertySymbol>.GetInstance();
foreach (var property in properties)
{
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Collections.Generic;
......
......@@ -2,10 +2,13 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using Microsoft.CodeAnalysis.PooledObjects;
......@@ -18,14 +21,14 @@ namespace Microsoft.CodeAnalysis
{
internal partial struct SymbolKey
{
private abstract class Reader<TStringResult> : IDisposable
private abstract class Reader<TStringResult> : IDisposable where TStringResult : class
{
protected const char OpenParenChar = '(';
protected const char CloseParenChar = ')';
protected const char SpaceChar = ' ';
protected const char DoubleQuoteChar = '"';
private readonly ReadFunction<TStringResult> _readString;
private readonly ReadFunction<TStringResult?> _readString;
private readonly ReadFunction<bool> _readBoolean;
private readonly ReadFunction<RefKind> _readRefKind;
......@@ -39,6 +42,8 @@ public Reader()
_readString = ReadString;
_readBoolean = ReadBoolean;
_readRefKind = ReadRefKind;
Data = null!;
}
protected virtual void Initialize(string data, CancellationToken cancellationToken)
......@@ -50,7 +55,7 @@ protected virtual void Initialize(string data, CancellationToken cancellationTok
public virtual void Dispose()
{
Data = null;
Data = null!;
CancellationToken = default;
}
......@@ -106,7 +111,7 @@ protected char EatSpace()
public bool ReadBoolean()
=> ReadBoolean(out _);
public bool ReadBoolean(out string failureReason)
public bool ReadBoolean(out string? failureReason)
{
failureReason = null;
var val = ReadInteger();
......@@ -114,17 +119,17 @@ public bool ReadBoolean(out string failureReason)
return val == 1;
}
public TStringResult ReadString()
public TStringResult? ReadString()
=> ReadString(out _);
public TStringResult ReadString(out string failureReason)
public TStringResult? ReadString(out string? failureReason)
{
failureReason = null;
EatSpace();
return ReadStringNoSpace();
}
protected TStringResult ReadStringNoSpace()
protected TStringResult? ReadStringNoSpace()
{
if ((SymbolKeyType)Data[Position] == SymbolKeyType.Null)
{
......@@ -165,13 +170,13 @@ protected TStringResult ReadStringNoSpace()
return result;
}
protected abstract TStringResult CreateResultForString(int start, int end, bool hasEmbeddedQuote);
protected abstract TStringResult CreateNullForString();
protected abstract TStringResult? CreateResultForString(int start, int end, bool hasEmbeddedQuote);
protected abstract TStringResult? CreateNullForString();
private void EatDoubleQuote()
=> Eat(DoubleQuoteChar);
public PooledArrayBuilder<TStringResult> ReadStringArray()
public PooledArrayBuilder<TStringResult?> ReadStringArray()
=> ReadArray(_readString, out _);
public PooledArrayBuilder<bool> ReadBooleanArray()
......@@ -180,7 +185,7 @@ public PooledArrayBuilder<bool> ReadBooleanArray()
public PooledArrayBuilder<RefKind> ReadRefKindArray()
=> ReadArray(_readRefKind, out _);
public PooledArrayBuilder<T> ReadArray<T>(ReadFunction<T> readFunction, out string failureReason)
public PooledArrayBuilder<T> ReadArray<T>(ReadFunction<T> readFunction, out string? failureReason)
{
var builder = PooledArrayBuilder<T>.GetInstance();
EatSpace();
......@@ -190,7 +195,7 @@ public PooledArrayBuilder<T> ReadArray<T>(ReadFunction<T> readFunction, out stri
EatOpenParen();
Eat(SymbolKeyType.Array);
string totalFailureReason = null;
string? totalFailureReason = null;
var length = ReadInteger();
for (var i = 0; i < length; i++)
{
......@@ -214,7 +219,7 @@ public PooledArrayBuilder<T> ReadArray<T>(ReadFunction<T> readFunction, out stri
public RefKind ReadRefKind()
=> ReadRefKind(out _);
public RefKind ReadRefKind(out string failureReason)
public RefKind ReadRefKind(out string? failureReason)
{
failureReason = null;
return (RefKind)ReadInteger();
......@@ -269,7 +274,7 @@ public string RemoveAssemblySymbolKeys()
return _builder.ToString();
}
protected override object CreateResultForString(int start, int end, bool hasEmbeddedQuote)
protected override object? CreateResultForString(int start, int end, bool hasEmbeddedQuote)
{
// 'start' is right after the open quote, and 'end' is right before the close quote.
// However, we want to include both quotes in the result.
......@@ -285,11 +290,11 @@ protected override object CreateResultForString(int start, int end, bool hasEmbe
return null;
}
protected override object CreateNullForString()
protected override object? CreateNullForString()
=> null;
}
private delegate T ReadFunction<T>(out string failureReason);
private delegate T ReadFunction<T>(out string? failureReason);
private class SymbolKeyReader : Reader<string>
{
......@@ -297,27 +302,30 @@ private class SymbolKeyReader : Reader<string>
private readonly Dictionary<int, SymbolKeyResolution> _idToResult = new Dictionary<int, SymbolKeyResolution>();
private readonly ReadFunction<SymbolKeyResolution> _readSymbolKey;
private readonly ReadFunction<Location> _readLocation;
private readonly ReadFunction<Location?> _readLocation;
public Compilation Compilation { get; private set; }
public bool IgnoreAssemblyKey { get; private set; }
public SymbolEquivalenceComparer Comparer { get; private set; }
private readonly List<IMethodSymbol> _methodSymbolStack = new List<IMethodSymbol>();
private readonly List<IMethodSymbol?> _methodSymbolStack = new List<IMethodSymbol?>();
public SymbolKeyReader()
{
_readSymbolKey = ReadSymbolKey;
_readLocation = ReadLocation;
Compilation = null!;
Comparer = null!;
}
public override void Dispose()
{
base.Dispose();
_idToResult.Clear();
Compilation = null;
Compilation = null!;
IgnoreAssemblyKey = false;
Comparer = null;
Comparer = null!;
_methodSymbolStack.Clear();
// Place us back in the pool for future use.
......@@ -375,20 +383,20 @@ public override void Dispose()
return true;
}
public void PushMethod(IMethodSymbol methodOpt)
=> _methodSymbolStack.Add(methodOpt);
public void PushMethod(IMethodSymbol? method)
=> _methodSymbolStack.Add(method);
public void PopMethod(IMethodSymbol methodOpt)
public void PopMethod(IMethodSymbol? method)
{
Contract.ThrowIfTrue(_methodSymbolStack.Count == 0);
Contract.ThrowIfFalse(Equals(methodOpt, _methodSymbolStack[_methodSymbolStack.Count - 1]));
Contract.ThrowIfFalse(Equals(method, _methodSymbolStack[_methodSymbolStack.Count - 1]));
_methodSymbolStack.RemoveAt(_methodSymbolStack.Count - 1);
}
public IMethodSymbol ResolveMethod(int index)
public IMethodSymbol? ResolveMethod(int index)
=> _methodSymbolStack[index];
internal SyntaxTree GetSyntaxTree(string filePath)
internal SyntaxTree? GetSyntaxTree(string filePath)
{
foreach (var tree in this.Compilation.SyntaxTrees)
{
......@@ -403,7 +411,7 @@ internal SyntaxTree GetSyntaxTree(string filePath)
#region Symbols
public SymbolKeyResolution ReadSymbolKey(out string failureReason)
public SymbolKeyResolution ReadSymbolKey(out string? failureReason)
{
CancellationToken.ThrowIfCancellationRequested();
EatSpace();
......@@ -440,7 +448,7 @@ public SymbolKeyResolution ReadSymbolKey(out string failureReason)
return result;
}
private SymbolKeyResolution ReadWorker(SymbolKeyType type, out string failureReason)
private SymbolKeyResolution ReadWorker(SymbolKeyType type, out string? failureReason)
=> type switch
{
SymbolKeyType.Alias => AliasSymbolKey.Resolve(this, out failureReason),
......@@ -479,7 +487,7 @@ private SymbolKeyResolution ReadWorker(SymbolKeyType type, out string failureRea
/// Callers should <see cref="IDisposable.Dispose"/> the instance returned. No check is
/// necessary if <c>default</c> was returned before calling <see cref="IDisposable.Dispose"/>
/// </summary>
public PooledArrayBuilder<TSymbol> ReadSymbolKeyArray<TSymbol>(out string failureReason) where TSymbol : ISymbol
public PooledArrayBuilder<TSymbol> ReadSymbolKeyArray<TSymbol>(out string? failureReason) where TSymbol : ISymbol
{
using var resolutions = ReadArray(_readSymbolKey, out var elementsFailureReason);
if (elementsFailureReason != null)
......@@ -520,14 +528,14 @@ protected override string CreateResultForString(int start, int end, bool hasEmbe
return result;
}
protected override string CreateNullForString()
protected override string? CreateNullForString()
=> null;
#endregion
#region Locations
public Location ReadLocation(out string failureReason)
public Location? ReadLocation(out string? failureReason)
{
EatSpace();
if ((SymbolKeyType)Data[Position] == SymbolKeyType.Null)
......@@ -549,6 +557,12 @@ public Location ReadLocation(out string failureReason)
var start = ReadInteger();
var length = ReadInteger();
if (filePath == null)
{
failureReason = $"({nameof(ReadLocation)} failed -> '{nameof(filePath)}' came back null)";
return null;
}
var syntaxTree = GetSyntaxTree(filePath);
if (syntaxTree == null)
{
......@@ -570,6 +584,12 @@ public Location ReadLocation(out string failureReason)
return Location.None;
}
if (moduleName == null)
{
failureReason = $"({nameof(ReadLocation)} failed -> '{nameof(moduleName)}' came back null)";
return null;
}
// We may be resolving in a compilation where we don't have a module
// with this name. In that case, just map this location to none.
if (assemblyResolution.GetAnySymbol() is IAssemblySymbol assembly)
......@@ -577,7 +597,7 @@ public Location ReadLocation(out string failureReason)
var module = GetModule(assembly.Modules, moduleName);
if (module != null)
{
var location = FirstOrDefault(module.Locations);
var location = module.Locations.FirstOrDefault();
if (location != null)
{
failureReason = null;
......@@ -616,7 +636,7 @@ public Location ReadLocation(out string failureReason)
return null;
}
private static IModuleSymbol GetModule(IEnumerable<IModuleSymbol> modules, string moduleName)
private static IModuleSymbol? GetModule(IEnumerable<IModuleSymbol> modules, string moduleName)
{
foreach (var module in modules)
{
......@@ -629,7 +649,7 @@ private static IModuleSymbol GetModule(IEnumerable<IModuleSymbol> modules, strin
return null;
}
public PooledArrayBuilder<Location> ReadLocationArray(out string failureReason)
public PooledArrayBuilder<Location?> ReadLocationArray(out string? failureReason)
=> ReadArray(_readLocation, out failureReason);
#endregion
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
......@@ -49,13 +51,13 @@ private enum SymbolKeyType
TypeParameterOrdinal = '@',
}
private class SymbolKeyWriter : SymbolVisitor<object>, IDisposable
private class SymbolKeyWriter : SymbolVisitor, IDisposable
{
private static readonly ObjectPool<SymbolKeyWriter> s_writerPool = SharedPools.Default<SymbolKeyWriter>();
private readonly Action<ISymbol> _writeSymbolKey;
private readonly Action<string> _writeString;
private readonly Action<Location> _writeLocation;
private readonly Action<string?> _writeString;
private readonly Action<Location?> _writeLocation;
private readonly Action<bool> _writeBoolean;
private readonly Action<IParameterSymbol> _writeParameterType;
private readonly Action<IParameterSymbol> _writeRefKind;
......@@ -124,7 +126,7 @@ private void EndKey()
_stringBuilder.Append(')');
}
internal void WriteSymbolKey(ISymbol symbol)
internal void WriteSymbolKey(ISymbol? symbol)
{
WriteSpace();
......@@ -221,7 +223,7 @@ private void WriteIntegerRaw_DoNotCallDirectly(int value)
internal void WriteBoolean(bool value)
=> WriteInteger(value ? 1 : 0);
internal void WriteString(string value)
internal void WriteString(string? value)
{
// Strings are quoted, with all embedded quotes being doubled to escape them.
WriteSpace();
......@@ -237,7 +239,7 @@ internal void WriteString(string value)
}
}
internal void WriteLocation(Location location)
internal void WriteLocation(Location? location)
{
WriteSpace();
if (location == null)
......@@ -251,7 +253,7 @@ internal void WriteLocation(Location location)
location.Kind == LocationKind.MetadataFile);
WriteInteger((int)location.Kind);
if (location.Kind == LocationKind.SourceFile)
if (location.IsInSource)
{
WriteString(location.SourceTree.FilePath);
WriteInteger(location.SourceSpan.Start);
......@@ -259,7 +261,7 @@ internal void WriteLocation(Location location)
}
else if (location.Kind == LocationKind.MetadataFile)
{
WriteSymbolKey(location.MetadataModule.ContainingAssembly);
WriteSymbolKey(location.MetadataModule!.ContainingAssembly);
WriteString(location.MetadataModule.MetadataName);
}
}
......@@ -277,15 +279,22 @@ internal void WriteSymbolKeyArray<TSymbol>(ImmutableArray<TSymbol> symbols)
internal void WriteParameterTypesArray(ImmutableArray<IParameterSymbol> symbols)
=> WriteArray(symbols, _writeParameterType);
internal void WriteStringArray(ImmutableArray<string> strings)
=> WriteArray(strings, _writeString);
internal void WriteBooleanArray(ImmutableArray<bool> array)
=> WriteArray(array, _writeBoolean);
// annotating WriteStringArray and WriteLocationArray as allowing null elements
// then causes issues where we can't pass ImmutableArrays of non-null elements
#nullable disable
internal void WriteStringArray(ImmutableArray<string> strings)
=> WriteArray(strings, _writeString);
internal void WriteLocationArray(ImmutableArray<Location> array)
=> WriteArray(array, _writeLocation);
#nullable enable
internal void WriteRefKindArray(ImmutableArray<IParameterSymbol> values)
=> WriteArray(values, _writeRefKind);
......@@ -309,51 +318,46 @@ internal void WriteRefKindArray(ImmutableArray<IParameterSymbol> values)
internal void WriteRefKind(RefKind refKind) => WriteInteger((int)refKind);
public override object VisitAlias(IAliasSymbol aliasSymbol)
public override void VisitAlias(IAliasSymbol aliasSymbol)
{
WriteType(SymbolKeyType.Alias);
AliasSymbolKey.Create(aliasSymbol, this);
return null;
}
public override object VisitArrayType(IArrayTypeSymbol arrayTypeSymbol)
public override void VisitArrayType(IArrayTypeSymbol arrayTypeSymbol)
{
WriteType(SymbolKeyType.ArrayType);
ArrayTypeSymbolKey.Create(arrayTypeSymbol, this);
return null;
}
public override object VisitAssembly(IAssemblySymbol assemblySymbol)
public override void VisitAssembly(IAssemblySymbol assemblySymbol)
{
WriteType(SymbolKeyType.Assembly);
AssemblySymbolKey.Create(assemblySymbol, this);
return null;
}
public override object VisitDynamicType(IDynamicTypeSymbol dynamicTypeSymbol)
public override void VisitDynamicType(IDynamicTypeSymbol dynamicTypeSymbol)
{
WriteType(SymbolKeyType.DynamicType);
DynamicTypeSymbolKey.Create(this);
return null;
}
public override object VisitField(IFieldSymbol fieldSymbol)
public override void VisitField(IFieldSymbol fieldSymbol)
{
WriteType(SymbolKeyType.Field);
FieldSymbolKey.Create(fieldSymbol, this);
return null;
}
public override object VisitLabel(ILabelSymbol labelSymbol)
public override void VisitLabel(ILabelSymbol labelSymbol)
=> throw ExceptionUtilities.Unreachable;
public override object VisitLocal(ILocalSymbol localSymbol)
public override void VisitLocal(ILocalSymbol localSymbol)
=> throw ExceptionUtilities.Unreachable;
public override object VisitRangeVariable(IRangeVariableSymbol rangeVariableSymbol)
public override void VisitRangeVariable(IRangeVariableSymbol rangeVariableSymbol)
=> throw ExceptionUtilities.Unreachable;
public override object VisitMethod(IMethodSymbol methodSymbol)
public override void VisitMethod(IMethodSymbol methodSymbol)
{
if (!methodSymbol.Equals(methodSymbol.ConstructedFrom))
{
......@@ -383,18 +387,15 @@ public override object VisitMethod(IMethodSymbol methodSymbol)
break;
}
}
return null;
}
public override object VisitModule(IModuleSymbol moduleSymbol)
public override void VisitModule(IModuleSymbol moduleSymbol)
{
WriteType(SymbolKeyType.Module);
ModuleSymbolKey.Create(moduleSymbol, this);
return null;
}
public override object VisitNamedType(INamedTypeSymbol namedTypeSymbol)
public override void VisitNamedType(INamedTypeSymbol namedTypeSymbol)
{
if (namedTypeSymbol.TypeKind == TypeKind.Error)
{
......@@ -427,53 +428,45 @@ public override object VisitNamedType(INamedTypeSymbol namedTypeSymbol)
WriteType(SymbolKeyType.NamedType);
NamedTypeSymbolKey.Create(namedTypeSymbol, this);
}
return null;
}
public override object VisitNamespace(INamespaceSymbol namespaceSymbol)
public override void VisitNamespace(INamespaceSymbol namespaceSymbol)
{
WriteType(SymbolKeyType.Namespace);
NamespaceSymbolKey.Create(namespaceSymbol, this);
return null;
}
public override object VisitParameter(IParameterSymbol parameterSymbol)
public override void VisitParameter(IParameterSymbol parameterSymbol)
{
WriteType(SymbolKeyType.Parameter);
ParameterSymbolKey.Create(parameterSymbol, this);
return null;
}
public override object VisitPointerType(IPointerTypeSymbol pointerTypeSymbol)
public override void VisitPointerType(IPointerTypeSymbol pointerTypeSymbol)
{
WriteType(SymbolKeyType.PointerType);
PointerTypeSymbolKey.Create(pointerTypeSymbol, this);
return null;
}
public override object VisitFunctionPointerType(IFunctionPointerTypeSymbol symbol)
public override void VisitFunctionPointerType(IFunctionPointerTypeSymbol symbol)
{
WriteType(SymbolKeyType.FunctionPointer);
FunctionPointerTypeSymbolKey.Create(symbol, this);
return null;
}
public override object VisitProperty(IPropertySymbol propertySymbol)
public override void VisitProperty(IPropertySymbol propertySymbol)
{
WriteType(SymbolKeyType.Property);
PropertySymbolKey.Create(propertySymbol, this);
return null;
}
public override object VisitEvent(IEventSymbol eventSymbol)
public override void VisitEvent(IEventSymbol eventSymbol)
{
WriteType(SymbolKeyType.Event);
EventSymbolKey.Create(eventSymbol, this);
return null;
}
public override object VisitTypeParameter(ITypeParameterSymbol typeParameterSymbol)
public override void VisitTypeParameter(ITypeParameterSymbol typeParameterSymbol)
{
// If it's a reference to a method type parameter, and we're currently writing
// out a signture, then only write out the ordinal of type parameter. This
......@@ -488,7 +481,6 @@ public override object VisitTypeParameter(ITypeParameterSymbol typeParameterSymb
WriteType(SymbolKeyType.TypeParameter);
TypeParameterSymbolKey.Create(typeParameterSymbol, this);
}
return null;
}
public bool ShouldWriteTypeParameterOrdinal(ISymbol symbol, out int methodIndex)
......@@ -501,7 +493,7 @@ public bool ShouldWriteTypeParameterOrdinal(ISymbol symbol, out int methodIndex)
for (int i = 0, n = _methodSymbolStack.Count; i < n; i++)
{
var method = _methodSymbolStack[i];
if (typeParameter.DeclaringMethod.Equals(method))
if (typeParameter.DeclaringMethod!.Equals(method))
{
methodIndex = i;
return true;
......
......@@ -2,7 +2,10 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Linq;
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.PooledObjects;
......@@ -17,15 +20,15 @@ public static void Create(INamedTypeSymbol symbol, SymbolKeyWriter visitor)
{
Debug.Assert(symbol.IsTupleType);
var isError = symbol.TupleUnderlyingType.TypeKind == TypeKind.Error;
var isError = symbol.TupleUnderlyingType!.TypeKind == TypeKind.Error;
var friendlyNames = ArrayBuilder<string>.GetInstance();
var friendlyNames = ArrayBuilder<string?>.GetInstance();
var locations = ArrayBuilder<Location>.GetInstance();
foreach (var element in symbol.TupleElements)
{
friendlyNames.Add(element.IsImplicitlyDeclared ? null : element.Name);
locations.Add(FirstOrDefault(element.Locations) ?? Location.None);
locations.Add(element.Locations.FirstOrDefault() ?? Location.None);
}
visitor.WriteBoolean(isError);
......@@ -49,14 +52,14 @@ public static void Create(INamedTypeSymbol symbol, SymbolKeyWriter visitor)
}
}
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
var isError = reader.ReadBoolean();
return isError ? ResolveErrorTuple(reader, out failureReason) : ResolveNormalTuple(reader, out failureReason);
}
private static SymbolKeyResolution ResolveNormalTuple(SymbolKeyReader reader, out string failureReason)
private static SymbolKeyResolution ResolveNormalTuple(SymbolKeyReader reader, out string? failureReason)
{
using var elementNames = reader.ReadStringArray();
var elementLocations = ReadElementLocations(reader, out var elementLocationsFailureReason);
......@@ -73,14 +76,15 @@ private static SymbolKeyResolution ResolveNormalTuple(SymbolKeyReader reader, ou
var elementNamesArray = elementNames.ToImmutable();
foreach (var namedType in underlyingTypeResolution.OfType<INamedTypeSymbol>())
{
// Suppression on elementLocations due to https://github.com/dotnet/roslyn/issues/46527
result.AddIfNotNull(reader.Compilation.CreateTupleTypeSymbol(
namedType, elementNamesArray, elementLocations));
namedType, elementNamesArray, elementLocations!));
}
return CreateResolution(result, $"({nameof(TupleTypeSymbolKey)} failed)", out failureReason);
}
private static SymbolKeyResolution ResolveErrorTuple(SymbolKeyReader reader, out string failureReason)
private static SymbolKeyResolution ResolveErrorTuple(SymbolKeyReader reader, out string? failureReason)
{
using var elementNames = reader.ReadStringArray();
var elementLocations = ReadElementLocations(reader, out var elementLocationsFailureReason);
......@@ -104,13 +108,14 @@ private static SymbolKeyResolution ResolveErrorTuple(SymbolKeyReader reader, out
return default;
}
// Suppression on elementLocations due to https://github.com/dotnet/roslyn/issues/46527
var result = reader.Compilation.CreateTupleTypeSymbol(
elementTypes.ToImmutable(), elementNames.ToImmutable(), elementLocations);
elementTypes.ToImmutable(), elementNames.ToImmutable(), elementLocations!);
failureReason = null;
return new SymbolKeyResolution(result);
}
private static ImmutableArray<Location> ReadElementLocations(SymbolKeyReader reader, out string failureReason)
private static ImmutableArray<Location> ReadElementLocations(SymbolKeyReader reader, out string? failureReason)
{
using var elementLocations = reader.ReadLocationArray(out failureReason);
if (failureReason != null)
......@@ -121,7 +126,7 @@ private static ImmutableArray<Location> ReadElementLocations(SymbolKeyReader rea
if (elementLocations.Builder.All(loc => loc == null))
return default;
return elementLocations.ToImmutable();
return elementLocations.ToImmutable()!;
}
}
}
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis
......@@ -17,7 +19,7 @@ public static void Create(ITypeParameterSymbol symbol, int methodIndex, SymbolKe
visitor.WriteInteger(symbol.Ordinal);
}
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
var methodIndex = reader.ReadInteger();
var ordinal = reader.ReadInteger();
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using Microsoft.CodeAnalysis.Shared.Extensions;
namespace Microsoft.CodeAnalysis
......@@ -25,13 +27,13 @@ public static void Create(ITypeParameterSymbol symbol, SymbolKeyWriter visitor)
}
}
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string failureReason)
public static SymbolKeyResolution Resolve(SymbolKeyReader reader, out string? failureReason)
{
var isCref = reader.ReadBoolean();
if (isCref)
{
var location = reader.ReadLocation(out var locationFailureReason);
var location = reader.ReadLocation(out var locationFailureReason)!;
if (locationFailureReason != null)
{
failureReason = $"({nameof(TypeParameterSymbolKey)} {nameof(location)} failed -> {locationFailureReason})";
......
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
......@@ -121,7 +123,7 @@ public SymbolKey(string data)
/// <summary>
/// Constructs a new <see cref="SymbolKey"/> representing the provided <paramref name="symbol"/>.
/// </summary>
public static SymbolKey Create(ISymbol symbol, CancellationToken cancellationToken = default)
public static SymbolKey Create(ISymbol? symbol, CancellationToken cancellationToken = default)
=> new SymbolKey(CreateString(symbol, cancellationToken));
/// <summary>
......@@ -166,14 +168,14 @@ public static bool CanCreate(ISymbol symbol, CancellationToken cancellationToken
public static SymbolKeyResolution ResolveString(
string symbolKey, Compilation compilation,
out string failureReason, CancellationToken cancellationToken)
out string? failureReason, CancellationToken cancellationToken)
{
return ResolveString(symbolKey, compilation, ignoreAssemblyKey: false, out failureReason, cancellationToken);
}
public static SymbolKeyResolution ResolveString(
string symbolKey, Compilation compilation, bool ignoreAssemblyKey,
out string failureReason, CancellationToken cancellationToken)
out string? failureReason, CancellationToken cancellationToken)
{
using var reader = SymbolKeyReader.GetReader(
symbolKey, compilation, ignoreAssemblyKey, cancellationToken);
......@@ -189,11 +191,11 @@ public static bool CanCreate(ISymbol symbol, CancellationToken cancellationToken
return result;
}
public static string CreateString(ISymbol symbol, CancellationToken cancellationToken = default)
public static string CreateString(ISymbol? symbol, CancellationToken cancellationToken = default)
=> CreateStringWorker(FormatVersion, symbol, cancellationToken);
// Internal for testing purposes.
internal static string CreateStringWorker(int version, ISymbol symbol, CancellationToken cancellationToken = default)
internal static string CreateStringWorker(int version, ISymbol? symbol, CancellationToken cancellationToken = default)
{
using var writer = SymbolKeyWriter.GetWriter(cancellationToken);
writer.WriteFormatVersion(version);
......@@ -224,16 +226,9 @@ public override string ToString()
=> _symbolKeyData;
private static SymbolKeyResolution CreateResolution<TSymbol>(
PooledArrayBuilder<TSymbol> symbols, string reasonIfFailed, out string failureReason)
PooledArrayBuilder<TSymbol> symbols, string reasonIfFailed, out string? failureReason)
where TSymbol : class, ISymbol
{
#if DEBUG
foreach (var symbol in symbols)
{
Debug.Assert(symbol != null);
}
#endif
if (symbols.Builder.Count == 0)
{
failureReason = reasonIfFailed;
......@@ -253,10 +248,10 @@ public override string ToString()
}
}
private static bool Equals(Compilation compilation, string name1, string name2)
private static bool Equals(Compilation compilation, string? name1, string? name2)
=> Equals(compilation.IsCaseSensitive, name1, name2);
private static bool Equals(bool isCaseSensitive, string name1, string name2)
private static bool Equals(bool isCaseSensitive, string? name1, string? name2)
=> string.Equals(name1, name2, isCaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase);
private static string GetName(string metadataName)
......@@ -292,14 +287,14 @@ private static string GetName(string metadataName)
private static PooledArrayBuilder<TSymbol> GetMembersOfNamedType<TSymbol>(
SymbolKeyResolution containingTypeResolution,
string metadataNameOpt) where TSymbol : ISymbol
string? metadataName) where TSymbol : ISymbol
{
var result = PooledArrayBuilder<TSymbol>.GetInstance();
foreach (var containingType in containingTypeResolution.OfType<INamedTypeSymbol>())
{
var members = metadataNameOpt == null
var members = metadataName == null
? containingType.GetMembers()
: containingType.GetMembers(metadataNameOpt);
: containingType.GetMembers(metadataName);
foreach (var member in members)
{
......@@ -312,8 +307,5 @@ private static string GetName(string metadataName)
return result;
}
private static T FirstOrDefault<T>(ImmutableArray<T> values)
=> values.IsDefaultOrEmpty ? default : values[0];
}
}
......@@ -2,13 +2,15 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
using System.Threading;
namespace Microsoft.CodeAnalysis
{
internal static class SymbolKeyExtensions
{
public static SymbolKey GetSymbolKey(this ISymbol symbol, CancellationToken cancellationToken = default)
public static SymbolKey GetSymbolKey(this ISymbol? symbol, CancellationToken cancellationToken = default)
=> SymbolKey.Create(symbol, cancellationToken);
}
}
......@@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
namespace Microsoft.CodeAnalysis
{
internal partial struct SymbolKeyResolution
......
......@@ -2,11 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Collections.Immutable;
#nullable enable
#if DEBUG
using System.Diagnostics;
#endif
using System.Collections.Immutable;
namespace Microsoft.CodeAnalysis
{
......@@ -23,7 +21,7 @@ internal partial struct SymbolKeyResolution
{
private readonly ImmutableArray<ISymbol> _candidateSymbols;
internal SymbolKeyResolution(ISymbol symbol)
internal SymbolKeyResolution(ISymbol? symbol)
{
Symbol = symbol;
_candidateSymbols = default;
......@@ -35,18 +33,11 @@ internal SymbolKeyResolution(ImmutableArray<ISymbol> candidateSymbols, Candidate
Symbol = null;
_candidateSymbols = candidateSymbols;
CandidateReason = candidateReason;
#if DEBUG
foreach (var symbol in CandidateSymbols)
{
Debug.Assert(symbol != null);
}
#endif
}
internal int SymbolCount => Symbol != null ? 1 : CandidateSymbols.Length;
public ISymbol Symbol { get; }
public ISymbol? Symbol { get; }
public CandidateReason CandidateReason { get; }
public ImmutableArray<ISymbol> CandidateSymbols => _candidateSymbols.NullToEmpty();
......
......@@ -2,11 +2,13 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable enable
namespace Microsoft.CodeAnalysis
{
internal static class SymbolKeyResolutionExtensions
{
internal static ISymbol GetAnySymbol(this SymbolKeyResolution resolution)
internal static ISymbol? GetAnySymbol(this SymbolKeyResolution resolution)
{
if (resolution.Symbol != null)
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册