diff --git a/src/Bundle/index.js b/src/Bundle/index.js index ca872c1..bb31a83 100644 --- a/src/Bundle/index.js +++ b/src/Bundle/index.js @@ -93,7 +93,7 @@ class Bundle { mappings = getSemis( source.content.toString() ); } else { const sourceIndex = this.uniqueSourceIndexByFilename[ source.filename ]; - mappings = source.content.getMappings( options.hires, sourceIndex, offsets ); + mappings = source.content.getMappings( options.hires, sourceIndex, offsets, [], {} ); // TODO names and nameLocations } return prefix + mappings; diff --git a/src/MagicString/encodeMappings.js b/src/MagicString/encodeMappings.js index 25db161..e0938aa 100644 --- a/src/MagicString/encodeMappings.js +++ b/src/MagicString/encodeMappings.js @@ -1,6 +1,6 @@ import { encode } from 'vlq'; -export default function encodeMappings ( original, str, mappings, hires, sourcemapLocations, sourceIndex, offsets ) { +export default function encodeMappings ( original, str, mappings, hires, sourcemapLocations, sourceIndex, offsets, names, nameLocations ) { // store locations, for fast lookup let lineStart = 0; const locations = original.split( '\n' ).map( line => { @@ -20,6 +20,7 @@ export default function encodeMappings ( original, str, mappings, hires, sourcem let origin; let lastOrigin = -1; let location; + let nameIndex; let i; @@ -28,28 +29,29 @@ export default function encodeMappings ( original, str, mappings, hires, sourcem char = i + charOffset; origin = inverseMappings[ char ]; - location = ( !~origin && ~lastOrigin ) ? + nameIndex = -1; + location = null; - // if this character has no mapping, but the last one did, - // create a new segment - getLocation( locations, lastOrigin + 1 ) : + // if this character has no mapping, but the last one did, + // create a new segment + if ( !~origin && ~lastOrigin ) { + origin = lastOrigin + 1; + location = getLocation( locations, lastOrigin + 1 ); - // otherwise create a new segment if this character is mapped to an origin and - // a) we're in hires mode - // b) the origin isn't just lastOrigin + 1 - // c) there's a marked sourcemapLocation - ( ~origin && ( hires || ( ~lastOrigin && origin !== lastOrigin + 1 ) || sourcemapLocations[ origin ] ) ) ? - getLocation( locations, origin ) : + if ( origin in nameLocations ) nameIndex = names.indexOf( nameLocations[ origin ] ); + } - // otherwise skip it - null; + else if ( ~origin && ( hires || ( ~lastOrigin && origin !== lastOrigin + 1 ) || sourcemapLocations[ origin ] ) ) { + location = getLocation( locations, origin ); + } if ( location ) { segments.push({ generatedCodeColumn: i, sourceIndex: sourceIndex, sourceCodeLine: location.line, - sourceCodeColumn: location.column + sourceCodeColumn: location.column, + sourceCodeName: nameIndex }); } @@ -60,17 +62,16 @@ export default function encodeMappings ( original, str, mappings, hires, sourcem return segments; }); - offsets = offsets || {}; - offsets.sourceIndex = offsets.sourceIndex || 0; offsets.sourceCodeLine = offsets.sourceCodeLine || 0; offsets.sourceCodeColumn = offsets.sourceCodeColumn || 0; + offsets.sourceCodeName = offsets.sourceCodeName || 0; const encoded = lines.map( segments => { var generatedCodeColumn = 0; return segments.map( segment => { - const arr = [ + let arr = [ segment.generatedCodeColumn - generatedCodeColumn, segment.sourceIndex - offsets.sourceIndex, segment.sourceCodeLine - offsets.sourceCodeLine, @@ -82,6 +83,11 @@ export default function encodeMappings ( original, str, mappings, hires, sourcem offsets.sourceCodeLine = segment.sourceCodeLine; offsets.sourceCodeColumn = segment.sourceCodeColumn; + if ( ~segment.sourceCodeName ) { + arr.push( segment.sourceCodeName - offsets.sourceCodeName ); + offsets.sourceCodeName = segment.sourceCodeName; + } + return encode( arr ); }).join( ',' ); }).join( ';' ); diff --git a/src/MagicString/index.js b/src/MagicString/index.js index 431ab8a..1830448 100644 --- a/src/MagicString/index.js +++ b/src/MagicString/index.js @@ -14,6 +14,7 @@ class MagicString { this.indentExclusionRanges = options.indentExclusionRanges; this.sourcemapLocations = {}; + this.nameLocations = {}; this.indentStr = guessIndent( string ); } @@ -58,12 +59,18 @@ class MagicString { generateMap ( options ) { options = options || {}; + let names = []; + Object.keys( this.nameLocations ).forEach( location => { + const name = this.nameLocations[ location ]; + if ( !~names.indexOf( name ) ) names.push( name ); + }); + return new SourceMap({ file: ( options.file ? options.file.split( /[\/\\]/ ).pop() : null ), sources: [ options.source ? getRelativePath( options.file || '', options.source ) : null ], sourcesContent: options.includeContent ? [ this.original ] : [ null ], - names: [], - mappings: this.getMappings( options.hires, 0 ) + names, + mappings: this.getMappings( options.hires, 0, {}, names, this.nameLocations ) }); } @@ -71,8 +78,8 @@ class MagicString { return this.indentStr === null ? '\t' : this.indentStr; } - getMappings ( hires, sourceIndex, offsets ) { - return encodeMappings( this.original, this.str, this.mappings, hires, this.sourcemapLocations, sourceIndex, offsets ); + getMappings ( hires, sourceIndex, offsets, names, nameLocations ) { + return encodeMappings( this.original, this.str, this.mappings, hires, this.sourcemapLocations, sourceIndex, offsets, names, nameLocations ); } indent ( indentStr, options ) { @@ -238,7 +245,7 @@ class MagicString { return null; } - overwrite ( start, end, content ) { + overwrite ( start, end, content, storeName ) { if ( typeof content !== 'string' ) { throw new TypeError( 'replacement content must be a string' ); } @@ -259,6 +266,10 @@ class MagicString { ); } + if ( storeName ) { + this.nameLocations[ start ] = this.original.slice( start, end ); + } + this.str = this.str.substr( 0, firstChar ) + content + this.str.substring( lastChar + 1 ); d = content.length - ( lastChar + 1 - firstChar );