/// <summary>
        /// Create a SequencePointList with the raw sequence points from an ArrayBuilder.
        /// A linked list of instances for each syntax tree is created (almost always of length one).
        /// </summary>
        public static SequencePointList Create(ArrayBuilder<RawSequencePoint> seqPointBuilder, ILBuilder builder)
        {
            if (seqPointBuilder.Count == 0)
            {
                return SequencePointList.s_empty;
            }

            SequencePointList first = null, current = null;
            int totalPoints = seqPointBuilder.Count;
            int last = 0;

            for (int i = 1; i <= totalPoints; ++i)
            {
                if (i == totalPoints || seqPointBuilder[i].SyntaxTree != seqPointBuilder[i - 1].SyntaxTree)
                {
                    // Create a new list
                    SequencePointList next = new SequencePointList(seqPointBuilder[i - 1].SyntaxTree, GetSubArray(seqPointBuilder, last, i - last, builder));
                    last = i;

                    // Link together with any additional.
                    if (current == null)
                    {
                        first = current = next;
                    }
                    else
                    {
                        current._next = next;
                        current = next;
                    }
                }
            }

            return first;
        }
Ejemplo n.º 2
0
        public MethodBody(
            byte[] ilBits,
            ushort maxStack,
            Cci.IMethodDefinition parent,
            ImmutableArray <Cci.ILocalDefinition> locals,
            SequencePointList sequencePoints,
            DebugDocumentProvider debugDocumentProvider,
            ImmutableArray <Cci.ExceptionHandlerRegion> exceptionHandlers,
            ImmutableArray <Cci.LocalScope> localScopes,
            Cci.CustomDebugInfoKind customDebugInfoKind,
            bool hasDynamicLocalVariables,
            ImmutableArray <Cci.NamespaceScope> namespaceScopes = default(ImmutableArray <Cci.NamespaceScope>),
            string iteratorClassName = null,
            ImmutableArray <Cci.LocalScope> iteratorScopes    = default(ImmutableArray <Cci.LocalScope>),
            Cci.AsyncMethodBodyDebugInfo asyncMethodDebugInfo = null)
        {
            Debug.Assert(!locals.IsDefault);
            Debug.Assert(!exceptionHandlers.IsDefault);
            Debug.Assert(!localScopes.IsDefault);

            this.ilBits = ilBits;
            this.asyncMethodDebugInfo = asyncMethodDebugInfo;
            this.maxStack             = maxStack;
            this.parent                   = parent;
            this.locals                   = locals;
            this.sequencePoints           = sequencePoints;
            this.debugDocumentProvider    = debugDocumentProvider;
            this.exceptionHandlers        = exceptionHandlers;
            this.localScopes              = localScopes;
            this.customDebugInfoKind      = customDebugInfoKind;
            this.hasDynamicLocalVariables = hasDynamicLocalVariables;
            this.namespaceScopes          = namespaceScopes.IsDefault ? ImmutableArray <Cci.NamespaceScope> .Empty : namespaceScopes;
            this.iteratorClassName        = iteratorClassName;
            this.iteratorScopes           = iteratorScopes.IsDefault ? ImmutableArray <Cci.LocalScope> .Empty : iteratorScopes;
        }
