Skip to content
This repository has been archived by the owner on Aug 4, 2021. It is now read-only.

Commit

Permalink
Add extractAssignedNames (#59)
Browse files Browse the repository at this point in the history
  • Loading branch information
lukastaegert committed Apr 4, 2019
1 parent 21d199b commit 18e4fa5
Show file tree
Hide file tree
Showing 6 changed files with 344 additions and 52 deletions.
33 changes: 28 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,12 @@ See [rollup-plugin-inject](https://github.com/rollup/rollup-plugin-inject) or [r

```js
import { attachScopes } from 'rollup-pluginutils';
import { parse } from 'acorn';
import { walk } from 'estree-walker';

export default function myPlugin ( options = {} ) {
return {
transform ( code ) {
const ast = parse( code, {
ecmaVersion: 6,
sourceType: 'module'
});
const ast = this.parse( code );

let scope = attachScopes( ast, 'scope' );

Expand Down Expand Up @@ -128,6 +124,33 @@ Outputs the string ES module source:
*/
```

### extractAssignedNames

Extract the names of all assignment targets from patterns.

```js
import { extractAssignedNames } from 'rollup-pluginutils';
import { walk } from 'estree-walker';

export default function myPlugin ( options = {} ) {
return {
transform ( code ) {
const ast = this.parse( code );

walk( ast, {
enter ( node ) {
if ( node.type === 'VariableDeclarator' ) {
const declaredNames = extractAssignedNames(node.id);
// do something with the declared names
// e.g. for `const {x, y: z} = ... => declaredNames = ['x', 'z']
}
}
});
}
};
}
```


## License

Expand Down
50 changes: 3 additions & 47 deletions src/attachScopes.ts
Original file line number Diff line number Diff line change
@@ -1,56 +1,12 @@
import { Node, walk } from 'estree-walker';
import extractAssignedNames from './extractAssignedNames';
import { AttachedScope, AttachScopes } from './pluginutils';

const blockDeclarations = {
const: true,
let: true
};

interface Extractors {
[key: string]: (names: Array<string>, param: Node) => void;
}

const extractors: Extractors = {
Literal(names: Array<string>, param: Node) {
names.push(param.value as string);
},

Identifier(names: Array<string>, param: Node) {
names.push(param.name);
},

ObjectPattern(names: Array<string>, param: Node) {
param.properties.forEach((prop: Node) => {
if (prop.type === 'RestElement') {
extractors.RestElement(names, prop);
} else {
extractors[(prop.value || prop.key).type](names, prop.value || prop.key);
}
});
},

ArrayPattern(names: Array<string>, param: Node) {
param.elements.forEach((element: Node) => {
if (element) extractors[element.type](names, element);
});
},

RestElement(names: Array<string>, param: Node) {
extractors[param.argument.type](names, param.argument);
},

AssignmentPattern(names: Array<string>, param: Node) {
return extractors[param.left.type](names, param.left);
}
};

function extractNames(param: Node): Array<string> {
const names: Array<string> = [];

extractors[param.type](names, param);
return names;
}

interface ScopeOptions {
parent?: AttachedScope;
block?: boolean;
Expand All @@ -70,7 +26,7 @@ class Scope implements AttachedScope {

if (options.params) {
options.params.forEach(param => {
extractNames(param).forEach(name => {
extractAssignedNames(param).forEach(name => {
this.declarations[name] = true;
});
});
Expand All @@ -83,7 +39,7 @@ class Scope implements AttachedScope {
// is a block scope, so we need to go up
this.parent!.addDeclaration(node, isBlockDeclaration, isVar);
} else if (node.id) {
extractNames(node.id).forEach(name => {
extractAssignedNames(node.id).forEach(name => {
this.declarations[name] = true;
});
}
Expand Down
46 changes: 46 additions & 0 deletions src/extractAssignedNames.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { Node } from 'estree-walker';

interface Extractors {
[key: string]: (names: Array<string>, param: Node) => void;
}

const extractors: Extractors = {
ArrayPattern(names: Array<string>, param: Node) {
for (const element of param.elements) {
if (element) extractors[element.type](names, element);
}
},

AssignmentPattern(names: Array<string>, param: Node) {
extractors[param.left.type](names, param.left);
},

Identifier(names: Array<string>, param: Node) {
names.push(param.name);
},

MemberExpression() {},

ObjectPattern(names: Array<string>, param: Node) {
for (const prop of param.properties) {
if (prop.type === 'RestElement') {
extractors.RestElement(names, prop);
} else {
extractors[prop.value.type](names, prop.value);
}
}
},

RestElement(names: Array<string>, param: Node) {
extractors[param.argument.type](names, param.argument);
}
};

const extractAssignedNames = function extractAssignedNames(param: Node): Array<string> {
const names: Array<string> = [];

extractors[param.type](names, param);
return names;
};

export { extractAssignedNames as default };
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export { default as attachScopes } from './attachScopes';
export { default as createFilter } from './createFilter';
export { default as makeLegalIdentifier } from './makeLegalIdentifier';
export { default as dataToEsm } from './dataToEsm';
export { default as extractAssignedNames } from './extractAssignedNames';
3 changes: 3 additions & 0 deletions src/pluginutils.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,6 @@ export const makeLegalIdentifier: MakeLegalIdentifier;

export type DataToEsm = (data: any, options?: DataToEsmOptions) => string;
export const dataToEsm: DataToEsm;

export type ExtractAssignedNames = (param: Node) => Array<string>;
export const extractAssignedNames: ExtractAssignedNames;

0 comments on commit 18e4fa5

Please sign in to comment.