/// <summary> /// Called when a work item stops. The activity name = providerName + activityName without 'Stop' suffix. /// It updates CurrentActivityId to track this fact. The Stop event associated with stop should log the ActivityID associated with the event. /// /// If activity tracing is not on, then activityId and relatedActivityId are not set /// </summary> public void OnStop(string providerName, string activityName, int task, ref Guid activityId) { if (m_current == null) // We are not enabled { return; } var fullActivityName = NormalizeActivityName(providerName, activityName, task); var etwLog = TplEtwProvider.Log; if (etwLog.Debug) { etwLog.DebugFacilityMessage("OnStopEnter", fullActivityName); etwLog.DebugFacilityMessage("OnStopEnterActivityState", ActivityInfo.LiveActivities(m_current.Value)); } for (; ;) // This is a retry loop. { ActivityInfo currentActivity = m_current.Value; ActivityInfo newCurrentActivity = null; // if we have seen any live activities (orphans), at he first one we have seen. // Search to find the activity to stop in one pass. This insures that we don't let one mistake // (stopping something that was not started) cause all active starts to be stopped // By first finding the target start to stop we are more robust. ActivityInfo activityToStop = FindActiveActivity(fullActivityName, currentActivity); // ignore stops where we can't find a start because we may have popped them previously. if (activityToStop == null) { activityId = Guid.Empty; // if (etwLog.Debug) { etwLog.DebugFacilityMessage("OnStopRET", "Fail"); } return; } activityId = activityToStop.ActivityId; // See if there are any orphans that need to be stopped. ActivityInfo orphan = currentActivity; while (orphan != activityToStop && orphan != null) { if (orphan.m_stopped != 0) // Skip dead activities. { orphan = orphan.m_creator; continue; } if (orphan.CanBeOrphan()) { // We can't pop anything after we see a valid orphan, remember this for later when we update m_current. if (newCurrentActivity == null) { newCurrentActivity = orphan; } } else { orphan.m_stopped = 1; Contract.Assert(orphan.m_stopped != 0); } orphan = orphan.m_creator; } // try to Stop the activity atomically. Other threads may be trying to do this as well. if (Interlocked.CompareExchange(ref activityToStop.m_stopped, 1, 0) == 0) { // I succeeded stopping this activity. Now we update our m_current pointer // If I haven't yet determined the new current activity, it is my creator. if (newCurrentActivity == null) { newCurrentActivity = activityToStop.m_creator; } m_current.Value = newCurrentActivity; if (etwLog.Debug) { etwLog.DebugFacilityMessage("OnStopRetActivityState", ActivityInfo.LiveActivities(newCurrentActivity)); etwLog.DebugFacilityMessage("OnStopRet", activityId.ToString()); } return; } // We failed to stop it. We must have hit a ---- to stop it. Just start over and try again. } }
/// <summary> /// Called on work item begins. The activity name = providerName + activityName without 'Start' suffix. /// It updates CurrentActivityId to track. /// /// It returns true if the Start should be logged, otherwise (if it is illegal recurision) it return false. /// /// The start event should use as its activity ID the CurrentActivityId AFTER calling this routine and its /// RelatedActivityID the CurrentActivityId BEFORE calling this routine (the creator). /// /// If activity tracing is not on, then activityId and relatedActivityId are not set /// </summary> public void OnStart(string providerName, string activityName, int task, ref Guid activityId, ref Guid relatedActivityId, EventActivityOptions options) { if (m_current == null) // We are not enabled { return; } Contract.Assert((options & EventActivityOptions.Disable) == 0); var currentActivity = m_current.Value; var fullActivityName = NormalizeActivityName(providerName, activityName, task); var etwLog = TplEtwProvider.Log; if (etwLog.Debug) { etwLog.DebugFacilityMessage("OnStartEnter", fullActivityName); etwLog.DebugFacilityMessage("OnStartEnterActivityState", ActivityInfo.LiveActivities(currentActivity)); } if (currentActivity != null) { // Stop activity tracking if we reached the maximum allowed depth if (currentActivity.m_level >= MAX_ACTIVITY_DEPTH) { activityId = Guid.Empty; relatedActivityId = Guid.Empty; if (etwLog.Debug) { etwLog.DebugFacilityMessage("OnStartRET", "Fail"); } return; } // Check for recursion, and force-stop any activities if the activity already started. if ((options & EventActivityOptions.Recursive) == 0) { ActivityInfo existingActivity = FindActiveActivity(fullActivityName, currentActivity); if (existingActivity != null) { // OnStop(providerName, activityName, task, ref activityId); currentActivity = m_current.Value; } } } // Get a unique ID for this activity. long id; if (currentActivity == null) { id = Interlocked.Increment(ref m_nextId); } else { id = Interlocked.Increment(ref currentActivity.m_lastChildID); } // Remember the previous ID so we can log it relatedActivityId = currentActivity != null ? currentActivity.ActivityId : Guid.Empty; // Add to the list of started but not stopped activities. ActivityInfo newActivity = new ActivityInfo(fullActivityName, id, currentActivity, options); m_current.Value = newActivity; // Remember the current ID so we can log it activityId = newActivity.ActivityId; if (etwLog.Debug) { etwLog.DebugFacilityMessage("OnStartRetActivityState", ActivityInfo.LiveActivities(newActivity)); etwLog.DebugFacilityMessage1("OnStartRet", activityId.ToString(), relatedActivityId.ToString()); } }
private void UpdateQuickInfoContent(IQuickInfoSession session, SnapshotPoint triggerPoint) { /* use the experimental model to locate and process the expression */ Stopwatch stopwatch = Stopwatch.StartNew(); // lex the entire document var currentSnapshot = triggerPoint.Snapshot; var input = new SnapshotCharStream(currentSnapshot, new Span(0, currentSnapshot.Length)); var unicodeInput = new JavaUnicodeStream(input); var lexer = new Java2Lexer(unicodeInput); var tokens = new CommonTokenStream(lexer); tokens.Fill(); // locate the last token before the trigger point while (true) { IToken nextToken = tokens.LT(1); if (nextToken.Type == CharStreamConstants.EndOfFile) { break; } if (nextToken.StartIndex > triggerPoint.Position) { break; } tokens.Consume(); } IToken triggerToken = tokens.LT(-1); if (triggerToken == null) { return; } switch (triggerToken.Type) { // symbol references case Java2Lexer.IDENTIFIER: case Java2Lexer.THIS: case Java2Lexer.SUPER: // primitive types case Java2Lexer.BOOLEAN: case Java2Lexer.CHAR: case Java2Lexer.BYTE: case Java2Lexer.SHORT: case Java2Lexer.INT: case Java2Lexer.LONG: case Java2Lexer.FLOAT: case Java2Lexer.DOUBLE: // literals case Java2Lexer.INTLITERAL: case Java2Lexer.LONGLITERAL: case Java2Lexer.FLOATLITERAL: case Java2Lexer.DOUBLELITERAL: case Java2Lexer.CHARLITERAL: case Java2Lexer.STRINGLITERAL: case Java2Lexer.TRUE: case Java2Lexer.FALSE: case Java2Lexer.NULL: break; default: return; } NetworkInterpreter interpreter = CreateNetworkInterpreter(tokens); while (interpreter.TryStepBackward()) { if (interpreter.Contexts.Count == 0 || interpreter.Contexts.Count > 400) { break; } if (interpreter.Contexts.All(context => context.BoundedStart)) { break; } } interpreter.Contexts.RemoveAll(i => !i.BoundedStart); interpreter.CombineBoundedStartContexts(); IOutputWindowPane pane = Provider.OutputWindowService.TryGetPane(PredefinedOutputWindowPanes.TvlIntellisense); if (pane != null) { pane.WriteLine(string.Format("Located {0} QuickInfo expression(s) in {1}ms.", interpreter.Contexts.Count, stopwatch.ElapsedMilliseconds)); } HashSet <string> intermediateResult = new HashSet <string>(); HashSet <string> finalResult = new HashSet <string>(); List <object> quickInfoContent = new List <object>(); foreach (var context in interpreter.Contexts) { Span?span = null; foreach (var transition in context.Transitions) { if (!transition.Transition.IsMatch) { continue; } IToken token = transition.Token; Span tokenSpan = new Span(token.StartIndex, token.StopIndex - token.StartIndex + 1); if (span == null) { span = tokenSpan; } else { span = Span.FromBounds(Math.Min(span.Value.Start, tokenSpan.Start), Math.Max(span.Value.End, tokenSpan.End)); } } if (span.HasValue && !span.Value.IsEmpty) { string text = currentSnapshot.GetText(span.Value); if (!intermediateResult.Add(text)) { continue; } AstParserRuleReturnScope <CommonTree, CommonToken> result = null; try { var expressionInput = new ANTLRStringStream(text); var expressionUnicodeInput = new JavaUnicodeStream(expressionInput); var expressionLexer = new Java2Lexer(expressionUnicodeInput); var expressionTokens = new CommonTokenStream(expressionLexer); var expressionParser = new Java2Parser(expressionTokens); result = expressionParser.primary(); // anchors experiment Contract.Assert(TextBuffer.CurrentSnapshot == triggerPoint.Snapshot); ClassAnchorTracker tracker = new ClassAnchorTracker(TextBuffer, null); SnapshotSpan trackedSpan = new SnapshotSpan(triggerPoint.Snapshot, 0, triggerPoint.Position); ITagSpan <ScopeAnchorTag>[] tags = tracker.GetTags(new NormalizedSnapshotSpanCollection(trackedSpan)).ToArray(); text = result.Tree.ToStringTree(); } catch (RecognitionException) { text = "Could not parse: " + text; } text = text.Replace("\n", "\\n").Replace("\r", "\\r"); finalResult.Add(text); //if (Regex.IsMatch(text, @"^[A-Za-z_]+(?:\.\w+)*$")) //{ // NameResolutionContext resolutionContext = NameResolutionContext.Global(Provider.IntelliSenseCache); // resolutionContext = resolutionContext.Filter(text, null, true); // CodeElement[] matching = resolutionContext.GetMatchingElements(); // if (matching.Length > 0) // { // foreach (var element in matching) // { // element.AugmentQuickInfoSession(quickInfoContent); // } // } // else // { // // check if this is a package // CodePhysicalFile[] files = Provider.IntelliSenseCache.GetPackageFiles(text, true); // if (files.Length > 0) // { // finalResult.Add(string.Format("package {0}", text)); // } // else // { // // check if this is a type // string typeName = text.Substring(text.LastIndexOf('.') + 1); // CodeType[] types = Provider.IntelliSenseCache.GetTypes(typeName, true); // foreach (var type in types) // { // if (type.FullName == text) // finalResult.Add(string.Format("{0}: {1}", type.GetType().Name, type.FullName)); // } // } // } //} //else //{ // finalResult.Add(text); //} } } ITrackingSpan applicableToSpan = null; foreach (var result in finalResult) { quickInfoContent.Add(result); } applicableToSpan = currentSnapshot.CreateTrackingSpan(new Span(triggerToken.StartIndex, triggerToken.StopIndex - triggerToken.StartIndex + 1), SpanTrackingMode.EdgeExclusive); //try //{ // Expression currentExpression = Provider.IntellisenseCache.ParseExpression(selection); // if (currentExpression != null) // { // SnapshotSpan? span = currentExpression.Span; // if (span.HasValue) // applicableToSpan = span.Value.Snapshot.CreateTrackingSpan(span.Value, SpanTrackingMode.EdgeExclusive); // quickInfoContent.Add(currentExpression.ToString()); // } // else // { // quickInfoContent.Add("Could not parse expression."); // } //} //catch (Exception ex) //{ // if (ErrorHandler.IsCriticalException(ex)) // throw; // quickInfoContent.Add(ex.Message); //} lock (_contentUpdateLock) { _triggerPoint = triggerPoint; _applicableToSpan = applicableToSpan; _quickInfoContent = quickInfoContent; } IWpfTextView wpfTextView = session.TextView as IWpfTextView; if (wpfTextView != null && wpfTextView.VisualElement != null) { ITrackingPoint trackingTriggerPoint = triggerPoint.Snapshot.CreateTrackingPoint(triggerPoint.Position, PointTrackingMode.Negative); wpfTextView.VisualElement.Dispatcher.BeginInvoke((Action <IQuickInfoSession, ITrackingPoint, bool>)RetriggerQuickInfo, session, trackingTriggerPoint, true); } }
/// <summary> /// Called on work item begins. The activity name = providerName + activityName without 'Start' suffix. /// It updates CurrentActivityId to track. /// /// It returns true if the Start should be logged, otherwise (if it is illegal recursion) it return false. /// /// The start event should use as its activity ID the CurrentActivityId AFTER calling this routine and its /// RelatedActivityID the CurrentActivityId BEFORE calling this routine (the creator). /// /// If activity tracing is not on, then activityId and relatedActivityId are not set /// </summary> public void OnStart(string providerName, string activityName, int task, ref Guid activityId, ref Guid relatedActivityId, EventActivityOptions options) { if (m_current == null) // We are not enabled { // We used to rely on the TPL provider turning us on, but that has the disadvantage that you don't get Start-Stop tracking // until you use Tasks for the first time (which you may never do). Thus we change it to pull rather tan push for whether // we are enabled. if (m_checkedForEnable) { return; } m_checkedForEnable = true; if (TplEtwProvider.Log.IsEnabled(EventLevel.Informational, TplEtwProvider.Keywords.TasksFlowActivityIds)) { Enable(); } if (m_current == null) { return; } } Contract.Assert((options & EventActivityOptions.Disable) == 0); var currentActivity = m_current.Value; var fullActivityName = NormalizeActivityName(providerName, activityName, task); var etwLog = TplEtwProvider.Log; if (etwLog.Debug) { etwLog.DebugFacilityMessage("OnStartEnter", fullActivityName); etwLog.DebugFacilityMessage("OnStartEnterActivityState", ActivityInfo.LiveActivities(currentActivity)); } if (currentActivity != null) { // Stop activity tracking if we reached the maximum allowed depth if (currentActivity.m_level >= MAX_ACTIVITY_DEPTH) { activityId = Guid.Empty; relatedActivityId = Guid.Empty; if (etwLog.Debug) { etwLog.DebugFacilityMessage("OnStartRET", "Fail"); } return; } // Check for recursion, and force-stop any activities if the activity already started. if ((options & EventActivityOptions.Recursive) == 0) { ActivityInfo existingActivity = FindActiveActivity(fullActivityName, currentActivity); if (existingActivity != null) { OnStop(providerName, activityName, task, ref activityId); currentActivity = m_current.Value; } } } // Get a unique ID for this activity. long id; if (currentActivity == null) { id = Interlocked.Increment(ref m_nextId); } else { id = Interlocked.Increment(ref currentActivity.m_lastChildID); } // The previous ID is my 'causer' and becomes my related activity ID relatedActivityId = EventSource.CurrentThreadActivityId; // Add to the list of started but not stopped activities. ActivityInfo newActivity = new ActivityInfo(fullActivityName, id, currentActivity, relatedActivityId, options); m_current.Value = newActivity; // Remember the current ID so we can log it activityId = newActivity.ActivityId; if (etwLog.Debug) { etwLog.DebugFacilityMessage("OnStartRetActivityState", ActivityInfo.LiveActivities(newActivity)); etwLog.DebugFacilityMessage1("OnStartRet", activityId.ToString(), relatedActivityId.ToString()); } }
public void Apply(Lexer lexer) { lexer._mode = this.Mode; Contract.Assert(_modeStack != null); lexer._modeStack.AddRange(_modeStack ?? EmptyModeStack); }