internal AnalysisQueue(VsProjectAnalyzer analyzer) { _workEvent = new AutoResetEvent(false); _cancel = new CancellationTokenSource(); _analyzer = analyzer; // save the analysis once it's ready, but give us a little time to be // initialized and start processing stuff... _lastSave = DateTime.Now - _SaveAnalysisTime + TimeSpan.FromSeconds(10); _queue = new List<IAnalyzable>[PriorityCount]; for (int i = 0; i < PriorityCount; i++) { _queue[i] = new List<IAnalyzable>(); } _enqueuedGroups = new HashSet<IGroupableAnalysisProject>(); _workThread = new Thread(Worker); _workThread.Name = "Node.js Analysis Queue"; _workThread.Priority = ThreadPriority.BelowNormal; _workThread.IsBackground = true; // start the thread, wait for our synchronization context to be created using (AutoResetEvent threadStarted = new AutoResetEvent(false)) { _workThread.Start(threadStarted); threadStarted.WaitOne(); } }
public NormalCompletionAnalysis(VsProjectAnalyzer vsProjectAnalyzer, ITextSnapshot snapshot, VisualStudio.Text.ITrackingSpan applicableSpan, VisualStudio.Text.ITextBuffer textBuffer, GetMemberOptions options) : base(applicableSpan, textBuffer) { _analyzer = vsProjectAnalyzer; _snapshot = snapshot; _applicableSpan = applicableSpan; _textBuffer = textBuffer; _options = options; }
public RequireCompletionAnalysis(VsProjectAnalyzer vsProjectAnalyzer, ITextSnapshot snapshot, VisualStudio.Text.ITrackingSpan applicableSpan, VisualStudio.Text.ITextBuffer textBuffer, bool quote) : base(applicableSpan, textBuffer) { _analyzer = vsProjectAnalyzer; _snapshot = snapshot; _applicableSpan = applicableSpan; _textBuffer = textBuffer; _quote = quote; }
internal ExpressionAnalysis(VsProjectAnalyzer analyzer, string expression, ModuleAnalysis analysis, int index, ITrackingSpan span, ITextSnapshot snapshot) { _expr = expression; _analysis = analysis; _index = index; _span = span; _analyzer = analyzer; _snapshot = snapshot; }
private const int ReparseDelay = 1000; // delay in MS before we re-parse a buffer w/ non-line changes. public BufferParser(IProjectEntry initialProjectEntry, VsProjectAnalyzer parser, ITextBuffer buffer) { _parser = parser; _timer = new Timer(ReparseTimer, null, Timeout.Infinite, Timeout.Infinite); _buffers = new[] { buffer }; _currentProjEntry = initialProjectEntry; AttachedViews = 1; InitBuffer(buffer); }
private void DataTipTest(string input, string selectionRegex, string expectedDataTip) { var buffer = new MockTextBuffer(input, @"C:\fob.js", "Node.js"); var view = new MockTextView(buffer); var classifierProvider = new NodejsClassifierProvider(new MockContentTypeRegistryService(NodejsConstants.Nodejs)); classifierProvider._classificationRegistry = new MockClassificationTypeRegistryService(); classifierProvider.GetClassifier(buffer); var analyzer = new VsProjectAnalyzer(); buffer.AddProperty(typeof(VsProjectAnalyzer), analyzer); analyzer.AddBuffer(buffer); analyzer.WaitForCompleteAnalysis(); var m = Regex.Match(input, selectionRegex); Assert.IsTrue(m.Success); var startPos = m.Index; var startLine = buffer.CurrentSnapshot.GetLineFromPosition(startPos); var endPos = m.Index + m.Length; var endLine = buffer.CurrentSnapshot.GetLineFromPosition(endPos); var selectionSpan = new TextSpan { iStartLine = startLine.LineNumber, iStartIndex = startPos - startLine.Start.Position, iEndLine = endLine.LineNumber, iEndIndex = endPos - endLine.Start.Position }; var dataTipSpan = DataTipTextViewFilter.GetDataTipSpan(view, selectionSpan); if (expectedDataTip == null) { Assert.IsNull(dataTipSpan); return; } Assert.IsNotNull(dataTipSpan); var actualSpan = dataTipSpan.Value; startPos = input.IndexOf(expectedDataTip); Assert.AreNotEqual(-1, startPos); startLine = buffer.CurrentSnapshot.GetLineFromPosition(startPos); endPos = startPos + expectedDataTip.Length; endLine = buffer.CurrentSnapshot.GetLineFromPosition(endPos); var expectedSpan = new TextSpan { iStartLine = startLine.LineNumber, iStartIndex = startPos - startLine.Start.Position, iEndLine = endLine.LineNumber, iEndIndex = endPos - endLine.Start.Position }; // TextSpan doesn't override ToString, so test output is unusable in case of failure when comparing // two spans directly - use an anonymous type instead to produce pretty output. Assert.AreEqual( new { expectedSpan.iStartLine, expectedSpan.iStartIndex, expectedSpan.iEndLine, expectedSpan.iEndIndex }, new { actualSpan.iStartLine, actualSpan.iStartIndex, actualSpan.iEndLine, actualSpan.iEndIndex }); }
public override CompletionSet GetCompletions(IGlyphService glyphService) { var analysis = GetAnalysisEntry(); var members = Enumerable.Empty <MemberResult>(); var text = PrecedingExpression; if (!string.IsNullOrEmpty(text)) { string fixedText = FixupCompletionText(text); if (analysis != null && fixedText != null) { members = analysis.GetMembersByIndex( fixedText, VsProjectAnalyzer.TranslateIndex( Span.GetEndPoint(_snapshot).Position, _snapshot, analysis ), _options ); } } else if (analysis != null) { members = analysis.GetAllAvailableMembersByIndex( VsProjectAnalyzer.TranslateIndex( Span.GetStartPoint(_snapshot).Position, _snapshot, analysis ), _options ); } return(new FuzzyCompletionSet( "Node.js", "Node.js", Span, members.Select(m => JsCompletion(glyphService, m)), CompletionComparer.UnderscoresLast, matchInsertionText: true )); }
private void UnHookErrorsAndWarnings(VsProjectAnalyzer res) { res.ErrorAdded -= OnErrorAdded; res.ErrorRemoved -= OnErrorRemoved; res.WarningAdded -= OnWarningAdded; res.WarningRemoved -= OnWarningRemoved; }
/* * Needed if we switch to per project Analysis levels internal NodejsTools.Options.AnalysisLevel AnalysisLevel(){ var analyzer = _analyzer; if (_analyzer != null) { return _analyzer.AnalysisLevel; } return NodejsTools.Options.AnalysisLevel.None; } */ private void IntellisenseOptionsPageAnalysisLevelChanged(object sender, EventArgs e) { var oldAnalyzer = _analyzer; _analyzer = null; var analyzer = new VsProjectAnalyzer(ProjectFolder); Reanalyze(this, analyzer); if (oldAnalyzer != null) { analyzer.SwitchAnalyzers(oldAnalyzer); if (oldAnalyzer.RemoveUser()) { oldAnalyzer.Dispose(); } } _analyzer = analyzer; _analyzer.MaxLogLength = NodejsPackage.Instance.IntellisenseOptionsPage.AnalysisLogMax; LogAnalysisLevel(); }
private void Reanalyze(HierarchyNode node, VsProjectAnalyzer newAnalyzer) { if (node != null) { for (var child = node.FirstChild; child != null; child = child.NextSibling) { if (child is PackageJsonFileNode) { ((PackageJsonFileNode)child).AnalyzePackageJson(newAnalyzer); } else if (child is NodejsFileNode) { if (((NodejsFileNode)child).ShouldAnalyze) { newAnalyzer.AnalyzeFile(child.Url, !child.IsNonMemberItem); } } Reanalyze(child, newAnalyzer); } } }
protected override void Reload() { using (new DebugTimer("Project Load")) { _intermediateOutputPath = Path.Combine(ProjectHome, GetProjectProperty("BaseIntermediateOutputPath")); if (_analyzer != null && _analyzer.RemoveUser()) { _analyzer.Dispose(); } _analyzer = new VsProjectAnalyzer(ProjectFolder); _analyzer.MaxLogLength = NodejsPackage.Instance.IntellisenseOptionsPage.AnalysisLogMax; LogAnalysisLevel(); base.Reload(); SyncFileSystem(); NodejsPackage.Instance.CheckSurveyNews(false); ModulesNode.ReloadHierarchySafe(); // scan for files which were loaded from cached analysis but no longer // exist and remove them. _analyzer.ReloadComplete(); var ignoredPaths = GetProjectProperty(NodejsConstants.AnalysisIgnoredDirectories); if (!string.IsNullOrWhiteSpace(ignoredPaths)) { _analysisIgnoredDirs = ignoredPaths.Split(';').Select(x => '\\' + x + '\\').ToArray(); } else { _analysisIgnoredDirs = new string[0]; } var maxFileSizeProp = GetProjectProperty(NodejsConstants.AnalysisMaxFileSize); int maxFileSize; if (maxFileSizeProp != null && Int32.TryParse(maxFileSizeProp, out maxFileSize)) { _maxFileSize = maxFileSize; } } }
public void SwitchAnalyzers(VsProjectAnalyzer oldAnalyzer) { lock (_activeBufferParsers) { // copy the Keys here as ReAnalyzeTextBuffers can mutuate the dictionary BufferParser[] bufferParsers; lock (oldAnalyzer._activeBufferParsers) { bufferParsers = oldAnalyzer._activeBufferParsers.ToArray(); } foreach (var bufferParser in bufferParsers) { _activeBufferParsers.Add(bufferParser); ReAnalyzeTextBuffers(bufferParser); } } }
private void IntellisenseOptionsPageAnalysisLevelChanged(object sender, EventArgs e) { if (_analyzer != null) { var analyzer = CreateLooseVsProjectAnalyzer(); analyzer.SwitchAnalyzers(_analyzer); if (_analyzer.RemoveUser()) { _analyzer.Dispose(); } _analyzer = analyzer; LogLooseFileAnalysisLevel(); } TelemetryLogger.LogAnalysisLevelChanged(IntellisenseOptionsPage.AnalysisLevel); }
protected override void Reload() { using (new DebugTimer("Project Load")) { // Populate values from project properties before we do anything else. // Otherwise we run into race conditions where, for instance, _analysisIgnoredDirectories // is not properly set before the FileNodes get created in base.Reload() UpdateProjectNodeFromProjectProperties(); if (_analyzer != null && _analyzer.RemoveUser()) { _analyzer.Dispose(); } _analyzer = new VsProjectAnalyzer(ProjectFolder); _analyzer.MaxLogLength = NodejsPackage.Instance.IntellisenseOptionsPage.AnalysisLogMax; LogAnalysisLevel(); base.Reload(); SyncFileSystem(); NodejsPackage.Instance.CheckSurveyNews(false); ModulesNode.ReloadHierarchySafe(); // scan for files which were loaded from cached analysis but no longer // exist and remove them. _analyzer.ReloadComplete(); } }
private void LogAnalysisLevel(VsProjectAnalyzer analyzer) { if (analyzer != null) { var level = analyzer.AnalysisLevel; NodejsPackage.Instance.Logger.LogEvent(Logging.NodejsToolsLogEvent.AnalysisLevel, (int)level); NodejsPackage.Instance.TelemetryLogger.LogAnalysisActivatedForProject(ProjectGuid, level); } }
public AddDirectoryAnalysis(string dir, VsProjectAnalyzer analyzer, ProjectItem originatingItem) { _dir = dir; _analyzer = analyzer; _originatingItem = originatingItem; }
private VsProjectAnalyzer CreateNewAnalyser() { var analyzer = new VsProjectAnalyzer(NodejsPackage.Instance.IntellisenseOptionsPage.AnalysisLevel, NodejsPackage.Instance.IntellisenseOptionsPage.SaveToDisk, ProjectFolder); analyzer.MaxLogLength = NodejsPackage.Instance.IntellisenseOptionsPage.AnalysisLogMax; LogAnalysisLevel(analyzer); return analyzer; }
protected override void Reload() { using (new DebugTimer("Project Load")) { // Populate values from project properties before we do anything else. // Otherwise we run into race conditions where, for instance, _analysisIgnoredDirectories // is not properly set before the FileNodes get created in base.Reload() UpdateProjectNodeFromProjectProperties(); if (_analyzer != null && _analyzer.RemoveUser()) { _analyzer.Dispose(); } _analyzer = CreateNewAnalyser(); base.Reload(); SyncFileSystem(); NodejsPackage.Instance.CheckSurveyNews(false); ModulesNode.ReloadHierarchySafe(); #if DEV14 TryToAcquireTypings(new[] { "node" }); #endif // scan for files which were loaded from cached analysis but no longer // exist and remove them. _analyzer.ReloadComplete(); } }
protected override void Dispose(bool disposing) { if (disposing) { if (_analyzer != null) { UnHookErrorsAndWarnings(_analyzer); if (WarningFiles.Count > 0 || ErrorFiles.Count > 0) { foreach (var file in WarningFiles.Concat(ErrorFiles)) { var node = FindNodeByFullPath(file) as NodejsFileNode; if (node != null) { //_analyzer.RemoveErrors(node.GetAnalysis(), suppressUpdate: false); } } } if (_analyzer.RemoveUser()) { _analyzer.Dispose(); } _analyzer = null; } lock (_idleNodeModulesLock) { if (_idleNodeModulesTimer != null) { _idleNodeModulesTimer.Dispose(); } _idleNodeModulesTimer = null; } NodejsPackage.Instance.IntellisenseOptionsPage.SaveToDiskChanged -= IntellisenseOptionsPageSaveToDiskChanged; NodejsPackage.Instance.IntellisenseOptionsPage.AnalysisLevelChanged -= IntellisenseOptionsPageAnalysisLevelChanged; NodejsPackage.Instance.IntellisenseOptionsPage.AnalysisLogMaximumChanged -= AnalysisLogMaximumChanged; NodejsPackage.Instance.GeneralOptionsPage.ShowBrowserAndNodeLabelsChanged -= ShowBrowserAndNodeLabelsChanged; OnDispose?.Invoke(this, EventArgs.Empty); RemoveChild(ModulesNode); ModulesNode?.Dispose(); ModulesNode = null; DelayedAnalysisQueue.Clear(); #if DEV14 _typingsAcquirer = null; #endif } base.Dispose(disposing); }
/// <summary> /// Updates the current parameter for the caret's current position. /// /// This will analyze the buffer for where we are currently located, find the current /// parameter that we're entering, and then update the signature. If our current /// signature does not have enough parameters we'll find a signature which does. /// </summary> private void UpdateCurrentParameter() { if (_sigHelpSession == null) { // we moved out of the original span for sig help, re-trigger based upon the position TriggerSignatureHelp(); return; } int position = _textView.Caret.Position.BufferPosition.Position; // we advance to the next parameter // TODO: need to parse and see if we have keyword arguments entered into the current signature yet NodejsSignature sig = _sigHelpSession.SelectedSignature as NodejsSignature; if (sig != null) { var prevBuffer = sig.ApplicableToSpan.TextBuffer; var textBuffer = _textView.TextBuffer; var targetPt = _textView.BufferGraph.MapDownToFirstMatch( new SnapshotPoint(_textView.TextBuffer.CurrentSnapshot, position), PointTrackingMode.Positive, EditorExtensions.IsNodeJsContent, PositionAffinity.Successor ); if (targetPt != null) { var span = targetPt.Value.Snapshot.CreateTrackingSpan(targetPt.Value.Position, 0, SpanTrackingMode.EdgeInclusive); var sigs = VsProjectAnalyzer.GetSignatures(targetPt.Value.Snapshot, span); bool retrigger = false; if (sigs.Signatures.Count == _sigHelpSession.Signatures.Count) { for (int i = 0; i < sigs.Signatures.Count && !retrigger; i++) { var leftSig = sigs.Signatures[i]; var rightSig = _sigHelpSession.Signatures[i]; if (leftSig.Parameters.Count == rightSig.Parameters.Count) { for (int j = 0; j < leftSig.Parameters.Count; j++) { var leftParam = leftSig.Parameters[j]; var rightParam = rightSig.Parameters[j]; if (leftParam.Name != rightParam.Name || leftParam.Documentation != rightParam.Documentation) { retrigger = true; break; } } } if (leftSig.Content != rightSig.Content || leftSig.Documentation != rightSig.Documentation) { retrigger = true; } } } else { retrigger = true; } if (retrigger) { _sigHelpSession.Dismiss(); TriggerSignatureHelp(); } else { int curParam = sigs.ParameterIndex; if (sigs.LastKeywordArgument != null) { curParam = Int32.MaxValue; for (int i = 0; i < sig.Parameters.Count; i++) { if (sig.Parameters[i].Name == sigs.LastKeywordArgument) { curParam = i; break; } } } if (curParam < sig.Parameters.Count) { sig.SetCurrentParameter(sig.Parameters[curParam]); } else if (sigs.LastKeywordArgument == String.Empty) { sig.SetCurrentParameter(null); } else { CommaFindBestSignature(curParam, sigs.LastKeywordArgument); } } } } }
protected override void Dispose(bool disposing) { if (disposing) { if (_analyzer != null) { UnHookErrorsAndWarnings(_analyzer); if (WarningFiles.Count > 0 || ErrorFiles.Count > 0) { foreach (var file in WarningFiles.Concat(ErrorFiles)) { var node = FindNodeByFullPath(file) as NodejsFileNode; if (node != null) { //_analyzer.RemoveErrors(node.GetAnalysis(), suppressUpdate: false); } } } if (_analyzer.RemoveUser()) { _analyzer.Dispose(); } _analyzer = null; } NodejsPackage.Instance.IntellisenseOptionsPage.SaveToDiskChanged -= IntellisenseOptionsPageSaveToDiskChanged; NodejsPackage.Instance.IntellisenseOptionsPage.AnalysisLevelChanged -= IntellisenseOptionsPageAnalysisLevelChanged; NodejsPackage.Instance.IntellisenseOptionsPage.AnalysisLogMaximumChanged -= AnalysisLogMaximumChanged; } base.Dispose(disposing); }
private void IntellisenseOptionsPageAnalysisLevelChanged(object sender, EventArgs e) { var analyzer = new VsProjectAnalyzer(IntellisenseOptionsPage.AnalysisLevel, IntellisenseOptionsPage.SaveToDisk); analyzer.SwitchAnalyzers(_analyzer); if (_analyzer.RemoveUser()) { _analyzer.Dispose(); } _analyzer = analyzer; LogLooseFileAnalysisLevel(); }
public RequireCompletionAnalysis(VsProjectAnalyzer vsProjectAnalyzer, ITextSnapshot snapshot, VisualStudio.Text.ITrackingSpan applicableSpan, VisualStudio.Text.ITextBuffer textBuffer, bool quote) : base(applicableSpan, textBuffer) { _snapshot = snapshot; _quote = quote; }
private static void LogAnalysisLevel(VsProjectAnalyzer analyzer) { if (analyzer != null) { NodejsPackage.Instance.Logger.LogEvent(Logging.NodejsToolsLogEvent.AnalysisLevel, (int)analyzer.AnalysisLevel); } }
private void IntellisenseOptionsPageAnalysisLevelChanged(object sender, EventArgs e) { var oldAnalyzer = _analyzer; _analyzer = null; var analyzer = CreateNewAnalyser(); Reanalyze(this, analyzer); if (oldAnalyzer != null) { analyzer.SwitchAnalyzers(oldAnalyzer); if (oldAnalyzer.RemoveUser()) { oldAnalyzer.Dispose(); } } _analyzer = analyzer; #if DEV14 TryToAcquireCurrentTypings(); #endif }