protected GherkinTextBufferParserListenerBase(GherkinDialect gherkinDialect, ITextSnapshot textSnapshot, IProjectScope projectScope)
        {
            this.textSnapshot            = textSnapshot;
            this.classifications         = projectScope.Classifications;
            this.projectScope            = projectScope;
            this.enableStepMatchColoring = projectScope.IntegrationOptionsProvider.GetOptions().EnableStepMatchColoring;

            gherkinFileScope = new GherkinFileScope(gherkinDialect, textSnapshot);
        }
 protected GherkinTextBufferParserListenerBase(GherkinDialect gherkinDialect, ITextSnapshot textSnapshot, IProjectScope projectScope)
 {
     this.textSnapshot = textSnapshot;
     this.classifications = projectScope.Classifications;
     this.projectScope = projectScope;
     this.enableStepMatchColoring = projectScope.IntegrationOptionsProvider.GetOptions().EnableStepMatchColoring;
    
     gherkinFileScope = new GherkinFileScope(gherkinDialect, textSnapshot);
 }
        private GherkinFileScopeChange GetInvalidDialectScopeChange(GherkinTextBufferChange change)
        {
            var fileScope = new GherkinFileScope(null, change.ResultTextSnapshot)
            {
                InvalidFileEndingBlock = new InvalidFileBlock(0,
                                                              change.ResultTextSnapshot.LineCount - 1,
                                                              new ErrorInfo("Invalid Gherkin dialect!", 0, 0, null))
            };

            return(GherkinFileScopeChange.CreateEntireScopeChange(fileScope));
        }
        private GherkinFileScopeChange GetInvalidDialectScopeChange(GherkinTextBufferChange change)
        {
            var fileScope = new GherkinFileScope(null, change.ResultTextSnapshot)
                                {
                                    InvalidFileEndingBlock = new InvalidFileBlock(0, 
                                        change.ResultTextSnapshot.LineCount - 1,
                                        new ErrorInfo("Invalid Gherkin dialect!", 0, 0, null))
                                };

            return GherkinFileScopeChange.CreateEntireScopeChange(fileScope);
        }
        public void Build(GherkinFileScope gherkinFileEditorInfo, int endLine, int contentEndLine)
        {
            VisualStudioTracer.Assert(IsComplete, "The block builder is not complete");
            int blockRelativeEndLine        = endLine - KeywordLine;
            int blockRelativeContentEndLine = contentEndLine - KeywordLine;

            if (BlockType == typeof(IInvalidFileBlock))
            {
                VisualStudioTracer.Assert(gherkinFileEditorInfo.InvalidFileEndingBlock == null, "no invalid file block");
                if (gherkinFileEditorInfo.InvalidFileEndingBlock == null)
                {
                    gherkinFileEditorInfo.InvalidFileEndingBlock =
                        new InvalidFileBlock(StartLine, endLine, blockRelativeContentEndLine, ClassificationSpans.ToArray(), OutliningRegions.ToArray(), Errors.ToArray());
                }
            }
            else if (BlockType == typeof(IHeaderBlock))
            {
                VisualStudioTracer.Assert(gherkinFileEditorInfo.HeaderBlock == null, "no header block");
                if (gherkinFileEditorInfo.HeaderBlock == null)
                {
                    gherkinFileEditorInfo.HeaderBlock =
                        new HeaderBlock(Keyword, Title, KeywordLine, Tags.ToArray(), BlockRelativeStartLine, blockRelativeEndLine, blockRelativeContentEndLine, ClassificationSpans.ToArray(), OutliningRegions.ToArray(), Errors.ToArray());
                }
            }
            else if (BlockType == typeof(IBackgroundBlock))
            {
                VisualStudioTracer.Assert(gherkinFileEditorInfo.BackgroundBlock == null, "no background block");
                if (gherkinFileEditorInfo.BackgroundBlock == null)
                {
                    gherkinFileEditorInfo.BackgroundBlock =
                        new BackgroundBlock(Keyword, Title, KeywordLine, BlockRelativeStartLine, blockRelativeEndLine, blockRelativeContentEndLine, ClassificationSpans.ToArray(), OutliningRegions.ToArray(), Errors.ToArray(), Steps.ToArray());
                }
            }
            else if (BlockType == typeof(IScenarioBlock))
            {
                var scenarioBlock = new ScenarioBlock(Keyword, Title, KeywordLine, BlockRelativeStartLine, blockRelativeEndLine, blockRelativeContentEndLine, ClassificationSpans.ToArray(), OutliningRegions.ToArray(), Errors.ToArray(), Steps.ToArray());
                gherkinFileEditorInfo.ScenarioBlocks.Add(scenarioBlock);
            }
            else if (BlockType == typeof(IScenarioOutlineBlock))
            {
                var scenarioBlock = new ScenarioOutlineBlock(Keyword, Title, KeywordLine, BlockRelativeStartLine, blockRelativeEndLine, blockRelativeContentEndLine, ClassificationSpans.ToArray(), OutliningRegions.ToArray(), Errors.ToArray(), Steps.ToArray(), ExampleSets.ToArray());
                gherkinFileEditorInfo.ScenarioBlocks.Add(scenarioBlock);
            }
            else
            {
                throw new NotSupportedException("Block type not supported: " + BlockType);
            }
        }
        private GherkinFileScopeChange MergePartialResult(IGherkinFileScope previousScope, IGherkinFileScope partialResult, IScenarioBlock firstAffectedScenario, IScenarioBlock firstUnchangedScenario, int lineCountDelta)
        {
            Debug.Assert(partialResult.HeaderBlock == null, "Partial parse cannot re-parse header");
            Debug.Assert(partialResult.BackgroundBlock == null, "Partial parse cannot re-parse background");

            List <IGherkinFileBlock> changedBlocks = new List <IGherkinFileBlock>();
            List <IGherkinFileBlock> shiftedBlocks = new List <IGherkinFileBlock>();

            GherkinFileScope fileScope = new GherkinFileScope(previousScope.GherkinDialect, partialResult.TextSnapshot)
            {
                HeaderBlock     = previousScope.HeaderBlock,
                BackgroundBlock = previousScope.BackgroundBlock
            };

            // inserting the non-affected scenarios
            fileScope.ScenarioBlocks.AddRange(previousScope.ScenarioBlocks.TakeUntilItemExclusive(firstAffectedScenario));

            //inserting partial result
            fileScope.ScenarioBlocks.AddRange(partialResult.ScenarioBlocks);
            changedBlocks.AddRange(partialResult.ScenarioBlocks);
            if (partialResult.InvalidFileEndingBlock != null)
            {
                VisualStudioTracer.Assert(firstUnchangedScenario == null, "first affected scenario is not null");
                // the last scenario was changed, but it became invalid
                fileScope.InvalidFileEndingBlock = partialResult.InvalidFileEndingBlock;
                changedBlocks.Add(fileScope.InvalidFileEndingBlock);
            }

            if (firstUnchangedScenario != null)
            {
                Tracing.VisualStudioTracer.Assert(partialResult.InvalidFileEndingBlock == null, "there is an invalid file ending block");

                // inserting the non-effected scenarios at the end
                var shiftedScenarioBlocks = previousScope.ScenarioBlocks.SkipFromItemInclusive(firstUnchangedScenario)
                                            .Select(scenario => scenario.Shift(lineCountDelta)).ToArray();
                fileScope.ScenarioBlocks.AddRange(shiftedScenarioBlocks);
                shiftedBlocks.AddRange(shiftedScenarioBlocks);

                if (previousScope.InvalidFileEndingBlock != null)
                {
                    fileScope.InvalidFileEndingBlock = previousScope.InvalidFileEndingBlock.Shift(lineCountDelta);
                    shiftedBlocks.Add(fileScope.InvalidFileEndingBlock);
                }
            }

            return(new GherkinFileScopeChange(fileScope, false, false, changedBlocks, shiftedBlocks));
        }
        private GherkinFileScopeChange MergePartialResult(IGherkinFileScope previousScope, IGherkinFileScope partialResult, IScenarioBlock firstAffectedScenario, IScenarioBlock firstUnchangedScenario, int lineCountDelta)
        {
            Debug.Assert(partialResult.HeaderBlock == null, "Partial parse cannot re-parse header");
            Debug.Assert(partialResult.BackgroundBlock == null, "Partial parse cannot re-parse background");

            List<IGherkinFileBlock> changedBlocks = new List<IGherkinFileBlock>();
            List<IGherkinFileBlock> shiftedBlocks = new List<IGherkinFileBlock>();

            GherkinFileScope fileScope = new GherkinFileScope(previousScope.GherkinDialect, partialResult.TextSnapshot)
                                             {
                                                 HeaderBlock = previousScope.HeaderBlock,
                                                 BackgroundBlock = previousScope.BackgroundBlock
                                             };

            // inserting the non-affected scenarios
            fileScope.ScenarioBlocks.AddRange(previousScope.ScenarioBlocks.TakeUntilItemExclusive(firstAffectedScenario));

            //inserting partial result
            fileScope.ScenarioBlocks.AddRange(partialResult.ScenarioBlocks);
            changedBlocks.AddRange(partialResult.ScenarioBlocks);
            if (partialResult.InvalidFileEndingBlock != null)
            {
                VisualStudioTracer.Assert(firstUnchangedScenario == null, "first affected scenario is not null");
                // the last scenario was changed, but it became invalid
                fileScope.InvalidFileEndingBlock = partialResult.InvalidFileEndingBlock;
                changedBlocks.Add(fileScope.InvalidFileEndingBlock);
            }

            if (firstUnchangedScenario != null)
            {
                Tracing.VisualStudioTracer.Assert(partialResult.InvalidFileEndingBlock == null, "there is an invalid file ending block");

                // inserting the non-effected scenarios at the end
                var shiftedScenarioBlocks = previousScope.ScenarioBlocks.SkipFromItemInclusive(firstUnchangedScenario)
                    .Select(scenario => scenario.Shift(lineCountDelta)).ToArray();
                fileScope.ScenarioBlocks.AddRange(shiftedScenarioBlocks);
                shiftedBlocks.AddRange(shiftedScenarioBlocks);

                if (previousScope.InvalidFileEndingBlock != null)
                {
                    fileScope.InvalidFileEndingBlock = previousScope.InvalidFileEndingBlock.Shift(lineCountDelta);
                    shiftedBlocks.Add(fileScope.InvalidFileEndingBlock);
                }
            }

            return new GherkinFileScopeChange(fileScope, false, false, changedBlocks, shiftedBlocks);
        }