Skip to content

Commit

Permalink
fix: properly support loc on HTMLClose comment
Browse files Browse the repository at this point in the history
  • Loading branch information
3cp committed Oct 26, 2020
1 parent c445b90 commit f72dd4f
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 36 deletions.
57 changes: 30 additions & 27 deletions src/lexer/comments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,15 @@ export function skipHashBang(parser: ParserState): void {
// #! SingleLineCommentChars_opt
const source = parser.source;
if (parser.currentChar === Chars.Hash && source.charCodeAt(parser.index + 1) === Chars.Exclamation) {
skipSingleLineComment(parser, source, LexerState.None, CommentType.HashBang);
skipSingleLineComment(
parser,
source,
LexerState.None,
CommentType.HashBang,
parser.tokenPos,
parser.linePos,
parser.colPos
);
}
}

Expand All @@ -32,10 +40,13 @@ export function skipSingleHTMLComment(
source: string,
state: LexerState,
context: Context,
type: CommentType
type: CommentType,
start: number,
line: number,
column: number
): LexerState {
if (context & Context.Module) report(parser, Errors.Unexpected);
return skipSingleLineComment(parser, source, state, type);
return skipSingleLineComment(parser, source, state, type, start, line, column);
}

/**
Expand All @@ -48,12 +59,12 @@ export function skipSingleLineComment(
parser: ParserState,
source: string,
state: LexerState,
type: CommentType
type: CommentType,
start: number,
line: number,
column: number
): LexerState {
const { index, line, column } = parser;
let end = index;
let endLine = line;
let endColumn = column;
const { index } = parser;
while (parser.index < parser.end) {
if (CharTypes[parser.currentChar] & CharFlags.LineTerminator) {
const isCR = parser.currentChar === Chars.CarriageReturn;
Expand All @@ -66,36 +77,25 @@ export function skipSingleLineComment(
break;
}
advanceChar(parser);
endLine = parser.line;
endColumn = parser.column;
end++;
parser.tokenPos = parser.index;
parser.linePos = parser.line;
parser.colPos = parser.column;
}
if (parser.onComment) {
const loc = {
start: {
// FIXME: there is a bug for HTMLClose.
// the start loc of should be before \n-->
// which is end of last line.
// But there is lack of information on column
// size of last line in our implementation.
// The linePos and colPos is recorded after \n.
line: parser.linePos,
column: parser.colPos
line,
column
},
end: {
line: endLine,
column: endColumn
line: parser.linePos,
column: parser.colPos
}
};
// For Single, start before "//",
// For HTMLOpen, start before "<!--",
// For HTMLClose, start before "\n-->"
let start = index - (type === CommentType.Single ? 2 : 4);
// HTMLClose would start with "-->" on first line.
if (start < 0) {
start = 0;
}
parser.onComment(CommentTypes[type & 0xff], source.slice(index, end), start, end, loc);
parser.onComment(CommentTypes[type & 0xff], source.slice(index, parser.tokenPos), start, parser.tokenPos, loc);
}
return state | LexerState.NewLine;
}
Expand Down Expand Up @@ -137,6 +137,9 @@ export function skipMultiLineComment(parser: ParserState, source: string, state:
loc
);
}
parser.tokenPos = parser.index;
parser.linePos = parser.line;
parser.colPos = parser.column;
return state;
}
}
Expand Down
49 changes: 46 additions & 3 deletions src/lexer/scan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,11 @@ export function scanSingleToken(parser: ParserState, context: Context, state: Le

const source = parser.source;

// These three are only for HTMLClose comment
let startPos = parser.index;
let startLine = parser.line;
let startColumn = parser.column;

while (parser.index < parser.end) {
parser.tokenPos = parser.index;
parser.colPos = parser.column;
Expand Down Expand Up @@ -253,7 +258,19 @@ export function scanSingleToken(parser: ParserState, context: Context, state: Le
) {
parser.column += 3;
parser.currentChar = source.charCodeAt((parser.index += 3));
state = skipSingleHTMLComment(parser, source, state, context, CommentType.HTMLOpen);
state = skipSingleHTMLComment(
parser,
source,
state,
context,
CommentType.HTMLOpen,
parser.tokenPos,
parser.linePos,
parser.colPos
);
startPos = parser.tokenPos;
startLine = parser.linePos;
startColumn = parser.colPos;
continue;
}
return Token.LessThan;
Expand Down Expand Up @@ -369,7 +386,19 @@ export function scanSingleToken(parser: ParserState, context: Context, state: Le
if ((state & LexerState.NewLine || isStartOfLine) && parser.currentChar === Chars.GreaterThan) {
if ((context & Context.OptionsWebCompat) === 0) report(parser, Errors.HtmlCommentInWebCompat);
advanceChar(parser);
state = skipSingleHTMLComment(parser, source, state, context, CommentType.HTMLClose);
state = skipSingleHTMLComment(
parser,
source,
state,
context,
CommentType.HTMLClose,
startPos,
startLine,
startColumn
);
startPos = parser.tokenPos;
startLine = parser.linePos;
startColumn = parser.colPos;
continue;
}

Expand All @@ -391,12 +420,26 @@ export function scanSingleToken(parser: ParserState, context: Context, state: Le
const ch = parser.currentChar;
if (ch === Chars.Slash) {
advanceChar(parser);
state = skipSingleLineComment(parser, source, state, CommentType.Single);
state = skipSingleLineComment(
parser,
source,
state,
CommentType.Single,
parser.tokenPos,
parser.linePos,
parser.colPos
);
startPos = parser.tokenPos;
startLine = parser.linePos;
startColumn = parser.colPos;
continue;
}
if (ch === Chars.Asterisk) {
advanceChar(parser);
state = skipMultiLineComment(parser, source, state) as LexerState;
startPos = parser.tokenPos;
startLine = parser.linePos;
startColumn = parser.colPos;
continue;
}
if (context & Context.AllowRegExp) {
Expand Down
64 changes: 58 additions & 6 deletions test/parser/miscellaneous/onComment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -399,12 +399,7 @@ describe('Miscellaneous - onComment', () => {
end: 29,
range: [14, 29],
loc: {
// FIXME: the start loc of should be before
// \n--> which is end of last line.
// But there is lack of information on column
// size of last line in our implementation.
// start: { line: 1, column: 14 },
start: { line: 2, column: 0 },
start: { line: 1, column: 14 },
end: { line: 2, column: 14 }
}
}
Expand Down Expand Up @@ -433,4 +428,61 @@ describe('Miscellaneous - onComment', () => {
}
]);
});

it('should extract htmlclose comment', () => {
const arr: any[] = [];
parseScript('a;\n--> comment #2\n', {
ranges: true,
loc: true,
onComment: arr,
webcompat: true
});
t.deepEqual(arr, [
{
type: 'HTMLClose',
value: ' comment #2',
start: 2,
end: 17,
range: [2, 17],
loc: {
start: { line: 1, column: 2 },
end: { line: 2, column: 14 }
}
}
]);
});

it('should extract htmlclose comment after multiline comment', () => {
const arr: any[] = [];
parseScript('/*\na\n*/\n--> comment #2\n', {
ranges: true,
loc: true,
onComment: arr,
webcompat: true
});
t.deepEqual(arr, [
{
start: 0,
end: 7,
range: [0, 7],
loc: {
start: { line: 1, column: 0 },
end: { line: 3, column: 2 }
},
type: 'MultiLine',
value: '\na\n'
},
{
type: 'HTMLClose',
value: ' comment #2',
start: 7,
end: 22,
range: [7, 22],
loc: {
start: { line: 3, column: 2 },
end: { line: 4, column: 14 }
}
}
]);
});
});

0 comments on commit f72dd4f

Please sign in to comment.