From 9788885fd9b3e6a69c75c2e16dffaccb8ac7a7c0 Mon Sep 17 00:00:00 2001 From: Milan Hauth Date: Sun, 29 Nov 2020 15:44:22 +0100 Subject: [PATCH 1/6] add: import decoded sourcemaps from SourceMapGenerator --- src/compiler/preprocess/index.ts | 74 +++++++++++++++++++ .../samples/source-map-generator/_config.js | 25 +++++++ .../samples/source-map-generator/input.svelte | 12 +++ .../samples/source-map-generator/test.js | 1 + 4 files changed, 112 insertions(+) create mode 100644 test/sourcemaps/samples/source-map-generator/_config.js create mode 100644 test/sourcemaps/samples/source-map-generator/input.svelte create mode 100644 test/sourcemaps/samples/source-map-generator/test.js diff --git a/src/compiler/preprocess/index.ts b/src/compiler/preprocess/index.ts index 1de41cf9bf2f..88f351924a93 100644 --- a/src/compiler/preprocess/index.ts +++ b/src/compiler/preprocess/index.ts @@ -2,6 +2,7 @@ import { RawSourceMap, DecodedSourceMap } from '@ampproject/remapping/dist/types import { decode as decode_mappings } from 'sourcemap-codec'; import { getLocator } from 'locate-character'; import { StringWithSourcemap, sourcemap_add_offset, combine_sourcemaps } from '../utils/string_with_sourcemap'; +import { compareByGeneratedPositionsInflated } from 'source-map/lib/util'; export interface Processed { code: string; @@ -83,6 +84,72 @@ async function replace_async( return out.concat(final_content); } + + +// import decoded sourcemap from mozilla/source-map/SourceMapGenerator +// forked from source-map/lib/source-map-generator.js +// from methods _serializeMappings and toJSON +function DecodedSourcemapFromSourceMapGenerator(this: any) { + function convertMappings(this: any) { + let previousGeneratedLine = 1; + const result = [[]]; + let resultLine; + let resultSegment; + let mapping; + + const sourceIdx = this._sources.toArray().reduce((acc, val, idx) => (acc[val] = idx, acc), {}); + const nameIdx = this._names.toArray().reduce((acc, val, idx) => (acc[val] = idx, acc), {}); + + const mappings = this._mappings.toArray(); + resultLine = result[0]; + + for (let i = 0, len = mappings.length; i < len; i++) { + mapping = mappings[i]; + + if (mapping.generatedLine > previousGeneratedLine) { + while (mapping.generatedLine > previousGeneratedLine) { + result.push([]); + previousGeneratedLine++; + } + resultLine = result[mapping.generatedLine - 1]; // line is one-based + } else if (i > 0) { + if ( + !compareByGeneratedPositionsInflated(mapping, mappings[i - 1]) + ) { + continue; + } + } + resultLine.push([mapping.generatedColumn]); + resultSegment = resultLine[resultLine.length - 1]; + + if (mapping.source != null) { + resultSegment.push(...[ + sourceIdx[mapping.source], + mapping.originalLine - 1, // line is one-based + mapping.originalColumn + ]); + if (mapping.name != null) { + resultSegment.push(nameIdx[mapping.name]); + } + } + } + return result; + } + const map = { + version: this._version, + sources: this._sources.toArray(), + names: this._names.toArray(), + mappings: convertMappings.apply(this) + }; + if (this._file != null) { + (map as any).file = this._file; + } + // not needed: map.sourcesContent and map.sourceRoot + return map; +} + + + /** * Convert a preprocessor output and its leading prefix and trailing suffix into StringWithSourceMap */ @@ -109,6 +176,13 @@ function get_replacement( if (typeof(decoded_map.mappings) === 'string') { decoded_map.mappings = decode_mappings(decoded_map.mappings); } + if ( + (decoded_map as any)._mappings && + decoded_map.constructor.name == 'SourceMapGenerator' + ) { + // import decoded sourcemap from mozilla/source-map/SourceMapGenerator + decoded_map = DecodedSourcemapFromSourceMapGenerator.apply(decoded_map); + } sourcemap_add_offset(decoded_map, get_location(offset + prefix.length)); } const processed_with_map = StringWithSourcemap.from_processed(processed.code, decoded_map); diff --git a/test/sourcemaps/samples/source-map-generator/_config.js b/test/sourcemaps/samples/source-map-generator/_config.js new file mode 100644 index 000000000000..fefb776f33fe --- /dev/null +++ b/test/sourcemaps/samples/source-map-generator/_config.js @@ -0,0 +1,25 @@ +import MagicString from 'magic-string'; +import { SourceMapConsumer, SourceMapGenerator } from 'source-map'; + +export default { + preprocess: { + style: async ({ content, filename }) => { + const src = new MagicString(content); + const idx = content.indexOf('baritone'); + src.overwrite(idx, idx+'baritone'.length, 'bar'); + + const map = SourceMapGenerator.fromSourceMap( + await new SourceMapConsumer( + // sourcemap must be encoded for SourceMapConsumer + src.generateMap({ + source: filename, + hires: true, + includeContent: false + }) + ) + ); + + return { code: src.toString(), map }; + } + } +}; diff --git a/test/sourcemaps/samples/source-map-generator/input.svelte b/test/sourcemaps/samples/source-map-generator/input.svelte new file mode 100644 index 000000000000..0d942390f4b8 --- /dev/null +++ b/test/sourcemaps/samples/source-map-generator/input.svelte @@ -0,0 +1,12 @@ +

