OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 library dart2js.source_information; | 5 library dart2js.source_information; |
6 | 6 |
7 import '../dart2jslib.dart' show SourceSpan; | 7 import '../dart2jslib.dart' show SourceSpan; |
8 import '../elements/elements.dart' show AstElement; | 8 import '../elements/elements.dart' show AstElement; |
9 import '../scanner/scannerlib.dart' show Token; | 9 import '../scanner/scannerlib.dart' show Token; |
10 import '../tree/tree.dart' show Node; | 10 import '../tree/tree.dart' show Node; |
11 import '../js/js.dart' show JavaScriptNodeSourceInformation; | 11 import '../js/js.dart' show JavaScriptNodeSourceInformation; |
12 import 'code_output.dart'; | 12 import 'code_output.dart'; |
13 import 'source_file.dart'; | 13 import 'source_file.dart'; |
14 | 14 |
15 /// Interface for passing source information, for instance for use in source | 15 /// Interface for passing source information, for instance for use in source |
16 /// maps, through the backend. | 16 /// maps, through the backend. |
17 abstract class SourceInformation extends JavaScriptNodeSourceInformation { | 17 abstract class SourceInformation extends JavaScriptNodeSourceInformation { |
18 SourceSpan get sourceSpan; | 18 SourceSpan get sourceSpan; |
19 void beginMapping(CodeOutput output); | 19 void beginMapping(CodeOutput output); |
20 void endMapping(CodeOutput output); | 20 void endMapping(CodeOutput output); |
21 } | 21 } |
22 | 22 |
23 /// Source information that contains start source position and optionally an | 23 /// Source information that contains start source position and optionally an |
24 /// end source position. | 24 /// end source position. |
25 class StartEndSourceInformation implements SourceInformation { | 25 class StartEndSourceInformation implements SourceInformation { |
26 final SourceFileLocation startPosition; | 26 final SourceLocation startPosition; |
27 final SourceFileLocation endPosition; | 27 final SourceLocation endPosition; |
28 | 28 |
29 StartEndSourceInformation(this.startPosition, [this.endPosition]); | 29 StartEndSourceInformation(this.startPosition, [this.endPosition]); |
30 | 30 |
31 SourceSpan get sourceSpan { | 31 SourceSpan get sourceSpan { |
32 Uri uri = Uri.parse(startPosition.sourceFile.filename); | 32 Uri uri = startPosition.sourceUri; |
33 int begin = startPosition.offset; | 33 int begin = startPosition.offset; |
34 int end = endPosition == null ? begin : endPosition.offset; | 34 int end = endPosition == null ? begin : endPosition.offset; |
35 return new SourceSpan(uri, begin, end); | 35 return new SourceSpan(uri, begin, end); |
36 } | 36 } |
37 | 37 |
38 void beginMapping(CodeBuffer output) { | 38 void beginMapping(CodeBuffer output) { |
39 output.beginMappedRange(); | 39 output.beginMappedRange(); |
40 output.setSourceLocation(startPosition); | 40 output.setSourceLocation(startPosition); |
41 } | 41 } |
42 | 42 |
(...skipping 30 matching lines...) Expand all Loading... |
73 Token endToken; | 73 Token endToken; |
74 if (node == null) { | 74 if (node == null) { |
75 // Synthesized node. Use the enclosing element for the location. | 75 // Synthesized node. Use the enclosing element for the location. |
76 beginToken = endToken = element.position; | 76 beginToken = endToken = element.position; |
77 } else { | 77 } else { |
78 beginToken = node.getBeginToken(); | 78 beginToken = node.getBeginToken(); |
79 endToken = node.getEndToken(); | 79 endToken = node.getEndToken(); |
80 } | 80 } |
81 // TODO(podivilov): find the right sourceFile here and remove offset | 81 // TODO(podivilov): find the right sourceFile here and remove offset |
82 // checks below. | 82 // checks below. |
83 SourceFileLocation sourcePosition, endSourcePosition; | 83 SourceLocation sourcePosition, endSourcePosition; |
84 if (beginToken.charOffset < sourceFile.length) { | 84 if (beginToken.charOffset < sourceFile.length) { |
85 sourcePosition = | 85 sourcePosition = |
86 new TokenSourceFileLocation(sourceFile, beginToken, name); | 86 new TokenSourceLocation(sourceFile, beginToken, name); |
87 } | 87 } |
88 if (endToken.charOffset < sourceFile.length) { | 88 if (endToken.charOffset < sourceFile.length) { |
89 endSourcePosition = | 89 endSourcePosition = |
90 new TokenSourceFileLocation(sourceFile, endToken, name); | 90 new TokenSourceLocation(sourceFile, endToken, name); |
91 } | 91 } |
92 return new StartEndSourceInformation(sourcePosition, endSourcePosition); | 92 return new StartEndSourceInformation(sourcePosition, endSourcePosition); |
93 } | 93 } |
94 | 94 |
95 String toString() { | 95 String toString() { |
96 StringBuffer sb = new StringBuffer(); | 96 StringBuffer sb = new StringBuffer(); |
97 sb.write('${startPosition.getSourceUrl()}:'); | 97 sb.write('${startPosition.sourceUri}:'); |
98 sb.write('[${startPosition.getLine()},${startPosition.getColumn()}]'); | 98 sb.write('[${startPosition.line},${startPosition.column}]'); |
99 if (endPosition != null) { | 99 if (endPosition != null) { |
100 sb.write('-[${endPosition.getLine()},${endPosition.getColumn()}]'); | 100 sb.write('-[${endPosition.line},${endPosition.column}]'); |
101 } | 101 } |
102 return sb.toString(); | 102 return sb.toString(); |
103 } | 103 } |
104 } | 104 } |
105 | 105 |
106 // TODO(johnniwinther): Refactor this class to use getters. | 106 /// A location in a source file. |
107 abstract class SourceFileLocation { | 107 abstract class SourceLocation { |
108 SourceFile sourceFile; | 108 final SourceFile _sourceFile; |
| 109 int _line; |
109 | 110 |
110 SourceFileLocation(this.sourceFile) { | 111 SourceLocation(this._sourceFile) { |
111 assert(isValid()); | 112 assert(isValid); |
112 } | 113 } |
113 | 114 |
114 int line; | 115 /// The absolute URI of the source file of this source location. |
| 116 Uri get sourceUri => _sourceFile.uri; |
115 | 117 |
| 118 /// The character offset of the this source location into the source file. |
116 int get offset; | 119 int get offset; |
117 | 120 |
118 String getSourceUrl() => sourceFile.filename; | 121 /// The 0-based line number of the [offset]. |
119 | 122 int get line { |
120 int getLine() { | 123 if (_line == null) _line = _sourceFile.getLine(offset); |
121 if (line == null) line = sourceFile.getLine(offset); | 124 return _line; |
122 return line; | |
123 } | 125 } |
124 | 126 |
125 int getColumn() => sourceFile.getColumn(getLine(), offset); | 127 /// The 0-base column number of the [offset] with its line. |
| 128 int get column => _sourceFile.getColumn(line, offset); |
126 | 129 |
127 String getSourceName(); | 130 /// The name associated with this source location, if any. |
| 131 String get sourceName; |
128 | 132 |
129 bool isValid() => offset < sourceFile.length; | 133 /// `true` if the offset within the length of the source file. |
| 134 bool get isValid => offset < _sourceFile.length; |
130 | 135 |
131 int get hashCode { | 136 int get hashCode { |
132 return getSourceUrl().hashCode * 17 + | 137 return sourceUri.hashCode * 17 + |
133 offset.hashCode * 17 + | 138 offset.hashCode * 17 + |
134 getSourceName().hashCode * 23; | 139 sourceName.hashCode * 23; |
135 } | 140 } |
136 | 141 |
137 bool operator ==(other) { | 142 bool operator ==(other) { |
138 if (identical(this, other)) return true; | 143 if (identical(this, other)) return true; |
139 if (other is! SourceFileLocation) return false; | 144 if (other is! SourceLocation) return false; |
140 return getSourceUrl() == other.getSourceUrl() && | 145 return sourceUri == other.sourceUri && |
141 offset == other.offset && | 146 offset == other.offset && |
142 getSourceName() == other.getSourceName(); | 147 sourceName == other.sourceName; |
143 } | 148 } |
144 | 149 |
145 String toString() => '${getSourceUrl()}:[${getLine()},${getColumn()}]'; | 150 String toString() => '${sourceUri}:[${line},${column}]'; |
146 } | 151 } |
147 | 152 |
148 class TokenSourceFileLocation extends SourceFileLocation { | 153 class TokenSourceLocation extends SourceLocation { |
149 final Token token; | 154 final Token token; |
150 final String name; | 155 final String sourceName; |
151 | 156 |
152 TokenSourceFileLocation(SourceFile sourceFile, this.token, this.name) | 157 TokenSourceLocation(SourceFile sourceFile, this.token, this.sourceName) |
153 : super(sourceFile); | 158 : super(sourceFile); |
154 | 159 |
| 160 @override |
155 int get offset => token.charOffset; | 161 int get offset => token.charOffset; |
156 | 162 |
157 String getSourceName() { | |
158 return name; | |
159 } | |
160 | |
161 String toString() { | 163 String toString() { |
162 return '${super.toString()}:$name'; | 164 return '${super.toString()}:$sourceName'; |
163 } | 165 } |
164 } | 166 } |
OLD | NEW |