Make AtDirectiveCompletionPoint resilient to null owners.

- Added a test to verify the new owner == null case.

#1733
This commit is contained in:
N. Taylor Mullen 2017-10-24 12:26:57 -07:00
parent fea4095833
commit 6ac0137a9f
2 changed files with 27 additions and 1 deletions

View File

@ -147,12 +147,19 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
return completionItems; return completionItems;
} }
private bool AtDirectiveCompletionPoint(RazorSyntaxTree syntaxTree, CompletionContext context) // Internal for testing
internal bool AtDirectiveCompletionPoint(RazorSyntaxTree syntaxTree, CompletionContext context)
{ {
if (TryGetRazorSnapshotPoint(context, out var razorSnapshotPoint)) if (TryGetRazorSnapshotPoint(context, out var razorSnapshotPoint))
{ {
var change = new SourceChange(razorSnapshotPoint.Position, 0, string.Empty); var change = new SourceChange(razorSnapshotPoint.Position, 0, string.Empty);
var owner = syntaxTree.Root.LocateOwner(change); var owner = syntaxTree.Root.LocateOwner(change);
if (owner == null)
{
return false;
}
if (owner.ChunkGenerator is ExpressionChunkGenerator && if (owner.ChunkGenerator is ExpressionChunkGenerator &&
owner.Symbols.All(IsDirectiveCompletableSymbol) && owner.Symbols.All(IsDirectiveCompletableSymbol) &&
// Do not provide IntelliSense for explicit expressions. Explicit expressions will usually look like: // Do not provide IntelliSense for explicit expressions. Explicit expressions will usually look like:

View File

@ -4,6 +4,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.ComponentModel.Composition;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -29,6 +30,24 @@ namespace Microsoft.VisualStudio.LanguageServices.Razor.Editor
CSharpCodeParser.TagHelperPrefixDirectiveDescriptor, CSharpCodeParser.TagHelperPrefixDirectiveDescriptor,
}; };
[Fact]
public void AtDirectiveCompletionPoint_ReturnsFalseIfChangeHasNoOwner()
{
// Arrange
var codeDocumentProvider = CreateCodeDocumentProvider("@", Enumerable.Empty<DirectiveDescriptor>());
var completionProvider = new FailOnGetCompletionsProvider(codeDocumentProvider);
var document = CreateDocument();
codeDocumentProvider.Value.TryGetFromDocument(document, out var codeDocument);
var syntaxTree = codeDocument.GetSyntaxTree();
var completionContext = CreateContext(2, completionProvider, document);
// Act
var result = completionProvider.AtDirectiveCompletionPoint(syntaxTree, completionContext);
// Assert
Assert.False(result);
}
[Fact] [Fact]
public async Task GetDescriptionAsync_AddsDirectiveDescriptionIfPropertyExists() public async Task GetDescriptionAsync_AddsDirectiveDescriptionIfPropertyExists()
{ {