public async Task <bool?> IsActiveStatementInExceptionRegionAsync(ActiveInstructionId instructionId, CancellationToken cancellationToken) { try { if (_editSession == null) { return(null); } Debug.Assert(_debuggingSession != null); // TODO: Avoid enumerating active statements for unchanged documents. // We would need to add a document path parameter to be able to find the document we need to check for changes. // https://github.com/dotnet/roslyn/issues/24324 var baseActiveStatements = await _editSession.BaseActiveStatements.GetValueAsync(cancellationToken).ConfigureAwait(false); if (!baseActiveStatements.InstructionMap.TryGetValue(instructionId, out var baseActiveStatement)) { return(null); } // TODO: avoid waiting for ERs of all active statements to be calculated and just calculate the one we are interested in at this moment: // https://github.com/dotnet/roslyn/issues/24324 var baseExceptionRegions = await _editSession.BaseActiveExceptionRegions.GetValueAsync(cancellationToken).ConfigureAwait(false); return(baseExceptionRegions[baseActiveStatement.Ordinal].IsActiveStatementCovered); } catch (Exception e) when(FatalError.ReportWithoutCrashUnlessCanceled(e)) { return(null); } }
public async Task <bool?> IsActiveStatementInExceptionRegionAsync(ActiveInstructionId instructionId, CancellationToken cancellationToken) { try { var editSession = _editSession; if (editSession == null) { return(null); } // This method is only called when the EnC is about to apply changes, at which point all active statements and // their exception regions will be needed. Hence it's not necessary to scope this query down to just the instruction // the debugger is interested at this point while not calculating the others. var baseActiveStatements = await editSession.BaseActiveStatements.GetValueAsync(cancellationToken).ConfigureAwait(false); if (!baseActiveStatements.InstructionMap.TryGetValue(instructionId, out var baseActiveStatement)) { return(null); } var baseExceptionRegions = (await editSession.GetBaseActiveExceptionRegionsAsync(cancellationToken).ConfigureAwait(false))[baseActiveStatement.Ordinal]; // If the document is out-of-sync the exception regions can't be determined. return(baseExceptionRegions.Spans.IsDefault ? (bool?)null : baseExceptionRegions.IsActiveStatementCovered); } catch (Exception e) when(FatalError.ReportWithoutCrashUnlessCanceled(e)) { return(null); } }
public async Task <LinePositionSpan?> GetCurrentActiveStatementPositionAsync(ActiveInstructionId instructionId, CancellationToken cancellationToken) { try { // It is allowed to call this method before entering or after exiting break mode. In fact, the VS debugger does so. // We return null since there the concept of active statement only makes sense during break mode. var editSession = _editSession; if (editSession == null) { return(null); } // TODO: Avoid enumerating active statements for unchanged documents. // We would need to add a document path parameter to be able to find the document we need to check for changes. // https://github.com/dotnet/roslyn/issues/24324 var baseActiveStatements = await editSession.BaseActiveStatements.GetValueAsync(cancellationToken).ConfigureAwait(false); if (!baseActiveStatements.InstructionMap.TryGetValue(instructionId, out var baseActiveStatement)) { return(null); } var(oldPrimaryDocument, _) = await editSession.DebuggingSession.LastCommittedSolution.GetDocumentAndStateAsync(baseActiveStatement.PrimaryDocumentId, cancellationToken).ConfigureAwait(false); if (oldPrimaryDocument == null) { // Can't determine position of an active statement if the document is out-of-sync with loaded module debug information. return(null); } var primaryDocument = _workspace.CurrentSolution.GetDocument(baseActiveStatement.PrimaryDocumentId); if (primaryDocument == null) { // The document has been deleted. return(null); } var documentAnalysis = await editSession.GetDocumentAnalysis(oldPrimaryDocument, primaryDocument).GetValueAsync(cancellationToken).ConfigureAwait(false); var currentActiveStatements = documentAnalysis.ActiveStatements; if (currentActiveStatements.IsDefault) { // The document has syntax errors. return(null); } return(currentActiveStatements[baseActiveStatement.PrimaryDocumentOrdinal].Span); } catch (Exception e) when(FatalError.ReportWithoutCrashUnlessCanceled(e)) { return(null); } }
public ActiveStatement(int ordinal, int primaryDocumentOrdinal, ImmutableArray <DocumentId> documentIds, ActiveStatementFlags flags, LinePositionSpan span, ActiveInstructionId instructionId, ImmutableArray <Guid> threadIds) { Debug.Assert(ordinal >= 0); Debug.Assert(primaryDocumentOrdinal >= 0); Debug.Assert(!documentIds.IsDefaultOrEmpty); Ordinal = ordinal; PrimaryDocumentOrdinal = primaryDocumentOrdinal; DocumentIds = documentIds; Flags = flags; Span = span; ThreadIds = threadIds; InstructionId = instructionId; }
public ActiveStatementDebugInfo( ActiveInstructionId instructionId, string documentNameOpt, LinePositionSpan linePositionSpan, ImmutableArray <Guid> threadIds, ActiveStatementFlags flags) { Debug.Assert(!threadIds.IsDefaultOrEmpty); ThreadIds = threadIds; InstructionId = instructionId; Flags = flags; DocumentNameOpt = documentNameOpt; LinePositionSpan = linePositionSpan; }