Skip to content

Commit

Permalink
test: add test case
Browse files Browse the repository at this point in the history
  • Loading branch information
edison1105 committed Jan 13, 2025
1 parent 29b4ab7 commit d81b83e
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 84 deletions.
29 changes: 28 additions & 1 deletion packages/compiler-sfc/__tests__/compileScript.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import { BindingTypes } from '@vue/compiler-core'
import { assertCode, compileSFCScript as compile, mockId } from './utils'
import {
assertCode,
compileSFCScript as compile,
getPositionInCode,
mockId,
} from './utils'
import { type RawSourceMap, SourceMapConsumer } from 'source-map-js'

describe('SFC compile <script setup>', () => {
test('should compile JS syntax', () => {
Expand Down Expand Up @@ -690,6 +696,27 @@ describe('SFC compile <script setup>', () => {
expect(content).toMatch(`new (_unref(Foo)).Bar()`)
assertCode(content)
})

// #12682
test('source map', () => {
const source = `
<script setup>
const count = ref(0)
</script>
<template>
<button @click="throw new Error(\`msg\`);"></button>
</template>
`
const { content, map } = compile(source, { inlineTemplate: true })
expect(map).not.toBeUndefined()
const consumer = new SourceMapConsumer(map as RawSourceMap)
expect(
consumer.originalPositionFor(getPositionInCode(content, 'count')),
).toMatchObject(getPositionInCode(source, `count`))
expect(
consumer.originalPositionFor(getPositionInCode(content, 'Error')),
).toMatchObject(getPositionInCode(source, `Error`))
})
})

describe('with TypeScript', () => {
Expand Down
34 changes: 1 addition & 33 deletions packages/compiler-sfc/__tests__/compileTemplate.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
} from '../src/compileTemplate'
import { type SFCTemplateBlock, parse } from '../src/parse'
import { compileScript } from '../src'
import { getPositionInCode } from './utils'

function compile(opts: Omit<SFCTemplateCompileOptions, 'id'>) {
return compileTemplate({
Expand Down Expand Up @@ -482,36 +483,3 @@ test('non-identifier expression in legacy filter syntax', () => {
babelParse(compilationResult.code, { sourceType: 'module' })
}).not.toThrow()
})

interface Pos {
line: number
column: number
name?: string
}

function getPositionInCode(
code: string,
token: string,
expectName: string | boolean = false,
): Pos {
const generatedOffset = code.indexOf(token)
let line = 1
let lastNewLinePos = -1
for (let i = 0; i < generatedOffset; i++) {
if (code.charCodeAt(i) === 10 /* newline char code */) {
line++
lastNewLinePos = i
}
}
const res: Pos = {
line,
column:
lastNewLinePos === -1
? generatedOffset
: generatedOffset - lastNewLinePos - 1,
}
if (expectName) {
res.name = typeof expectName === 'string' ? expectName : token
}
return res
}
33 changes: 33 additions & 0 deletions packages/compiler-sfc/__tests__/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,36 @@ export function assertCode(code: string): void {
}
expect(code).toMatchSnapshot()
}

interface Pos {
line: number
column: number
name?: string
}

export function getPositionInCode(
code: string,
token: string,
expectName: string | boolean = false,
): Pos {
const generatedOffset = code.indexOf(token)
let line = 1
let lastNewLinePos = -1
for (let i = 0; i < generatedOffset; i++) {
if (code.charCodeAt(i) === 10 /* newline char code */) {
line++
lastNewLinePos = i
}
}
const res: Pos = {
line,
column:
lastNewLinePos === -1
? generatedOffset
: generatedOffset - lastNewLinePos - 1,
}
if (expectName) {
res.name = typeof expectName === 'string' ? expectName : token
}
return res
}
54 changes: 49 additions & 5 deletions packages/compiler-sfc/src/compileScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@ import type {
Statement,
} from '@babel/types'
import { walk } from 'estree-walker'
import type { RawSourceMap } from 'source-map-js'
import {
type RawSourceMap,
SourceMapConsumer,
SourceMapGenerator,
} from 'source-map-js'
import {
normalScriptDefaultVar,
processNormalScript,
Expand All @@ -32,7 +36,6 @@ import { CSS_VARS_HELPER, genCssVarsCode } from './style/cssVars'
import {
type SFCTemplateCompileOptions,
compileTemplate,
mergeSourceMaps,
} from './compileTemplate'
import { warnOnce } from './warn'
import { transformDestructuredProps } from './script/definePropsDestructure'
Expand Down Expand Up @@ -1034,10 +1037,12 @@ export function compileScript(
includeContent: true,
}) as unknown as RawSourceMap)
: undefined
if (map && templateMap) {
// merge source maps of the script setup and template in inline mode
if (templateMap && map) {
const offset = content.indexOf(returned)
const lineOffset = content.slice(0, offset).split(/\r?\n/).length - 1
map = mergeSourceMaps(map, templateMap, lineOffset)
const templateLineOffset =
content.slice(0, offset).split(/\r?\n/).length - 1
map = mergeSourceMaps(map, templateMap, templateLineOffset)
}
return {
...scriptSetup,
Expand Down Expand Up @@ -1301,3 +1306,42 @@ function isStaticNode(node: Node): boolean {
}
return false
}

export function mergeSourceMaps(
scriptMap: RawSourceMap,
templateMap: RawSourceMap,
templateLineOffset: number,
): RawSourceMap {
const generator = new SourceMapGenerator()
const addMapping = (map: RawSourceMap, lineOffset = 0) => {
const consumer = new SourceMapConsumer(map)
;(consumer as any).sources.forEach((sourceFile: string) => {
;(generator as any)._sources.add(sourceFile)
const sourceContent = consumer.sourceContentFor(sourceFile)
if (sourceContent != null) {
generator.setSourceContent(sourceFile, sourceContent)
}
})
consumer.eachMapping(m => {
if (m.originalLine == null) return
generator.addMapping({
generated: {
line: m.generatedLine + lineOffset,
column: m.generatedColumn,
},
original: {
line: m.originalLine,
column: m.originalColumn,
},
source: m.source,
name: m.name,
})
})
}

addMapping(scriptMap)
addMapping(templateMap, templateLineOffset)
;(generator as any)._sourceRoot = scriptMap.sourceRoot
;(generator as any)._file = scriptMap.file
return (generator as any).toJSON()
}
45 changes: 0 additions & 45 deletions packages/compiler-sfc/src/compileTemplate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,51 +327,6 @@ function mapLines(oldMap: RawSourceMap, newMap: RawSourceMap): RawSourceMap {
return generator.toJSON()
}

export function mergeSourceMaps(
scriptMap: RawSourceMap,
templateMap: RawSourceMap,
templateLineOffset: number,
): RawSourceMap {
if (!templateMap) return scriptMap
if (!scriptMap) return templateMap

const mergedMapGenerator = new SourceMapGenerator() as any
const scriptConsumer = new SourceMapConsumer(scriptMap)
scriptConsumer.eachMapping(mapping => {
if (mapping.originalLine == null) return
mergedMapGenerator.addMapping({
generated: {
line: mapping.generatedLine,
column: mapping.generatedColumn,
},
original: {
line: mapping.originalLine,
column: mapping.originalColumn,
},
source: mapping.source,
name: mapping.name,
})
})

const templateConsumer = new SourceMapConsumer(templateMap)
templateConsumer.eachMapping(mapping => {
if (mapping.originalLine == null) return
mergedMapGenerator.addMapping({
generated: {
line: mapping.generatedLine + templateLineOffset,
column: mapping.generatedColumn,
},
original: {
line: mapping.originalLine,
column: mapping.originalColumn,
},
source: mapping.source,
name: mapping.name,
})
})
return mergedMapGenerator.toJSON()
}

function patchErrors(
errors: CompilerError[],
source: string,
Expand Down

0 comments on commit d81b83e

Please sign in to comment.