blob: f8306390c1aaca5f72055d97a173f697af39511c [file] [log] [blame]
// 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));
}