diff --git a/src/__tests__/__snapshots__/disallowed-syntax.ts.snap b/src/__tests__/__snapshots__/disallowed-syntax.ts.snap index 0437de668..299402c29 100644 --- a/src/__tests__/__snapshots__/disallowed-syntax.ts.snap +++ b/src/__tests__/__snapshots__/disallowed-syntax.ts.snap @@ -11476,6 +11476,179 @@ typeof x;", } `; +exports[`no var statements - verbose: expectParsedError 1`] = ` +Object { + "alertResult": Array [], + "code": "\\"enable verbose\\"; + var x = 1;", + "displayResult": Array [], + "errors": Array [ + NoVarError { + "node": Node { + "declarations": Array [ + Node { + "end": 28, + "id": Node { + "end": 24, + "loc": SourceLocation { + "end": Position { + "column": 6, + "line": 2, + }, + "start": Position { + "column": 5, + "line": 2, + }, + }, + "name": "x", + "start": 23, + "type": "Identifier", + }, + "init": Node { + "end": 28, + "loc": SourceLocation { + "end": Position { + "column": 10, + "line": 2, + }, + "start": Position { + "column": 9, + "line": 2, + }, + }, + "raw": "1", + "start": 27, + "type": "Literal", + "value": 1, + }, + "loc": SourceLocation { + "end": Position { + "column": 10, + "line": 2, + }, + "start": Position { + "column": 5, + "line": 2, + }, + }, + "start": 23, + "type": "VariableDeclarator", + }, + ], + "end": 29, + "kind": "var", + "loc": SourceLocation { + "end": Position { + "column": 11, + "line": 2, + }, + "start": Position { + "column": 1, + "line": 2, + }, + }, + "start": 19, + "type": "VariableDeclaration", + }, + "severity": "Error", + "type": "Syntax", + }, + ], + "parsedErrors": "Line 2, Column 1: Variable declaration using \\"var\\" is not allowed. +Use keyword \\"let\\" instead, to declare a variable: + + let x = 1; +", + "result": undefined, + "resultStatus": "error", + "visualiseListResult": Array [], +} +`; + +exports[`no var statements: expectParsedError 1`] = ` +Object { + "alertResult": Array [], + "code": "var x = 1;", + "displayResult": Array [], + "errors": Array [ + NoVarError { + "node": Node { + "declarations": Array [ + Node { + "end": 9, + "id": Node { + "end": 5, + "loc": SourceLocation { + "end": Position { + "column": 5, + "line": 1, + }, + "start": Position { + "column": 4, + "line": 1, + }, + }, + "name": "x", + "start": 4, + "type": "Identifier", + }, + "init": Node { + "end": 9, + "loc": SourceLocation { + "end": Position { + "column": 9, + "line": 1, + }, + "start": Position { + "column": 8, + "line": 1, + }, + }, + "raw": "1", + "start": 8, + "type": "Literal", + "value": 1, + }, + "loc": SourceLocation { + "end": Position { + "column": 9, + "line": 1, + }, + "start": Position { + "column": 4, + "line": 1, + }, + }, + "start": 4, + "type": "VariableDeclarator", + }, + ], + "end": 10, + "kind": "var", + "loc": SourceLocation { + "end": Position { + "column": 10, + "line": 1, + }, + "start": Position { + "column": 0, + "line": 1, + }, + }, + "start": 0, + "type": "VariableDeclaration", + }, + "severity": "Error", + "type": "Syntax", + }, + ], + "parsedErrors": "Line 1: Variable declaration using \\"var\\" is not allowed.", + "result": undefined, + "resultStatus": "error", + "visualiseListResult": Array [], +} +`; + exports[`while needs braces - verbose: expectParsedError 1`] = ` Object { "alertResult": Array [], diff --git a/src/__tests__/disallowed-syntax.ts b/src/__tests__/disallowed-syntax.ts index c758ad858..7b97d96e5 100644 --- a/src/__tests__/disallowed-syntax.ts +++ b/src/__tests__/disallowed-syntax.ts @@ -435,6 +435,31 @@ For instance, to assign 20 to x, you can write: `) }) +test('no var statements', () => { + return expectParsedError( + stripIndent` + var x = 1; + `, + { chapter: 100 } + ).toMatchInlineSnapshot(`"Line 1: Variable declaration using \\"var\\" is not allowed."`) +}) + +test('no var statements - verbose', () => { + return expectParsedError( + stripIndent` + "enable verbose"; + var x = 1; + `, + { chapter: 100 } + ).toMatchInlineSnapshot(` +"Line 2, Column 1: Variable declaration using \\"var\\" is not allowed. +Use keyword \\"let\\" instead, to declare a variable: + + let x = 1; +" +`) +}) + test('Cannot use update statements', () => { return expectParsedError( stripIndent` diff --git a/src/rules/index.ts b/src/rules/index.ts index e29a0a165..bc699eb9b 100644 --- a/src/rules/index.ts +++ b/src/rules/index.ts @@ -17,6 +17,7 @@ import noNull from './noNull' import noUnspecifiedLiteral from './noUnspecifiedLiteral' import noUnspecifiedOperator from './noUnspecifiedOperator' import noUpdateAssignment from './noUpdateAssignment' +import noVar from './noVar' import singleVariableDeclaration from './singleVariableDeclaration' const rules: Array> = [ @@ -34,6 +35,7 @@ const rules: Array> = [ noUnspecifiedLiteral, noUnspecifiedOperator, noUpdateAssignment, + noVar, singleVariableDeclaration, noEval ] diff --git a/src/rules/noVar.ts b/src/rules/noVar.ts new file mode 100644 index 000000000..16c7539c1 --- /dev/null +++ b/src/rules/noVar.ts @@ -0,0 +1,42 @@ +import { generate } from 'astring' +import * as es from 'estree' + +import { ErrorSeverity, ErrorType, Rule, SourceError } from '../types' + +export class NoVarError implements SourceError { + public type = ErrorType.SYNTAX + public severity = ErrorSeverity.ERROR + + constructor(public node: es.VariableDeclaration) {} + + get location() { + return this.node.loc! + } + + public explain() { + return 'Variable declaration using "var" is not allowed.' + } + + public elaborate() { + const name = (this.node.declarations[0].id as es.Identifier).name + const value = generate(this.node.declarations[0].init) + + return `Use keyword "let" instead, to declare a variable:\n\n\tlet ${name} = ${value};` + } +} + +const noVar: Rule = { + name: 'no-var', + + checkers: { + VariableDeclaration(node: es.VariableDeclaration, ancestors: [es.Node]) { + if (node.kind === 'var') { + return [new NoVarError(node)] + } else { + return [] + } + } + } +} + +export default noVar