| import {has, isArray} from "./util" |
| import {SourceLocation} from "./locutil" |
| |
| // A second optional argument can be given to further configure |
| // the parser process. These options are recognized: |
| |
| export const defaultOptions = { |
| // `ecmaVersion` indicates the ECMAScript version to parse. Must |
| // be either 3, or 5, or 6. This influences support for strict |
| // mode, the set of reserved words, support for getters and |
| // setters and other features. The default is 6. |
| ecmaVersion: 6, |
| // Source type ("script" or "module") for different semantics |
| sourceType: "script", |
| // `onInsertedSemicolon` can be a callback that will be called |
| // when a semicolon is automatically inserted. It will be passed |
| // th position of the comma as an offset, and if `locations` is |
| // enabled, it is given the location as a `{line, column}` object |
| // as second argument. |
| onInsertedSemicolon: null, |
| // `onTrailingComma` is similar to `onInsertedSemicolon`, but for |
| // trailing commas. |
| onTrailingComma: null, |
| // By default, reserved words are only enforced if ecmaVersion >= 5. |
| // Set `allowReserved` to a boolean value to explicitly turn this on |
| // an off. When this option has the value "never", reserved words |
| // and keywords can also not be used as property names. |
| allowReserved: null, |
| // When enabled, a return at the top level is not considered an |
| // error. |
| allowReturnOutsideFunction: false, |
| // When enabled, import/export statements are not constrained to |
| // appearing at the top of the program. |
| allowImportExportEverywhere: false, |
| // When enabled, hashbang directive in the beginning of file |
| // is allowed and treated as a line comment. |
| allowHashBang: false, |
| // When `locations` is on, `loc` properties holding objects with |
| // `start` and `end` properties in `{line, column}` form (with |
| // line being 1-based and column 0-based) will be attached to the |
| // nodes. |
| locations: false, |
| // A function can be passed as `onToken` option, which will |
| // cause Acorn to call that function with object in the same |
| // format as tokens returned from `tokenizer().getToken()`. Note |
| // that you are not allowed to call the parser from the |
| // callback—that will corrupt its internal state. |
| onToken: null, |
| // A function can be passed as `onComment` option, which will |
| // cause Acorn to call that function with `(block, text, start, |
| // end)` parameters whenever a comment is skipped. `block` is a |
| // boolean indicating whether this is a block (`/* */`) comment, |
| // `text` is the content of the comment, and `start` and `end` are |
| // character offsets that denote the start and end of the comment. |
| // When the `locations` option is on, two more parameters are |
| // passed, the full `{line, column}` locations of the start and |
| // end of the comments. Note that you are not allowed to call the |
| // parser from the callback—that will corrupt its internal state. |
| onComment: null, |
| // Nodes have their start and end characters offsets recorded in |
| // `start` and `end` properties (directly on the node, rather than |
| // the `loc` object, which holds line/column data. To also add a |
| // [semi-standardized][range] `range` property holding a `[start, |
| // end]` array with the same numbers, set the `ranges` option to |
| // `true`. |
| // |
| // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678 |
| ranges: false, |
| // It is possible to parse multiple files into a single AST by |
| // passing the tree produced by parsing the first file as |
| // `program` option in subsequent parses. This will add the |
| // toplevel forms of the parsed file to the `Program` (top) node |
| // of an existing parse tree. |
| program: null, |
| // When `locations` is on, you can pass this to record the source |
| // file in every node's `loc` object. |
| sourceFile: null, |
| // This value, if given, is stored in every node, whether |
| // `locations` is on or off. |
| directSourceFile: null, |
| // When enabled, parenthesized expressions are represented by |
| // (non-standard) ParenthesizedExpression nodes |
| preserveParens: false, |
| plugins: {} |
| } |
| |
| // Interpret and default an options object |
| |
| export function getOptions(opts) { |
| let options = {} |
| for (let opt in defaultOptions) |
| options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt] |
| if (options.allowReserved == null) |
| options.allowReserved = options.ecmaVersion < 5 |
| |
| if (isArray(options.onToken)) { |
| let tokens = options.onToken |
| options.onToken = (token) => tokens.push(token) |
| } |
| if (isArray(options.onComment)) |
| options.onComment = pushComment(options, options.onComment) |
| |
| return options |
| } |
| |
| function pushComment(options, array) { |
| return function (block, text, start, end, startLoc, endLoc) { |
| let comment = { |
| type: block ? 'Block' : 'Line', |
| value: text, |
| start: start, |
| end: end |
| } |
| if (options.locations) |
| comment.loc = new SourceLocation(this, startLoc, endLoc) |
| if (options.ranges) |
| comment.range = [start, end] |
| array.push(comment) |
| } |
| } |
| |