Ejemplo n.º 3
0
        private FileLinePositionSpan?FindFirstRealSequencePoint()
        {
            SequencePointList current = this;

            while (current != null)
            {
                foreach (var offsetAndSpan in current._points)
                {
                    TextSpan span     = offsetAndSpan.Span;
                    bool     isHidden = span == RawSequencePoint.HiddenSequencePointSpan;
                    if (!isHidden)
                    {
                        FileLinePositionSpan fileLinePositionSpan =
                            current._tree.GetMappedLineSpanAndVisibility(span, out isHidden);
                        if (!isHidden)
                        {
                            return(fileLinePositionSpan);
                        }
                    }
                }
                current = current._next;
            }

            return(null);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Create a SequencePointList with the raw sequence points from an ArrayBuilder.
        /// A linked list of instances for each syntax tree is created (almost always of length one).
        /// </summary>
        public static SequencePointList Create(ArrayBuilder <RawSequencePoint> seqPointBuilder, ILBuilder builder)
        {
            if (seqPointBuilder.Count == 0)
            {
                return(SequencePointList.s_empty);
            }

            SequencePointList first = null, current = null;
            int totalPoints = seqPointBuilder.Count;
            int last = 0;

            for (int i = 1; i <= totalPoints; ++i)
            {
                if (i == totalPoints || seqPointBuilder[i].SyntaxTree != seqPointBuilder[i - 1].SyntaxTree)
                {
                    // Create a new list
                    SequencePointList next = new SequencePointList(seqPointBuilder[i - 1].SyntaxTree, GetSubArray(seqPointBuilder, last, i - last, builder));
                    last = i;

                    // Link together with any additional.
                    if (current == null)
                    {
                        first = current = next;
                    }
                    else
                    {
                        current._next = next;
                        current       = next;
                    }
                }
            }

            return(first);
        }
        public MethodBody(
            byte[] ilBits,
            ushort maxStack,
            Cci.IMethodDefinition parent,
            ImmutableArray<Cci.ILocalDefinition> locals,
            SequencePointList sequencePoints,
            DebugDocumentProvider debugDocumentProvider,
            ImmutableArray<Cci.ExceptionHandlerRegion> exceptionHandlers,
            ImmutableArray<Cci.LocalScope> localScopes,
            Cci.CustomDebugInfoKind customDebugInfoKind,
            bool hasDynamicLocalVariables,
            ImmutableArray<Cci.NamespaceScope> namespaceScopes = default(ImmutableArray<Cci.NamespaceScope>),
            string iteratorClassName = null,
            ImmutableArray<Cci.LocalScope> iteratorScopes = default(ImmutableArray<Cci.LocalScope>),
            Cci.AsyncMethodBodyDebugInfo asyncMethodDebugInfo = null)
        {
            Debug.Assert(!locals.IsDefault);
            Debug.Assert(!exceptionHandlers.IsDefault);
            Debug.Assert(!localScopes.IsDefault);

            this.ilBits = ilBits;
            this.asyncMethodDebugInfo = asyncMethodDebugInfo;
            this.maxStack = maxStack;
            this.parent = parent;
            this.locals = locals;
            this.sequencePoints = sequencePoints;
            this.debugDocumentProvider = debugDocumentProvider;
            this.exceptionHandlers = exceptionHandlers;
            this.localScopes = localScopes;
            this.customDebugInfoKind = customDebugInfoKind;
            this.hasDynamicLocalVariables = hasDynamicLocalVariables;
            this.namespaceScopes = namespaceScopes.IsDefault ? ImmutableArray<Cci.NamespaceScope>.Empty : namespaceScopes;
            this.iteratorClassName = iteratorClassName;
            this.iteratorScopes = iteratorScopes.IsDefault ? ImmutableArray<Cci.LocalScope>.Empty : iteratorScopes;
        }
Ejemplo n.º 6
0
        private static ImmutableArray <Cci.SequencePoint> GetSequencePoints(SequencePointList sequencePoints, DebugDocumentProvider debugDocumentProvider)
        {
            if (sequencePoints == null || sequencePoints.IsEmpty)
            {
                return(ImmutableArray <Cci.SequencePoint> .Empty);
            }

            var sequencePointsBuilder = ArrayBuilder <Cci.SequencePoint> .GetInstance();

            sequencePoints.GetSequencePoints(debugDocumentProvider, sequencePointsBuilder);
            return(sequencePointsBuilder.ToImmutableAndFree());
        }
Ejemplo n.º 7
0
        public MethodBody(
            ImmutableArray <byte> ilBits,
            ushort maxStack,
            Cci.IMethodDefinition parent,
            DebugId methodId,
            ImmutableArray <Cci.ILocalDefinition> locals,
            SequencePointList sequencePoints,
            DebugDocumentProvider debugDocumentProvider,
            ImmutableArray <Cci.ExceptionHandlerRegion> exceptionHandlers,
            bool areLocalsZeroed,
            bool hasStackalloc,
            ImmutableArray <Cci.LocalScope> localScopes,
            bool hasDynamicLocalVariables,
            Cci.IImportScope importScopeOpt,
            ImmutableArray <LambdaDebugInfo> lambdaDebugInfo,
            ImmutableArray <ClosureDebugInfo> closureDebugInfo,
            string stateMachineTypeNameOpt,
            ImmutableArray <StateMachineHoistedLocalScope> stateMachineHoistedLocalScopes,
            ImmutableArray <EncHoistedLocalInfo> stateMachineHoistedLocalSlots,
            ImmutableArray <Cci.ITypeReference?> stateMachineAwaiterSlots,
            StateMachineStatesDebugInfo stateMachineStatesDebugInfo,
            StateMachineMoveNextBodyDebugInfo stateMachineMoveNextDebugInfoOpt,
            DynamicAnalysisMethodBodyData dynamicAnalysisDataOpt)
        {
            Debug.Assert(!locals.IsDefault);
            Debug.Assert(!exceptionHandlers.IsDefault);
            Debug.Assert(!localScopes.IsDefault);

            _ilBits                           = ilBits;
            _maxStack                         = maxStack;
            _parent                           = parent;
            _methodId                         = methodId;
            _locals                           = locals;
            _exceptionHandlers                = exceptionHandlers;
            _areLocalsZeroed                  = areLocalsZeroed;
            HasStackalloc                     = hasStackalloc;
            _localScopes                      = localScopes;
            _hasDynamicLocalVariables         = hasDynamicLocalVariables;
            _importScopeOpt                   = importScopeOpt;
            _lambdaDebugInfo                  = lambdaDebugInfo;
            _closureDebugInfo                 = closureDebugInfo;
            _stateMachineTypeNameOpt          = stateMachineTypeNameOpt;
            _stateMachineHoistedLocalScopes   = stateMachineHoistedLocalScopes;
            _stateMachineHoistedLocalSlots    = stateMachineHoistedLocalSlots;
            _stateMachineAwaiterSlots         = stateMachineAwaiterSlots;
            _stateMachineStatesDebugInfo      = stateMachineStatesDebugInfo;
            _stateMachineMoveNextDebugInfoOpt = stateMachineMoveNextDebugInfoOpt;
            _dynamicAnalysisDataOpt           = dynamicAnalysisDataOpt;
            _sequencePoints                   = GetSequencePoints(sequencePoints, debugDocumentProvider);
        }
Ejemplo n.º 8
0
        public MethodBody(
            ImmutableArray<byte> ilBits,
            ushort maxStack,
            Cci.IMethodDefinition parent,
            DebugId methodId,
            ImmutableArray<Cci.ILocalDefinition> locals,
            SequencePointList sequencePoints,
            DebugDocumentProvider debugDocumentProvider,
            ImmutableArray<Cci.ExceptionHandlerRegion> exceptionHandlers,
            ImmutableArray<Cci.LocalScope> localScopes,
            bool hasDynamicLocalVariables,
            Cci.IImportScope importScopeOpt,
            ImmutableArray<LambdaDebugInfo> lambdaDebugInfo,
            ImmutableArray<ClosureDebugInfo> closureDebugInfo,
            string stateMachineTypeNameOpt,
            ImmutableArray<Cci.StateMachineHoistedLocalScope> stateMachineHoistedLocalScopes,
            ImmutableArray<EncHoistedLocalInfo> stateMachineHoistedLocalSlots,
            ImmutableArray<Cci.ITypeReference> stateMachineAwaiterSlots,
            Cci.AsyncMethodBodyDebugInfo asyncMethodDebugInfo,
            DynamicAnalysisMethodBodyData dynamicAnalysisDataOpt)
        {
            Debug.Assert(!locals.IsDefault);
            Debug.Assert(!exceptionHandlers.IsDefault);
            Debug.Assert(!localScopes.IsDefault);

            _ilBits = ilBits;
            _asyncMethodDebugInfo = asyncMethodDebugInfo;
            _maxStack = maxStack;
            _parent = parent;
            _methodId = methodId;
            _locals = locals;
            _sequencePoints = sequencePoints;
            _debugDocumentProvider = debugDocumentProvider;
            _exceptionHandlers = exceptionHandlers;
            _localScopes = localScopes;
            _hasDynamicLocalVariables = hasDynamicLocalVariables;
            _importScopeOpt = importScopeOpt;
            _lambdaDebugInfo = lambdaDebugInfo;
            _closureDebugInfo = closureDebugInfo;
            _stateMachineTypeNameOpt = stateMachineTypeNameOpt;
            _stateMachineHoistedLocalScopes = stateMachineHoistedLocalScopes;
            _stateMachineHoistedLocalSlots = stateMachineHoistedLocalSlots;
            _stateMachineAwaiterSlots = stateMachineAwaiterSlots;
            _dynamicAnalysisDataOpt = dynamicAnalysisDataOpt;
        }
Ejemplo n.º 9
0
        public MethodBody(
            byte[] ilBits,
            ushort maxStack,
            Cci.IMethodDefinition parent,
            int methodOrdinal,
            ImmutableArray <Cci.ILocalDefinition> locals,
            SequencePointList sequencePoints,
            DebugDocumentProvider debugDocumentProvider,
            ImmutableArray <Cci.ExceptionHandlerRegion> exceptionHandlers,
            ImmutableArray <Cci.LocalScope> localScopes,
            bool hasDynamicLocalVariables,
            ImmutableArray <Cci.NamespaceScope> namespaceScopes,
            Cci.NamespaceScopeEncoding namespaceScopeEncoding,
            ImmutableArray <LambdaDebugInfo> lambdaDebugInfo,
            ImmutableArray <ClosureDebugInfo> closureDebugInfo,
            string stateMachineTypeNameOpt,
            ImmutableArray <Cci.StateMachineHoistedLocalScope> stateMachineHoistedLocalScopes,
            ImmutableArray <EncHoistedLocalInfo> stateMachineHoistedLocalSlots,
            ImmutableArray <Cci.ITypeReference> stateMachineAwaiterSlots,
            Cci.AsyncMethodBodyDebugInfo asyncMethodDebugInfo)
        {
            Debug.Assert(!locals.IsDefault);
            Debug.Assert(!exceptionHandlers.IsDefault);
            Debug.Assert(!localScopes.IsDefault);

            _ilBits = ilBits;
            _asyncMethodDebugInfo = asyncMethodDebugInfo;
            _maxStack             = maxStack;
            _parent                         = parent;
            _methodOrdinal                  = methodOrdinal;
            _locals                         = locals;
            _sequencePoints                 = sequencePoints;
            _debugDocumentProvider          = debugDocumentProvider;
            _exceptionHandlers              = exceptionHandlers;
            _localScopes                    = localScopes;
            _namespaceScopeEncoding         = namespaceScopeEncoding;
            _hasDynamicLocalVariables       = hasDynamicLocalVariables;
            _namespaceScopes                = namespaceScopes.IsDefault ? ImmutableArray <Cci.NamespaceScope> .Empty : namespaceScopes;
            _lambdaDebugInfo                = lambdaDebugInfo;
            _closureDebugInfo               = closureDebugInfo;
            _stateMachineTypeNameOpt        = stateMachineTypeNameOpt;
            _stateMachineHoistedLocalScopes = stateMachineHoistedLocalScopes;
            _stateMachineHoistedLocalSlots  = stateMachineHoistedLocalSlots;
            _stateMachineAwaiterSlots       = stateMachineAwaiterSlots;
        }
Ejemplo n.º 10
0
        private void RealizeSequencePoints()
        {
            if (this.SeqPointsOpt != null)
            {
                // we keep track of the latest sequence point location to make sure
                // we don't emit multiple sequence points for the same location
                int lastOffset = -1;

                ArrayBuilder <RawSequencePoint> seqPoints = ArrayBuilder <RawSequencePoint> .GetInstance();

                foreach (var seqPoint in this.SeqPointsOpt)
                {
                    int offset = this.GetILOffsetFromMarker(seqPoint.ILMarker);
                    if (offset >= 0)
                    {
                        // valid IL offset
                        if (lastOffset != offset)
                        {
                            Debug.Assert(lastOffset < offset);
                            // if there are any sequence points, there must
                            // be a sequence point at offset 0.
#if !XSHARP
                            Debug.Assert((lastOffset >= 0) || (offset == 0));
#endif
                            // the first sequence point on tree/offset location
                            lastOffset = offset;
                            seqPoints.Add(seqPoint);
                        }
                        else
                        {
                            // override previous sequence point at the same location
                            seqPoints[seqPoints.Count - 1] = seqPoint;
                        }
                    }
                }

                if (seqPoints.Count > 0)
                {
                    this.RealizedSequencePoints = SequencePointList.Create(seqPoints, this);
                }

                seqPoints.Free();
            }
        }
Ejemplo n.º 11
0
        private void RealizeSequencePoints()
        {
            if (this.SeqPointsOpt != null)
            {
                // we keep track of the latest sequence point location to make sure 
                // we don't emit multiple sequence points for the same location
                int lastOffset = -1;

                ArrayBuilder<RawSequencePoint> seqPoints = ArrayBuilder<RawSequencePoint>.GetInstance();
                foreach (var seqPoint in this.SeqPointsOpt)
                {
                    int offset = this.GetILOffsetFromMarker(seqPoint.ILMarker);
                    if (offset >= 0)
                    {
                        // valid IL offset
                        if (lastOffset != offset)
                        {
                            Debug.Assert(lastOffset < offset);
                            // if there are any sequence points, there must
                            // be a sequence point at offset 0.
                            Debug.Assert((lastOffset >= 0) || (offset == 0));
                            // the first sequence point on tree/offset location
                            lastOffset = offset;
                            seqPoints.Add(seqPoint);
                        }
                        else
                        {
                            // override previous sequence point at the same location
                            seqPoints[seqPoints.Count - 1] = seqPoint;
                        }
                    }
                }

                if (seqPoints.Count > 0)
                {
                    this.RealizedSequencePoints = SequencePointList.Create(seqPoints, this);
                }

                seqPoints.Free();
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Get all the sequence points, possibly mapping them using #line/ExternalSource directives, and mapping
        /// file names to debug documents with the given mapping function.
        /// </summary>
        /// <param name="documentProvider">Function that maps file paths to CCI debug documents</param>
        public ImmutableArray <Cci.SequencePoint> GetSequencePoints(DebugDocumentProvider documentProvider)
        {
            bool   lastPathIsMapped = false;
            string lastPath         = null;

            Cci.DebugSourceDocument lastDebugDocument = null;

            // First, count the number of sequence points.
            int count = 0;
            SequencePointList current = this;

            while (current != null)
            {
                count  += current._points.Length;
                current = current._next;
            }

            ArrayBuilder <Cci.SequencePoint> result = ArrayBuilder <Cci.SequencePoint> .GetInstance(count);

            current = this;
            while (current != null)
            {
                SyntaxTree currentTree = current._tree;

                foreach (var offsetAndSpan in current._points)
                {
                    TextSpan span = offsetAndSpan.Span;

                    // if it's a hidden sequence point, or a sequence point with syntax that points to a position that is inside
                    // of a hidden region (can be defined with #line hidden (C#) or implicitly by #ExternalSource (VB), make it
                    // a hidden sequence point.

                    bool isHidden = span == RawSequencePoint.HiddenSequencePointSpan;
                    FileLinePositionSpan fileLinePositionSpan = default(FileLinePositionSpan);
                    if (!isHidden)
                    {
                        fileLinePositionSpan = currentTree.GetMappedLineSpanAndVisibility(span, out isHidden);
                    }

                    if (isHidden)
                    {
                        if (lastPath == null)
                        {
                            lastPath          = currentTree.FilePath;
                            lastDebugDocument = documentProvider(lastPath, basePath: null);
                        }

                        if (lastDebugDocument != null)
                        {
                            result.Add(new Cci.SequencePoint(
                                           lastDebugDocument,
                                           offset: offsetAndSpan.Offset,
                                           startLine: HiddenSequencePointLine,
                                           startColumn: 0,
                                           endLine: HiddenSequencePointLine,
                                           endColumn: 0));
                        }
                    }
                    else
                    {
                        if (lastPath != fileLinePositionSpan.Path || lastPathIsMapped != fileLinePositionSpan.HasMappedPath)
                        {
                            lastPath          = fileLinePositionSpan.Path;
                            lastPathIsMapped  = fileLinePositionSpan.HasMappedPath;
                            lastDebugDocument = documentProvider(lastPath, basePath: lastPathIsMapped ? currentTree.FilePath : null);
                        }

                        if (lastDebugDocument != null)
                        {
                            result.Add(new Cci.SequencePoint(
                                           lastDebugDocument,
                                           offset: offsetAndSpan.Offset,
                                           startLine: (fileLinePositionSpan.StartLinePosition.Line == -1) ? 0 : fileLinePositionSpan.StartLinePosition.Line + 1,
                                           startColumn: fileLinePositionSpan.StartLinePosition.Character + 1,
                                           endLine: (fileLinePositionSpan.EndLinePosition.Line == -1) ? 0 : fileLinePositionSpan.EndLinePosition.Line + 1,
                                           endColumn: fileLinePositionSpan.EndLinePosition.Character + 1
                                           ));
                        }
                    }
                }

                current = current._next;
            }

            return(result.ToImmutableAndFree());
        }
Ejemplo n.º 13
0
        public void GetSequencePoints(
            DebugDocumentProvider documentProvider,
            ArrayBuilder <Cci.SequencePoint> builder
            )
        {
            bool   lastPathIsMapped = false;
            string lastPath         = null;

            Cci.DebugSourceDocument lastDebugDocument = null;

            FileLinePositionSpan?firstReal = FindFirstRealSequencePoint();

            if (!firstReal.HasValue)
            {
                return;
            }
            lastPath          = firstReal.Value.Path;
            lastPathIsMapped  = firstReal.Value.HasMappedPath;
            lastDebugDocument = documentProvider(
                lastPath,
                basePath: lastPathIsMapped ? this._tree.FilePath : null
                );

            SequencePointList current = this;

            while (current != null)
            {
                SyntaxTree currentTree = current._tree;

                foreach (var offsetAndSpan in current._points)
                {
                    TextSpan span = offsetAndSpan.Span;

                    // if it's a hidden sequence point, or a sequence point with syntax that points to a position that is inside
                    // of a hidden region (can be defined with #line hidden (C#) or implicitly by #ExternalSource (VB), make it
                    // a hidden sequence point.

                    bool isHidden = span == RawSequencePoint.HiddenSequencePointSpan;
                    FileLinePositionSpan fileLinePositionSpan = default;
                    if (!isHidden)
                    {
                        fileLinePositionSpan = currentTree.GetMappedLineSpanAndVisibility(
                            span,
                            out isHidden
                            );
                    }

                    if (isHidden)
                    {
                        if (lastPath == null)
                        {
                            lastPath          = currentTree.FilePath;
                            lastDebugDocument = documentProvider(lastPath, basePath: null);
                        }

                        if (lastDebugDocument != null)
                        {
                            builder.Add(
                                new Cci.SequencePoint(
                                    lastDebugDocument,
                                    offset: offsetAndSpan.Offset,
                                    startLine: Cci.SequencePoint.HiddenLine,
                                    startColumn: 0,
                                    endLine: Cci.SequencePoint.HiddenLine,
                                    endColumn: 0
                                    )
                                );
                        }
                    }
                    else
                    {
                        if (
                            lastPath != fileLinePositionSpan.Path ||
                            lastPathIsMapped != fileLinePositionSpan.HasMappedPath
                            )
                        {
                            lastPath          = fileLinePositionSpan.Path;
                            lastPathIsMapped  = fileLinePositionSpan.HasMappedPath;
                            lastDebugDocument = documentProvider(
                                lastPath,
                                basePath: lastPathIsMapped ? currentTree.FilePath : null
                                );
                        }

                        if (lastDebugDocument != null)
                        {
                            int startLine =
                                (fileLinePositionSpan.StartLinePosition.Line == -1)
                                    ? 0
                                    : fileLinePositionSpan.StartLinePosition.Line + 1;
                            int endLine =
                                (fileLinePositionSpan.EndLinePosition.Line == -1)
                                    ? 0
                                    : fileLinePositionSpan.EndLinePosition.Line + 1;
                            int startColumn = fileLinePositionSpan.StartLinePosition.Character + 1;
                            int endColumn   = fileLinePositionSpan.EndLinePosition.Character + 1;

                            // Trim column number if necessary.
                            // Column must be in range [0, 0xffff) and end column must be greater than start column if on the same line.
                            // The Portable PDB specifies 0x10000, but System.Reflection.Metadata reader has an off-by-one error.
                            // Windows PDBs allow the same range.
                            const int MaxColumn = ushort.MaxValue - 1;

                            if (startColumn > MaxColumn)
                            {
                                startColumn = (startLine == endLine) ? MaxColumn - 1 : MaxColumn;
                            }

                            if (endColumn > MaxColumn)
                            {
                                endColumn = MaxColumn;
                            }

                            builder.Add(
                                new Cci.SequencePoint(
                                    lastDebugDocument,
                                    offset: offsetAndSpan.Offset,
                                    startLine: startLine,
                                    startColumn: (ushort)startColumn,
                                    endLine: endLine,
                                    endColumn: (ushort)endColumn
                                    )
                                );
                        }
                    }
                }

                current = current._next;
            }
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Get all the sequence points, possibly mapping them using #line/ExternalSource directives, and mapping
        /// file names to debug documents with the given mapping function.
        /// </summary>
        /// <param name="documentProvider">Function that maps file paths to CCI debug documents</param>
        /// <param name="builder">where sequence points should be deposited</param>
        public void GetSequencePoints(
            DebugDocumentProvider documentProvider,
            ArrayBuilder <Cci.SequencePoint> builder)
        {
            bool   lastPathIsMapped = false;
            string lastPath         = null;

            Cci.DebugSourceDocument lastDebugDocument = null;

            FileLinePositionSpan?firstReal = FindFirstRealSequencePoint();

            if (!firstReal.HasValue)
            {
                return;
            }
            lastPath          = firstReal.Value.Path;
            lastPathIsMapped  = firstReal.Value.HasMappedPath;
            lastDebugDocument = documentProvider(lastPath, basePath: lastPathIsMapped ? this._tree.FilePath : null);

            SequencePointList current = this;

            while (current != null)
            {
                SyntaxTree currentTree = current._tree;

                foreach (OffsetAndSpan offsetAndSpan in current._points)
                {
                    TextSpan span = offsetAndSpan.Span;

                    // if it's a hidden sequence point, or a sequence point with syntax that points to a position that is inside
                    // of a hidden region (can be defined with #line hidden (C#) or implicitly by #ExternalSource (VB), make it
                    // a hidden sequence point.

                    bool isHidden = span == RawSequencePoint.HiddenSequencePointSpan;
                    FileLinePositionSpan fileLinePositionSpan = default(FileLinePositionSpan);
                    if (!isHidden)
                    {
                        fileLinePositionSpan = currentTree.GetMappedLineSpanAndVisibility(span, out isHidden);
                    }

                    if (isHidden)
                    {
                        if (lastPath == null)
                        {
                            lastPath          = currentTree.FilePath;
                            lastDebugDocument = documentProvider(lastPath, basePath: null);
                        }

                        if (lastDebugDocument != null)
                        {
                            builder.Add(new Cci.SequencePoint(
                                            lastDebugDocument,
                                            offset: offsetAndSpan.Offset,
                                            startLine: HiddenSequencePointLine,
                                            startColumn: 0,
                                            endLine: HiddenSequencePointLine,
                                            endColumn: 0));
                        }
                    }
                    else
                    {
                        if (lastPath != fileLinePositionSpan.Path || lastPathIsMapped != fileLinePositionSpan.HasMappedPath)
                        {
                            lastPath          = fileLinePositionSpan.Path;
                            lastPathIsMapped  = fileLinePositionSpan.HasMappedPath;
                            lastDebugDocument = documentProvider(lastPath, basePath: lastPathIsMapped ? currentTree.FilePath : null);
                        }

                        if (lastDebugDocument != null)
                        {
                            builder.Add(new Cci.SequencePoint(
                                            lastDebugDocument,
                                            offset: offsetAndSpan.Offset,
                                            startLine: (fileLinePositionSpan.StartLinePosition.Line == -1) ? 0 : fileLinePositionSpan.StartLinePosition.Line + 1,
                                            startColumn: fileLinePositionSpan.StartLinePosition.Character + 1,
                                            endLine: (fileLinePositionSpan.EndLinePosition.Line == -1) ? 0 : fileLinePositionSpan.EndLinePosition.Line + 1,
                                            endColumn: fileLinePositionSpan.EndLinePosition.Character + 1
                                            ));
                        }
                    }
                }

                current = current._next;
            }
        }