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;
 }
Example #5
0
            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);
            }
Example #6
0
        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 });
        }
Example #7
0
        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);
         }
     }
 }
Example #13
0
 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);
 }
Example #14
0
        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();
            }
        }
Example #15
0
 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();
 }
Example #23
0
 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
        }