-
Notifications
You must be signed in to change notification settings - Fork 5
rewrite orchestrion in javascript #41
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
Open
rochdev
wants to merge
27
commits into
nodejs:main
Choose a base branch
from
rochdev:js-rewrite
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 10 commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
b17de5f
wip
rochdev 8521cef
fix transformer tests
rochdev f5cf14f
fix typo
rochdev a070d3e
rewrite tests to js and fix super support in constructors
rochdev 82f2d96
add support for isExportAlias
rochdev 5cd96c7
add missing features from rust
rochdev 41c8860
add oxc + tests and remove build requirement
rochdev 73f786d
update type definitions
rochdev dec3766
add custom transforms
rochdev c39a725
rename old ci tests
rochdev 65bd0c8
switch to npm in ci and fix typo
rochdev cbbb118
downgrade meriyah for node 18 compat
rochdev 4117dbe
add linting and fix errors
rochdev 0eb4999
add jsdoc
rochdev 66c92c0
add test for astQuery
rochdev 14164d4
add source map test
rochdev 5fa920f
fix support for node 18
rochdev 8a6ed12
remove iterator support for now
rochdev bf0c5b1
simplify code and remove custom parser for now
rochdev 357cffb
update jsdoc
rochdev d4fa04f
remove all rust and update docs
rochdev b3b1715
update 3rd party licenses
rochdev 4443619
remove oxc-parser
rochdev ef0131a
temporarily revert lockfile ignore
rochdev 5a55f86
delete yarn lockfile
rochdev 0587761
add back ignore for lockfiles
rochdev 1fee50d
remove copyright from new files
rochdev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,5 +5,3 @@ tests/*/instrumented.* | |
| pkg/ | ||
| node_modules/ | ||
| package-lock.json | ||
| index.js | ||
| index.d.ts | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,114 @@ | ||
| /* tslint:disable */ | ||
| /* eslint-disable */ | ||
| import type { Node } from 'estree'; | ||
| /** | ||
| * Create a new instrumentation matcher from an array of instrumentation configs. | ||
| */ | ||
| export function create(configs: InstrumentationConfig[], dc_module?: string | null): InstrumentationMatcher; | ||
| /** | ||
| * Output of a transformation operation | ||
| */ | ||
| export interface TransformOutput { | ||
| /** | ||
| * The transformed JavaScript code | ||
| */ | ||
| code: string; | ||
| /** | ||
| * The sourcemap for the transformation (if generated) | ||
| */ | ||
| map: string | undefined; | ||
| } | ||
|
|
||
| /** | ||
| * The kind of function | ||
| */ | ||
| export type FunctionKind = "Sync" | "Async" | "AsyncIterator" | "Callback" | "Iterator"; | ||
|
|
||
| /** | ||
| * Describes which function to instrument | ||
| */ | ||
| export type FunctionQuery = { className: string; methodName: string; kind: FunctionKind; index?: number; isExportAlias?: boolean } | { className: string; privateMethodName: string; kind: FunctionKind; index?: number } | { className: string; index?: number; isExportAlias?: boolean } | { methodName: string; kind: FunctionKind; index?: number } | { functionName: string; kind: FunctionKind; index?: number; isExportAlias?: boolean } | { expressionName: string; kind: FunctionKind; index?: number; isExportAlias?: boolean }; | ||
|
|
||
| /** | ||
| * A custom transform function registered via `addTransform`. | ||
| * Receives the instrumentation state and the matched AST node. | ||
| */ | ||
| export type CustomTransform = (state: unknown, node: Node, parent: Node, ancestry: Node[]) => void; | ||
|
|
||
| /** | ||
| * Configuration for injecting instrumentation code | ||
| */ | ||
| export interface InstrumentationConfig { | ||
| /** | ||
| * The name of the diagnostics channel to publish to | ||
| */ | ||
| channelName: string; | ||
| /** | ||
| * The module matcher to identify the module and file to instrument | ||
| */ | ||
| module: ModuleMatcher; | ||
| /** | ||
| * The function query to identify the function to instrument | ||
| */ | ||
| functionQuery: FunctionQuery; | ||
| /** | ||
| * The name of a custom transform registered via `addTransform`. | ||
| * When set, takes precedence over `functionQuery.kind`. | ||
| */ | ||
| transform?: string; | ||
| } | ||
|
|
||
| /** | ||
| * Describes the module and file path you would like to match | ||
| */ | ||
| export interface ModuleMatcher { | ||
| /** | ||
| * The name of the module you want to match | ||
| */ | ||
| name: string; | ||
| /** | ||
| * The semver range that you want to match | ||
| */ | ||
| versionRange: string; | ||
| /** | ||
| * The path of the file you want to match from the module root | ||
| */ | ||
| filePath: string; | ||
| } | ||
|
|
||
| /** | ||
| * The type of module being passed - ESM, CJS or unknown | ||
| */ | ||
| export type ModuleType = "esm" | "cjs" | "unknown"; | ||
|
|
||
| /** | ||
| * The InstrumentationMatcher is responsible for matching specific modules | ||
| */ | ||
| export class InstrumentationMatcher { | ||
| private constructor(); | ||
| free(): void; | ||
| /** | ||
| * Get a transformer for the given module name, version and file path. | ||
| * Returns `undefined` if no matching instrumentations are found. | ||
| */ | ||
| getTransformer(module_name: string, version: string, file_path: string): Transformer | undefined; | ||
| /** | ||
| * Register a custom transform function under the given name. | ||
| * The name can then be referenced via the `transform` option in an `InstrumentationConfig`. | ||
| */ | ||
| addTransform(name: string, fn: CustomTransform): void; | ||
| } | ||
| /** | ||
| * The Transformer is responsible for transforming JavaScript code. | ||
| */ | ||
| export class Transformer { | ||
| private constructor(); | ||
| free(): void; | ||
| /** | ||
| * Transform JavaScript code and optionally sourcemap. | ||
| * | ||
| * # Errors | ||
| * Returns an error if the transformation fails to find injection points. | ||
| */ | ||
| transform(code: string, module_type: ModuleType, sourcemap?: string | null): TransformOutput; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| "use strict"; | ||
|
|
||
| module.exports = require('./lib') | ||
rochdev marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| 'use strict' | ||
|
|
||
| const runtimeRequire = typeof __webpack_require__ === 'function' ? __non_webpack_require__ : require | ||
|
|
||
| const { ORCHESTRION_PARSER } = process.env | ||
|
|
||
| const compiler = { | ||
| parse: (sourceText, options) => { | ||
| const useOxc = () => { | ||
| // TODO: Figure out ESBuild `createRequire` issue and remove this hack. | ||
| const oxc = runtimeRequire(['oxc', 'parser'].join('-')) | ||
|
|
||
| compiler.parse = (sourceText, options) => { | ||
| const { program, errors } = oxc.parseSync('index.js', sourceText, { | ||
| ...options, | ||
| preserveParens: false, | ||
| }) | ||
|
|
||
| if (errors?.length > 0) throw errors[0] | ||
|
|
||
| if (options?.range) addLoc(program, sourceText.toString()) | ||
|
|
||
| return program | ||
| } | ||
| } | ||
|
|
||
| const useMeriyah = () => { | ||
| const meriyah = require('meriyah') | ||
|
|
||
| compiler.parse = (sourceText, { range, sourceType } = {}) => { | ||
| return meriyah.parse(sourceText.toString(), { | ||
| loc: range, | ||
| ranges: range, | ||
| raw: true, | ||
| module: sourceType === 'module', | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| if (ORCHESTRION_PARSER === 'meriyah') { | ||
| useMeriyah() | ||
| } else { | ||
| try { | ||
| useOxc() | ||
| } catch (e) { | ||
| if (ORCHESTRION_PARSER === 'oxc') throw e | ||
| useMeriyah() // Fallback for when OXC is not available. | ||
| } | ||
| } | ||
|
|
||
| return compiler.parse(sourceText, options) | ||
| }, | ||
|
|
||
| generate: (...args) => { | ||
| const astring = require('astring') | ||
|
|
||
| compiler.generate = astring.generate | ||
|
|
||
| return compiler.generate(...args) | ||
| }, | ||
|
|
||
| traverse: (ast, query, visitor) => { | ||
| const esquery = require('esquery') | ||
|
|
||
| compiler.traverse = (ast, query, visitor) => { | ||
| return esquery.traverse(ast, esquery.parse(query), visitor) | ||
| } | ||
|
|
||
| return compiler.traverse(ast, query, visitor) | ||
| }, | ||
|
|
||
| query: (ast, query) => { | ||
| const esquery = require('esquery') | ||
|
|
||
| compiler.query = esquery.query | ||
|
|
||
| return compiler.query(ast, query) | ||
| }, | ||
| } | ||
|
|
||
| function addLoc (node, sourceText) { | ||
| const lineOffsets = [0] | ||
| for (let i = 0; i < sourceText.length; i++) { | ||
| if (sourceText[i] === '\n') lineOffsets.push(i + 1) | ||
| } | ||
| const offsetToLoc = (offset) => { | ||
| let lo = 0, hi = lineOffsets.length - 1 | ||
| while (lo < hi) { | ||
| const mid = (lo + hi + 1) >> 1 | ||
| if (lineOffsets[mid] <= offset) lo = mid; else hi = mid - 1 | ||
| } | ||
| return { line: lo + 1, column: offset - lineOffsets[lo] } | ||
| } | ||
|
|
||
| compiler.traverse(node, '*', (node) => { | ||
| if ('start' in node && !node.loc) { | ||
| node.loc = { start: offsetToLoc(node.start), end: offsetToLoc(node.end) } | ||
| } | ||
| }) | ||
| } | ||
|
|
||
| module.exports = { | ||
| parse: (...args) => compiler.parse(...args), | ||
| generate: (...args) => compiler.generate(...args), | ||
| traverse: (...args) => compiler.traverse(...args), | ||
| query: (...args) => compiler.query(...args), | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| 'use strict' | ||
|
|
||
| const { InstrumentationMatcher } = require('./matcher') | ||
|
|
||
| function create (configs, dc_module) { | ||
| return new InstrumentationMatcher(configs, dc_module) | ||
| } | ||
|
|
||
| module.exports = { create } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| 'use strict' | ||
|
|
||
| const semifies = require('semifies') | ||
| const { Transformer } = require('./transformer') | ||
|
|
||
| class InstrumentationMatcher { | ||
| #configs = [] | ||
| #dc_module = null | ||
| #transformers = {} | ||
| #customTransforms = {} | ||
|
|
||
| constructor (configs, dc_module) { | ||
| this.#configs = configs | ||
| this.#dc_module = dc_module || 'diagnostics_channel' | ||
| } | ||
|
|
||
| free () { | ||
| this.#transformers = {} | ||
| } | ||
|
|
||
| addTransform (name, fn) { | ||
| this.#customTransforms[name] = fn | ||
| } | ||
|
|
||
| getTransformer (module_name, version, file_path) { | ||
| file_path = file_path.replace(/\\/g, '/') | ||
|
|
||
| const id = `${module_name}/${file_path}@${version}` | ||
|
|
||
| if (this.#transformers[id]) return this.#transformers[id] | ||
|
|
||
| const configs = this.#configs.filter(({ module: { name, filePath, versionRange } }) => | ||
| name === module_name && | ||
| filePath === file_path && | ||
| semifies(version, versionRange) | ||
| ) | ||
|
|
||
| if (configs.length === 0) return | ||
|
|
||
| this.#transformers[id] = new Transformer( | ||
| module_name, | ||
| version, | ||
| file_path, | ||
| configs, | ||
| this.#dc_module, | ||
| this.#customTransforms | ||
| ) | ||
|
|
||
| return this.#transformers[id] | ||
| } | ||
| } | ||
|
|
||
| module.exports = { InstrumentationMatcher } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.