Testing Styles

+

Testing Styles 2

+ + diff --git a/test/sourcemaps/samples/source-map-generator/test.js b/test/sourcemaps/samples/source-map-generator/test.js new file mode 100644 index 000000000000..72ad1da1d8e2 --- /dev/null +++ b/test/sourcemaps/samples/source-map-generator/test.js @@ -0,0 +1 @@ +export { test } from '../preprocessed-styles/test'; From 38a3ebaf0bb81e7fe623a1235fa165d1cb3c9615 Mon Sep 17 00:00:00 2001 From: Milan Hauth Date: Sun, 29 Nov 2020 21:26:46 +0100 Subject: [PATCH 2/6] fix: remove dep source-map --- src/compiler/preprocess/index.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/compiler/preprocess/index.ts b/src/compiler/preprocess/index.ts index 88f351924a93..ed8088ded913 100644 --- a/src/compiler/preprocess/index.ts +++ b/src/compiler/preprocess/index.ts @@ -2,7 +2,6 @@ import { RawSourceMap, DecodedSourceMap } from '@ampproject/remapping/dist/types import { decode as decode_mappings } from 'sourcemap-codec'; import { getLocator } from 'locate-character'; import { StringWithSourcemap, sourcemap_add_offset, combine_sourcemaps } from '../utils/string_with_sourcemap'; -import { compareByGeneratedPositionsInflated } from 'source-map/lib/util'; export interface Processed { code: string; @@ -90,6 +89,16 @@ async function replace_async( // forked from source-map/lib/source-map-generator.js // from methods _serializeMappings and toJSON function DecodedSourcemapFromSourceMapGenerator(this: any) { + function areEqualMappings(a, b) { + return ( + a.generatedLine == b.generatedLine && + a.generatedColumn == b.generatedColumn && + a.source == b.source && + a.originalLine == b.originalLine && + a.originalColumn == b.originalColumn && + a.name == b.name + ); + } function convertMappings(this: any) { let previousGeneratedLine = 1; const result = [[]]; @@ -113,9 +122,7 @@ function DecodedSourcemapFromSourceMapGenerator(this: any) { } resultLine = result[mapping.generatedLine - 1]; // line is one-based } else if (i > 0) { - if ( - !compareByGeneratedPositionsInflated(mapping, mappings[i - 1]) - ) { + if (areEqualMappings(mapping, mappings[i - 1])) { continue; } } From 19e42f73fad1a3ba200682fae522f389ddcb2ac9 Mon Sep 17 00:00:00 2001 From: Milan Hauth Date: Mon, 30 Nov 2020 10:14:11 +0100 Subject: [PATCH 3/6] fix: lowercase fn name, jsdoc comment --- src/compiler/preprocess/index.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/compiler/preprocess/index.ts b/src/compiler/preprocess/index.ts index ed8088ded913..2bef72815539 100644 --- a/src/compiler/preprocess/index.ts +++ b/src/compiler/preprocess/index.ts @@ -85,10 +85,12 @@ async function replace_async( -// import decoded sourcemap from mozilla/source-map/SourceMapGenerator -// forked from source-map/lib/source-map-generator.js -// from methods _serializeMappings and toJSON -function DecodedSourcemapFromSourceMapGenerator(this: any) { +/** + * import decoded sourcemap from mozilla/source-map/SourceMapGenerator + * forked from source-map/lib/source-map-generator.js + * from methods _serializeMappings and toJSON + */ +function decodedSourcemapFromSourceMapGenerator(this: any) { function areEqualMappings(a, b) { return ( a.generatedLine == b.generatedLine && @@ -188,7 +190,7 @@ function get_replacement( decoded_map.constructor.name == 'SourceMapGenerator' ) { // import decoded sourcemap from mozilla/source-map/SourceMapGenerator - decoded_map = DecodedSourcemapFromSourceMapGenerator.apply(decoded_map); + decoded_map = decodedSourcemapFromSourceMapGenerator.apply(decoded_map); } sourcemap_add_offset(decoded_map, get_location(offset + prefix.length)); } From 6311a85d559271c0c93f338361fe124d3d92146e Mon Sep 17 00:00:00 2001 From: Milan Hauth Date: Mon, 30 Nov 2020 19:21:00 +0100 Subject: [PATCH 4/6] fix: avoid f.apply, rename fn, optimize, prettify --- src/compiler/preprocess/index.ts | 43 +++++++++++++++++--------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/src/compiler/preprocess/index.ts b/src/compiler/preprocess/index.ts index 2bef72815539..ed2066c1413c 100644 --- a/src/compiler/preprocess/index.ts +++ b/src/compiler/preprocess/index.ts @@ -89,29 +89,35 @@ async function replace_async( * import decoded sourcemap from mozilla/source-map/SourceMapGenerator * forked from source-map/lib/source-map-generator.js * from methods _serializeMappings and toJSON + * we cannot use source-map.d.ts types, cos we access hidden properties */ -function decodedSourcemapFromSourceMapGenerator(this: any) { +function decoded_sourcemap_from_generator(generator: any) { function areEqualMappings(a, b) { return ( - a.generatedLine == b.generatedLine && + // sorted by selectivity a.generatedColumn == b.generatedColumn && - a.source == b.source && - a.originalLine == b.originalLine && a.originalColumn == b.originalColumn && - a.name == b.name + a.name == b.name && + a.generatedLine == b.generatedLine && + a.originalLine == b.originalLine && + a.source == b.source ); } - function convertMappings(this: any) { + function convertMappings() { + // use global variable: generator let previousGeneratedLine = 1; const result = [[]]; let resultLine; let resultSegment; let mapping; - const sourceIdx = this._sources.toArray().reduce((acc, val, idx) => (acc[val] = idx, acc), {}); - const nameIdx = this._names.toArray().reduce((acc, val, idx) => (acc[val] = idx, acc), {}); + const sourceIdx = generator._sources.toArray() + .reduce((acc, val, idx) => (acc[val] = idx, acc), {}); + + const nameIdx = generator._names.toArray() + .reduce((acc, val, idx) => (acc[val] = idx, acc), {}); - const mappings = this._mappings.toArray(); + const mappings = generator._mappings.toArray(); resultLine = result[0]; for (let i = 0, len = mappings.length; i < len; i++) { @@ -145,13 +151,13 @@ function decodedSourcemapFromSourceMapGenerator(this: any) { return result; } const map = { - version: this._version, - sources: this._sources.toArray(), - names: this._names.toArray(), - mappings: convertMappings.apply(this) + version: generator._version, + sources: generator._sources.toArray(), + names: generator._names.toArray(), + mappings: convertMappings() }; - if (this._file != null) { - (map as any).file = this._file; + if (generator._file != null) { + (map as any).file = generator._file; } // not needed: map.sourcesContent and map.sourceRoot return map; @@ -185,12 +191,9 @@ function get_replacement( if (typeof(decoded_map.mappings) === 'string') { decoded_map.mappings = decode_mappings(decoded_map.mappings); } - if ( - (decoded_map as any)._mappings && - decoded_map.constructor.name == 'SourceMapGenerator' - ) { + if ((decoded_map as any)._mappings && decoded_map.constructor.name == 'SourceMapGenerator') { // import decoded sourcemap from mozilla/source-map/SourceMapGenerator - decoded_map = decodedSourcemapFromSourceMapGenerator.apply(decoded_map); + decoded_map = decoded_sourcemap_from_generator(decoded_map); } sourcemap_add_offset(decoded_map, get_location(offset + prefix.length)); } From d8c553f51fb007af8bfa246dccfe76031a0eb481 Mon Sep 17 00:00:00 2001 From: Milan Hauth Date: Mon, 30 Nov 2020 20:32:41 +0100 Subject: [PATCH 5/6] fix: snake case fns --- src/compiler/preprocess/index.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/preprocess/index.ts b/src/compiler/preprocess/index.ts index ed2066c1413c..39ba353e945f 100644 --- a/src/compiler/preprocess/index.ts +++ b/src/compiler/preprocess/index.ts @@ -92,7 +92,7 @@ async function replace_async( * we cannot use source-map.d.ts types, cos we access hidden properties */ function decoded_sourcemap_from_generator(generator: any) { - function areEqualMappings(a, b) { + function are_equal_mappings(a, b) { return ( // sorted by selectivity a.generatedColumn == b.generatedColumn && @@ -103,7 +103,7 @@ function decoded_sourcemap_from_generator(generator: any) { a.source == b.source ); } - function convertMappings() { + function convert_mappings() { // use global variable: generator let previousGeneratedLine = 1; const result = [[]]; @@ -130,7 +130,7 @@ function decoded_sourcemap_from_generator(generator: any) { } resultLine = result[mapping.generatedLine - 1]; // line is one-based } else if (i > 0) { - if (areEqualMappings(mapping, mappings[i - 1])) { + if (are_equal_mappings(mapping, mappings[i - 1])) { continue; } } @@ -154,7 +154,7 @@ function decoded_sourcemap_from_generator(generator: any) { version: generator._version, sources: generator._sources.toArray(), names: generator._names.toArray(), - mappings: convertMappings() + mappings: convert_mappings() }; if (generator._file != null) { (map as any).file = generator._file; From 484a04bfd9bf4ddc6637cf8a4f336bf60eec4f2f Mon Sep 17 00:00:00 2001 From: Conduitry Date: Mon, 30 Nov 2020 15:21:40 -0500 Subject: [PATCH 6/6] tidy --- src/compiler/preprocess/index.ts | 125 ++++++++++++++----------------- 1 file changed, 58 insertions(+), 67 deletions(-) diff --git a/src/compiler/preprocess/index.ts b/src/compiler/preprocess/index.ts index 39ba353e945f..b51b67bb2345 100644 --- a/src/compiler/preprocess/index.ts +++ b/src/compiler/preprocess/index.ts @@ -83,78 +83,71 @@ async function replace_async( return out.concat(final_content); } - - /** - * import decoded sourcemap from mozilla/source-map/SourceMapGenerator - * forked from source-map/lib/source-map-generator.js - * from methods _serializeMappings and toJSON - * we cannot use source-map.d.ts types, cos we access hidden properties + * Import decoded sourcemap from mozilla/source-map/SourceMapGenerator + * Forked from source-map/lib/source-map-generator.js + * from methods _serializeMappings and toJSON. + * We cannot use source-map.d.ts types, because we access hidden properties. */ function decoded_sourcemap_from_generator(generator: any) { - function are_equal_mappings(a, b) { - return ( - // sorted by selectivity - a.generatedColumn == b.generatedColumn && - a.originalColumn == b.originalColumn && - a.name == b.name && - a.generatedLine == b.generatedLine && - a.originalLine == b.originalLine && - a.source == b.source - ); - } - function convert_mappings() { - // use global variable: generator - let previousGeneratedLine = 1; - const result = [[]]; - let resultLine; - let resultSegment; - let mapping; - - const sourceIdx = generator._sources.toArray() - .reduce((acc, val, idx) => (acc[val] = idx, acc), {}); - - const nameIdx = generator._names.toArray() - .reduce((acc, val, idx) => (acc[val] = idx, acc), {}); - - const mappings = generator._mappings.toArray(); - resultLine = result[0]; - - for (let i = 0, len = mappings.length; i < len; i++) { - mapping = mappings[i]; - - if (mapping.generatedLine > previousGeneratedLine) { - while (mapping.generatedLine > previousGeneratedLine) { - result.push([]); - previousGeneratedLine++; - } - resultLine = result[mapping.generatedLine - 1]; // line is one-based - } else if (i > 0) { - if (are_equal_mappings(mapping, mappings[i - 1])) { - continue; - } + let previous_generated_line = 1; + const converted_mappings = [[]]; + let result_line; + let result_segment; + let mapping; + + const source_idx = generator._sources.toArray() + .reduce((acc, val, idx) => (acc[val] = idx, acc), {}); + + const name_idx = generator._names.toArray() + .reduce((acc, val, idx) => (acc[val] = idx, acc), {}); + + const mappings = generator._mappings.toArray(); + result_line = converted_mappings[0]; + + for (let i = 0, len = mappings.length; i < len; i++) { + mapping = mappings[i]; + + if (mapping.generatedLine > previous_generated_line) { + while (mapping.generatedLine > previous_generated_line) { + converted_mappings.push([]); + previous_generated_line++; } - resultLine.push([mapping.generatedColumn]); - resultSegment = resultLine[resultLine.length - 1]; - - if (mapping.source != null) { - resultSegment.push(...[ - sourceIdx[mapping.source], - mapping.originalLine - 1, // line is one-based - mapping.originalColumn - ]); - if (mapping.name != null) { - resultSegment.push(nameIdx[mapping.name]); - } + result_line = converted_mappings[mapping.generatedLine - 1]; // line is one-based + } else if (i > 0) { + const previous_mapping = mappings[i - 1]; + if ( + // sorted by selectivity + mapping.generatedColumn === previous_mapping.generatedColumn && + mapping.originalColumn === previous_mapping.originalColumn && + mapping.name === previous_mapping.name && + mapping.generatedLine === previous_mapping.generatedLine && + mapping.originalLine === previous_mapping.originalLine && + mapping.source === previous_mapping.source + ) { + continue; + } + } + result_line.push([mapping.generatedColumn]); + result_segment = result_line[result_line.length - 1]; + + if (mapping.source != null) { + result_segment.push(...[ + source_idx[mapping.source], + mapping.originalLine - 1, // line is one-based + mapping.originalColumn + ]); + if (mapping.name != null) { + result_segment.push(name_idx[mapping.name]); } } - return result; } + const map = { version: generator._version, sources: generator._sources.toArray(), names: generator._names.toArray(), - mappings: convert_mappings() + mappings: converted_mappings }; if (generator._file != null) { (map as any).file = generator._file; @@ -163,10 +156,8 @@ function decoded_sourcemap_from_generator(generator: any) { return map; } - - -/** - * Convert a preprocessor output and its leading prefix and trailing suffix into StringWithSourceMap +/** + * Convert a preprocessor output and its leading prefix and trailing suffix into StringWithSourceMap */ function get_replacement( filename: string, @@ -191,7 +182,7 @@ function get_replacement( if (typeof(decoded_map.mappings) === 'string') { decoded_map.mappings = decode_mappings(decoded_map.mappings); } - if ((decoded_map as any)._mappings && decoded_map.constructor.name == 'SourceMapGenerator') { + if ((decoded_map as any)._mappings && decoded_map.constructor.name === 'SourceMapGenerator') { // import decoded sourcemap from mozilla/source-map/SourceMapGenerator decoded_map = decoded_sourcemap_from_generator(decoded_map); } @@ -250,7 +241,7 @@ export default async function preprocess( async function preprocess_tag_content(tag_name: 'style' | 'script', preprocessor: Preprocessor) { const get_location = getLocator(source); - const tag_regex = tag_name == 'style' + const tag_regex = tag_name === 'style' ? /|([^]*?)<\/style>|\/>)/gi : /|([^]*?)<\/script>|\/>)/gi;