OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 const int _LF = 0x0A; | 5 const int _LF = 0x0A; |
6 const int _CR = 0x0D; | 6 const int _CR = 0x0D; |
7 const int _LBRACE = 0x7B; | 7 const int _LBRACE = 0x7B; |
8 | 8 |
| 9 const Pattern atBraceStart = '@{'; |
| 10 const Pattern braceEnd = '}'; |
| 11 |
| 12 final Pattern commentStart = new RegExp(r' */\*'); |
| 13 final Pattern commentEnd = new RegExp(r'\*/ *'); |
| 14 |
9 class Annotation { | 15 class Annotation { |
10 /// 1-based line number of the annotation. | 16 /// 1-based line number of the annotation. |
11 final int lineNo; | 17 final int lineNo; |
12 | 18 |
13 /// 1-based column number of the annotation. | 19 /// 1-based column number of the annotation. |
14 final int columnNo; | 20 final int columnNo; |
15 | 21 |
16 /// 0-based character offset of the annotation within the source text. | 22 /// 0-based character offset of the annotation within the source text. |
17 final int offset; | 23 final int offset; |
18 | 24 |
(...skipping 29 matching lines...) Expand all Loading... |
48 List<int> _lineStarts; | 54 List<int> _lineStarts; |
49 | 55 |
50 AnnotatedCode(this.sourceCode, this.annotations); | 56 AnnotatedCode(this.sourceCode, this.annotations); |
51 | 57 |
52 AnnotatedCode.internal(this.sourceCode, this.annotations, this._lineStarts); | 58 AnnotatedCode.internal(this.sourceCode, this.annotations, this._lineStarts); |
53 | 59 |
54 /// Creates an [AnnotatedCode] by processing [annotatedCode]. Annotation | 60 /// Creates an [AnnotatedCode] by processing [annotatedCode]. Annotation |
55 /// delimited by [start] and [end] are converted into [Annotation]s and | 61 /// delimited by [start] and [end] are converted into [Annotation]s and |
56 /// removed from the [annotatedCode] to produce the source code. | 62 /// removed from the [annotatedCode] to produce the source code. |
57 factory AnnotatedCode.fromText(String annotatedCode, | 63 factory AnnotatedCode.fromText(String annotatedCode, |
58 [String start = '@{', String end = '}']) { | 64 [Pattern start = atBraceStart, Pattern end = braceEnd]) { |
59 StringBuffer codeBuffer = new StringBuffer(); | 65 StringBuffer codeBuffer = new StringBuffer(); |
60 List<Annotation> annotations = <Annotation>[]; | 66 List<Annotation> annotations = <Annotation>[]; |
61 int index = 0; | 67 int index = 0; |
62 int offset = 0; | 68 int offset = 0; |
63 int lineNo = 1; | 69 int lineNo = 1; |
64 int columnNo = 1; | 70 int columnNo = 1; |
65 List<int> lineStarts = <int>[]; | 71 List<int> lineStarts = <int>[]; |
66 lineStarts.add(offset); | 72 lineStarts.add(offset); |
67 while (index < annotatedCode.length) { | 73 while (index < annotatedCode.length) { |
68 if (annotatedCode.startsWith(start, index)) { | 74 Match startMatch = start.matchAsPrefix(annotatedCode, index); |
69 int endIndex = annotatedCode.indexOf(end, index + start.length); | 75 if (startMatch != null) { |
70 String text = annotatedCode.substring(index + start.length, endIndex); | 76 int startIndex = startMatch.end; |
71 annotations.add(new Annotation(lineNo, columnNo, offset, text)); | 77 Iterable<Match> endMatches = |
72 index = endIndex + end.length; | 78 end.allMatches(annotatedCode, startMatch.end); |
73 } else { | 79 if (!endMatches.isEmpty) { |
74 int charCode = annotatedCode.codeUnitAt(index); | 80 Match endMatch = endMatches.first; |
75 switch (charCode) { | 81 annotatedCode.indexOf(end, startIndex); |
76 case _LF: | 82 String text = annotatedCode.substring(startMatch.end, endMatch.start); |
77 codeBuffer.write('\n'); | 83 annotations.add(new Annotation(lineNo, columnNo, offset, text)); |
78 offset++; | 84 index = endMatch.end; |
79 lineStarts.add(offset); | 85 continue; |
80 lineNo++; | |
81 columnNo = 1; | |
82 break; | |
83 case _CR: | |
84 if (index + 1 < annotatedCode.length && | |
85 annotatedCode.codeUnitAt(index + 1) == _LF) { | |
86 index++; | |
87 } | |
88 codeBuffer.write('\n'); | |
89 offset++; | |
90 lineStarts.add(offset); | |
91 lineNo++; | |
92 columnNo = 1; | |
93 break; | |
94 default: | |
95 codeBuffer.writeCharCode(charCode); | |
96 offset++; | |
97 columnNo++; | |
98 } | 86 } |
99 index++; | |
100 } | 87 } |
| 88 |
| 89 int charCode = annotatedCode.codeUnitAt(index); |
| 90 switch (charCode) { |
| 91 case _LF: |
| 92 codeBuffer.write('\n'); |
| 93 offset++; |
| 94 lineStarts.add(offset); |
| 95 lineNo++; |
| 96 columnNo = 1; |
| 97 break; |
| 98 case _CR: |
| 99 if (index + 1 < annotatedCode.length && |
| 100 annotatedCode.codeUnitAt(index + 1) == _LF) { |
| 101 index++; |
| 102 } |
| 103 codeBuffer.write('\n'); |
| 104 offset++; |
| 105 lineStarts.add(offset); |
| 106 lineNo++; |
| 107 columnNo = 1; |
| 108 break; |
| 109 default: |
| 110 codeBuffer.writeCharCode(charCode); |
| 111 offset++; |
| 112 columnNo++; |
| 113 } |
| 114 index++; |
101 } | 115 } |
102 lineStarts.add(offset); | 116 lineStarts.add(offset); |
103 return new AnnotatedCode.internal( | 117 return new AnnotatedCode.internal( |
104 codeBuffer.toString(), annotations, lineStarts); | 118 codeBuffer.toString(), annotations, lineStarts); |
105 } | 119 } |
106 | 120 |
107 void _ensureLineStarts() { | 121 void _ensureLineStarts() { |
108 if (_lineStarts == null) { | 122 if (_lineStarts == null) { |
109 int index = 0; | 123 int index = 0; |
110 int offset = 0; | 124 int offset = 0; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 int offset = 0; | 161 int offset = 0; |
148 for (Annotation annotation in list) { | 162 for (Annotation annotation in list) { |
149 sb.write(sourceCode.substring(offset, annotation.offset)); | 163 sb.write(sourceCode.substring(offset, annotation.offset)); |
150 sb.write('@{${annotation.text}}'); | 164 sb.write('@{${annotation.text}}'); |
151 offset = annotation.offset; | 165 offset = annotation.offset; |
152 } | 166 } |
153 sb.write(sourceCode.substring(offset)); | 167 sb.write(sourceCode.substring(offset)); |
154 return sb.toString(); | 168 return sb.toString(); |
155 } | 169 } |
156 } | 170 } |
OLD | NEW |