Skip to content

Commit

Permalink
Merge pull request #464 from mousetraps/i462
Browse files Browse the repository at this point in the history
Fix #462 completions should not be displayed after funciton, let, const
  • Loading branch information
mousetraps committed Sep 16, 2015
2 parents 33ac229 + f1cad85 commit 43eae98
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 57 deletions.
72 changes: 38 additions & 34 deletions Nodejs/Product/Nodejs/Intellisense/VsProjectAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ sealed partial class VsProjectAnalyzer : IDisposable {

private readonly TaskProvider _defaultTaskProvider = CreateDefaultTaskProvider();

internal static readonly string[] _emptyCompletionContextKeywords = new string[] {
"var", "function", "const", "let"
};
#if FALSE
private readonly UnresolvedImportSquiggleProvider _unresolvedSquiggles;
#endif
Expand Down Expand Up @@ -156,9 +159,9 @@ private void CreateNewAnalyzer(AnalysisLimits limits) {
_fullyLoaded = true;
}

private bool ShouldEnqueue() {
return _analysisLevel != AnalysisLevel.None && _analysisLevel != AnalysisLevel.Preview;
}
private bool ShouldEnqueue() {
return _analysisLevel != AnalysisLevel.None && _analysisLevel != AnalysisLevel.Preview;
}

#region Public API

Expand Down Expand Up @@ -257,7 +260,7 @@ public void RemoveBuffer(ITextBuffer buffer) {
}

BufferParser bufferParser;
if (!buffer.Properties.TryGetProperty<BufferParser>(typeof(BufferParser), out bufferParser)) {
if (!buffer.Properties.TryGetProperty<BufferParser>(typeof(BufferParser), out bufferParser)) {
return;
}

Expand Down Expand Up @@ -323,7 +326,7 @@ private void AnalyzeFile(string path, bool reportErrors, ProjectItem originating
if (!reportErrors) {
TaskProvider.Clear(item.Entry, ParserTaskMoniker);
}

if ((_reparseDateTime != null && new FileInfo(path).LastWriteTime > _reparseDateTime.Value)
|| (reportErrors && !item.ReportErrors) ||
(item.Entry.Module == null || item.Entry.Unit == null)) {
Expand Down Expand Up @@ -378,21 +381,21 @@ public void AddPackageJson(string packageJsonPath) {
AddPackageJson(packageJsonPath, (string)mainFile, dependencyList);
}
}
}

private static List<string> GetDependencyListFromJson(Dictionary<string, object> json, params string[] dependencyTypes) {
var allDependencies = new List<string>();
foreach (var type in dependencyTypes) {
object dependencies;
json.TryGetValue(type, out dependencies);
var dep = dependencies as Dictionary<string, object>;
if (dep != null) {
allDependencies.AddRange(dep.Keys.ToList());
}
}
return allDependencies;
}

}

private static List<string> GetDependencyListFromJson(Dictionary<string, object> json, params string[] dependencyTypes) {
var allDependencies = new List<string>();
foreach (var type in dependencyTypes) {
object dependencies;
json.TryGetValue(type, out dependencies);
var dep = dependencies as Dictionary<string, object>;
if (dep != null) {
allDependencies.AddRange(dep.Keys.ToList());
}
}
return allDependencies;
}

public void AddPackageJson(string path, string mainFile, List<string> dependencies) {
if (!_fullyLoaded) {
lock (_loadingDeltas) {
Expand Down Expand Up @@ -1191,17 +1194,17 @@ private static CompletionAnalysis TrySpecialCompletions(ITextSnapshot snapshot,
if (range != null) {
start = range.Value.Start;
}
}

// Get the classifiers from beginning of the line to the beginning of snapSpan.
// The contents of snapSpan differ depending on what is determined in
// CompletionSource.GetApplicableSpan.
//
// In the case of:
// var myIdentifier<cursor>
// the applicable span will be "myIdentifier", so GetClassificationSpans will operate on "var "
//
// In the case of comments and string literals, the applicable span will be empty,
}

// Get the classifiers from beginning of the line to the beginning of snapSpan.
// The contents of snapSpan differ depending on what is determined in
// CompletionSource.GetApplicableSpan.
//
// In the case of:
// var myIdentifier<cursor>
// the applicable span will be "myIdentifier", so GetClassificationSpans will operate on "var "
//
// In the case of comments and string literals, the applicable span will be empty,
// so snapSpan.Start will occur at the current cursor position.
var tokens = classifier.GetClassificationSpans(new SnapshotSpan(start.GetContainingLine().Start, snapSpan.Start));
if (tokens.Count > 0) {
Expand All @@ -1210,8 +1213,9 @@ private static CompletionAnalysis TrySpecialCompletions(ITextSnapshot snapshot,

if (lastClass.ClassificationType == classifier.Provider.Comment ||
lastClass.ClassificationType == classifier.Provider.StringLiteral ||
(lastClass.ClassificationType == classifier.Provider.Keyword && lastClass.Span.GetText() == "var")) {
// No completions in comments, strings, or directly after "var" keywords.
(lastClass.ClassificationType == classifier.Provider.Keyword &&
_emptyCompletionContextKeywords.Contains(lastClass.Span.GetText()))) {
// No completions in comments, strings, or directly after certain keywords.
return CompletionAnalysis.EmptyCompletionContext;
}
return null;
Expand Down Expand Up @@ -1288,7 +1292,7 @@ private void OnErrorRemoved(string path) {
private void ClearParserTasks(IProjectEntry entry) {
if (entry != null) {
TaskProvider.Clear(entry, ParserTaskMoniker);

bool changed;
lock (_hasParseErrors) {
changed = _hasParseErrors.Remove(entry);
Expand Down
49 changes: 26 additions & 23 deletions Nodejs/Tests/Core.UI/BasicIntellisense.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using System;
using System.Linq;
using System.Windows;
using Microsoft.NodejsTools.Intellisense;
using Microsoft.VisualStudio.Language.Intellisense;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.Text;
Expand Down Expand Up @@ -272,29 +273,31 @@ public void IntellisenseAfterMultiLineComment() {
/// </summary>
[TestMethod, Priority(0), TestCategory("Core")]
[HostType("VSTestHost")]
public void IntellisenseAfterVarKeyword() {
var project = Project("IntellisenseAfterVarKeywordTest",
Compile("server", "var c \r\nexports.var = 3; exports.var ")
);

using (var solution = project.Generate().ToVs()) {
var server = solution.OpenItem("IntellisenseAfterVarKeywordTest", "server.js");

server.MoveCaret(1, 4);
Keyboard.Type(Keyboard.CtrlSpace.ToString());
using (var sh = server.WaitForSession<ICompletionSession>(true)) { }

server.MoveCaret(1, 6);
Keyboard.Type(Keyboard.CtrlSpace.ToString());
server.AssertNoIntellisenseSession();

server.MoveCaret(1, 7);
Keyboard.Type(Keyboard.CtrlSpace.ToString());
using (var sh = server.WaitForSession<ICompletionSession>(true)) { }

server.MoveCaret(2, 30);
Keyboard.Type(Keyboard.CtrlSpace.ToString());
using (var sh = server.WaitForSession<ICompletionSession>(true)) { }
public void IntellisenseAfterEmptyCompletionContextKeywords() {
foreach (var keyword in VsProjectAnalyzer._emptyCompletionContextKeywords) {
var project = Project("IntellisenseAfterEmptyCompletionContextKeywordTest",
Compile("server", String.Format("{0} c \r\nexports.{0} = 3; exports.{0} ", keyword))
);

using (var solution = project.Generate().ToVs()) {
var server = solution.OpenItem("IntellisenseAfterEmptyCompletionContextKeywordTest", "server.js");

server.MoveCaret(1, keyword.Length + 1);
Keyboard.Type(Keyboard.CtrlSpace.ToString());
using (var sh = server.WaitForSession<ICompletionSession>(true)) { }

server.MoveCaret(1, keyword.Length + 3);
Keyboard.Type(Keyboard.CtrlSpace.ToString());
server.AssertNoIntellisenseSession();

server.MoveCaret(1, keyword.Length + 4);
Keyboard.Type(Keyboard.CtrlSpace.ToString());
using (var sh = server.WaitForSession<ICompletionSession>(true)) { }

server.MoveCaret(2, keyword.Length*2 + 24);
Keyboard.Type(Keyboard.CtrlSpace.ToString());
using (var sh = server.WaitForSession<ICompletionSession>(true)) { }
}
}
}

Expand Down

0 comments on commit 43eae98

Please sign in to comment.