Skip to content

Commit 94838ba

Browse files
authored
Disallow var statements (#310)
1 parent 045fdb4 commit 94838ba

File tree

4 files changed

+242
-0
lines changed

4 files changed

+242
-0
lines changed

src/__tests__/__snapshots__/disallowed-syntax.ts.snap

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11476,6 +11476,179 @@ typeof x;",
1147611476
}
1147711477
`;
1147811478

11479+
exports[`no var statements - verbose: expectParsedError 1`] = `
11480+
Object {
11481+
"alertResult": Array [],
11482+
"code": "\\"enable verbose\\";
11483+
var x = 1;",
11484+
"displayResult": Array [],
11485+
"errors": Array [
11486+
NoVarError {
11487+
"node": Node {
11488+
"declarations": Array [
11489+
Node {
11490+
"end": 28,
11491+
"id": Node {
11492+
"end": 24,
11493+
"loc": SourceLocation {
11494+
"end": Position {
11495+
"column": 6,
11496+
"line": 2,
11497+
},
11498+
"start": Position {
11499+
"column": 5,
11500+
"line": 2,
11501+
},
11502+
},
11503+
"name": "x",
11504+
"start": 23,
11505+
"type": "Identifier",
11506+
},
11507+
"init": Node {
11508+
"end": 28,
11509+
"loc": SourceLocation {
11510+
"end": Position {
11511+
"column": 10,
11512+
"line": 2,
11513+
},
11514+
"start": Position {
11515+
"column": 9,
11516+
"line": 2,
11517+
},
11518+
},
11519+
"raw": "1",
11520+
"start": 27,
11521+
"type": "Literal",
11522+
"value": 1,
11523+
},
11524+
"loc": SourceLocation {
11525+
"end": Position {
11526+
"column": 10,
11527+
"line": 2,
11528+
},
11529+
"start": Position {
11530+
"column": 5,
11531+
"line": 2,
11532+
},
11533+
},
11534+
"start": 23,
11535+
"type": "VariableDeclarator",
11536+
},
11537+
],
11538+
"end": 29,
11539+
"kind": "var",
11540+
"loc": SourceLocation {
11541+
"end": Position {
11542+
"column": 11,
11543+
"line": 2,
11544+
},
11545+
"start": Position {
11546+
"column": 1,
11547+
"line": 2,
11548+
},
11549+
},
11550+
"start": 19,
11551+
"type": "VariableDeclaration",
11552+
},
11553+
"severity": "Error",
11554+
"type": "Syntax",
11555+
},
11556+
],
11557+
"parsedErrors": "Line 2, Column 1: Variable declaration using \\"var\\" is not allowed.
11558+
Use keyword \\"let\\" instead, to declare a variable:
11559+
11560+
let x = 1;
11561+
",
11562+
"result": undefined,
11563+
"resultStatus": "error",
11564+
"visualiseListResult": Array [],
11565+
}
11566+
`;
11567+
11568+
exports[`no var statements: expectParsedError 1`] = `
11569+
Object {
11570+
"alertResult": Array [],
11571+
"code": "var x = 1;",
11572+
"displayResult": Array [],
11573+
"errors": Array [
11574+
NoVarError {
11575+
"node": Node {
11576+
"declarations": Array [
11577+
Node {
11578+
"end": 9,
11579+
"id": Node {
11580+
"end": 5,
11581+
"loc": SourceLocation {
11582+
"end": Position {
11583+
"column": 5,
11584+
"line": 1,
11585+
},
11586+
"start": Position {
11587+
"column": 4,
11588+
"line": 1,
11589+
},
11590+
},
11591+
"name": "x",
11592+
"start": 4,
11593+
"type": "Identifier",
11594+
},
11595+
"init": Node {
11596+
"end": 9,
11597+
"loc": SourceLocation {
11598+
"end": Position {
11599+
"column": 9,
11600+
"line": 1,
11601+
},
11602+
"start": Position {
11603+
"column": 8,
11604+
"line": 1,
11605+
},
11606+
},
11607+
"raw": "1",
11608+
"start": 8,
11609+
"type": "Literal",
11610+
"value": 1,
11611+
},
11612+
"loc": SourceLocation {
11613+
"end": Position {
11614+
"column": 9,
11615+
"line": 1,
11616+
},
11617+
"start": Position {
11618+
"column": 4,
11619+
"line": 1,
11620+
},
11621+
},
11622+
"start": 4,
11623+
"type": "VariableDeclarator",
11624+
},
11625+
],
11626+
"end": 10,
11627+
"kind": "var",
11628+
"loc": SourceLocation {
11629+
"end": Position {
11630+
"column": 10,
11631+
"line": 1,
11632+
},
11633+
"start": Position {
11634+
"column": 0,
11635+
"line": 1,
11636+
},
11637+
},
11638+
"start": 0,
11639+
"type": "VariableDeclaration",
11640+
},
11641+
"severity": "Error",
11642+
"type": "Syntax",
11643+
},
11644+
],
11645+
"parsedErrors": "Line 1: Variable declaration using \\"var\\" is not allowed.",
11646+
"result": undefined,
11647+
"resultStatus": "error",
11648+
"visualiseListResult": Array [],
11649+
}
11650+
`;
11651+
1147911652
exports[`while needs braces - verbose: expectParsedError 1`] = `
1148011653
Object {
1148111654
"alertResult": Array [],

src/__tests__/disallowed-syntax.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,31 @@ For instance, to assign 20 to x, you can write:
435435
`)
436436
})
437437

438+
test('no var statements', () => {
439+
return expectParsedError(
440+
stripIndent`
441+
var x = 1;
442+
`,
443+
{ chapter: 100 }
444+
).toMatchInlineSnapshot(`"Line 1: Variable declaration using \\"var\\" is not allowed."`)
445+
})
446+
447+
test('no var statements - verbose', () => {
448+
return expectParsedError(
449+
stripIndent`
450+
"enable verbose";
451+
var x = 1;
452+
`,
453+
{ chapter: 100 }
454+
).toMatchInlineSnapshot(`
455+
"Line 2, Column 1: Variable declaration using \\"var\\" is not allowed.
456+
Use keyword \\"let\\" instead, to declare a variable:
457+
458+
let x = 1;
459+
"
460+
`)
461+
})
462+
438463
test('Cannot use update statements', () => {
439464
return expectParsedError(
440465
stripIndent`

src/rules/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import noNull from './noNull'
1717
import noUnspecifiedLiteral from './noUnspecifiedLiteral'
1818
import noUnspecifiedOperator from './noUnspecifiedOperator'
1919
import noUpdateAssignment from './noUpdateAssignment'
20+
import noVar from './noVar'
2021
import singleVariableDeclaration from './singleVariableDeclaration'
2122

2223
const rules: Array<Rule<es.Node>> = [
@@ -34,6 +35,7 @@ const rules: Array<Rule<es.Node>> = [
3435
noUnspecifiedLiteral,
3536
noUnspecifiedOperator,
3637
noUpdateAssignment,
38+
noVar,
3739
singleVariableDeclaration,
3840
noEval
3941
]

src/rules/noVar.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { generate } from 'astring'
2+
import * as es from 'estree'
3+
4+
import { ErrorSeverity, ErrorType, Rule, SourceError } from '../types'
5+
6+
export class NoVarError implements SourceError {
7+
public type = ErrorType.SYNTAX
8+
public severity = ErrorSeverity.ERROR
9+
10+
constructor(public node: es.VariableDeclaration) {}
11+
12+
get location() {
13+
return this.node.loc!
14+
}
15+
16+
public explain() {
17+
return 'Variable declaration using "var" is not allowed.'
18+
}
19+
20+
public elaborate() {
21+
const name = (this.node.declarations[0].id as es.Identifier).name
22+
const value = generate(this.node.declarations[0].init)
23+
24+
return `Use keyword "let" instead, to declare a variable:\n\n\tlet ${name} = ${value};`
25+
}
26+
}
27+
28+
const noVar: Rule<es.VariableDeclaration> = {
29+
name: 'no-var',
30+
31+
checkers: {
32+
VariableDeclaration(node: es.VariableDeclaration, ancestors: [es.Node]) {
33+
if (node.kind === 'var') {
34+
return [new NoVarError(node)]
35+
} else {
36+
return []
37+
}
38+
}
39+
}
40+
}
41+
42+
export default noVar

0 commit comments

Comments
 (0)