| 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 |