public void Init(GherkinBuffer buffer, bool isPartialScan) { gherkinBuffer = buffer; InitializeFirstBlock(gherkinBuffer.GetLineStartPosition(gherkinBuffer.LineOffset)); VisualStudioTracer.Assert(currentFileBlockBuilder != null, "no current file block builder"); }
public static SnapshotSpan CreateSpan(this IEnumerable <IGherkinFileBlock> changedBlocks, ITextSnapshot textSnapshot) { VisualStudioTracer.Assert(changedBlocks.Any(), "there is no changed block"); int minLineNumber = changedBlocks.First().GetStartLine(); int maxLineNumber = changedBlocks.Last().GetEndLine(); var minLine = textSnapshot.GetLineFromLineNumber(minLineNumber); var maxLine = minLineNumber == maxLineNumber ? minLine : textSnapshot.GetLineFromLineNumber(maxLineNumber); return(new SnapshotSpan(minLine.Start, maxLine.EndIncludingLineBreak)); }
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); } }
protected override string GenerateError(IVsGeneratorProgress pGenerateProgress, Exception ex) { if (ex == null) { VisualStudioTracer.Assert(generationResult != null, "no reneration result found"); VisualStudioTracer.Assert(!generationResult.Success, "generation result is not a failure"); foreach (var error in generationResult.Errors) { pGenerateProgress.GeneratorError(0, 4, error.Message, (uint)error.Line, (uint)error.LinePosition); } return(string.Join(Environment.NewLine, generationResult.Errors.Select(e => e.Message))); } return(base.GenerateError(pGenerateProgress, ex)); }
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 PartialParse(GherkinTextBufferChange change, IGherkinFileScope previousScope) { visualStudioTracer.Trace("Start incremental parsing", ParserTraceCategory); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); partialParseCount++; var textSnapshot = change.ResultTextSnapshot; IScenarioBlock firstAffectedScenario = GetFirstAffectedScenario(change, previousScope); VisualStudioTracer.Assert(firstAffectedScenario != null, "first affected scenario is null"); int parseStartPosition = textSnapshot.GetLineFromLineNumber(firstAffectedScenario.GetStartLine()).Start; string fileContent = textSnapshot.GetText(parseStartPosition, textSnapshot.Length - parseStartPosition); var gherkinListener = new GherkinTextBufferPartialParserListener( previousScope.GherkinDialect, textSnapshot, projectScope, previousScope, change.EndLine, change.LineCountDelta); var scanner = new GherkinScanner(previousScope.GherkinDialect, fileContent, firstAffectedScenario.GetStartLine()); IScenarioBlock firstUnchangedScenario = null; try { scanner.Scan(gherkinListener); } catch (PartialListeningDoneException partialListeningDoneException) { firstUnchangedScenario = partialListeningDoneException.FirstUnchangedScenario; } var partialResult = gherkinListener.GetResult(); var result = MergePartialResult(previousScope, partialResult, firstAffectedScenario, firstUnchangedScenario, change.LineCountDelta); stopwatch.Stop(); TraceFinishParse(stopwatch, "incremental", result); return(result); }
public static GherkinTextBufferChange Merge(GherkinTextBufferChange change1, GherkinTextBufferChange change2) { VisualStudioTracer.Assert(change1.ResultTextSnapshot.Version.VersionNumber <= change2.ResultTextSnapshot.Version.VersionNumber, "different snapshot version numbers for merging"); if (change1.Type == GherkinTextBufferChangeType.EntireFile || change2.Type == GherkinTextBufferChangeType.EntireFile) { return(CreateEntireBufferChange(change2.ResultTextSnapshot)); } return(new GherkinTextBufferChange( change1.Type == GherkinTextBufferChangeType.MultiLine || change2.Type == GherkinTextBufferChangeType.MultiLine ? GherkinTextBufferChangeType.MultiLine : GherkinTextBufferChangeType.SingleLine, Math.Min(change1.StartLine, change2.StartLine), Math.Max(change1.EndLine, change2.EndLine), Math.Min(change1.StartPosition, change2.StartPosition), Math.Max(change1.EndPosition, change2.EndPosition), change1.LineCountDelta + change2.LineCountDelta, change1.PositionDelta + change2.PositionDelta, change2.ResultTextSnapshot)); }