Skip to content

Commit

Permalink
fix: fix wrong cooked value in TemplateElement, fix wrong loc and ran…
Browse files Browse the repository at this point in the history
…ge in various template nodes

closes #109, #108
  • Loading branch information
3cp committed Oct 15, 2020
1 parent 6c3cd40 commit ff71744
Show file tree
Hide file tree
Showing 4 changed files with 247 additions and 26 deletions.
2 changes: 1 addition & 1 deletion src/estree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -732,7 +732,7 @@ export interface TemplateElement extends _Node {
type: 'TemplateElement';
value: {
raw: string;
cooked: string;
cooked: string | null;
};
tail: boolean;
}
Expand Down
58 changes: 39 additions & 19 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4000,13 +4000,13 @@ export function parseMemberOrUpdateExpression(
/* Tagged Template */
parser.assignable = AssignmentKind.CannotAssign;

expr = finishNode(parser, context, parser.tokenPos, parser.linePos, parser.colPos, {
expr = finishNode(parser, context, start, line, column, {
type: 'TaggedTemplateExpression',
tag: expr,
quasi:
parser.token === Token.TemplateContinuation
? parseTemplate(parser, context | Context.TaggedTemplate, start, line, column)
: parseTemplateLiteral(parser, context, start, line, column)
? parseTemplate(parser, context | Context.TaggedTemplate, parser.tokenPos, parser.linePos, parser.colPos)
: parseTemplateLiteral(parser, context, parser.tokenPos, parser.linePos, parser.colPos)
});
}

Expand Down Expand Up @@ -4503,11 +4503,14 @@ export function parseTemplateLiteral(
*/

parser.assignable = AssignmentKind.CannotAssign;
const { tokenValue, tokenRaw, tokenPos, linePos, colPos } = parser;
consume(parser, context, Token.TemplateSpan);
const quasis = [parseTemplateElement(parser, context, tokenValue, tokenRaw, tokenPos, linePos, colPos, true)];

return finishNode(parser, context, start, line, column, {
type: 'TemplateLiteral',
expressions: [],
quasis: [parseTemplateElement(parser, context, true)]
quasis
});
}

Expand All @@ -4526,25 +4529,34 @@ export function parseTemplate(
): ESTree.TemplateLiteral {
context = (context | Context.DisallowIn) ^ Context.DisallowIn;

const quasis = [parseTemplateElement(parser, context, /* tail */ false)];

const { tokenValue, tokenRaw, tokenPos, linePos, colPos } = parser;
consume(parser, context | Context.AllowRegExp, Token.TemplateContinuation);
const quasis = [
parseTemplateElement(parser, context, tokenValue, tokenRaw, tokenPos, linePos, colPos, /* tail */ false)
];

const expressions = [parseExpressions(parser, context, 0, 1, parser.tokenPos, parser.linePos, parser.colPos)];

if (parser.token !== Token.RightBrace) report(parser, Errors.InvalidTemplateContinuation);

while ((parser.token = scanTemplateTail(parser, context)) !== Token.TemplateSpan) {
const { tokenPos, linePos, colPos } = parser;
quasis.push(parseTemplateElement(parser, context, /* tail */ false));
const { tokenValue, tokenRaw, tokenPos, linePos, colPos } = parser;
consume(parser, context | Context.AllowRegExp, Token.TemplateContinuation);
quasis.push(
parseTemplateElement(parser, context, tokenValue, tokenRaw, tokenPos, linePos, colPos, /* tail */ false)
);

expressions.push(parseExpressions(parser, context, 0, 1, tokenPos, linePos, colPos));
if (parser.token !== Token.RightBrace) report(parser, Errors.InvalidTemplateContinuation);
}

quasis.push(parseTemplateElement(parser, context, /* tail */ true));

consume(parser, context, Token.TemplateSpan);
{
const { tokenValue, tokenRaw, tokenPos, linePos, colPos } = parser;
consume(parser, context, Token.TemplateSpan);
quasis.push(
parseTemplateElement(parser, context, tokenValue, tokenRaw, tokenPos, linePos, colPos, /* tail */ true)
);
}

return finishNode(parser, context, start, line, column, {
type: 'TemplateLiteral',
Expand All @@ -4559,13 +4571,21 @@ export function parseTemplate(
* @param parser Parser object
* @param tail
*/
export function parseTemplateElement(parser: ParserState, context: Context, tail: boolean): ESTree.TemplateElement {
const { tokenPos, linePos, colPos } = parser;
return finishNode(parser, context, tokenPos, linePos, colPos, {
export function parseTemplateElement(
parser: ParserState,
context: Context,
cooked: string | null,
raw: string,
start: number,
line: number,
col: number,
tail: boolean
): ESTree.TemplateElement {
return finishNode(parser, context, start, line, col, {
type: 'TemplateElement',
value: {
cooked: parser.tokenValue,
raw: parser.tokenRaw
cooked,
raw
},
tail
});
Expand Down Expand Up @@ -7422,13 +7442,13 @@ export function parseMembeExpressionNoCall(
return parseMembeExpressionNoCall(
parser,
context,
finishNode(parser, context, parser.tokenPos, parser.linePos, parser.colPos, {
finishNode(parser, context, start, line, column, {
type: 'TaggedTemplateExpression',
tag: expr,
quasi:
parser.token === Token.TemplateContinuation
? parseTemplate(parser, context | Context.TaggedTemplate, start, line, column)
: parseTemplateLiteral(parser, context, start, line, column)
? parseTemplate(parser, context | Context.TaggedTemplate, parser.tokenPos, parser.linePos, parser.colPos)
: parseTemplateLiteral(parser, context, parser.tokenPos, parser.linePos, parser.colPos)
}),
0,
start,
Expand Down
12 changes: 6 additions & 6 deletions test/parser/expressions/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4505,9 +4505,9 @@ describe('Expressions - Object', () => {
quasis: [
{
type: 'TemplateElement',
start: 23,
start: 20,
end: 23,
range: [23, 23],
range: [20, 23],
value: {
raw: 'c',
cooked: 'c'
Expand Down Expand Up @@ -4590,8 +4590,8 @@ describe('Expressions - Object', () => {
{
type: 'TemplateElement',
start: 46,
end: 46,
range: [46, 46],
end: 49,
range: [46, 49],
value: {
raw: '',
cooked: ''
Expand All @@ -4601,8 +4601,8 @@ describe('Expressions - Object', () => {
{
type: 'TemplateElement',
start: 50,
end: 50,
range: [50, 50],
end: 53,
range: [50, 53],
value: {
raw: 'e',
cooked: 'e'
Expand Down
201 changes: 201 additions & 0 deletions test/parser/expressions/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3470,6 +3470,207 @@ describe('Expressions - Template', () => {
}
]
}
],
[
'tagA`a`\ntagB`b`',
Context.None | Context.OptionsRanges | Context.OptionsLoc,
{
type: 'Program',
sourceType: 'script',
body: [
{
type: 'ExpressionStatement',
expression: {
type: 'TaggedTemplateExpression',
tag: {
type: 'Identifier',
name: 'tagA',
start: 0,
end: 4,
range: [0, 4],
loc: {
start: {
line: 1,
column: 0
},
end: {
line: 1,
column: 4
}
}
},
quasi: {
type: 'TemplateLiteral',
expressions: [],
quasis: [
{
type: 'TemplateElement',
value: {
cooked: 'a',
raw: 'a'
},
tail: true,
start: 4,
end: 7,
range: [4, 7],
loc: {
start: {
line: 1,
column: 4
},
end: {
line: 1,
column: 7
}
}
}
],
start: 4,
end: 7,
range: [4, 7],
loc: {
start: {
line: 1,
column: 4
},
end: {
line: 1,
column: 7
}
}
},
start: 0,
end: 7,
range: [0, 7],
loc: {
start: {
line: 1,
column: 0
},
end: {
line: 1,
column: 7
}
}
},
start: 0,
end: 7,
range: [0, 7],
loc: {
start: {
line: 1,
column: 0
},
end: {
line: 1,
column: 7
}
}
},
{
type: 'ExpressionStatement',
expression: {
type: 'TaggedTemplateExpression',
tag: {
type: 'Identifier',
name: 'tagB',
start: 8,
end: 12,
range: [8, 12],
loc: {
start: {
line: 2,
column: 0
},
end: {
line: 2,
column: 4
}
}
},
quasi: {
type: 'TemplateLiteral',
expressions: [],
quasis: [
{
type: 'TemplateElement',
value: {
cooked: 'b',
raw: 'b'
},
tail: true,
start: 12,
end: 15,
range: [12, 15],
loc: {
start: {
line: 2,
column: 4
},
end: {
line: 2,
column: 7
}
}
}
],
start: 12,
end: 15,
range: [12, 15],
loc: {
start: {
line: 2,
column: 4
},
end: {
line: 2,
column: 7
}
}
},
start: 8,
end: 15,
range: [8, 15],
loc: {
start: {
line: 2,
column: 0
},
end: {
line: 2,
column: 7
}
}
},
start: 8,
end: 15,
range: [8, 15],
loc: {
start: {
line: 2,
column: 0
},
end: {
line: 2,
column: 7
}
}
}
],
start: 0,
end: 15,
range: [0, 15],
loc: {
start: {
line: 1,
column: 0
},
end: {
line: 2,
column: 7
}
}
}
]
]);
});

0 comments on commit ff71744

Please sign in to comment.