Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
767 changes: 767 additions & 0 deletions index.cjs

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions index.d.cts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import * as jsx from './index.js';

export = jsx;
65 changes: 38 additions & 27 deletions index.d.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,49 @@
import * as acorn from 'acorn';

interface JsxTokTypes extends AcornTokTypes {
export declare class TokContext {
constructor(
token: string,
isExpr: boolean,
preserveSpace: boolean,
override?: (parser: any) => void
)
}

export interface JsxTokTypes extends AcornTokTypes {
jsxName: acorn.TokenType,
jsxText: acorn.TokenType,
jsxTagEnd: acorn.TokenType,
jsxTagStart: acorn.TokenType
}

declare const jsx: {
tokTypes: JsxTokTypes;
(options?: jsx.Options): (BaseParser: typeof acorn.Parser) => jsx.AcornJsxParserCtor
}

type AcornTokTypes = typeof acorn.tokTypes;

declare namespace jsx {
export type AcornTokTypes = typeof acorn.tokTypes;

type TokTypes = JsxTokTypes
export type TokTypes = JsxTokTypes

interface Options {
export interface Options {
allowNamespacedObjects?: boolean;
allowNamespaces?: boolean;
}
}

interface TokContexts {
tc_oTag: acorn.TokContext,
tc_cTag: acorn.TokContext,
tc_expr: acorn.TokContext
}
export interface TokContexts {
tc_oTag: TokContext,
tc_cTag: TokContext,
tc_expr: TokContext
}

// We pick (statics) from acorn rather than plain extending to avoid complaint
// about base constructors needing the same return type (i.e., we return
// `AcornJsxParser` here)
interface AcornJsxParserCtor extends Pick<typeof acorn.Parser, keyof typeof acorn.Parser> {
// We pick (statics) from acorn rather than plain extending to avoid complaint
// about base constructors needing the same return type (i.e., we return
// `AcornJsxParser` here)
export interface AcornJsxParserCtor extends Pick<typeof acorn.Parser, keyof typeof acorn.Parser> {
readonly acornJsx: {
tokTypes: TokTypes;
tokContexts: TokContexts
tokTypes: TokTypes;
tokContexts: TokContexts
};

new (options: acorn.Options, input: string, startPos?: number): AcornJsxParser;
}
}

interface AcornJsxParser extends acorn.Parser {
export interface AcornJsxParser extends acorn.Parser {
jsx_readToken(): string;
jsx_readNewLine(normalizeCRLF: boolean): void;
jsx_readString(quote: number): void;
Expand All @@ -59,7 +61,16 @@ declare namespace jsx {
jsx_parseElementAt(startPos: number, startLoc?: acorn.SourceLocation): acorn.Node;
jsx_parseText(): acorn.Node;
jsx_parseElement(): acorn.Node;
}
}

export = jsx;
export interface JsxFunctionProperties {
tokTypes: JsxTokTypes;
}

export type JsxFunctionSignature = (options?: Options) => (BaseParser: typeof acorn.Parser) => AcornJsxParserCtor

export type JsxFunction = JsxFunctionSignature & JsxFunctionProperties;

declare const jsx: JsxFunction;

export default jsx;
26 changes: 14 additions & 12 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
'use strict';

const XHTMLEntities = require('./xhtml');
import * as acorn from "acorn";
import XHTMLEntities from './xhtml.js';

const hexNumber = /^[\da-fA-F]+$/;
const decimalNumber = /^\d+$/;
Expand Down Expand Up @@ -70,7 +69,7 @@ function getQualifiedJSXName(object) {
getQualifiedJSXName(object.property);
}

module.exports = function(options) {
function acornJsx(options) {
options = options || {};
return function(Parser) {
return plugin({
Expand All @@ -82,26 +81,29 @@ module.exports = function(options) {

// This is `tokTypes` of the peer dep.
// This can be different instances from the actual `tokTypes` this plugin uses.
Object.defineProperty(module.exports, "tokTypes", {
Object.defineProperty(acornJsx, "tokTypes", {
get: function get_tokTypes() {
return getJsxTokens(require("acorn")).tokTypes;
return getJsxTokens(acorn).tokTypes;
},
configurable: true,
enumerable: true
});


export default acornJsx;

function plugin(options, Parser) {
const acorn = Parser.acorn || require("acorn");
const acrn = Parser.acorn || acorn;
const acornJsx = getJsxTokens(acorn);
const tt = acorn.tokTypes;
const tt = acrn.tokTypes;
const tok = acornJsx.tokTypes;
const tokContexts = acorn.tokContexts;
const tokContexts = acrn.tokContexts;
const tc_oTag = acornJsx.tokContexts.tc_oTag;
const tc_cTag = acornJsx.tokContexts.tc_cTag;
const tc_expr = acornJsx.tokContexts.tc_expr;
const isNewLine = acorn.isNewLine;
const isIdentifierStart = acorn.isIdentifierStart;
const isIdentifierChar = acorn.isIdentifierChar;
const isNewLine = acrn.isNewLine;
const isIdentifierStart = acrn.isIdentifierStart;
const isIdentifierChar = acrn.isIdentifierChar;

return class extends Parser {
// Expose actual `tokTypes` and `tokContexts` to other plugins.
Expand Down
20 changes: 18 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@
"description": "Modern, fast React.js JSX parser",
"homepage": "https://github.com/acornjs/acorn-jsx",
"version": "5.3.2",
"type": "module",
"main": "index.cjs",
"exports": {
"types": {
"import": "./index.d.ts",
"require": "./index.d.cts"
},
"import": "./index.js",
"require": "./index.cjs"
},
"maintainers": [
{
"name": "Ingvar Stepanyan",
Expand All @@ -16,12 +26,18 @@
},
"license": "MIT",
"scripts": {
"test": "node test/run.js"
"attw": "attw --pack",
"test": "node test/run.js",
"build": "rollup -c",
"prepublishOnly": "npm run build"
},
"peerDependencies": {
"acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
},
"devDependencies": {
"acorn": "^8.0.1"
"@arethetypeswrong/cli": "^0.18.2",
"@rollup/plugin-commonjs": "^12.0.0",
"acorn": "^8.15.0",
"rollup": "^2.12.0"
}
}
10 changes: 10 additions & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export default {
input: "index.js",
external: ["acorn"],
output: {
file: "index.cjs",
exports: 'default',
format: "cjs",
banner: "// DO NOT edit this file, it's auto-generated from 'rollup.config.js'; any changes will be overwritten. \n"
}
};
10 changes: 5 additions & 5 deletions test/driver.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
var tests = [];

exports.test = function(code, ast, options, pluginOptions) {
export function test(code, ast, options, pluginOptions) {
tests.push({code, ast, options, pluginOptions});
};
exports.testFail = function(code, message, options, pluginOptions) {
export function testFail(code, message, options, pluginOptions) {
tests.push({code, error: message, options, pluginOptions});
};
exports.testAssert = function(code, assert, options) {
export function testAssert(code, assert, options) {
tests.push({code, assert, options});
};

exports.runTests = function(config, callback) {
export function runTests(config, callback) {
var parse = config.parse;

for (var i = 0; i < tests.length; ++i) {
Expand Down Expand Up @@ -72,7 +72,7 @@ function addPath(str, pt) {
return str + " (" + pt + ")";
}

var misMatch = exports.misMatch = function(exp, act) {
var misMatch = function(exp, act) {
if (!exp || !act || (typeof exp != "object") || (typeof act != "object")) {
if (exp !== act) return ppJSON(exp) + " !== " + ppJSON(act);
} else if (exp instanceof RegExp || act instanceof RegExp) {
Expand Down
9 changes: 5 additions & 4 deletions test/run.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
var driver = require("./driver.js");
require("./tests-jsx.js");
require("./tests-misc.js");
import * as driver from "./driver.js";
import "./tests-jsx.js";
import "./tests-misc.js";
import * as acorn from "acorn";
import jsx from "../index.js";

function group(name) {
if (typeof console === "object" && console.group) {
Expand All @@ -18,7 +20,6 @@ function log(title, message) {
if (typeof console === "object") console.log(title, message);
}

const acorn = require("acorn"), jsx = require("..")
const Parser = acorn.Parser.extend(jsx())

var stats, modes = {
Expand Down
14 changes: 7 additions & 7 deletions test/tests-jsx.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

import { test } from "./driver.js";
import { testFail } from "./driver.js";
import acornJsx from "../index.js";
import { tokTypes as acornTokens } from "acorn";

let jsxTokens = acornJsx.tokTypes;

var fbTestFixture = {
// Taken and adapted from esprima-fb/fbtest.js.
'JSX': {
Expand Down Expand Up @@ -3725,13 +3732,6 @@ var fbTestFixture = {
}
};

if (typeof exports !== "undefined") {
var test = require("./driver.js").test;
var testFail = require("./driver.js").testFail;
var jsxTokens = require("..").tokTypes;
var acornTokens = require("acorn").tokTypes;
}

testFail("var x = <div>one</div><div>two</div>;", "Adjacent JSX elements must be wrapped in an enclosing tag (1:22)");

testFail("<a:b.c />", "Unexpected token (1:4)");
Expand Down
12 changes: 4 additions & 8 deletions test/tests-misc.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
"use strict";

if (typeof exports !== "undefined") {
var assert = require("assert");
var acorn = require("acorn");
var jsx = require("..");
var testAssert = require("./driver.js").testAssert;
}
import assert from "assert";
import * as acorn from "acorn";
import jsx from "../index.js";
import { testAssert } from "./driver.js";

testAssert("// the enhanced Parser instance should have a static property 'acornJsx'.", function() {
const JsxParser = acorn.Parser.extend(jsx());
Expand Down
2 changes: 1 addition & 1 deletion xhtml.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = {
export default {
quot: '\u0022',
amp: '&',
apos: '\u0027',
Expand Down