source: trip-planner-front/node_modules/istanbul-lib-source-maps/lib/get-mapping.js@ 1ad8e64

Last change on this file since 1ad8e64 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 5.7 KB
RevLine 
[6a3a178]1/*
2 Copyright 2015, Yahoo Inc.
3 Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms.
4 */
5'use strict';
6
7const pathutils = require('./pathutils');
8const {
9 GREATEST_LOWER_BOUND,
10 LEAST_UPPER_BOUND
11} = require('source-map').SourceMapConsumer;
12
13/**
14 * AST ranges are inclusive for start positions and exclusive for end positions.
15 * Source maps are also logically ranges over text, though interacting with
16 * them is generally achieved by working with explicit positions.
17 *
18 * When finding the _end_ location of an AST item, the range behavior is
19 * important because what we're asking for is the _end_ of whatever range
20 * corresponds to the end location we seek.
21 *
22 * This boils down to the following steps, conceptually, though the source-map
23 * library doesn't expose primitives to do this nicely:
24 *
25 * 1. Find the range on the generated file that ends at, or exclusively
26 * contains the end position of the AST node.
27 * 2. Find the range on the original file that corresponds to
28 * that generated range.
29 * 3. Find the _end_ location of that original range.
30 */
31function originalEndPositionFor(sourceMap, generatedEnd) {
32 // Given the generated location, find the original location of the mapping
33 // that corresponds to a range on the generated file that overlaps the
34 // generated file end location. Note however that this position on its
35 // own is not useful because it is the position of the _start_ of the range
36 // on the original file, and we want the _end_ of the range.
37 const beforeEndMapping = originalPositionTryBoth(
38 sourceMap,
39 generatedEnd.line,
40 generatedEnd.column - 1
41 );
42 if (beforeEndMapping.source === null) {
43 return null;
44 }
45
46 // Convert that original position back to a generated one, with a bump
47 // to the right, and a rightward bias. Since 'generatedPositionFor' searches
48 // for mappings in the original-order sorted list, this will find the
49 // mapping that corresponds to the one immediately after the
50 // beforeEndMapping mapping.
51 const afterEndMapping = sourceMap.generatedPositionFor({
52 source: beforeEndMapping.source,
53 line: beforeEndMapping.line,
54 column: beforeEndMapping.column + 1,
55 bias: LEAST_UPPER_BOUND
56 });
57 if (
58 // If this is null, it means that we've hit the end of the file,
59 // so we can use Infinity as the end column.
60 afterEndMapping.line === null ||
61 // If these don't match, it means that the call to
62 // 'generatedPositionFor' didn't find any other original mappings on
63 // the line we gave, so consider the binding to extend to infinity.
64 sourceMap.originalPositionFor(afterEndMapping).line !==
65 beforeEndMapping.line
66 ) {
67 return {
68 source: beforeEndMapping.source,
69 line: beforeEndMapping.line,
70 column: Infinity
71 };
72 }
73
74 // Convert the end mapping into the real original position.
75 return sourceMap.originalPositionFor(afterEndMapping);
76}
77
78/**
79 * Attempts to determine the original source position, first
80 * returning the closest element to the left (GREATEST_LOWER_BOUND),
81 * and next returning the closest element to the right (LEAST_UPPER_BOUND).
82 */
83function originalPositionTryBoth(sourceMap, line, column) {
84 const mapping = sourceMap.originalPositionFor({
85 line,
86 column,
87 bias: GREATEST_LOWER_BOUND
88 });
89 if (mapping.source === null) {
90 return sourceMap.originalPositionFor({
91 line,
92 column,
93 bias: LEAST_UPPER_BOUND
94 });
95 } else {
96 return mapping;
97 }
98}
99
100function isInvalidPosition(pos) {
101 return (
102 !pos ||
103 typeof pos.line !== 'number' ||
104 typeof pos.column !== 'number' ||
105 pos.line < 0 ||
106 pos.column < 0
107 );
108}
109
110/**
111 * determines the original position for a given location
112 * @param {SourceMapConsumer} sourceMap the source map
113 * @param {Object} generatedLocation the original location Object
114 * @returns {Object} the remapped location Object
115 */
116function getMapping(sourceMap, generatedLocation, origFile) {
117 if (!generatedLocation) {
118 return null;
119 }
120
121 if (
122 isInvalidPosition(generatedLocation.start) ||
123 isInvalidPosition(generatedLocation.end)
124 ) {
125 return null;
126 }
127
128 const start = originalPositionTryBoth(
129 sourceMap,
130 generatedLocation.start.line,
131 generatedLocation.start.column
132 );
133 let end = originalEndPositionFor(sourceMap, generatedLocation.end);
134
135 /* istanbul ignore if: edge case too hard to test for */
136 if (!(start && end)) {
137 return null;
138 }
139
140 if (!(start.source && end.source)) {
141 return null;
142 }
143
144 if (start.source !== end.source) {
145 return null;
146 }
147
148 /* istanbul ignore if: edge case too hard to test for */
149 if (start.line === null || start.column === null) {
150 return null;
151 }
152
153 /* istanbul ignore if: edge case too hard to test for */
154 if (end.line === null || end.column === null) {
155 return null;
156 }
157
158 if (start.line === end.line && start.column === end.column) {
159 end = sourceMap.originalPositionFor({
160 line: generatedLocation.end.line,
161 column: generatedLocation.end.column,
162 bias: LEAST_UPPER_BOUND
163 });
164 end.column -= 1;
165 }
166
167 return {
168 source: pathutils.relativeTo(start.source, origFile),
169 loc: {
170 start: {
171 line: start.line,
172 column: start.column
173 },
174 end: {
175 line: end.line,
176 column: end.column
177 }
178 }
179 };
180}
181
182module.exports = getMapping;
Note: See TracBrowser for help on using the repository browser.