提交 c41b1421 编写于 作者: C Cyrus Najmabadi

Add #nullable

上级 f07a4b03
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System;
using System.Collections.Immutable;
using System.Diagnostics.CodeAnalysis;
using Microsoft.CodeAnalysis.Operations;
using Microsoft.CodeAnalysis.PooledObjects;
using Microsoft.CodeAnalysis.Shared.Extensions;
......@@ -19,17 +22,17 @@ private struct OperationDeconstructor : IDisposable
{
private readonly Analyzer _analyzer;
private readonly IMethodSymbol _method;
private readonly ILocalSymbol _hashCodeVariableOpt;
private readonly ILocalSymbol? _hashCodeVariable;
private readonly ArrayBuilder<ISymbol> _hashedSymbols;
private bool _accessesBase;
public OperationDeconstructor(
Analyzer analyzer, IMethodSymbol method, ILocalSymbol hashCodeVariableOpt)
Analyzer analyzer, IMethodSymbol method, ILocalSymbol? hashCodeVariable)
{
_analyzer = analyzer;
_method = method;
_hashCodeVariableOpt = hashCodeVariableOpt;
_hashCodeVariable = hashCodeVariable;
_hashedSymbols = ArrayBuilder<ISymbol>.GetInstance();
_accessesBase = false;
}
......@@ -63,7 +66,7 @@ public bool TryAddHashedSymbol(IOperation value, bool seenHash)
}
if (targetMethod.Name == nameof(GetHashCode) &&
Equals(_analyzer._equalityComparerTypeOpt, targetMethod.ContainingType.OriginalDefinition) &&
Equals(_analyzer._equalityComparerType, targetMethod.ContainingType.OriginalDefinition) &&
invocation.Arguments.Length == 1)
{
// EqualityComparer<T>.Default.GetHashCode(i)
......@@ -77,10 +80,10 @@ public bool TryAddHashedSymbol(IOperation value, bool seenHash)
//
// This is generated by both VS and ReSharper. Though each use different mathematical
// ops to combine the values.
if (_hashCodeVariableOpt != null && value is IBinaryOperation topBinary)
if (_hashCodeVariable != null && value is IBinaryOperation topBinary)
{
return topBinary.LeftOperand is IBinaryOperation leftBinary &&
IsLocalReference(leftBinary.LeftOperand, _hashCodeVariableOpt) &&
IsLocalReference(leftBinary.LeftOperand, _hashCodeVariable) &&
IsLiteralNumber(leftBinary.RightOperand) &&
TryAddHashedSymbol(topBinary.RightOperand, seenHash: true);
}
......@@ -159,7 +162,7 @@ public bool TryAddHashedSymbol(IOperation value, bool seenHash)
return false;
}
private static bool TryGetFieldOrProperty(IOperation operation, out ISymbol symbol)
private static bool TryGetFieldOrProperty(IOperation operation, [NotNullWhen(true)]out ISymbol? symbol)
{
operation = Unwrap(operation);
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
......@@ -17,7 +19,7 @@ internal partial struct Analyzer
{
private readonly Compilation _compilation;
private readonly IMethodSymbol _objectGetHashCodeMethod;
private readonly INamedTypeSymbol _equalityComparerTypeOpt;
private readonly INamedTypeSymbol? _equalityComparerType;
public readonly INamedTypeSymbol SystemHashCodeType;
......@@ -26,8 +28,10 @@ public Analyzer(Compilation compilation)
_compilation = compilation;
var objectType = compilation.GetSpecialType(SpecialType.System_Object);
_objectGetHashCodeMethod = objectType?.GetMembers(nameof(GetHashCode)).FirstOrDefault() as IMethodSymbol;
_equalityComparerTypeOpt = compilation.GetTypeByMetadataName(typeof(EqualityComparer<>).FullName);
// This may not find anything. However, CanAnalyze checks for this. So
// we represent the value as non-nullable for all future code.
_objectGetHashCodeMethod = (objectType?.GetMembers(nameof(GetHashCode)).FirstOrDefault() as IMethodSymbol)!;
_equalityComparerType = compilation.GetTypeByMetadataName(typeof(EqualityComparer<>).FullName);
SystemHashCodeType = compilation.GetTypeByMetadataName("System.HashCode");
}
......@@ -96,7 +100,7 @@ public bool CanAnalyze()
return default;
}
using var analyzer = new OperationDeconstructor(this, method, hashCodeVariableOpt: null);
using var analyzer = new OperationDeconstructor(this, method, hashCodeVariable: null);
if (!analyzer.TryAddHashedSymbol(returnOperation.ReturnedValue, seenHash: false))
{
return default;
......@@ -204,7 +208,7 @@ public bool CanAnalyze()
return valueAnalyzer.GetResult();
}
private bool OverridesSystemObject(IMethodSymbol method)
private bool OverridesSystemObject(IMethodSymbol? method)
{
for (var current = method; current != null; current = current.OverriddenMethod)
{
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System;
using System.Collections.Immutable;
using System.Composition;
......@@ -43,7 +45,7 @@ public override Task RegisterCodeFixesAsync(CodeFixContext context)
var generator = SyntaxGenerator.GetGenerator(document);
var declarationService = document.GetLanguageService<ISymbolDeclarationService>();
var semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var semanticModel = await document.RequireSemanticModelAsync(cancellationToken).ConfigureAwait(false);
var analyzer = new Analyzer(semanticModel.Compilation);
Debug.Assert(analyzer.CanAnalyze());
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
#nullable enable
using System.Collections.Immutable;
using Microsoft.CodeAnalysis.CodeStyle;
using Microsoft.CodeAnalysis.Diagnostics;
......
......@@ -203,5 +203,11 @@ public static bool IsGeneratedCode(this Document document, CancellationToken can
var generatedCodeRecognitionService = document.GetLanguageService<IGeneratedCodeRecognitionService>();
return generatedCodeRecognitionService?.IsGeneratedCode(document, cancellationToken) == true;
}
public static async Task<SemanticModel> RequireSemanticModelAsync(this Document document, CancellationToken cancellationToken)
{
var model = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
return model ?? throw new InvalidOperationException();
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册