Skip to content

Commit

Permalink
fix(parser): tweaked some code
Browse files Browse the repository at this point in the history
  • Loading branch information
KFlash committed Jul 6, 2019
1 parent 6624f57 commit 6acf9ad
Show file tree
Hide file tree
Showing 6 changed files with 281 additions and 97 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion src/lexer/charClassifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const enum CharFlags {
Underscore = 1 << 21,
StringLiteral = 1 << 22,
JSXToken = 1 << 23,
Hyphen = 1 << 24,
}

/**
Expand Down Expand Up @@ -70,7 +71,7 @@ export const CharTypes = [
CharFlags.None /* 0x2A */,
CharFlags.Exponent /* 0x2B */,
CharFlags.None /* 0x2C */,
CharFlags.Exponent /* 0x2D */,
CharFlags.Exponent | CharFlags.Hyphen /* 0x2D */,
CharFlags.None /* 0x2E */,
CharFlags.None /* 0x2F */,
CharFlags.IdentifierPart | CharFlags.Decimal | CharFlags.Binary | CharFlags.Octal | CharFlags.Hex /* 0x30 0 */,
Expand Down
13 changes: 5 additions & 8 deletions src/lexer/jsx.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CharFlags, CharTypes, isIdentifierStart, isIdentifierPart } from './charClassifier';
import { CharFlags, CharTypes } from './charClassifier';
import { Chars } from '../chars';
import { Token } from '../token';
import { ParserState, Context } from '../common';
Expand Down Expand Up @@ -81,18 +81,15 @@ export function scanJSXToken(parser: ParserState): Token {

/**
* Scans JSX identifier
*
* @param parser The parser instance
* @param context Context masks
*/
export function scanJSXIdentifier(parser: ParserState): Token {
if ((parser.token & Token.IsIdentifier) === Token.IsIdentifier) {
const { index } = parser;

while (parser.index < parser.end) {
const char = parser.nextCP;
if (char === Chars.Hyphen || (index === parser.index ? isIdentifierStart(char) : isIdentifierPart(char))) {
nextCP(parser);
} else break;
let char = parser.nextCP;
while ((CharTypes[char] & (CharFlags.Hyphen | CharFlags.IdentifierPart)) !== 0) {
char = nextCP(parser);
}
parser.tokenValue += parser.source.slice(index, parser.index);
}
Expand Down
2 changes: 1 addition & 1 deletion src/meriyah.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,4 @@ export function parse(source: string, options: Options | void): ESTree.Program {
return parseSource(source, options, Context.None);
}

export const version = '1.2.6';
export const version = '1.3.0';
107 changes: 53 additions & 54 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import * as ESTree from './estree';
import { report, reportAt, Errors } from './errors';
import { scanTemplateTail } from './lexer/template';
import { scanJSXIdentifier, scanJSXToken, scanJSXAttributeValue } from './lexer/jsx';
import { isEqualTagName } from './common';

import {
declareName,
declareAndDedupe,
Expand Down Expand Up @@ -41,7 +39,8 @@ import {
validateAndDeclareLabel,
finishNode,
HoistedClassFlags,
HoistedFunctionFlags
HoistedFunctionFlags,
isEqualTagName
} from './common';

/**
Expand Down Expand Up @@ -7975,6 +7974,7 @@ function parseAndClassifyIdentifier(
* @param line
* @param column
*/

function parseJSXRootElementOrFragment(
parser: ParserState,
context: Context,
Expand All @@ -7983,36 +7983,35 @@ function parseJSXRootElementOrFragment(
line: number,
column: number
): ESTree.JSXElement | ESTree.JSXFragment {
const openingElement:
| ESTree.JSXOpeningElement
| ESTree.JSXOpeningFragment = parseJSXOpeningFragmentOrSelfCloseElement(
nextToken(parser, context);

// JSX fragments

This comment has been minimized.

Copy link
@KFlash

KFlash Jul 6, 2019

Author Contributor

@aladdin-add There is the fragment code :) I shipped v. 1.3 now and need to take some time off, but Meriyah should be stable to be used in production now.

Please open a issue ticket regarding the extensibility you mentioned earlier.

Meriyah's JSX implementation is around 70% faster than Acorn with JSX plugin. Just try to do a comparison :) The main reason for this is that Acorn accept plugin and the core Class is extended. Very slow :)

if (parser.token === Token.GreaterThan) {
return finishNode(parser, context, start, line, column, {
type: 'JSXFragment',
openingFragment: parseOpeningFragment(parser, context, start, line, column),
children: parseJSXChildren(parser, context),
closingFragment: parseJSXClosingFragment(
parser,
context,
isJSXChild,
parser.tokenIndex,
parser.linePos,
parser.colPos
)
});
}

let closingElement: ESTree.JSXClosingElement | null = null;
let children: ESTree.JSXChild[] = [];
const openingElement: ESTree.JSXOpeningElement = parseJSXOpeningFragmentOrSelfCloseElement(
parser,
context,
isJSXChild,
start,
line,
column
);
let children: ESTree.JSXChild[] = [];
let closingElement: ESTree.JSXClosingElement | ESTree.JSXClosingFragment | null = null;

if (openingElement.type === 'JSXOpeningFragment') {
children = parseJSXChildren(parser, context);
closingElement = parseJSXClosingFragment(
parser,
context,
isJSXChild,
parser.tokenIndex,
parser.linePos,
parser.colPos
);
return finishNode(parser, context, start, line, column, {
type: 'JSXFragment',
children,
openingFragment: openingElement,
closingFragment: closingElement
});
}

if (!openingElement.selfClosing) {
children = parseJSXChildren(parser, context);
Expand All @@ -8024,9 +8023,8 @@ function parseJSXRootElementOrFragment(
parser.linePos,
parser.colPos
);
const open = isEqualTagName(openingElement.name);
const close = isEqualTagName(closingElement.name);
if (open !== close) report(parser, Errors.Unexpected);
if (isEqualTagName(openingElement.name) !== close) report(parser, Errors.ExpectedJSXClosingTag, close);
}

return finishNode(parser, context, start, line, column, {
Expand All @@ -8037,6 +8035,28 @@ function parseJSXRootElementOrFragment(
});
}

/**
* Parses JSX opening fragment
*
* @param parser Parser object
* @param context Context masks
* @param start
* @param line
* @param column
*/
export function parseOpeningFragment(
parser: ParserState,
context: Context,
start: number,
line: number,
column: number
): ESTree.JSXOpeningFragment {
scanJSXToken(parser);
return finishNode(parser, context, start, line, column, {
type: 'JSXOpeningFragment'
});
}

/**
* Parses JSX Closing element
*
Expand Down Expand Up @@ -8161,23 +8181,10 @@ export function parseJSXText(
): ESTree.JSXText {
const value = parser.tokenValue;
scanJSXToken(parser);
return finishNode(
parser,
context,
start,
line,
column,
context & Context.OptionsRaw
? {
type: 'JSXText',
value,
raw: value
}
: {
type: 'JSXText',
value
}
);
return finishNode(parser, context, start, line, column, {
type: 'JSXText',
value
});
}

/**
Expand All @@ -8197,15 +8204,7 @@ function parseJSXOpeningFragmentOrSelfCloseElement(
start: number,
line: number,
column: number
): ESTree.JSXOpeningElement | ESTree.JSXOpeningFragment {
consume(parser, context, Token.LessThan);
if (parser.token === Token.GreaterThan) {
scanJSXToken(parser);
return finishNode(parser, context, start, line, column, {
type: 'JSXOpeningFragment'
});
}

): ESTree.JSXOpeningElement {
if ((parser.token & Token.IsIdentifier) !== Token.IsIdentifier && (parser.token & Token.Keyword) !== Token.Keyword)
report(parser, Errors.Unexpected);

Expand Down
Loading

0 comments on commit 6acf9ad

Please sign in to comment.