Repository navigation
feat(lexer): add opt-in extended export detection #128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -85,7 +85,42 @@ const { exports } = parse( | |
| // exports === ['b'] | ||
| ``` | ||
|
|
||
| ### Grammar | ||
| ### Extended detection | ||
|
|
||
| The third argument selects an opt-in detection mode: | ||
|
|
||
| ```js | ||
| parse(source, filename, { mode: 'extended' }); | ||
| ``` | ||
|
|
||
| Omitting the options, using `{}`, or selecting `mode: 'default'` preserves default detection. | ||
| An invalid mode throws a `TypeError`. | ||
| `allowMinifiedEnumerable` can be used with either mode. | ||
| Both modes use the existing lexer and assume valid JavaScript input. | ||
| They do not execute the source or validate the complete JavaScript grammar. | ||
|
|
||
| Extended mode detects literal names in `Object.defineProperty` calls regardless of the descriptor expression or getter body. | ||
| It also detects names in object literals passed to `Object.defineProperties(exports, ...)` or assigned to `module.exports`. | ||
| Object values can contain arbitrary expressions. | ||
| Methods, accessors, and computed string literal keys contribute their names. | ||
| Parentheses around these object literals are supported. | ||
| Parenthesized comma expressions can skip leading identifiers, integer literals, string literals, and empty object literals. | ||
| Other comma expressions are not supported. | ||
| For `module.exports = ({ a: 1 }, { b: 2 })`, extended mode detects `a`, although the expression evaluates to `{ b: 2 }`. | ||
| The same limitation applies to `Object.defineProperties`. | ||
| Direct reexport assignments contribute all detected dependencies instead of only the last assignment. | ||
| Object spreads of `require('literal')` contribute reexports, but named properties with require-valued expressions do not. | ||
|
|
||
| The result contains syntactic candidates, which can include non-enumerable properties, throwing getters, and unreachable assignments. | ||
| Extended mode does not apply the default getter side-effect veto. | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dropping the unsafe-getter veto is a semantic change rather than broader syntax: the veto exists because non-matching getters can have side effects when names are snapshotted. |
||
| It does not resolve bindings or aliases, evaluate computed names, or determine runtime control flow. | ||
| Names created by dynamic expressions can therefore remain undetected, and shadowed identifiers can produce false positives. | ||
|
|
||
| Division and regular-expression detection remains heuristic. | ||
| Ambiguous cases can cause extended mode's bracket tracking to report parse errors on valid JavaScript. | ||
| Selecting extended mode in this package does not change Node.js's built-in CommonJS detection. | ||
|
|
||
| ### Grammar (default mode) | ||
|
|
||
| CommonJS exports matches are run against the source token stream. The grammar below describes default detection. | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.