| Index: pkg/compiler/lib/src/io/source_information.dart
|
| diff --git a/pkg/compiler/lib/src/io/source_information.dart b/pkg/compiler/lib/src/io/source_information.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..529426190dd8407ec9f5f9fc04d28faca10c2e75
|
| --- /dev/null
|
| +++ b/pkg/compiler/lib/src/io/source_information.dart
|
| @@ -0,0 +1,163 @@
|
| +// Copyright (c) 2015, 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 file.
|
| +
|
| +library dart2js.source_information;
|
| +
|
| +import '../dart2jslib.dart' show SourceSpan;
|
| +import '../elements/elements.dart' show AstElement;
|
| +import '../scanner/scannerlib.dart' show Token;
|
| +import '../tree/tree.dart' show Node;
|
| +import 'code_output.dart';
|
| +import 'source_file.dart';
|
| +
|
| +/// Interface for passing source information, for instance for use in source
|
| +/// maps, through the backend.
|
| +abstract class SourceInformation {
|
| + SourceSpan get sourceSpan;
|
| + void beginMapping(CodeOutput output);
|
| + void endMapping(CodeOutput output);
|
| +}
|
| +
|
| +/// Source information that contains start source position and optionally an
|
| +/// end source position.
|
| +class StartEndSourceInformation implements SourceInformation {
|
| + final SourceFileLocation startPosition;
|
| + final SourceFileLocation endPosition;
|
| +
|
| + StartEndSourceInformation(this.startPosition, [this.endPosition]);
|
| +
|
| + SourceSpan get sourceSpan {
|
| + Uri uri = Uri.parse(startPosition.sourceFile.filename);
|
| + int begin = startPosition.offset;
|
| + int end = endPosition == null ? begin : endPosition.offset;
|
| + return new SourceSpan(uri, begin, end);
|
| + }
|
| +
|
| + void beginMapping(CodeBuffer output) {
|
| + output.beginMappedRange();
|
| + output.setSourceLocation(startPosition);
|
| + }
|
| +
|
| + void endMapping(CodeBuffer output) {
|
| + if (endPosition != null) {
|
| + output.setSourceLocation(endPosition);
|
| + }
|
| + output.endMappedRange();
|
| + }
|
| +
|
| + int get hashCode {
|
| + return (startPosition.hashCode * 17 +
|
| + endPosition.hashCode * 19)
|
| + & 0x7FFFFFFF;
|
| + }
|
| +
|
| + bool operator ==(other) {
|
| + if (identical(this, other)) return true;
|
| + if (other is! StartEndSourceInformation) return false;
|
| + return startPosition == other.startPosition &&
|
| + endPosition == other.endPosition;
|
| + }
|
| +
|
| + // TODO(johnniwinther): Remove this method. Source information should be
|
| + // computed based on the element by provided from statements and expressions.
|
| + static StartEndSourceInformation computeSourceInformation(
|
| + AstElement element) {
|
| +
|
| + AstElement implementation = element.implementation;
|
| + SourceFile sourceFile = implementation.compilationUnit.script.file;
|
| + String name = element.name;
|
| + Node node = implementation.node;
|
| + Token beginToken;
|
| + Token endToken;
|
| + if (node == null) {
|
| + // Synthesized node. Use the enclosing element for the location.
|
| + beginToken = endToken = element.position;
|
| + } else {
|
| + beginToken = node.getBeginToken();
|
| + endToken = node.getEndToken();
|
| + }
|
| + // TODO(podivilov): find the right sourceFile here and remove offset
|
| + // checks below.
|
| + SourceFileLocation sourcePosition, endSourcePosition;
|
| + if (beginToken.charOffset < sourceFile.length) {
|
| + sourcePosition =
|
| + new TokenSourceFileLocation(sourceFile, beginToken, name);
|
| + }
|
| + if (endToken.charOffset < sourceFile.length) {
|
| + endSourcePosition =
|
| + new TokenSourceFileLocation(sourceFile, endToken, name);
|
| + }
|
| + return new StartEndSourceInformation(sourcePosition, endSourcePosition);
|
| + }
|
| +
|
| + String toString() {
|
| + StringBuffer sb = new StringBuffer();
|
| + sb.write('${startPosition.getSourceUrl()}:');
|
| + sb.write('[${startPosition.getLine()},${startPosition.getColumn()}]');
|
| + if (endPosition != null) {
|
| + sb.write('-[${endPosition.getLine()},${endPosition.getColumn()}]');
|
| + }
|
| + return sb.toString();
|
| + }
|
| +}
|
| +
|
| +// TODO(johnniwinther): Refactor this class to use getters.
|
| +abstract class SourceFileLocation {
|
| + SourceFile sourceFile;
|
| +
|
| + SourceFileLocation(this.sourceFile) {
|
| + assert(isValid());
|
| + }
|
| +
|
| + int line;
|
| +
|
| + int get offset;
|
| +
|
| + String getSourceUrl() => sourceFile.filename;
|
| +
|
| + int getLine() {
|
| + if (line == null) line = sourceFile.getLine(offset);
|
| + return line;
|
| + }
|
| +
|
| + int getColumn() => sourceFile.getColumn(getLine(), offset);
|
| +
|
| + String getSourceName();
|
| +
|
| + bool isValid() => offset < sourceFile.length;
|
| +
|
| + int get hashCode {
|
| + return getSourceUrl().hashCode * 17 +
|
| + offset.hashCode * 17 +
|
| + getSourceName().hashCode * 23;
|
| + }
|
| +
|
| + bool operator ==(other) {
|
| + if (identical(this, other)) return true;
|
| + if (other is! SourceFileLocation) return false;
|
| + return getSourceUrl() == other.getSourceUrl() &&
|
| + offset == other.offset &&
|
| + getSourceName() == other.getSourceName();
|
| + }
|
| +
|
| + String toString() => '${getSourceUrl()}:[${getLine()},${getColumn()}]';
|
| +}
|
| +
|
| +class TokenSourceFileLocation extends SourceFileLocation {
|
| + final Token token;
|
| + final String name;
|
| +
|
| + TokenSourceFileLocation(SourceFile sourceFile, this.token, this.name)
|
| + : super(sourceFile);
|
| +
|
| + int get offset => token.charOffset;
|
| +
|
| + String getSourceName() {
|
| + return name;
|
| + }
|
| +
|
| + String toString() {
|
| + return '${super.toString()}:$name';
|
| + }
|
| +}
|
|
|