[Pkg-javascript-commits] [node-is-reference] 01/02: New upstream version 1.0.0

Julien Puydt julien.puydt at laposte.net
Mon Jul 3 16:55:29 UTC 2017


This is an automated email from the git hooks/post-receive script.

jpuydt-guest pushed a commit to branch master
in repository node-is-reference.

commit 069ae3d9a7f5573a2da8b1841ab8919184ff4159
Author: Julien Puydt <julien.puydt at laposte.net>
Date:   Mon Jul 3 18:34:33 2017 +0200

    New upstream version 1.0.0
---
 .eslintrc.json   | 39 ++++++++++++++++++++++++++++
 .gitignore       |  2 ++
 CHANGELOG.md     |  5 ++++
 README.md        | 61 +++++++++++++++++++++++++++++++++++++++++++
 index.js         | 38 +++++++++++++++++++++++++++
 module.js        | 28 ++++++++++++++++++++
 package.json     | 41 +++++++++++++++++++++++++++++
 rollup.config.js |  6 +++++
 test/test.js     | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 9 files changed, 299 insertions(+)

diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 0000000..6b09cd6
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,39 @@
+{
+    "root": true,
+    "rules": {
+        "indent": [ 2, "tab", { "SwitchCase": 1 } ],
+        "semi": [ 2, "always" ],
+        "keyword-spacing": [ 2, { "before": true, "after": true } ],
+        "space-before-blocks": [ 2, "always" ],
+        "space-before-function-paren": [ 2, "always" ],
+        "no-mixed-spaces-and-tabs": [ 2, "smart-tabs" ],
+        "no-cond-assign": 0,
+        "no-unused-vars": 2,
+        "object-shorthand":  [ 2, "always" ],
+        "no-const-assign": 2,
+        "no-class-assign": 2,
+        "no-this-before-super": 2,
+        "no-var": 2,
+        "no-unreachable": 2,
+        "valid-typeof": 2,
+        "quote-props": [ 2, "as-needed" ],
+        "one-var": [ 2, "never" ],
+        "prefer-arrow-callback": 2,
+        "prefer-const": [ 2, { "destructuring": "all" } ],
+        "arrow-spacing": 2,
+        "no-inner-declarations": 0
+    },
+    "env": {
+        "es6": true,
+        "browser": true,
+        "node": true,
+        "mocha": true
+    },
+    "extends": [
+        "eslint:recommended"
+    ],
+    "parserOptions": {
+        "ecmaVersion": 6,
+        "sourceType": "module"
+    }
+}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9daa824
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+.DS_Store
+node_modules
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..7461c07
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,5 @@
+# is-reference changelog
+
+## 1.0.0
+
+* First release
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..1989fca
--- /dev/null
+++ b/README.md
@@ -0,0 +1,61 @@
+# is-reference
+
+Utility for determining whether an AST node is a reference.
+
+`foo` is a reference in these cases:
+
+```js
+console.log( foo );
+var foo;
+function foo () {}
+function bar ( foo ) {}
+export { foo as x };
+```
+
+`foo` is *not* a reference in these cases:
+
+```js
+var obj = { foo: 1 };
+console.log( obj.foo );
+export { x as foo };
+```
+
+In all cases, `foo` is an `Identifier` node, but the two kinds must be treated differently for the purposes of scope analysis etc. (The examples are non-exhaustive.)
+
+
+## Installation
+
+```bash
+npm install is-reference
+```
+
+
+## Usage
+
+Example using [Acorn](https://github.com/ternjs/acorn) and [estree-walker](https://github.com/Rich-Harris/estree-walker):
+
+```js
+const { parse } = require( 'acorn' );
+const { walk } = require( 'estree-walker' );
+const isReference = require( 'is-reference' );
+
+const identifiers = [];
+const references = [];
+
+const ast = parse( `var a = b.c;` );
+
+walk( ast, {
+	enter ( node, parent ) {
+		if ( node.type === 'Identifier' ) identifiers.push( node );
+		if ( isReference( node, parent ) ) references.push( node );
+	}
+});
+
+identifiers.forEach( node => console.log( node.name ) ); // a, b, c
+references.forEach( node => console.log( node.name ) ); // a, b
+```
+
+
+## License
+
+MIT
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..f143a39
--- /dev/null
+++ b/index.js
@@ -0,0 +1,38 @@
+(function (global, factory) {
+	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+	typeof define === 'function' && define.amd ? define(factory) :
+	(global.isReference = factory());
+}(this, (function () { 'use strict';
+
+function isReference ( node, parent ) {
+	if ( node.type === 'MemberExpression' ) {
+		return !node.computed && isReference( node.object, node );
+	}
+
+	if ( node.type === 'Identifier' ) {
+		// the only time we could have an identifier node without a parent is
+		// if it's the entire body of a function without a block statement –
+		// i.e. an arrow function expression like `a => a`
+		if ( !parent ) return true;
+
+		// TODO is this right?
+		if ( parent.type === 'MemberExpression' || parent.type === 'MethodDefinition' ) {
+			return parent.computed || node === parent.object;
+		}
+
+		// disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
+		if ( parent.type === 'Property' ) return parent.computed || node === parent.value;
+
+		// disregard the `bar` in `class Foo { bar () {...} }`
+		if ( parent.type === 'MethodDefinition' ) return false;
+
+		// disregard the `bar` in `export { foo as bar }`
+		if ( parent.type === 'ExportSpecifier' && node !== parent.local ) return;
+
+		return true;
+	}
+}
+
+return isReference;
+
+})));
diff --git a/module.js b/module.js
new file mode 100644
index 0000000..c2e6c89
--- /dev/null
+++ b/module.js
@@ -0,0 +1,28 @@
+export default function isReference ( node, parent ) {
+	if ( node.type === 'MemberExpression' ) {
+		return !node.computed && isReference( node.object, node );
+	}
+
+	if ( node.type === 'Identifier' ) {
+		// the only time we could have an identifier node without a parent is
+		// if it's the entire body of a function without a block statement –
+		// i.e. an arrow function expression like `a => a`
+		if ( !parent ) return true;
+
+		// TODO is this right?
+		if ( parent.type === 'MemberExpression' || parent.type === 'MethodDefinition' ) {
+			return parent.computed || node === parent.object;
+		}
+
+		// disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
+		if ( parent.type === 'Property' ) return parent.computed || node === parent.value;
+
+		// disregard the `bar` in `class Foo { bar () {...} }`
+		if ( parent.type === 'MethodDefinition' ) return false;
+
+		// disregard the `bar` in `export { foo as bar }`
+		if ( parent.type === 'ExportSpecifier' && node !== parent.local ) return;
+
+		return true;
+	}
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..06b97ee
--- /dev/null
+++ b/package.json
@@ -0,0 +1,41 @@
+{
+  "name": "is-reference",
+  "version": "1.0.0",
+  "description": "Determine whether an AST node is a reference",
+  "main": "index.js",
+  "module": "module.js",
+  "files": [
+    "index.js",
+    "module.js"
+  ],
+  "scripts": {
+    "test": "mocha",
+    "build": "rollup -c",
+    "pretest": "npm run build",
+    "lint": "eslint module.js",
+    "prepublish": "npm run lint && npm test"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git+https://github.com/Rich-Harris/is-reference.git"
+  },
+  "keywords": [
+    "ast",
+    "javascript",
+    "estree",
+    "acorn"
+  ],
+  "author": "Rich Harris",
+  "license": "MIT",
+  "bugs": {
+    "url": "https://github.com/Rich-Harris/is-reference/issues"
+  },
+  "homepage": "https://github.com/Rich-Harris/is-reference#readme",
+  "devDependencies": {
+    "acorn": "^4.0.4",
+    "eslint": "^3.12.2",
+    "estree-walker": "^0.3.0",
+    "mocha": "^3.2.0",
+    "rollup": "^0.37.2"
+  }
+}
diff --git a/rollup.config.js b/rollup.config.js
new file mode 100644
index 0000000..0171586
--- /dev/null
+++ b/rollup.config.js
@@ -0,0 +1,6 @@
+export default {
+	entry: 'module.js',
+	dest: 'index.js',
+	format: 'umd',
+	moduleName: 'isReference'
+};
diff --git a/test/test.js b/test/test.js
new file mode 100644
index 0000000..56f749d
--- /dev/null
+++ b/test/test.js
@@ -0,0 +1,79 @@
+const assert = require( 'assert' );
+const { parse } = require( 'acorn' );
+const { walk } = require( 'estree-walker' );
+
+const isReference = require( '../' );
+
+describe( 'is-reference', () => {
+	const positive = {
+		'simple identifier': `
+			foo;`,
+
+		'variable declaration': `
+			var foo;`,
+
+		'function name': `
+			function foo () {}`,
+
+		'function parameter': `
+			function x ( foo ) {}`,
+
+		'object pattern': `
+			function x ({ foo }) {}`,
+
+		'array pattern': `
+			function x ([ foo ]) {}`,
+
+		'assignment pattern': `
+			function x ( foo = 1 ) {}`,
+
+		'assignment pattern in object pattern': `
+			function x ({ foo = 42 }) {}`
+	};
+
+	const negative = {
+		'object literal property': `
+			var obj = { foo: 1 };`,
+
+		'member expression property': `
+			obj.foo;`
+	};
+
+	describe( 'positive', () => {
+		Object.keys( positive ).forEach( name => {
+			it( name, () => {
+				const code = positive[ name ];
+				const matches = findFooReferences( code );
+
+				assert.equal( matches.size, 1 );
+			});
+		});
+	});
+
+	describe( 'negative', () => {
+		Object.keys( negative ).forEach( name => {
+			it( name, () => {
+				const code = negative[ name ];
+				const matches = findFooReferences( code );
+
+				assert.equal( matches.size, 0 );
+			});
+		});
+	});
+
+	function findFooReferences ( code ) {
+		const ast = parse( code );
+
+		const matches = new Set;
+
+		walk( ast, {
+			enter ( node, parent ) {
+				if ( isReference( node, parent ) && node.name === 'foo' ) {
+					matches.add( node );
+				}
+			}
+		});
+
+		return matches;
+	}
+});

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-is-reference.git



More information about the Pkg-javascript-commits mailing list