Skip to content

Commit e8a2c74

Browse files
committed
Major rewrite of the Runtime
1 parent c3821bf commit e8a2c74

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1108
-694
lines changed

.babelrc

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"plugins": [
3+
"transform-async-to-generator",
4+
"transform-es2015-modules-commonjs"
5+
],
6+
"env": {
7+
"test": {
8+
"plugins": ["istanbul"]
9+
}
10+
}
11+
}

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1+
lib
12
node_modules
23
.nyc_output
34
coverage
4-
5+
test/Runtime/fixtures/access-denied.tpl

.istanbul.yml

-18
This file was deleted.

.nycrc

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"lines": 100,
3+
"statements": 100,
4+
"functions": 100,
5+
"branches": 100,
6+
"include": [
7+
"src/**/*.js"
8+
],
9+
"exclude": [
10+
],
11+
"reporter": [
12+
"json",
13+
"text-summary",
14+
"html"
15+
],
16+
"all": true,
17+
"check-coverage": true,
18+
"produce-source-map": true,
19+
"report-dir": "./coverage",
20+
"require": [
21+
"babel-register"
22+
],
23+
"sourceMap": false,
24+
"instrument": false
25+
}

package.json

+11-5
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,30 @@
77
"test": "test"
88
},
99
"scripts": {
10+
"build": "babel src/ --out-dir lib/",
1011
"lint": "eslint .",
1112
"test": "eslint . && npm run test:coverage",
12-
"test:unit": "mocha",
13-
"test:coverage": "istanbul cover _mocha"
13+
"test:unit": "BABEL_ENV=test test/test.sh",
14+
"test:coverage": "BABEL_ENV=test nyc test/test.sh"
1415
},
1516
"author": "Tim Oram <[email protected]>",
1617
"license": "ISC",
1718
"devDependencies": {
19+
"babel-cli": "^6.24.1",
20+
"babel-plugin-istanbul": "^4.1.3",
21+
"babel-plugin-transform-async-to-generator": "^6.24.1",
22+
"babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
1823
"chai": "^3.5.0",
1924
"chalk": "^1.1.3",
2025
"diff": "^2.2.3",
2126
"eslint": "^3.0.0",
2227
"eslint-config-mitmaro": "^2.0.0",
2328
"eslint-plugin-strict-newline": "^1.0.0",
24-
"istanbul": "^0.4.4",
25-
"mocha": "^3.0.0"
29+
"mocha": "^3.0.0",
30+
"nyc": "10.2.2"
2631
},
2732
"dependencies": {
28-
"async": "^2.0.1"
33+
"es6-promisify": "^5.0.0",
34+
"lodash.get": "^4.4.2"
2935
}
3036
}

src/Lexer.js

+61-16
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/* eslint max-depth: "off" */
22
'use strict';
33

4-
const LexerError = require('./error/Lexer');
5-
const {
4+
import LexerError from './error/Lexer';
5+
import {
66
TOKEN_TYPE_VALUE,
77
TOKEN_TYPE_STRUCTURE,
88
TOKEN_TYPE_STATEMENT,
@@ -41,8 +41,8 @@ const {
4141
OPERATOR_GREATER_THAN,
4242
OPERATOR_LESS_THAN,
4343
OPERATOR_GREATER_EQUAL_THAN,
44-
OPERATOR_LESS_EQUAL_THAN
45-
} = require('./constants');
44+
OPERATOR_LESS_EQUAL_THAN,
45+
} from './constants';
4646

4747
const boundaryTypeLookup = {
4848
'{{': TOKEN_BOUNDARY_TAG_START,
@@ -97,20 +97,39 @@ Array.prototype.concat(
9797
delimiters[delimiter.length].push(delimiter);
9898
});
9999

100-
class Lexer {
100+
export default class Lexer {
101101
constructor(input) {
102102
this.state = STATE_TEXT_LITERAL;
103103
this.pointer = 0;
104+
this.columnNumber = 0;
105+
this.rowNumber = 0;
104106
this.input = input;
105107
// length used for cases of checking ahead by one character from pointer
106108
this.lookAheadLength = this.input.length - 1;
107109
this.stringDelimiter = null;
108110
}
109111

112+
movePointer() {
113+
if (this.input[this.pointer] === '\n') {
114+
this.rowNumber++;
115+
this.columnNumber = 0;
116+
}
117+
else {
118+
this.columnNumber++;
119+
}
120+
this.pointer++;
121+
}
122+
110123
// skip all whitespace or until EOF reached
111124
skipWhitespace() {
112125
while (this.pointer < this.input.length && this.input[this.pointer].trim().length === 0) {
113-
this.pointer++;
126+
this.movePointer();
127+
}
128+
}
129+
130+
skipNewline() {
131+
if (this.input[this.pointer] === '\n') {
132+
this.movePointer();
114133
}
115134
}
116135

@@ -123,13 +142,13 @@ class Lexer {
123142
&& this.input[this.pointer + 1] === '{'
124143
)
125144
) {
126-
this.pointer++;
145+
this.movePointer();
127146
}
128147

129148
// because we look two characters ahead, we need to increment the
130149
// pointer by one if end of input is reached
131150
if (this.lookAheadLength >= 0 && this.pointer >= this.lookAheadLength) {
132-
this.pointer++;
151+
this.movePointer();
133152
}
134153
}
135154

@@ -144,9 +163,9 @@ class Lexer {
144163
if (this.input[this.pointer + 1] === this.stringDelimiter && this.input[this.pointer] !== '\\') {
145164
break;
146165
}
147-
this.pointer++;
166+
this.movePointer();
148167
}
149-
this.pointer++;
168+
this.movePointer();
150169
}
151170

