Skip to content

Commit 8b9ab2a

Browse files
committed
Sourcemaps for JS
1 parent c6f15c5 commit 8b9ab2a

File tree

6 files changed

+421
-13
lines changed

6 files changed

+421
-13
lines changed

compiler/commands.nim

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool =
271271
of "patterns": result = contains(gOptions, optPatterns)
272272
of "experimental": result = gExperimentalMode
273273
of "excessivestacktrace": result = contains(gGlobalOptions, optExcessiveStackTrace)
274+
of "sourcemap": result = gOptions * {optLineDir, optSourceMap} == {optLineDir, optSourceMap}
274275
else: invalidCmdLineOption(passCmd1, switch, info)
275276

276277
proc processPath(path: string, info: TLineInfo,
@@ -698,6 +699,8 @@ proc processSwitch(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
698699
expectNoArg(switch, arg, pass, info)
699700
newDestructors = true
700701
defineSymbol("nimNewRuntime")
702+
of "sourcemap":
703+
processOnOffSwitch({optLineDir, optSourceMap}, arg, pass, info)
701704
else:
702705
if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg)
703706
else: invalidCmdLineOption(pass, switch, info)

compiler/jsgen.nim

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import
3333
ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp, options,
3434
nversion, nimsets, msgs, std / sha1, bitsets, idents, types, os, tables,
3535
times, ropes, math, passes, ccgutils, wordrecg, renderer, rodread, rodutils,
36-
intsets, cgmeth, lowerings, sighashes
36+
intsets, cgmeth, lowerings, sighashes, sets, sourcemap, json
3737

3838
from modulegraphs import ModuleGraph
3939

@@ -211,6 +211,8 @@ proc mapType(p: PProc; typ: PType): TJSTypeKind =
211211
if p.target == targetPHP: result = etyObject
212212
else: result = mapType(typ)
213213

214+
var mangled = initSet[string]()
215+
214216
proc mangleName(m: BModule, s: PSym): Rope =
215217
proc validJsName(name: string): bool =
216218
result = true
@@ -264,6 +266,11 @@ proc mangleName(m: BModule, s: PSym): Rope =
264266
add(result, rope(s.id))
265267
s.loc.r = result
266268

269+
# TODO: optimize
270+
let s = $result
271+
if '_' in s:
272+
mangled.incl(s)
273+
267274
proc escapeJSString(s: string): string =
268275
result = newStringOfCap(s.len + s.len shr 2)
269276
result.add("\"")
@@ -581,11 +588,19 @@ proc hasFrameInfo(p: PProc): bool =
581588
({optLineTrace, optStackTrace} * p.options == {optLineTrace, optStackTrace}) and
582589
((p.prc == nil) or not (sfPure in p.prc.flags))
583590

591+
proc lineDir(info: TLineInfo, line: int): Rope =
592+
ropes.`%`("$N// line $2 $1$N",
593+
[fileInfos[info.fileIndex].quotedFullName, rope(line)])
594+
584595
proc genLineDir(p: PProc, n: PNode) =
585596
let line = toLinenumber(n.info)
586-
if optLineDir in p.options:
587-
lineF(p, "// line $2 \"$1\"$n",
588-
[rope(toFilename(n.info)), rope(line)])
597+
if line < 0:
598+
return
599+
if optLineDir in p.options or optLineDir in gOptions:
600+
softRnl = noRnl
601+
line(p, lineDir(n.info, line))
602+
# lineF(p, "$N// line $2 $1$N",
603+
# [fileInfos[n.info.fileIndex].quotedFullName, rope(line)])
589604
if {optStackTrace, optEndb} * p.options == {optStackTrace, optEndb} and
590605
((p.prc == nil) or sfPure notin p.prc.flags):
591606
useMagic(p, "endb")
@@ -719,15 +734,16 @@ proc genTry(p: PProc, n: PNode, r: var TCompRes) =
719734
line(p, "}" & tnl)
720735

721736
proc genRaiseStmt(p: PProc, n: PNode) =
722-
genLineDir(p, n)
723737
if n.sons[0].kind != nkEmpty:
724738
var a: TCompRes
725739
gen(p, n.sons[0], a)
726740
let typ = skipTypes(n.sons[0].typ, abstractPtrs)
741+
genLineDir(p, n)
727742
useMagic(p, "raiseException")
728743
lineF(p, "raiseException($1, $2);$n",
729744
[a.rdLoc, makeJSString(typ.sym.name.s)])
730745
else:
746+
genLineDir(p, n)
731747
useMagic(p, "reraiseException")
732748
line(p, "reraiseException();" & tnl)
733749

@@ -2194,6 +2210,10 @@ proc genProc(oldProc: PProc, prc: PSym): Rope =
21942210

21952211
p.nested: genStmt(p, prc.getBody)
21962212

2213+
2214+
if optLineDir in prc.options or optLineDir in gOptions:
2215+
result = lineDir(prc.info, toLinenumber(prc.info))
2216+
21972217
var def: Rope
21982218
if not prc.constraint.isNil:
21992219
def = (prc.constraint.strVal & " {$n$#$#$#$#$#") %
@@ -2206,7 +2226,7 @@ proc genProc(oldProc: PProc, prc: PSym): Rope =
22062226
optionaLine(genProcBody(p, prc)),
22072227
optionaLine(p.indentLine(returnStmt))]
22082228
else:
2209-
result = ~tnl
2229+
result.add(softRnl)
22102230

22112231
if optHotCodeReloading in gOptions:
22122232
# Here, we introduce thunks that create the equivalent of a jump table
@@ -2516,13 +2536,19 @@ proc myClose(graph: ModuleGraph; b: PPassContext, n: PNode): PNode =
25162536
let ext = if m.target == targetJS: "js" else: "php"
25172537
let f = if globals.classes.len == 0: m.module.filename
25182538
else: "nimsystem"
2519-
let code = wholeCode(graph, m)
2539+
var code = wholeCode(graph, m)
25202540
let outfile =
25212541
if options.outFile.len > 0:
25222542
if options.outFile.isAbsolute: options.outFile
25232543
else: getCurrentDir() / options.outFile
25242544
else:
25252545
changeFileExt(completeCFilePath(f), ext)
2546+
2547+
if optSourceMap in gOptions:
2548+
var map: SourceMap
2549+
(code, map) = genSourceMap($code, mangled, m.module.filename, $outfile)
2550+
writeFile(outfile & ".map", $(%map))
2551+
25262552
discard writeRopeIfNotEqual(genHeader(m.target) & code, outfile)
25272553
for obj, content in items(globals.classes):
25282554
genClass(obj, content, ext)

compiler/options.nim

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,9 @@ type # please make sure we have under 32 options
3737
# evaluation
3838
optPatterns, # en/disable pattern matching
3939
optMemTracker,
40-
optHotCodeReloading
40+
optHotCodeReloading,
41+
optSourceMap
42+
4143

4244
TOptions* = set[TOption]
4345
TGlobalOption* = enum # **keep binary compatible**

compiler/ropes.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ proc len*(a: Rope): int =
8686
if a == nil: result = 0
8787
else: result = a.length
8888

89-
proc newRope(data: string = nil): Rope =
89+
proc newRope*(data: string = nil): Rope =
9090
new(result)
9191
if data != nil:
9292
result.length = len(data)

0 commit comments

Comments
 (0)