UNPKG

6.18 kBJavaScriptView Raw
1/**
2 * @fileoverview Main Espree file that converts Acorn into Esprima output.
3 *
4 * This file contains code from the following MIT-licensed projects:
5 * 1. Acorn
6 * 2. Babylon
7 * 3. Babel-ESLint
8 *
9 * This file also contains code from Esprima, which is BSD licensed.
10 *
11 * Acorn is Copyright 2012-2015 Acorn Contributors (https://github.com/marijnh/acorn/blob/master/AUTHORS)
12 * Babylon is Copyright 2014-2015 various contributors (https://github.com/babel/babel/blob/master/packages/babylon/AUTHORS)
13 * Babel-ESLint is Copyright 2014-2015 Sebastian McKenzie <sebmck@gmail.com>
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions are met:
17 *
18 * * Redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer.
20 * * Redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
28 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *
35 * Esprima is Copyright (c) jQuery Foundation, Inc. and Contributors, All Rights Reserved.
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in the
44 * documentation and/or other materials provided with the distribution.
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
47 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
50 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
51 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
52 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
53 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
54 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
55 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56 */
57/* eslint no-undefined:0, no-use-before-define: 0 */
58
59"use strict";
60
61const acorn = require("acorn");
62const jsx = require("acorn-jsx");
63const astNodeTypes = require("./lib/ast-node-types");
64const espree = require("./lib/espree");
65
66// To initialize lazily.
67const parsers = {
68 _regular: null,
69 _jsx: null,
70
71 get regular() {
72 if (this._regular === null) {
73 this._regular = acorn.Parser.extend(espree());
74 }
75 return this._regular;
76 },
77
78 get jsx() {
79 if (this._jsx === null) {
80 this._jsx = acorn.Parser.extend(jsx(), espree());
81 }
82 return this._jsx;
83 },
84
85 get(options) {
86 const useJsx = Boolean(
87 options &&
88 options.ecmaFeatures &&
89 options.ecmaFeatures.jsx
90 );
91 return useJsx ? this.jsx : this.regular;
92 }
93};
94
95//------------------------------------------------------------------------------
96// Tokenizer
97//------------------------------------------------------------------------------
98
99/**
100 * Tokenizes the given code.
101 * @param {string} code The code to tokenize.
102 * @param {Object} options Options defining how to tokenize.
103 * @returns {Token[]} An array of tokens.
104 * @throws {SyntaxError} If the input code is invalid.
105 * @private
106 */
107function tokenize(code, options) {
108 const Parser = parsers.get(options);
109
110 // Ensure to collect tokens.
111 if (!options || options.tokens !== true) {
112 options = Object.assign({}, options, { tokens: true });
113 }
114
115 return new Parser(options, code).tokenize();
116}
117
118//------------------------------------------------------------------------------
119// Parser
120//------------------------------------------------------------------------------
121
122/**
123 * Parses the given code.
124 * @param {string} code The code to tokenize.
125 * @param {Object} options Options defining how to tokenize.
126 * @returns {ASTNode} The "Program" AST node.
127 * @throws {SyntaxError} If the input code is invalid.
128 */
129function parse(code, options) {
130 const Parser = parsers.get(options);
131 return new Parser(options, code).parse();
132}
133
134//------------------------------------------------------------------------------
135// Public
136//------------------------------------------------------------------------------
137
138exports.version = require("./package.json").version;
139
140exports.tokenize = tokenize;
141
142exports.parse = parse;
143
144// Deep copy.
145/* istanbul ignore next */
146exports.Syntax = (function() {
147 var name, types = {};
148
149 if (typeof Object.create === "function") {
150 types = Object.create(null);
151 }
152
153 for (name in astNodeTypes) {
154 if (astNodeTypes.hasOwnProperty(name)) {
155 types[name] = astNodeTypes[name];
156 }
157 }
158
159 if (typeof Object.freeze === "function") {
160 Object.freeze(types);
161 }
162
163 return types;
164}());
165
166/* istanbul ignore next */
167exports.VisitorKeys = (function() {
168 return require("eslint-visitor-keys").KEYS;
169}());