| // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE.md file. |
| |
| library fasta.test.incremental_source_files; |
| |
| /// Expand a file with diffs in common merge conflict format into a [List] that |
| /// can be passed to [expandUpdates]. |
| /// |
| /// For example: |
| /// first |
| /// <<<< |
| /// v1 |
| /// ==== |
| /// v2 |
| /// ==== |
| /// v3 |
| /// >>>> |
| /// last |
| /// |
| /// Would be expanded to something equivalent to: |
| /// |
| /// ["first\n", ["v1\n", "v2\n", "v3\n"], "last\n"] |
| List expandDiff(String text) { |
| List result = [new StringBuffer()]; |
| bool inDiff = false; |
| for (String line in splitLines(text)) { |
| if (inDiff) { |
| if (line.startsWith("====")) { |
| result.last.add(new StringBuffer()); |
| } else if (line.startsWith(">>>>")) { |
| inDiff = false; |
| result.add(new StringBuffer()); |
| } else { |
| result.last.last.write(line); |
| } |
| } else if (line.startsWith("<<<<")) { |
| inDiff = true; |
| result.add(<StringBuffer>[new StringBuffer()]); |
| } else { |
| result.last.write(line); |
| } |
| } |
| return result; |
| } |
| |
| /// Returns [updates] expanded to full compilation units/source files. |
| /// |
| /// [updates] is a convenient way to write updates/patches to a single source |
| /// file without repeating common parts. |
| /// |
| /// For example: |
| /// ["head ", ["v1", "v2"], " tail"] |
| /// expands to: |
| /// ["head v1 tail", "head v2 tail"] |
| List<String> expandUpdates(List updates) { |
| int outputCount = updates.firstWhere((e) => e is Iterable).length; |
| List<StringBuffer> result = new List<StringBuffer>(outputCount); |
| for (int i = 0; i < outputCount; i++) { |
| result[i] = new StringBuffer(); |
| } |
| for (var chunk in updates) { |
| if (chunk is Iterable) { |
| int segmentCount = 0; |
| for (var segment in chunk) { |
| result[segmentCount++].write(segment); |
| } |
| if (segmentCount != outputCount) { |
| throw new ArgumentError("Expected ${outputCount} segments, " |
| "but found ${segmentCount} in $chunk"); |
| } |
| } else { |
| for (StringBuffer buffer in result) { |
| buffer.write(chunk); |
| } |
| } |
| } |
| |
| return result.map((e) => '$e').toList(); |
| } |
| |
| /// Split [text] into lines preserving trailing newlines (unlike |
| /// String.split("\n"). Also, if [text] is empty, return an empty list (unlike |
| /// String.split("\n")). |
| List<String> splitLines(String text) { |
| return text.split(new RegExp('^', multiLine: true)); |
| } |