Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Address NRT issues found by targeting net5.0 #50895

Merged
merged 13 commits into from
Mar 5, 2021
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,7 @@ internal override bool HasSubmissionResult()
}

// Is there a trailing expression?
var lastGlobalStatement = (GlobalStatementSyntax)root.Members.LastOrDefault(m => m.IsKind(SyntaxKind.GlobalStatement));
var lastGlobalStatement = (GlobalStatementSyntax?)root.Members.LastOrDefault(m => m.IsKind(SyntaxKind.GlobalStatement));
if (lastGlobalStatement != null)
{
var statement = lastGlobalStatement.Statement;
Expand Down
1 change: 1 addition & 0 deletions src/Compilers/Core/Portable/AssemblyUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public static ImmutableArray<string> FindSatelliteAssemblies(string filePath)
var builder = ImmutableArray.CreateBuilder<string>();

string? directory = Path.GetDirectoryName(filePath);
RoslynDebug.AssertNotNull(directory);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❔ Is it ever possible for PathUtilities.IsAbsolute(filePath) to return true but Path.GetDirectoryName(filePath) to return null? If not, I almost prefer this form:

Debug.Assert(PathUtilities.IsAbsolute(filePath));
string directory = Path.GetDirectoryName(filePath)!;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If path happens to be C:\?

Copy link
Member

@jasonmalinowski jasonmalinowski Feb 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, assert seems wise so I think this looks good -- there shouldn't ever be a directory name versus a file path being passed here, but if that were to happen...

string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(filePath);
string resourcesNameWithoutExtension = fileNameWithoutExtension + ".resources";
string resourcesNameWithExtension = resourcesNameWithoutExtension + ".dll";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -994,7 +994,7 @@ private void CompileAndEmit(
var path = Path.Combine(Arguments.GeneratedFilesOutputDirectory!, tree.FilePath);
if (Directory.Exists(Arguments.GeneratedFilesOutputDirectory))
{
Directory.CreateDirectory(Path.GetDirectoryName(path));
Directory.CreateDirectory(Path.GetDirectoryName(path)!);
}

var fileStream = OpenFile(path, diagnostics, FileMode.Create, FileAccess.Write, FileShare.ReadWrite | FileShare.Delete);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ internal static void AppendData(this IncrementalHash hash, IEnumerable<ArraySegm

internal static void AppendData(this IncrementalHash hash, ArraySegment<byte> segment)
{
RoslynDebug.AssertNotNull(segment.Array);
hash.AppendData(segment.Array, segment.Offset, segment.Count);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ public static T EnsureInitialized<T>([NotNull] ref T? target, Func<T> valueFacto
=> LazyInitializer.EnsureInitialized<T>(ref target!, valueFactory);

/// <inheritdoc cref="LazyInitializer.EnsureInitialized{T}(ref T, ref bool, ref object)"/>
public static T EnsureInitialized<T>([NotNull] ref T? target, ref bool initialized, [NotNull] ref object? syncLock)
public static T EnsureInitialized<T>([NotNull] ref T? target, ref bool initialized, [NotNullIfNotNull("syncLock")] ref object? syncLock)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's clever ;-)
Do we still need RoslynLazyInitializer now that LazyInitializer is annotated? If it's not a trivial change, please file an issue and assign it to me.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copied the annotation from net5.0.
Lack of [NotNull] should have impact on netstandard2.0

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. Thanks

=> LazyInitializer.EnsureInitialized<T>(ref target!, ref initialized, ref syncLock);

/// <inheritdoc cref="LazyInitializer.EnsureInitialized{T}(ref T, ref bool, ref object, Func{T})"/>
public static T EnsureInitialized<T>([NotNull] ref T? target, ref bool initialized, [NotNull] ref object? syncLock, Func<T> valueFactory)
public static T EnsureInitialized<T>([NotNull] ref T? target, ref bool initialized, [NotNullIfNotNull("syncLock")] ref object? syncLock, Func<T> valueFactory)
=> LazyInitializer.EnsureInitialized<T>(ref target!, ref initialized, ref syncLock, valueFactory);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ internal static TNode Copy<TNode>(this TNode node, bool copyAttributeAnnotations
{
XContainer temp = new XElement("temp");
temp.Add(node);
copy = temp.LastNode;
copy = temp.LastNode!;
temp.RemoveNodes();
}

Expand Down
2 changes: 1 addition & 1 deletion src/Compilers/Core/Portable/PEWriter/SigningUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ internal static int CalculateStrongNameSignatureSize(CommonPEModuleBuilder modul

if (keySize == 0 && privateKey.HasValue)
{
keySize = privateKey.Value.Modulus.Length;
keySize = privateKey.Value.Modulus?.Length ?? 0;
huoyaoyuan marked this conversation as resolved.
Show resolved Hide resolved
}

if (keySize == 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public static IEnumerable<TNode> GetCurrentNodes<TNode>(this SyntaxNode root, TN
/// </summary>
/// <param name="root">The root of the subtree containing the current node corresponding to the original tracked node.</param>
/// <param name="node">The node instance originally tracked.</param>
public static TNode GetCurrentNode<TNode>(this SyntaxNode root, TNode node)
public static TNode? GetCurrentNode<TNode>(this SyntaxNode root, TNode node)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is public API bug, and causing bug in Features layer.

where TNode : SyntaxNode
{
return GetCurrentNodes(root, node).SingleOrDefault();
Expand Down
2 changes: 1 addition & 1 deletion src/Compilers/Core/Portable/TreeDumper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ public TreeDumperNode(string text) : this(text, null, null) { }
public object? Value { get; }
public string Text { get; }
public IEnumerable<TreeDumperNode> Children { get; }
public TreeDumperNode this[string child]
public TreeDumperNode? this[string child]
{
get
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,9 @@ where node.IsKind(SyntaxKind.IdentifierName)
{
if (ctor.Initializer != null)
{
bodyTokens = ctor.Initializer.DescendantTokens().Concat(bodyTokens);
bodyTokens = bodyTokens != null
? ctor.Initializer.DescendantTokens().Concat(bodyTokens)
: ctor.Initializer.DescendantTokens();
huoyaoyuan marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ protected override async Task FixAllAsync(
var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
var spanNodes = diagnostics.SelectAsArray(
d => root.FindNode(d.Location.SourceSpan, getInnermostNodeForTie: true)
.GetAncestorsOrThis<TExpressionSyntax>().FirstOrDefault());
.GetAncestorsOrThis<TExpressionSyntax>().First());
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code looks very confidential about it (defensive in outer code but not this), so I changed to First.


await editor.ApplyExpressionLevelSemanticEditsAsync(
document, spanNodes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -744,7 +744,7 @@ await FixReferencesAsync(document, changeNamespaceService, addImportService, ref

var fixedDocument = editor.GetChangedDocument();
root = await fixedDocument.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
var result = (fixedDocument, containers.SelectAsArray(c => root.GetCurrentNode(c)));
var result = (fixedDocument, containers.SelectAsArray(c => root.GetCurrentNode(c)!));
jasonmalinowski marked this conversation as resolved.
Show resolved Hide resolved

return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ ImmutableArray<CompletionItem> GetItemsFromCacheResult(GetCacheResult cacheResul
{
var compilation = await referencedProject.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false);
var assembly = SymbolFinder.FindSimilarSymbols(compilation.Assembly, currentCompilation, cancellationToken).SingleOrDefault();
var metadataReference = currentCompilation.GetMetadataReference(assembly);
var metadataReference = assembly != null ? currentCompilation.GetMetadataReference(assembly) : null;
jasonmalinowski marked this conversation as resolved.
Show resolved Hide resolved

if (HasGlobalAlias(metadataReference))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ private async Task<Document> AddAllSymbolInitializationsAsync(
IBlockOperation? currentBlockStatementOpt = null;
if (blockStatementOpt != null)
{
currentBlockStatementOpt = (IBlockOperation?)currentSemanticModel.GetOperation(currentRoot.GetCurrentNode(blockStatementOpt.Syntax), cancellationToken);
currentBlockStatementOpt = (IBlockOperation?)currentSemanticModel.GetOperation(currentRoot.GetCurrentNode(blockStatementOpt.Syntax)!, cancellationToken);
if (currentBlockStatementOpt == null)
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ public async Task<MetadataAsSourceFile> GetGeneratedFileAsync(Project project, I

// Create the directory. It's possible a parallel deletion is happening in another process, so we may have
// to retry this a few times.
var directoryToCreate = Path.GetDirectoryName(fileInfo.TemporaryFilePath);
var directoryToCreate = Path.GetDirectoryName(fileInfo.TemporaryFilePath)!;
while (!Directory.Exists(directoryToCreate))
{
try
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ private static bool HasGetPrefix(string text)
private static bool HasPrefix(string text, string prefix)
=> text.StartsWith(prefix, StringComparison.OrdinalIgnoreCase) && text.Length > prefix.Length && !char.IsLower(text[prefix.Length]);

private static IMethodSymbol FindSetMethod(IMethodSymbol getMethod)
private static IMethodSymbol? FindSetMethod(IMethodSymbol getMethod)
{
var containingType = getMethod.ContainingType;
var setMethodName = "Set" + getMethod.Name[GetPrefix.Length..];
Expand Down
8 changes: 6 additions & 2 deletions src/Workspaces/Core/Portable/Editing/SyntaxEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -316,10 +316,10 @@ public ReplaceChange(
public override SyntaxNode Apply(SyntaxNode root, SyntaxGenerator generator)
{
var current = root.GetCurrentNode(this.Node);
Contract.ThrowIfNull(current, $"GetCurrentNode returned null with the following node: {this.Node}");

var newNode = _modifier(current, generator);
newNode = _editor.ApplyTrackingToNewNode(newNode);

Contract.ThrowIfNull(current, $"GetCurrentNode returned null with the following node: {this.Node}");
return generator.ReplaceNode(root, current, newNode);
}
}
Expand All @@ -342,6 +342,8 @@ public ReplaceWithCollectionChange(
public override SyntaxNode Apply(SyntaxNode root, SyntaxGenerator generator)
{
var current = root.GetCurrentNode(this.Node);
Contract.ThrowIfNull(current, $"GetCurrentNode returned null with the following node: {this.Node}");

var newNodes = _modifier(current, generator).ToList();
for (var i = 0; i < newNodes.Count; i++)
{
Expand Down Expand Up @@ -373,6 +375,8 @@ public ReplaceChange(
public override SyntaxNode Apply(SyntaxNode root, SyntaxGenerator generator)
{
var current = root.GetCurrentNode(this.Node);
Contract.ThrowIfNull(current, $"GetCurrentNode returned null with the following node: {this.Node}");

var newNode = _modifier(current, generator, _argument);
newNode = _editor.ApplyTrackingToNewNode(newNode);
return generator.ReplaceNode(root, current, newNode);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ private static async Task CascadeBetweenAnonymousFunctionParametersAsync(
{
var semanticModel = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false);

var lambdaNode = parameter.ContainingSymbol.DeclaringSyntaxReferences.Select(r => r.GetSyntax(cancellationToken)).FirstOrDefault();
var lambdaNode = parameter.ContainingSymbol.DeclaringSyntaxReferences.Select(r => r.GetSyntax(cancellationToken)).First();
jasonmalinowski marked this conversation as resolved.
Show resolved Hide resolved
var convertedType = semanticModel.GetTypeInfo(lambdaNode, cancellationToken).ConvertedType;

if (convertedType != null)
Expand Down Expand Up @@ -176,7 +176,7 @@ private static void CascadeBetweenAnonymousFunctionParameters(
SignatureComparer.Instance.HaveSameSignatureAndConstraintsAndReturnTypeAndAccessors(parameter.ContainingSymbol, symbol.ContainingSymbol, syntaxFacts.IsCaseSensitive) &&
ParameterNamesMatch(syntaxFacts, (IMethodSymbol)parameter.ContainingSymbol, (IMethodSymbol)symbol.ContainingSymbol))
{
var lambdaNode = symbol.ContainingSymbol.DeclaringSyntaxReferences.Select(r => r.GetSyntax(cancellationToken)).FirstOrDefault();
var lambdaNode = symbol.ContainingSymbol.DeclaringSyntaxReferences.Select(r => r.GetSyntax(cancellationToken)).First();
var convertedType2 = semanticModel.GetTypeInfo(lambdaNode, cancellationToken).ConvertedType;

if (convertedType1.Equals(convertedType2))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,7 @@ private async Task<bool> CheckForConflictAsync(
foreach (var originalReference in conflictAnnotation.RenameDeclarationLocationReferences.Where(loc => loc.IsSourceLocation))
{
var adjustedStartPosition = conflictResolution.GetAdjustedTokenStartingPosition(originalReference.TextSpan.Start, originalReference.DocumentId);
if (newLocations.Any(loc => loc.SourceSpan.Start == adjustedStartPosition))
if (newLocations.Any(loc => loc!.SourceSpan.Start == adjustedStartPosition))
jasonmalinowski marked this conversation as resolved.
Show resolved Hide resolved
{
hasConflict = false;
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ private static string GetString(ISymbol symbol)
/// <summary>
/// Gives the First Location for a given Symbol by ordering the locations using DocumentId first and Location starting position second
/// </summary>
private static async Task<Location> GetSymbolLocationAsync(Solution solution, ISymbol symbol, CancellationToken cancellationToken)
private static async Task<Location?> GetSymbolLocationAsync(Solution solution, ISymbol symbol, CancellationToken cancellationToken)
{
var locations = symbol.Locations;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,7 @@ private static XNode[] RewriteMany(ISymbol symbol, HashSet<ISymbol>? visitedSymb
string xpathValue;
if (string.IsNullOrEmpty(pathAttribute?.Value))
{
xpathValue = BuildXPathForElement(element.Parent);
xpathValue = BuildXPathForElement(element.Parent!);
}
else
{
Expand Down Expand Up @@ -571,7 +571,7 @@ private static TNode Copy<TNode>(TNode node, bool copyAttributeAnnotations)
{
XContainer temp = new XElement("temp");
temp.Add(node);
copy = temp.LastNode;
copy = temp.LastNode!;
temp.RemoveNodes();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ await TryCreatePersistentStorageAsync(solutionKey, bulkLoadSnapshot, workingFold
// this was not a normal exception that we expected during DB open.
// Report this so we can try to address whatever is causing this.
FatalError.ReportAndCatch(ex);
IOUtilities.PerformIO(() => Directory.Delete(Path.GetDirectoryName(databaseFilePath), recursive: true));
IOUtilities.PerformIO(() => Directory.Delete(Path.GetDirectoryName(databaseFilePath)!, recursive: true));
}

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ public void Dispose()
private static void EnsureDirectory(string databaseFilePath)
{
var directory = Path.GetDirectoryName(databaseFilePath);
Contract.ThrowIfNull(directory);

if (Directory.Exists(directory))
{
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,13 @@ public static ISet<SyntaxKind> GetPrecedingModifiers(
return result;
}

public static TypeDeclarationSyntax GetContainingTypeDeclaration(
public static TypeDeclarationSyntax? GetContainingTypeDeclaration(
jasonmalinowski marked this conversation as resolved.
Show resolved Hide resolved
this SyntaxTree syntaxTree, int position, CancellationToken cancellationToken)
{
return syntaxTree.GetContainingTypeDeclarations(position, cancellationToken).FirstOrDefault();
}

public static BaseTypeDeclarationSyntax GetContainingTypeOrEnumDeclaration(
public static BaseTypeDeclarationSyntax? GetContainingTypeOrEnumDeclaration(
this SyntaxTree syntaxTree, int position, CancellationToken cancellationToken)
{
return syntaxTree.GetContainingTypeOrEnumDeclarations(position, cancellationToken).FirstOrDefault();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public XElement ToXElement() =>
new("CodeStyleOption", // Ensure that we use "CodeStyleOption" as the name for back compat.
new XAttribute(nameof(SerializationVersion), SerializationVersion),
new XAttribute("Type", GetTypeNameForSerialization()),
new XAttribute(nameof(Value), GetValueForSerialization()),
new XAttribute(nameof(Value), GetValueForSerialization()!),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's going on here? GetValueForSerialization is pretty directly marked as null-returning; can we revise that and push the suppression somewhere closer if possible?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's only nullable when using uninitialized value with T=string. There could be a later refactor on that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I'd say in that case we should:

  1. annotate GetValueForSerialization to return not-null.
  2. In the branch for string, do a Contract.ThrowIfNull().
  3. In the branch for bool, just ! since that's more obvious what's going on here.

Now I'm also a bit confused because the docs for the type say that T is only allowed to be bool or an enum, so clearly we are breaking that rule somewhere...? @mavasani or @jmarolf any idea if nulls are supposed to be supported here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jmarolf confirmed that we don't expect to get nulls here, so current code is good.

new XAttribute(nameof(DiagnosticSeverity), Notification.Severity.ToDiagnosticSeverity() ?? DiagnosticSeverity.Hidden));

private object? GetValueForSerialization()
Expand Down Expand Up @@ -133,7 +133,7 @@ public static CodeStyleOption2<T> FromXElement(XElement element)
var typeAttribute = element.Attribute("Type");
var valueAttribute = element.Attribute(nameof(Value));
var severityAttribute = element.Attribute(nameof(DiagnosticSeverity));
var version = (int)element.Attribute(nameof(SerializationVersion));
var version = (int)element.Attribute(nameof(SerializationVersion))!;
huoyaoyuan marked this conversation as resolved.
Show resolved Hide resolved

if (typeAttribute == null || valueAttribute == null || severityAttribute == null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -493,29 +493,19 @@ public static async Task<TRoot> ReplaceSyntaxAsync<TRoot>(
{
if (nodesToReplace.TryGetValue(span, out var currentNode))
{
var original = (SyntaxNode)retryAnnotations.GetAnnotations(currentNode).SingleOrDefault() ?? currentNode;
var original = (SyntaxNode?)retryAnnotations.GetAnnotations(currentNode).SingleOrDefault() ?? currentNode;
var newNode = await computeReplacementNodeAsync!(original, currentNode, cancellationToken).ConfigureAwait(false);
nodeReplacements[currentNode] = newNode;
}
else if (tokensToReplace.TryGetValue(span, out var currentToken))
{
var original = (SyntaxToken)retryAnnotations.GetAnnotations(currentToken).SingleOrDefault();
if (original == default)
{
original = currentToken;
}

var original = (SyntaxToken?)retryAnnotations.GetAnnotations(currentToken).SingleOrDefault() ?? currentToken;
jasonmalinowski marked this conversation as resolved.
Show resolved Hide resolved
var newToken = await computeReplacementTokenAsync!(original, currentToken, cancellationToken).ConfigureAwait(false);
tokenReplacements[currentToken] = newToken;
}
else if (triviaToReplace.TryGetValue(span, out var currentTrivia))
{
var original = (SyntaxTrivia)retryAnnotations.GetAnnotations(currentTrivia).SingleOrDefault();
if (original == default)
{
original = currentTrivia;
}

var original = (SyntaxTrivia?)retryAnnotations.GetAnnotations(currentTrivia).SingleOrDefault() ?? currentTrivia;
var newTrivia = await computeReplacementTriviaAsync!(original, currentTrivia, cancellationToken).ConfigureAwait(false);
triviaReplacements[currentTrivia] = newTrivia;
}
Expand Down
Loading