Comparing version
@@ -435,2 +435,13 @@ 'use strict'; | ||
/** | ||
* True if Element is a code Token. | ||
* | ||
* @returns {Boolean} | ||
*/ | ||
}, { | ||
key: 'isCode', | ||
get: function get() { | ||
return true; | ||
} | ||
/** | ||
* True if Element is a comment Token. | ||
@@ -622,3 +633,3 @@ * | ||
var token = this.nextToken; | ||
while (token && (token.isWhitespace || token.isComment)) { | ||
while (token && !token.isCode) { | ||
token = token.nextToken; | ||
@@ -638,3 +649,3 @@ } | ||
var token = this.previousToken; | ||
while (token && (token.isWhitespace || token.isComment)) { | ||
while (token && !token.isCode) { | ||
token = token.previousToken; | ||
@@ -641,0 +652,0 @@ } |
@@ -473,6 +473,5 @@ /** | ||
var isWhitespace = _ref12.isWhitespace; | ||
var isComment = _ref12.isComment; | ||
var isCode = _ref12.isCode; | ||
if (!isWhitespace && !isComment) { | ||
if (isCode !== false) { | ||
break; | ||
@@ -493,6 +492,5 @@ } | ||
var isWhitespace = _ref13.isWhitespace; | ||
var isComment = _ref13.isComment; | ||
var isCode = _ref13.isCode; | ||
if (!isWhitespace && !isComment) { | ||
if (isCode !== false) { | ||
break; | ||
@@ -499,0 +497,0 @@ } |
@@ -68,12 +68,21 @@ 'use strict'; | ||
var isWhitespace = false; | ||
var isCode = true; | ||
switch (type) { | ||
case 'CommentLine': | ||
isComment = true; | ||
isCode = false; | ||
break; | ||
case 'CommentBlock': | ||
isComment = true; | ||
isCode = false; | ||
break; | ||
case 'Whitespace': | ||
isWhitespace = true; | ||
isCode = false; | ||
break; | ||
case 'AppleInstrumentationDirective': | ||
case 'GritDirective': | ||
case 'Hashbang': | ||
isCode = false; | ||
break; | ||
} | ||
@@ -86,2 +95,3 @@ this._value = value; | ||
this._isWhitespace = isWhitespace; | ||
this._isCode = isCode; | ||
} | ||
@@ -130,2 +140,7 @@ | ||
}, { | ||
key: 'isCode', | ||
get: function get() { | ||
return this._isCode; | ||
} | ||
}, { | ||
key: 'isWhitespace', | ||
@@ -132,0 +147,0 @@ get: function get() { |
@@ -1,3 +0,1 @@ | ||
/* jshint ignore:start */ | ||
'use strict'; | ||
@@ -4,0 +2,0 @@ |
@@ -41,2 +41,6 @@ 'use strict'; | ||
value: function _acceptChildren(children) { | ||
if (children.isToken('Hashbang')) { | ||
children.passToken(); | ||
} | ||
children.skipNonCode(); | ||
@@ -43,0 +47,0 @@ |
@@ -13,2 +13,6 @@ 'use strict'; | ||
var _visitorKeys = require('./visitorKeys'); | ||
var _visitorKeys2 = _interopRequireDefault(_visitorKeys); | ||
var _elementsElementIndex = require('./elements/elementIndex'); | ||
@@ -26,89 +30,2 @@ | ||
var visitorKeys = { | ||
/* jscs: disable */ | ||
// -- Implement later | ||
// I Implemented | ||
// T Tested | ||
/*IT*/AssignmentExpression: ['left', 'right'], | ||
/*IT*/AssignmentPattern: ['left', 'right'], | ||
/*IT*/ArrayExpression: ['elements'], | ||
/*IT*/ArrayPattern: ['elements'], | ||
/*IT*/ArrowFunctionExpression: ['params', 'body'], | ||
/*IT*/AwaitExpression: ['argument'], | ||
/*IT*/BlockStatement: ['body'], | ||
/*IT*/BinaryExpression: ['left', 'right'], | ||
/*IT*/BreakStatement: ['label'], | ||
/*IT*/CallExpression: ['callee', 'arguments'], | ||
/*IT*/CatchClause: ['param', 'body'], | ||
/*IT*/ClassBody: ['body'], | ||
/*IT*/ClassDeclaration: ['id', 'superClass', 'body'], | ||
/*IT*/ClassExpression: ['id', 'superClass', 'body'], | ||
/*IT*/ConditionalExpression: ['test', 'consequent', 'alternate'], | ||
/*IT*/ContinueStatement: ['label'], | ||
/*IT*/DebuggerStatement: [], | ||
/*IT*/DoWhileStatement: ['body', 'test'], | ||
/*IT*/EmptyStatement: [], | ||
/*IT*/ExportAllDeclaration: ['source'], | ||
/*IT*/ExportDefaultDeclaration: ['declaration'], | ||
/*IT*/ExportNamedDeclaration: ['declaration', 'specifiers', 'source'], | ||
/*IT*/ExportSpecifier: ['exported', 'local'], | ||
/*IT*/ExpressionStatement: ['expression'], | ||
/*IT*/ForStatement: ['init', 'test', 'update', 'body'], | ||
/*IT*/ForInStatement: ['left', 'right', 'body'], | ||
/*IT*/ForOfStatement: ['left', 'right', 'body'], | ||
/*IT*/FunctionDeclaration: ['id', 'params', 'body'], | ||
/*IT*/FunctionExpression: ['id', 'params', 'body'], | ||
/*IT*/Identifier: [], | ||
/*IT*/IfStatement: ['test', 'consequent', 'alternate'], | ||
/*IT*/ImportDeclaration: ['specifiers', 'source'], | ||
/*IT*/ImportDefaultSpecifier: ['local'], | ||
/*IT*/ImportNamespaceSpecifier: ['local'], | ||
/*IT*/ImportSpecifier: ['imported', 'local'], | ||
/*IT*/LabeledStatement: ['label', 'body'], | ||
/*IT*/Literal: [], | ||
/*IT*/LogicalExpression: ['left', 'right'], | ||
/*IT*/MemberExpression: ['object', 'property'], | ||
/*IT*/MetaProperty: ['meta', 'property'], | ||
/*IT*/MethodDefinition: ['key', 'value'], | ||
/*IT*/ModuleDeclaration: [], | ||
/*IT*/ModuleSpecifier: ['local'], | ||
/*IT*/NewExpression: ['callee', 'arguments'], | ||
/*IT*/ObjectExpression: ['properties'], | ||
/*IT*/ObjectPattern: ['properties'], | ||
/*IT*/Program: ['body'], | ||
/*IT*/Property: ['key', 'value'], | ||
/*IT*/RestElement: ['argument'], | ||
/*IT*/ReturnStatement: ['argument'], | ||
/*IT*/SequenceExpression: ['expressions'], | ||
/*IT*/SpreadElement: ['argument'], | ||
/*IT*/SpreadProperty: ['argument'], | ||
/*IT*/Super: [], | ||
/*IT*/SwitchStatement: ['discriminant', 'cases'], | ||
/*IT*/SwitchCase: ['test', 'consequent'], | ||
/*IT*/TaggedTemplateExpression: ['tag', 'quasi'], | ||
/*IT*/TemplateElement: [], | ||
/*IT*/TemplateLiteral: ['quasis', 'expressions'], | ||
/*IT*/ThisExpression: [], | ||
/*IT*/ThrowStatement: ['argument'], | ||
/*IT*/TryStatement: ['block', 'handler', 'finalizer'], | ||
/*IT*/UnaryExpression: ['argument'], | ||
/*IT*/UpdateExpression: ['argument'], | ||
/*IT*/VariableDeclaration: ['declarations'], | ||
/*IT*/VariableDeclarator: ['id', 'init'], | ||
/*IT*/WhileStatement: ['test', 'body'], | ||
/*IT*/WithStatement: ['object', 'body'], | ||
/*IT*/YieldExpression: ['argument'], | ||
/*IT*/JSXIdentifier: [], | ||
/*IT*/JSXNamespacedName: ['namespace', 'name'], | ||
/*IT*/JSXMemberExpression: ['object', 'property'], | ||
/*IT*/JSXEmptyExpression: [], | ||
/*IT*/JSXExpressionContainer: ['expression'], | ||
/*IT*/JSXElement: ['openingElement', 'closingElement', 'children'], | ||
/*IT*/JSXClosingElement: ['name'], | ||
/*IT*/JSXOpeningElement: ['name', 'attributes'], | ||
/*IT*/JSXAttribute: ['name', 'value'], | ||
/*IT*/JSXSpreadAttribute: ['argument'] | ||
/* jscs: enable */ | ||
}; | ||
/** | ||
@@ -140,3 +57,3 @@ * Creates CST using AST and token list. | ||
var elementType = ast.type; | ||
var childProps = visitorKeys[elementType]; | ||
var childProps = _visitorKeys2['default'][elementType]; | ||
@@ -143,0 +60,0 @@ if (!childProps) { |
@@ -7,2 +7,4 @@ 'use strict'; | ||
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; | ||
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })(); | ||
@@ -16,25 +18,111 @@ | ||
/** | ||
* @typedef {Object} CSTParserOptions | ||
* @property {String} sourceType Type of parsed code: "module" or "script". | ||
* @property {Boolean} strictMode | ||
* @property {Boolean} allowHashBang | ||
* @property {Number} ecmaVersion | ||
* @property {CSTParserExperimentalFeatureOptions} experimentalFeatures | ||
* @property {CSTParserLanguageExtensionsOptions} languageExtensions | ||
*/ | ||
/** | ||
* @typedef {Object} CSTParserLanguageExtensionsOptions | ||
* @property {Boolean} jsx | ||
* @property {Boolean} flow | ||
*/ | ||
/** | ||
* @typedef {Object} CSTParserExperimentalFeatureOptions | ||
* @property {Boolean} 'es7.asyncFunctions' | ||
* @property {Boolean} 'es7.classProperties' | ||
* @property {Boolean} 'es7.comprehensions' | ||
* @property {Boolean} 'es7.decorators' | ||
* @property {Boolean} 'es7.doExpressions' | ||
* @property {Boolean} 'es7.exponentiationOperator' | ||
* @property {Boolean} 'es7.exportExtensions' | ||
* @property {Boolean} 'es7.functionBind' | ||
* @property {Boolean} 'es7.objectRestSpread' | ||
* @property {Boolean} 'es7.trailingFunctionCommas' | ||
*/ | ||
// https://developer.apple.com/library/watchos/documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/UIAutomation.html | ||
var DIRECTIVE_APPLE_INSTRUMENTATION = { | ||
type: 'AppleInstrumentationDirective', | ||
regexp: /^#([^\n]+)/gm | ||
}; | ||
// https://www.chromium.org/developers/web-development-style-guide | ||
var DIRECTIVE_GRIT = { | ||
type: 'GritDirective', | ||
regexp: /^\s*<(\/?\s*(?:if|include)(?!\w)[^]*?)>/gim | ||
}; | ||
/** | ||
* CST Parser. | ||
*/ | ||
var Parser = (function () { | ||
function Parser() { | ||
/** | ||
* @param {CSTParserOptions} options | ||
*/ | ||
function Parser(options) { | ||
_classCallCheck(this, Parser); | ||
this._strictModeEnabled = true; | ||
this._options = { | ||
sourceType: 'module', | ||
strictMode: true, | ||
allowHashBang: true, | ||
ecmaVersion: Infinity, | ||
experimentalFeatures: { | ||
'es7.asyncFunctions': true, | ||
'es7.classProperties': true, | ||
'es7.comprehensions': true, | ||
'es7.decorators': true, | ||
'es7.doExpressions': true, | ||
'es7.exponentiationOperator': true, | ||
'es7.exportExtensions': true, | ||
'es7.functionBind': true, | ||
'es7.objectRestSpread': true, | ||
'es7.trailingFunctionCommas': true | ||
}, | ||
languageExtensions: { | ||
jsx: true, | ||
flow: true | ||
} | ||
}; | ||
if (options) { | ||
this.setOptions(options); | ||
} | ||
} | ||
/** | ||
* @returns {CSTParserOptions} | ||
*/ | ||
_createClass(Parser, [{ | ||
key: 'isStrictModeEnabled', | ||
value: function isStrictModeEnabled() { | ||
return this._strictModeEnabled; | ||
key: 'getOptions', | ||
value: function getOptions() { | ||
return this._options; | ||
} | ||
/** | ||
* @param {CSTParserOptions} newOptions | ||
*/ | ||
}, { | ||
key: 'enableStrictMode', | ||
value: function enableStrictMode() { | ||
this._strictModeEnabled = true; | ||
key: 'setOptions', | ||
value: function setOptions(newOptions) { | ||
var currentOptions = this._options; | ||
var currentExperimentalFeatures = currentOptions.experimentalFeatures; | ||
var currentLanguageExtensions = currentOptions.languageExtensions; | ||
var newExperimentalFeatures = newOptions.experimentalFeatures; | ||
var newLanguageExtensions = newOptions.languageExtensions; | ||
this._options = _extends({}, currentOptions, newOptions, { | ||
experimentalFeatures: _extends({}, currentExperimentalFeatures, newExperimentalFeatures), | ||
languageExtensions: _extends({}, currentLanguageExtensions, newLanguageExtensions) | ||
}); | ||
} | ||
}, { | ||
key: 'disableStrictMode', | ||
value: function disableStrictMode() { | ||
this._strictModeEnabled = false; | ||
} | ||
}, { | ||
key: 'parse', | ||
@@ -49,28 +137,105 @@ value: function parse(code) { | ||
value: function _parseAst(code) { | ||
var opts = { | ||
sourceType: 'module', | ||
strictMode: this._strictModeEnabled, | ||
ecmaVersion: Infinity, | ||
allowHashBang: true, | ||
// generate with | ||
// $ node -p "Object.keys(require('babel-core/lib/transformation').pipeline.transformers) | ||
// .filter(/^$/.test.bind(/^es([7-9]|[0-9]{2,})./)) | ||
// .sort().reduce(function(o, k) { o[k] = true; return o; }, {})" | ||
features: { | ||
'es7.asyncFunctions': true, | ||
'es7.classProperties': true, | ||
'es7.comprehensions': true, | ||
'es7.decorators': true, | ||
'es7.doExpressions': true, | ||
'es7.exponentiationOperator': true, | ||
'es7.exportExtensions': true, | ||
'es7.functionBind': true, | ||
'es7.objectRestSpread': true, | ||
'es7.trailingFunctionCommas': true | ||
}, | ||
plugins: { jsx: true, flow: true } | ||
}; | ||
var ast = (0, _babylon.parse)(code, opts); | ||
var options = this._options; | ||
var languageExtensions = options.languageExtensions; | ||
var directiveInstances = {}; | ||
var hasDirectives = false; | ||
var directiveTypes = []; | ||
if (languageExtensions.appleInstrumentationDirectives) { | ||
directiveTypes.push(DIRECTIVE_APPLE_INSTRUMENTATION); | ||
} | ||
if (languageExtensions.gritDirectives) { | ||
directiveTypes.push(DIRECTIVE_GRIT); | ||
} | ||
var _iteratorNormalCompletion = true; | ||
var _didIteratorError = false; | ||
var _iteratorError = undefined; | ||
try { | ||
var _loop = function () { | ||
var directive = _step.value; | ||
code = code.replace(directive.regexp, function (str, value, pos) { | ||
hasDirectives = true; | ||
directiveInstances[pos] = { | ||
type: directive.type, value: value | ||
}; | ||
// Cut 4 characters to save correct line/column info for surrounding code | ||
return '/*' + str.slice(4) + '*/'; | ||
}); | ||
}; | ||
for (var _iterator = directiveTypes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { | ||
_loop(); | ||
} | ||
} catch (err) { | ||
_didIteratorError = true; | ||
_iteratorError = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion && _iterator['return']) { | ||
_iterator['return'](); | ||
} | ||
} finally { | ||
if (_didIteratorError) { | ||
throw _iteratorError; | ||
} | ||
} | ||
} | ||
var ast = (0, _babylon.parse)(code, { | ||
sourceType: options.sourceType, | ||
strictMode: options.strictMode, | ||
ecmaVersion: options.ecmaVersion, | ||
allowHashBang: options.allowHashBang, | ||
features: options.experimentalFeatures, | ||
plugins: { | ||
jsx: languageExtensions.jsx, | ||
flow: languageExtensions.flow | ||
} | ||
}); | ||
var program = ast.program; | ||
program.tokens = ast.tokens; | ||
if (hasDirectives) { | ||
var _iteratorNormalCompletion2 = true; | ||
var _didIteratorError2 = false; | ||
var _iteratorError2 = undefined; | ||
try { | ||
for (var _iterator2 = program.tokens[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { | ||
var token = _step2.value; | ||
var directiveInstance = directiveInstances[token.start]; | ||
if (directiveInstances[token.start]) { | ||
token.type = directiveInstance.type; | ||
token.value = directiveInstance.value; | ||
} | ||
} | ||
} catch (err) { | ||
_didIteratorError2 = true; | ||
_iteratorError2 = err; | ||
} finally { | ||
try { | ||
if (!_iteratorNormalCompletion2 && _iterator2['return']) { | ||
_iterator2['return'](); | ||
} | ||
} finally { | ||
if (_didIteratorError2) { | ||
throw _iteratorError2; | ||
} | ||
} | ||
} | ||
} | ||
if (options.allowHashBang) { | ||
if (code.substr(0, 2) === '#!') { | ||
program.tokens[0].type = 'Hashbang'; | ||
} | ||
} | ||
return program; | ||
@@ -77,0 +242,0 @@ } |
{ | ||
"name": "cst", | ||
"version": "0.0.12", | ||
"version": "0.0.13", | ||
"description": "JavaScript CST Implementation", | ||
@@ -19,5 +19,4 @@ "author": "Marat Dulin", | ||
"test:benchmark": "babel-node test/benchmarks/benchmarks.js", | ||
"lint": "npm run lint:jscs && npm run lint:jshint", | ||
"lint": "npm run lint:jscs", | ||
"lint:jscs": "jscs src test", | ||
"lint:jshint": "jshint src test", | ||
"build": "babel src -d lib", | ||
@@ -29,3 +28,3 @@ "precommit": "npm test", | ||
"devDependencies": { | ||
"babel": "5.8.23", | ||
"babel": "5.8.29", | ||
"benchmark": "^1.0.0", | ||
@@ -38,8 +37,7 @@ "chai": "^3.0.0", | ||
"jscs-jsdoc": "^1.1.0", | ||
"jshint": "^2.8.0", | ||
"mocha": "^2.2.5" | ||
}, | ||
"dependencies": { | ||
"babylon": "^5.8.23" | ||
"babylon": "^5.8.29" | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
448691
3.32%9
-10%112
0.9%6931
2.53%Updated