UNPKG

5.16 kBJavaScriptView Raw
1"use strict";
2/**
3 * @license
4 * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
5 * This code may only be used under the BSD style license found at
6 * http://polymer.github.io/LICENSE.txt
7 * The complete set of authors may be found at
8 * http://polymer.github.io/AUTHORS.txt
9 * The complete set of contributors may be found at
10 * http://polymer.github.io/CONTRIBUTORS.txt
11 * Code distributed by Google as part of the polymer project is also
12 * subject to an additional IP rights grant found at
13 * http://polymer.github.io/PATENTS.txt
14 */
15Object.defineProperty(exports, "__esModule", { value: true });
16const source_range_1 = require("../model/source-range");
17/**
18 * A parsed Document.
19 *
20 * @template AstNode The AST type of the document.
21 * @template Visitor The type of the visitors that can walk the document.
22 */
23class ParsedDocument {
24 constructor(from) {
25 /**
26 * The 0-based offsets into `contents` of all newline characters.
27 *
28 * Useful for converting between string offsets and SourcePositions.
29 */
30 this.newlineIndexes = [];
31 this.url = from.url;
32 this.baseUrl = from.baseUrl === undefined ? this.url : from.baseUrl;
33 this.contents = from.contents;
34 this.ast = from.ast;
35 this._locationOffset = from.locationOffset;
36 this.astNode = from.astNode;
37 this.isInline = from.isInline;
38 let lastSeenLine = -1;
39 while (true) {
40 lastSeenLine = from.contents.indexOf('\n', lastSeenLine + 1);
41 if (lastSeenLine === -1) {
42 break;
43 }
44 this.newlineIndexes.push(lastSeenLine);
45 }
46 this.sourceRange = this.offsetsToSourceRange(0, this.contents.length);
47 }
48 sourceRangeForNode(node) {
49 const baseSource = this._sourceRangeForNode(node);
50 return this.relativeToAbsoluteSourceRange(baseSource);
51 }
52 offsetToSourcePosition(offset) {
53 const linesLess = binarySearch(offset, this.newlineIndexes);
54 let colOffset = this.newlineIndexes[linesLess - 1];
55 if (colOffset == null) {
56 colOffset = 0;
57 }
58 else {
59 colOffset = colOffset + 1;
60 }
61 return { line: linesLess, column: offset - colOffset };
62 }
63 offsetsToSourceRange(start, end) {
64 const sourceRange = {
65 file: this.url,
66 start: this.offsetToSourcePosition(start),
67 end: this.offsetToSourcePosition(end)
68 };
69 return source_range_1.correctSourceRange(sourceRange, this._locationOffset);
70 }
71 sourcePositionToOffset(position) {
72 const line = Math.max(0, position.line);
73 let lineOffset;
74 if (line === 0) {
75 lineOffset = -1;
76 }
77 else if (line > this.newlineIndexes.length) {
78 lineOffset = this.contents.length - 1;
79 }
80 else {
81 lineOffset = this.newlineIndexes[line - 1];
82 }
83 const result = position.column + lineOffset + 1;
84 // Clamp within bounds.
85 return Math.min(Math.max(0, result), this.contents.length);
86 }
87 relativeToAbsoluteSourceRange(sourceRange) {
88 return source_range_1.correctSourceRange(sourceRange, this._locationOffset);
89 }
90 absoluteToRelativeSourceRange(sourceRange) {
91 return source_range_1.uncorrectSourceRange(sourceRange, this._locationOffset);
92 }
93 sourceRangeToOffsets(range) {
94 return [
95 this.sourcePositionToOffset(range.start),
96 this.sourcePositionToOffset(range.end)
97 ];
98 }
99 toString() {
100 if (this.isInline) {
101 return `Inline ${this.constructor.name} on line ` +
102 `${this.sourceRange.start.line} of ${this.url}`;
103 }
104 return `${this.constructor.name} at ${this.url}`;
105 }
106}
107exports.ParsedDocument = ParsedDocument;
108/**
109 * Used solely for constructing warnings about unparsable or unloadable
110 * documents.
111 */
112class UnparsableParsedDocument extends ParsedDocument {
113 constructor(url, contents) {
114 super({
115 ast: null,
116 url,
117 baseUrl: url,
118 astNode: undefined,
119 contents: contents,
120 isInline: false,
121 locationOffset: undefined
122 });
123 this.type = 'unparsable';
124 }
125 visit(_visitors) {
126 return;
127 }
128 _sourceRangeForNode(_node) {
129 return undefined;
130 }
131 stringify() {
132 return `<FakeParsedDocument url="${this.url}">`;
133 }
134}
135exports.UnparsableParsedDocument = UnparsableParsedDocument;
136/**
137 * The variant of binary search that returns the number of elements in the
138 * array that is strictly less than the target.
139 */
140function binarySearch(target, arr) {
141 let lower = 0;
142 let upper = arr.length - 1;
143 while (true) {
144 if (lower > upper) {
145 return lower;
146 }
147 const m = Math.floor((upper + lower) / 2);
148 if (target === arr[m]) {
149 return m;
150 }
151 if (target > arr[m]) {
152 lower = m + 1;
153 }
154 else {
155 upper = m - 1;
156 }
157 }
158}
159//# sourceMappingURL=document.js.map
\No newline at end of file