152171
isAtDelimiter() {
@@ -176,26 +195,31 @@ class Lexer {
176195
if (this.isAtDelimiter()) {
177196
return;
178197
}
179-
this.pointer++;
198+
this.movePointer();
180199

181200
while (this.pointer < this.input.length) {
182201
if (this.isAtDelimiter()) {
183202
return;
184203
}
185-
this.pointer++;
204+
this.movePointer();
186205
}
187206
}
188207

189208
// scan pass the next delimiter
190209
scanNextDelimiter() {
191210
const delimiter = this.isAtDelimiter() || '';
192-
193-
this.pointer = this.pointer + delimiter.length;
211+
for (let i = 0; i < delimiter.length; i++) {
212+
this.movePointer();
213+
}
194214
}
195215

196216
*tokens() {
217+
let column = -1;
218+
let row = -1;
197219
while (this.pointer < this.input.length) {
198220
if (this.state === STATE_TEXT_LITERAL) {
221+
column = this.columnNumber;
222+
row = this.rowNumber;
199223
const startIndex = this.pointer;
200224

201225
this.scanTextLiteral();
@@ -207,6 +231,8 @@ class Lexer {
207231
continue;
208232
}
209233
yield {
234+
column,
235+
row,
210236
type: TOKEN_TYPE_STRUCTURE,
211237
subType: TOKEN_STRUCTURE_TEXT_LITERAL,
212238
value,
@@ -219,6 +245,8 @@ class Lexer {
219245

220246
this.skipWhitespace();
221247

248+
column = this.columnNumber;
249+
row = this.rowNumber;
222250
let startIndex = this.pointer;
223251

224252
// scan until next delimiter
@@ -229,6 +257,8 @@ class Lexer {
229257
type = statementTypeLookup[value];
230258
if (type) {
231259
yield {
260+
column,
261+
row,
232262
type: TOKEN_TYPE_STATEMENT,
233263
subType: type,
234264
value,
@@ -253,6 +283,8 @@ class Lexer {
253283
}
254284

255285
yield {
286+
column,
287+
row,
256288
type: TOKEN_TYPE_VALUE,
257289
subType: type,
258290
value,
@@ -262,6 +294,8 @@ class Lexer {
262294
continue;
263295
}
264296

297+
column = this.columnNumber;
298+
row = this.rowNumber;
265299
startIndex = this.pointer;
266300
this.scanNextDelimiter();
267301
value = this.input.substring(startIndex, this.pointer);
@@ -273,9 +307,12 @@ class Lexer {
273307
this.state = this.state === STATE_END_STRING ? STATE_TAG : STATE_STRING;
274308
}
275309
else if (type === TOKEN_BOUNDARY_TAG_END) {
310+
this.skipNewline();
276311
this.state = STATE_TEXT_LITERAL;
277312
}
278313
yield {
314+
column,
315+
row,
279316
type: TOKEN_TYPE_BOUNDARY,
280317
subType: type,
281318
value,
@@ -287,6 +324,8 @@ class Lexer {
287324
type = binaryOperatorTypeLookup[value];
288325
if (type) {
289326
yield {
327+
column,
328+
row,
290329
type: TOKEN_TYPE_BINARY_OPERATOR,
291330
subType: type,
292331
value,
@@ -297,6 +336,8 @@ class Lexer {
297336
}
298337
type = unaryOperatorTypeLookup[value];
299338
yield {
339+
column,
340+
row,
300341
type: TOKEN_TYPE_UNARY_OPERATOR,
301342
subType: type,
302343
value,
@@ -305,11 +346,15 @@ class Lexer {
305346
};
306347
}
307348
else if (this.state === STATE_STRING) {
349+
column = this.columnNumber;
350+
row = this.rowNumber;
308351
const startIndex = this.pointer;
309352

310353
this.scanString();
311354
this.state = STATE_END_STRING;
312355
yield {
356+
column,
357+
row,
313358
type: TOKEN_TYPE_VALUE,
314359
subType: TOKEN_VALUE_STRING,
315360
value: this.input.substring(startIndex, this.pointer),
@@ -323,6 +368,8 @@ class Lexer {
323368
}
324369

325370
yield {
371+
column: this.columnNumber,
372+
row: this.rowNumber,
326373
type: TOKEN_TYPE_STRUCTURE,
327374
subType: TOKEN_STRUCTURE_EOF,
328375
value: null,
@@ -331,5 +378,3 @@ class Lexer {
331378
};
332379
}
333380
}
334-
335-
module.exports = Lexer;

0 commit comments

Comments
 (0)