Skip to content

Commit e1e493d

Browse files
committed
Force an error for obvious assignments to top-level consts
1 parent 30adb9f commit e1e493d

1 file changed

Lines changed: 25 additions & 1 deletion

File tree

html/js/sandbox.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,8 +356,11 @@
356356
if (tryPos == 0) tryPos = stat.start
357357
catchPos = stat.end
358358
}
359-
if (stat.type == "VariableDeclaration" && stat.kind != "var")
359+
if (stat.type == "VariableDeclaration" && stat.kind != "var") {
360+
let found = findAssignmentsTo(stat.declarations, ast)
361+
if (found) patches.push({from: 0, text: `throw new TypeError("invalid assignment to const '${found}'");`})
360362
patches.push({from: stat.start, to: stat.start + stat.kind.length, text: "var"})
363+
}
361364
if (stat.type == "ClassDeclaration")
362365
patches.push({from: stat.start, text: "var " + stat.id.name + " = "})
363366
}
@@ -376,6 +379,27 @@
376379
return {code: (strict ? '"use strict";' : "") + out, dependencies}
377380
}
378381

382+
function findAssignmentsTo(decls, ast) {
383+
let found = null
384+
for (let i = 0; i < decls.length; i++)
385+
acorn.walk.simple(decls[i].id, {
386+
VariablePattern(node) { if (findAssignments(node.name, ast)) found = node.name }
387+
}, null, null, "Pattern")
388+
return found
389+
}
390+
391+
function findAssignments(name, ast) {
392+
let found = false
393+
acorn.walk.ancestor(ast, {
394+
AssignmentExpression(node, ancestors) {
395+
if (node.left.type != "Identifier" || node.left.name != name) return
396+
for (let i = 2; i < ancestors.length; i++) if (/Statement|Declaration/.test(ancestors[i].type)) return
397+
found = true
398+
}
399+
})
400+
return found
401+
}
402+
379403
function detectSourceType(code) {
380404
return /(^|\n)\s*(im|ex)port\b/.test(code) ? "module" : "script"
381405
}

0 commit comments

Comments
 (0)