GithubHelp home page GithubHelp logo

isabella232 / flast Goto Github PK

View Code? Open in Web Editor NEW

This project forked from perimeterx/flast

0.0 0.0 0.0 142 KB

Provides a flat Abstract Syntax Tree and an Arborist to trim and modify the tree

License: MIT License

Shell 0.33% JavaScript 99.67%

flast's Introduction

flAST - FLat Abstract Syntax Tree

Flatten an Abstract Syntax Tree by placing all of the nodes in a single flat array.

Features

  • Keeps all relations between parent and child nodes.
  • Tracks scope and connects each declaration to its references.
    See eslint-scope for more info on the scopes used.
  • Adds a unique id to each node to simplify tracking and understanding relations between nodes.
  • Arborist - marks nodes for replacement or deletion and applies all changes in a single iteration over the tree.

Installation

npm install flast

Expected Data Structure

Example of how a flat AST would look like.

Input code: console.log('flAST');. Output object:

const tree = [
	{
		type: 'program',
		start: 0,
		end: 21,
		range: [0, 21],
		body: [
			'<ref to nodeId#2>'
		],
		sourceType: 'script',
		comments: [],
		nodeId: 0,
		src: "console.log('flAST');",
		childNodes: [
			'<ref to nodeId#1>'
		],
		parentNode: null,
		scope: '<GlobalScope scopeId#0>'
	},
	{
		type: 'ExpressionStatement',
		start: 0,
		end: 21,
		range: [0, 21],
		expression: '<ref to nodeId#2>',
		nodeId: 1,
		src: "console.log('flAST');",
		childNodes: [
			'<ref to nodeId#2>'
		],
		parentNode: '<ref to nodeId#0>',
		scope: '<GlobalScope scopeId#0>'
	},
	{
		type: 'CallExpression',
		start: 0,
		end: 20,
		range: [0, 20],
		callee: '<ref to nodeId#3>',
		arguments: [
			'<ref to nodeId#6>'
		],
		optional: false,
		nodeId: 2,
		src: "console.log('flAST')",
		childNodes: [
			'<ref to nodeId#3>',
			'<ref to nodeId#6>'
		],
		parentNode: '<ref to nodeId#1>',
		scope: '<GlobalScope scopeId#0>'
	},
	{
		type: 'MemberExpression',
		start: 0,
		end: 11,
		range: [0, 11],
		object: '<ref to nodeId#4>',
		property: '<ref to nodeId#5>',
		computed: false,
		optional: false,
		nodeId: 3,
		src: 'console.log',
		childNodes: [
			'<ref to nodeId#4>',
			'<ref to nodeId#5>'
		],
		parentNode: '<ref to nodeId#2>',
		scope: '<GlobalScope scopeId#0>'
	},
	{
		type: 'Identifier',
		start: 0,
		end: 7,
		range: [0, 7],
		name: 'console',
		nodeId: 4,
		src: 'console',
		childNodes: [],
		parentNode: '<ref to nodeId#3>',
		scope: '<GlobalScope scopeId#0>'
	},
	{
		type: 'Identifier',
		start: 8,
		end: 11,
		range: [8, 11],
		name: 'log',
		nodeId: 5,
		src: 'log',
		childNodes: [],
		parentNode: '<ref to nodeId#3>',
		scope: '<GlobalScope scopeId#0>'
	},
	{
		type: 'Literal',
		start: 12,
		end: 19,
		range: [12, 19],
		value: "flAST",
		raw: "'flAST'",
		nodeId: 6,
		src: "'flAST'",
		childNodes: [],
		parentNode: '<ref to nodeId#2>',
		scope: '<GlobalScope scopeId#0>'
	}
];

Usage

flAST

const {generateFlatAST, generateCode} = require('flast');
const ast = generateFlatAST(`console.log('flAST')`);
const reconstructedCode = generateCode(ast[0]); // rebuild from root node

generateFlatAST Options

const generateFlatASTDefaultOptions = {
	detailed: true,   // If false, include only original node without any further details
	includeSrc: true, // If false, do not include node src. Only available when `detailed` option is true
};

generateCode Options

See Espree's documentation for more information

const generateCodeDefaultOptions = {
	format: {
		indent: {
			style: '  ',
			adjustMultilineComment: true,
		},
		quotes: 'auto',
		escapeless: true,
		compact: false,
	},
	comment: true,
};

Arborist

const {generateFlatAST, generateCode, Arborist} = require('flast');
const ast = generateFlatAST(`console.log('Hello' + ' ' + 'there!');`);
const replacements = {
  'Hello': 'General',
  'there!': 'Kenobi',
};
const arborist = new Arborist(ast);
// Mark all relevant nodes for replacement.
ast.filter(n => n.type === 'Literal' && replacements[n.value]).forEach(n => arborist.markNode(n, {
  type: 'Literal',
  value: replacements[n.value],
  raw: `'${replacements[n.value]}'`,
}));
const numberOfChangesMade = arborist.applyChanges();
console.log(generateCode(arborist.ast[0]));  // console.log('General' + ' ' + 'Kenobi');

The Arborist can be called with an extra argument - logFunc - which can be used to log inside the arborist.

Contribution

To contribute to this project see our contribution guide

Changes

v1.2.1

  • Overhaul scoping to account for declarations with the same name in different scopes.

v1.1.1

  • Improve getParentKey to include parsing the name of grouped nodes such as 'arguments' or 'body'.

v1.1.0

  • Added parentKey property.
  • Improved ASTNode definition (useful for intellisense).
  • Ability to pass options directly to the espree parser.

flast's People

Contributors

benbaryopx avatar benjamingr avatar ctrl-escp avatar extremecoders-re avatar naorpeled avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.