OLD | NEW |
| (Empty) |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 library trydart.source_update; | |
6 | |
7 /// Returns [updates] expanded to full compilation units/source files. | |
8 /// | |
9 /// [updates] is a convenient way to write updates/patches to a single source | |
10 /// file without repeating common parts. | |
11 /// | |
12 /// For example: | |
13 /// ["head ", ["v1", "v2"], " tail"] | |
14 /// expands to: | |
15 /// ["head v1 tail", "head v2 tail"] | |
16 List<String> expandUpdates(List updates) { | |
17 int outputCount = updates.firstWhere((e) => e is Iterable).length; | |
18 List<StringBuffer> result = new List<StringBuffer>(outputCount); | |
19 for (int i = 0; i < outputCount; i++) { | |
20 result[i] = new StringBuffer(); | |
21 } | |
22 for (var chunk in updates) { | |
23 if (chunk is Iterable) { | |
24 int segmentCount = 0; | |
25 for (var segment in chunk) { | |
26 result[segmentCount++].write(segment); | |
27 } | |
28 if (segmentCount != outputCount) { | |
29 throw new ArgumentError( | |
30 "Expected ${outputCount} segments, " | |
31 "but found ${segmentCount} in $chunk"); | |
32 } | |
33 } else { | |
34 for (StringBuffer buffer in result) { | |
35 buffer.write(chunk); | |
36 } | |
37 } | |
38 } | |
39 | |
40 return result.map((e) => '$e').toList(); | |
41 } | |
42 | |
43 /// Returns [files] split into multiple named files. The keys in the returned | |
44 /// map are filenames, the values are the files' content. | |
45 /// | |
46 /// Names are indicated by a line on the form "==> filename <==". Spaces are | |
47 /// significant. For example, given this input: | |
48 /// | |
49 /// ==> file1.dart <== | |
50 /// First line of file 1. | |
51 /// Second line of file 1. | |
52 /// Third line of file 1. | |
53 /// ==> empty.dart <== | |
54 /// ==> file2.dart <== | |
55 /// First line of file 2. | |
56 /// Second line of file 2. | |
57 /// Third line of file 2. | |
58 /// | |
59 /// This function would return: | |
60 /// | |
61 /// { | |
62 /// "file1.dart": """ | |
63 /// First line of file 1. | |
64 /// Second line of file 1. | |
65 /// Third line of file 1. | |
66 /// """, | |
67 /// | |
68 /// "empty.dart":"", | |
69 /// | |
70 /// "file2.dart":""" | |
71 /// First line of file 2. | |
72 /// Second line of file 2. | |
73 /// Third line of file 2. | |
74 /// """ | |
75 /// } | |
76 Map<String, String> splitFiles(String files) { | |
77 Map<String, String> result = <String, String>{}; | |
78 String currentName; | |
79 List<String> content; | |
80 void finishFile() { | |
81 if (currentName != null) { | |
82 if (result.containsKey(currentName)) { | |
83 throw new ArgumentError("Duplicated filename $currentName in $files"); | |
84 } | |
85 result[currentName] = content.join(''); | |
86 } | |
87 content = null; | |
88 } | |
89 void processDirective(String line) { | |
90 finishFile(); | |
91 if (line.length < 8 || !line.endsWith(" <==\n")) { | |
92 throw new ArgumentError( | |
93 "Malformed line: expected '==> ... <==', but got: '$line'"); | |
94 } | |
95 currentName = line.substring(4, line.length - 5); | |
96 content = <String>[]; | |
97 } | |
98 for (String line in splitLines(files)) { | |
99 if (line.startsWith("==>")) { | |
100 processDirective(line); | |
101 } else { | |
102 content.add(line); | |
103 } | |
104 } | |
105 finishFile(); | |
106 return result; | |
107 } | |
108 | |
109 /// Split [text] into lines preserving trailing newlines (unlike | |
110 /// String.split("\n"). Also, if [text] is empty, return an empty list (unlike | |
111 /// String.split("\n")). | |
112 List<String> splitLines(String text) { | |
113 return text.split(new RegExp('^', multiLine: true)); | |
114 } | |
115 | |
116 /// Expand a file with diffs in common merge conflict format into a [List] that | |
117 /// can be passed to [expandUpdates]. | |
118 /// | |
119 /// For example: | |
120 /// first | |
121 /// <<<<<<< | |
122 /// v1 | |
123 /// ======= | |
124 /// v2 | |
125 /// ======= | |
126 /// v3 | |
127 /// >>>>>>> | |
128 /// last | |
129 /// | |
130 /// Would be expanded to something equivalent to: | |
131 /// | |
132 /// ["first\n", ["v1\n", "v2\n", "v3\n"], "last\n"] | |
133 List expandDiff(String text) { | |
134 List result = [new StringBuffer()]; | |
135 bool inDiff = false; | |
136 for (String line in splitLines(text)) { | |
137 if (inDiff) { | |
138 if (line.startsWith("=======")) { | |
139 result.last.add(new StringBuffer()); | |
140 } else if (line.startsWith(">>>>>>>")) { | |
141 inDiff = false; | |
142 result.add(new StringBuffer()); | |
143 } else { | |
144 result.last.last.write(line); | |
145 } | |
146 } else if (line.startsWith("<<<<<<<")) { | |
147 inDiff = true; | |
148 result.add(<StringBuffer>[new StringBuffer()]); | |
149 } else { | |
150 result.last.write(line); | |
151 } | |
152 } | |
153 return result; | |
154 } | |
OLD | NEW |