diff options
Diffstat (limited to '')
-rw-r--r-- | third_party/webkit/PerformanceTests/ARES-6/Babylon/inspector-blob.js | 1146 |
1 files changed, 1146 insertions, 0 deletions
diff --git a/third_party/webkit/PerformanceTests/ARES-6/Babylon/inspector-blob.js b/third_party/webkit/PerformanceTests/ARES-6/Babylon/inspector-blob.js new file mode 100644 index 0000000000..7dcfbcf34c --- /dev/null +++ b/third_party/webkit/PerformanceTests/ARES-6/Babylon/inspector-blob.js @@ -0,0 +1,1146 @@ +/* + * Copyright (C) 2014-2017 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +WebInspector.ScriptSyntaxTree = class ScriptSyntaxTree extends WebInspector.Object +{ + constructor(sourceText, script) + { + super(); + + console.assert(script && script instanceof WebInspector.Script, script); + + this._script = script; + + try { + let sourceType = this._script.sourceType === WebInspector.Script.SourceType.Module ? "module" : "script"; + let esprimaSyntaxTree = esprima.parse(sourceText, {range: true, sourceType}); + this._syntaxTree = this._createInternalSyntaxTree(esprimaSyntaxTree); + this._parsedSuccessfully = true; + } catch (error) { + this._parsedSuccessfully = false; + this._syntaxTree = null; + console.error("Couldn't parse JavaScript File: " + script.url, error); + } + } + + // Public + + get parsedSuccessfully() + { + return this._parsedSuccessfully; + } + + forEachNode(callback) + { + console.assert(this._parsedSuccessfully); + if (!this._parsedSuccessfully) + return; + + this._recurse(this._syntaxTree, callback, this._defaultParserState()); + } + + filter(predicate, startNode) + { + console.assert(startNode && this._parsedSuccessfully); + if (!this._parsedSuccessfully) + return []; + + var nodes = []; + function filter(node, state) + { + if (predicate(node)) + nodes.push(node); + else + state.skipChildNodes = true; + } + + this._recurse(startNode, filter, this._defaultParserState()); + + return nodes; + } + + containersOfOffset(offset) + { + console.assert(this._parsedSuccessfully); + if (!this._parsedSuccessfully) + return []; + + let allNodes = []; + const start = 0; + const end = 1; + + this.forEachNode((node, state) => { + if (node.range[end] < offset) + state.skipChildNodes = true; + if (node.range[start] > offset) + state.shouldStopEarly = true; + if (node.range[start] <= offset && node.range[end] >= offset) + allNodes.push(node); + }); + + return allNodes; + } + + filterByRange(startOffset, endOffset) + { + console.assert(this._parsedSuccessfully); + if (!this._parsedSuccessfully) + return []; + + var allNodes = []; + var start = 0; + var end = 1; + function filterForNodesInRange(node, state) + { + // program start range program end + // [ [ ] ] + // [ ] [ [ ] ] [ ] + + // If a node's range ends before the range we're interested in starts, we don't need to search any of its + // enclosing ranges, because, by definition, those enclosing ranges are contained within this node's range. + if (node.range[end] < startOffset) + state.skipChildNodes = true; + + // We are only interested in nodes whose start position is within our range. + if (startOffset <= node.range[start] && node.range[start] <= endOffset) + allNodes.push(node); + + // Once we see nodes that start beyond our range, we can quit traversing the AST. We can do this safely + // because we know the AST is traversed using depth first search, so it will traverse into enclosing ranges + // before it traverses into adjacent ranges. + if (node.range[start] > endOffset) + state.shouldStopEarly = true; + } + + this.forEachNode(filterForNodesInRange); + + return allNodes; + } + + containsNonEmptyReturnStatement(startNode) + { + console.assert(startNode && this._parsedSuccessfully); + if (!this._parsedSuccessfully) + return false; + + if (startNode.attachments._hasNonEmptyReturnStatement !== undefined) + return startNode.attachments._hasNonEmptyReturnStatement; + + function removeFunctionsFilter(node) + { + return node.type !== WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression + && node.type !== WebInspector.ScriptSyntaxTree.NodeType.FunctionDeclaration + && node.type !== WebInspector.ScriptSyntaxTree.NodeType.ArrowFunctionExpression; + } + + var nodes = this.filter(removeFunctionsFilter, startNode); + var hasNonEmptyReturnStatement = false; + var returnStatementType = WebInspector.ScriptSyntaxTree.NodeType.ReturnStatement; + for (var node of nodes) { + if (node.type === returnStatementType && node.argument) { + hasNonEmptyReturnStatement = true; + break; + } + } + + startNode.attachments._hasNonEmptyReturnStatement = hasNonEmptyReturnStatement; + + return hasNonEmptyReturnStatement; + } + + static functionReturnDivot(node) + { + console.assert(node.type === WebInspector.ScriptSyntaxTree.NodeType.FunctionDeclaration || node.type === WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression || node.type === WebInspector.ScriptSyntaxTree.NodeType.MethodDefinition || node.type === WebInspector.ScriptSyntaxTree.NodeType.ArrowFunctionExpression); + + // COMPATIBILITY (iOS 9): Legacy Backends view the return type as being the opening "{" of the function body. + // After iOS 9, this is to move to the start of the function statement/expression. See below: + // FIXME: Need a better way to determine backend versions. Using DOM.pseudoElement because that was added after iOS 9. + if (!DOMAgent.hasEvent("pseudoElementAdded")) + return node.body.range[0]; + + // "f" in "function". "s" in "set". "g" in "get". First letter in any method name for classes and object literals. + // The "[" for computed methods in classes and object literals. + return node.typeProfilingReturnDivot; + } + + updateTypes(nodesToUpdate, callback) + { + console.assert(RuntimeAgent.getRuntimeTypesForVariablesAtOffsets); + console.assert(Array.isArray(nodesToUpdate) && this._parsedSuccessfully); + + if (!this._parsedSuccessfully) + return; + + var allRequests = []; + var allRequestNodes = []; + var sourceID = this._script.id; + + for (var node of nodesToUpdate) { + switch (node.type) { + case WebInspector.ScriptSyntaxTree.NodeType.FunctionDeclaration: + case WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression: + case WebInspector.ScriptSyntaxTree.NodeType.ArrowFunctionExpression: + for (var param of node.params) { + for (var identifier of this._gatherIdentifiersInDeclaration(param)) { + allRequests.push({ + typeInformationDescriptor: WebInspector.ScriptSyntaxTree.TypeProfilerSearchDescriptor.NormalExpression, + sourceID, + divot: identifier.range[0] + }); + allRequestNodes.push(identifier); + } + } + + allRequests.push({ + typeInformationDescriptor: WebInspector.ScriptSyntaxTree.TypeProfilerSearchDescriptor.FunctionReturn, + sourceID, + divot: WebInspector.ScriptSyntaxTree.functionReturnDivot(node) + }); + allRequestNodes.push(node); + break; + case WebInspector.ScriptSyntaxTree.NodeType.VariableDeclarator: + for (var identifier of this._gatherIdentifiersInDeclaration(node.id)) { + allRequests.push({ + typeInformationDescriptor: WebInspector.ScriptSyntaxTree.TypeProfilerSearchDescriptor.NormalExpression, + sourceID, + divot: identifier.range[0] + }); + allRequestNodes.push(identifier); + } + break; + } + } + + console.assert(allRequests.length === allRequestNodes.length); + + function handleTypes(error, typeInformationArray) + { + if (error) + return; + + console.assert(typeInformationArray.length === allRequests.length); + + for (var i = 0; i < typeInformationArray.length; i++) { + var node = allRequestNodes[i]; + var typeInformation = WebInspector.TypeDescription.fromPayload(typeInformationArray[i]); + if (allRequests[i].typeInformationDescriptor === WebInspector.ScriptSyntaxTree.TypeProfilerSearchDescriptor.FunctionReturn) + node.attachments.returnTypes = typeInformation; + else + node.attachments.types = typeInformation; + } + + callback(allRequestNodes); + } + + this._script.target.RuntimeAgent.getRuntimeTypesForVariablesAtOffsets(allRequests, handleTypes); + } + + // Private + + _gatherIdentifiersInDeclaration(node) + { + function gatherIdentifiers(node) + { + switch (node.type) { + case WebInspector.ScriptSyntaxTree.NodeType.Identifier: + return [node]; + case WebInspector.ScriptSyntaxTree.NodeType.Property: + return gatherIdentifiers(node.value); + case WebInspector.ScriptSyntaxTree.NodeType.ObjectPattern: + var identifiers = []; + for (var property of node.properties) { + for (var identifier of gatherIdentifiers(property)) + identifiers.push(identifier); + } + return identifiers; + case WebInspector.ScriptSyntaxTree.NodeType.ArrayPattern: + var identifiers = []; + for (var element of node.elements) { + for (var identifier of gatherIdentifiers(element)) + identifiers.push(identifier); + } + return identifiers; + case WebInspector.ScriptSyntaxTree.NodeType.AssignmentPattern: + return gatherIdentifiers(node.left); + case WebInspector.ScriptSyntaxTree.NodeType.RestElement: + case WebInspector.ScriptSyntaxTree.NodeType.RestProperty: + return gatherIdentifiers(node.argument); + default: + console.assert(false, "Unexpected node type in variable declarator: " + node.type); + return []; + } + } + + console.assert(node.type === WebInspector.ScriptSyntaxTree.NodeType.Identifier || node.type === WebInspector.ScriptSyntaxTree.NodeType.ObjectPattern || node.type === WebInspector.ScriptSyntaxTree.NodeType.ArrayPattern || node.type === WebInspector.ScriptSyntaxTree.NodeType.RestElement || node.type === WebInspector.ScriptSyntaxTree.NodeType.RestProperty); + + return gatherIdentifiers(node); + } + + _defaultParserState() + { + return { + shouldStopEarly: false, + skipChildNodes: false + }; + } + + _recurse(node, callback, state) + { + if (!node) + return; + + if (state.shouldStopEarly || state.skipChildNodes) + return; + + callback(node, state); + + switch (node.type) { + case WebInspector.ScriptSyntaxTree.NodeType.AssignmentExpression: + this._recurse(node.left, callback, state); + this._recurse(node.right, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.ArrayExpression: + case WebInspector.ScriptSyntaxTree.NodeType.ArrayPattern: + this._recurseArray(node.elements, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.AssignmentPattern: + this._recurse(node.left, callback, state); + this._recurse(node.right, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.AwaitExpression: + this._recurse(node.argument, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.BlockStatement: + this._recurseArray(node.body, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.BinaryExpression: + this._recurse(node.left, callback, state); + this._recurse(node.right, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.BreakStatement: + this._recurse(node.label, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.CatchClause: + this._recurse(node.param, callback, state); + this._recurse(node.body, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.CallExpression: + this._recurse(node.callee, callback, state); + this._recurseArray(node.arguments, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.ClassBody: + this._recurseArray(node.body, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.ClassDeclaration: + case WebInspector.ScriptSyntaxTree.NodeType.ClassExpression: + this._recurse(node.id, callback, state); + this._recurse(node.superClass, callback, state); + this._recurse(node.body, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.ContinueStatement: + this._recurse(node.label, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.DoWhileStatement: + this._recurse(node.body, callback, state); + this._recurse(node.test, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.ExpressionStatement: + this._recurse(node.expression, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.ForStatement: + this._recurse(node.init, callback, state); + this._recurse(node.test, callback, state); + this._recurse(node.update, callback, state); + this._recurse(node.body, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.ForInStatement: + case WebInspector.ScriptSyntaxTree.NodeType.ForOfStatement: + this._recurse(node.left, callback, state); + this._recurse(node.right, callback, state); + this._recurse(node.body, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.FunctionDeclaration: + case WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression: + case WebInspector.ScriptSyntaxTree.NodeType.ArrowFunctionExpression: + this._recurse(node.id, callback, state); + this._recurseArray(node.params, callback, state); + this._recurse(node.body, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.IfStatement: + this._recurse(node.test, callback, state); + this._recurse(node.consequent, callback, state); + this._recurse(node.alternate, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.LabeledStatement: + this._recurse(node.label, callback, state); + this._recurse(node.body, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.LogicalExpression: + this._recurse(node.left, callback, state); + this._recurse(node.right, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.MemberExpression: + this._recurse(node.object, callback, state); + this._recurse(node.property, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.MethodDefinition: + this._recurse(node.key, callback, state); + this._recurse(node.value, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.NewExpression: + this._recurse(node.callee, callback, state); + this._recurseArray(node.arguments, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.ObjectExpression: + case WebInspector.ScriptSyntaxTree.NodeType.ObjectPattern: + this._recurseArray(node.properties, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.Program: + this._recurseArray(node.body, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.Property: + this._recurse(node.key, callback, state); + this._recurse(node.value, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.RestElement: + this._recurse(node.argument, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.RestProperty: + this._recurse(node.argument, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.ReturnStatement: + this._recurse(node.argument, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.SequenceExpression: + this._recurseArray(node.expressions, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.SpreadElement: + this._recurse(node.argument, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.SpreadProperty: + this._recurse(node.argument, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.SwitchStatement: + this._recurse(node.discriminant, callback, state); + this._recurseArray(node.cases, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.SwitchCase: + this._recurse(node.test, callback, state); + this._recurseArray(node.consequent, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.ConditionalExpression: + this._recurse(node.test, callback, state); + this._recurse(node.consequent, callback, state); + this._recurse(node.alternate, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.TaggedTemplateExpression: + this._recurse(node.tag, callback, state); + this._recurse(node.quasi, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.TemplateLiteral: + this._recurseArray(node.quasis, callback, state); + this._recurseArray(node.expressions, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.ThrowStatement: + this._recurse(node.argument, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.TryStatement: + this._recurse(node.block, callback, state); + this._recurse(node.handler, callback, state); + this._recurse(node.finalizer, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.UnaryExpression: + this._recurse(node.argument, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.UpdateExpression: + this._recurse(node.argument, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.VariableDeclaration: + this._recurseArray(node.declarations, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.VariableDeclarator: + this._recurse(node.id, callback, state); + this._recurse(node.init, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.WhileStatement: + this._recurse(node.test, callback, state); + this._recurse(node.body, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.WithStatement: + this._recurse(node.object, callback, state); + this._recurse(node.body, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.YieldExpression: + this._recurse(node.argument, callback, state); + break; + + // Modules. + + case WebInspector.ScriptSyntaxTree.NodeType.ExportAllDeclaration: + this._recurse(node.source, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.ExportNamedDeclaration: + this._recurse(node.declaration, callback, state); + this._recurseArray(node.specifiers, callback, state); + this._recurse(node.source, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.ExportDefaultDeclaration: + this._recurse(node.declaration, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.ExportSpecifier: + this._recurse(node.local, callback, state); + this._recurse(node.exported, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.ImportDeclaration: + this._recurseArray(node.specifiers, callback, state); + this._recurse(node.source, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.ImportDefaultSpecifier: + this._recurse(node.local, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.ImportNamespaceSpecifier: + this._recurse(node.local, callback, state); + break; + case WebInspector.ScriptSyntaxTree.NodeType.ImportSpecifier: + this._recurse(node.imported, callback, state); + this._recurse(node.local, callback, state); + break; + + // All the leaf nodes go here. + case WebInspector.ScriptSyntaxTree.NodeType.DebuggerStatement: + case WebInspector.ScriptSyntaxTree.NodeType.EmptyStatement: + case WebInspector.ScriptSyntaxTree.NodeType.Identifier: + case WebInspector.ScriptSyntaxTree.NodeType.Import: + case WebInspector.ScriptSyntaxTree.NodeType.Literal: + case WebInspector.ScriptSyntaxTree.NodeType.MetaProperty: + case WebInspector.ScriptSyntaxTree.NodeType.Super: + case WebInspector.ScriptSyntaxTree.NodeType.ThisExpression: + case WebInspector.ScriptSyntaxTree.NodeType.TemplateElement: + break; + } + + state.skipChildNodes = false; + } + + _recurseArray(array, callback, state) + { + for (var node of array) + this._recurse(node, callback, state); + } + + // This function translates from esprima's Abstract Syntax Tree to ours. + // Mostly, this is just the identity function. We've added an extra typeProfilingReturnDivot property for functions/methods. + // Our AST complies with the Mozilla parser API: + // https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API + _createInternalSyntaxTree(node) + { + if (!node) + return null; + + var result = null; + switch (node.type) { + case "ArrayExpression": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ArrayExpression, + elements: node.elements.map(this._createInternalSyntaxTree, this) + }; + break; + case "ArrayPattern": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ArrayPattern, + elements: node.elements.map(this._createInternalSyntaxTree, this) + }; + break; + case "ArrowFunctionExpression": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ArrowFunctionExpression, + id: this._createInternalSyntaxTree(node.id), + params: node.params.map(this._createInternalSyntaxTree, this), + body: this._createInternalSyntaxTree(node.body), + generator: node.generator, + expression: node.expression, // Boolean indicating if the body a single expression or a block statement. + async: node.async, + typeProfilingReturnDivot: node.range[0] + }; + break; + case "AssignmentExpression": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.AssignmentExpression, + operator: node.operator, + left: this._createInternalSyntaxTree(node.left), + right: this._createInternalSyntaxTree(node.right) + }; + break; + case "AssignmentPattern": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.AssignmentPattern, + left: this._createInternalSyntaxTree(node.left), + right: this._createInternalSyntaxTree(node.right), + }; + break; + case "AwaitExpression": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.AwaitExpression, + argument: this._createInternalSyntaxTree(node.argument), + }; + break; + case "BlockStatement": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.BlockStatement, + body: node.body.map(this._createInternalSyntaxTree, this) + }; + break; + case "BinaryExpression": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.BinaryExpression, + operator: node.operator, + left: this._createInternalSyntaxTree(node.left), + right: this._createInternalSyntaxTree(node.right) + }; + break; + case "BreakStatement": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.BreakStatement, + label: this._createInternalSyntaxTree(node.label) + }; + break; + case "CallExpression": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.CallExpression, + callee: this._createInternalSyntaxTree(node.callee), + arguments: node.arguments.map(this._createInternalSyntaxTree, this) + }; + break; + case "CatchClause": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.CatchClause, + param: this._createInternalSyntaxTree(node.param), + body: this._createInternalSyntaxTree(node.body) + }; + break; + case "ClassBody": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ClassBody, + body: node.body.map(this._createInternalSyntaxTree, this) + }; + break; + case "ClassDeclaration": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ClassDeclaration, + id: this._createInternalSyntaxTree(node.id), + superClass: this._createInternalSyntaxTree(node.superClass), + body: this._createInternalSyntaxTree(node.body), + }; + break; + case "ClassExpression": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ClassExpression, + id: this._createInternalSyntaxTree(node.id), + superClass: this._createInternalSyntaxTree(node.superClass), + body: this._createInternalSyntaxTree(node.body), + }; + break; + case "ConditionalExpression": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ConditionalExpression, + test: this._createInternalSyntaxTree(node.test), + consequent: this._createInternalSyntaxTree(node.consequent), + alternate: this._createInternalSyntaxTree(node.alternate) + }; + break; + case "ContinueStatement": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ContinueStatement, + label: this._createInternalSyntaxTree(node.label) + }; + break; + case "DoWhileStatement": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.DoWhileStatement, + body: this._createInternalSyntaxTree(node.body), + test: this._createInternalSyntaxTree(node.test) + }; + break; + case "DebuggerStatement": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.DebuggerStatement + }; + break; + case "EmptyStatement": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.EmptyStatement + }; + break; + case "ExpressionStatement": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ExpressionStatement, + expression: this._createInternalSyntaxTree(node.expression) + }; + break; + case "ForStatement": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ForStatement, + init: this._createInternalSyntaxTree(node.init), + test: this._createInternalSyntaxTree(node.test), + update: this._createInternalSyntaxTree(node.update), + body: this._createInternalSyntaxTree(node.body) + }; + break; + case "ForInStatement": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ForInStatement, + left: this._createInternalSyntaxTree(node.left), + right: this._createInternalSyntaxTree(node.right), + body: this._createInternalSyntaxTree(node.body) + }; + break; + case "ForOfStatement": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ForOfStatement, + left: this._createInternalSyntaxTree(node.left), + right: this._createInternalSyntaxTree(node.right), + body: this._createInternalSyntaxTree(node.body) + }; + break; + case "FunctionDeclaration": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.FunctionDeclaration, + id: this._createInternalSyntaxTree(node.id), + params: node.params.map(this._createInternalSyntaxTree, this), + body: this._createInternalSyntaxTree(node.body), + generator: node.generator, + async: node.async, + typeProfilingReturnDivot: node.range[0] + }; + break; + case "FunctionExpression": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression, + id: this._createInternalSyntaxTree(node.id), + params: node.params.map(this._createInternalSyntaxTree, this), + body: this._createInternalSyntaxTree(node.body), + generator: node.generator, + async: node.async, + typeProfilingReturnDivot: node.range[0] // This may be overridden in the Property AST node. + }; + break; + case "Identifier": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.Identifier, + name: node.name + }; + break; + case "IfStatement": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.IfStatement, + test: this._createInternalSyntaxTree(node.test), + consequent: this._createInternalSyntaxTree(node.consequent), + alternate: this._createInternalSyntaxTree(node.alternate) + }; + break; + case "Literal": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.Literal, + value: node.value, + raw: node.raw + }; + break; + case "LabeledStatement": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.LabeledStatement, + label: this._createInternalSyntaxTree(node.label), + body: this._createInternalSyntaxTree(node.body) + }; + break; + case "LogicalExpression": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.LogicalExpression, + left: this._createInternalSyntaxTree(node.left), + right: this._createInternalSyntaxTree(node.right), + operator: node.operator + }; + break; + case "MemberExpression": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.MemberExpression, + object: this._createInternalSyntaxTree(node.object), + property: this._createInternalSyntaxTree(node.property), + computed: node.computed + }; + break; + case "MetaProperty": + // i.e: new.target produces {meta: "new", property: "target"} + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.MetaProperty, + meta: this._createInternalSyntaxTree(node.meta), + property: this._createInternalSyntaxTree(node.property), + }; + break; + case "MethodDefinition": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.MethodDefinition, + key: this._createInternalSyntaxTree(node.key), + value: this._createInternalSyntaxTree(node.value), + computed: node.computed, + kind: node.kind, + static: node.static + }; + result.value.typeProfilingReturnDivot = node.range[0]; // "g" in "get" or "s" in "set" or "[" in "['computed']" or "m" in "methodName". + break; + case "NewExpression": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.NewExpression, + callee: this._createInternalSyntaxTree(node.callee), + arguments: node.arguments.map(this._createInternalSyntaxTree, this) + }; + break; + case "ObjectExpression": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ObjectExpression, + properties: node.properties.map(this._createInternalSyntaxTree, this) + }; + break; + case "ObjectPattern": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ObjectPattern, + properties: node.properties.map(this._createInternalSyntaxTree, this) + }; + break; + case "Program": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.Program, + sourceType: node.sourceType, + body: node.body.map(this._createInternalSyntaxTree, this) + }; + break; + case "Property": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.Property, + key: this._createInternalSyntaxTree(node.key), + value: this._createInternalSyntaxTree(node.value), + kind: node.kind, + method: node.method, + computed: node.computed + }; + if (result.kind === "get" || result.kind === "set" || result.method) + result.value.typeProfilingReturnDivot = node.range[0]; // "g" in "get" or "s" in "set" or "[" in "['computed']" method or "m" in "methodName". + break; + case "RestElement": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.RestElement, + argument: this._createInternalSyntaxTree(node.argument) + }; + break; + case "RestProperty": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.RestProperty, + argument: this._createInternalSyntaxTree(node.argument), + }; + break; + case "ReturnStatement": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ReturnStatement, + argument: this._createInternalSyntaxTree(node.argument) + }; + break; + case "SequenceExpression": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.SequenceExpression, + expressions: node.expressions.map(this._createInternalSyntaxTree, this) + }; + break; + case "SpreadElement": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.SpreadElement, + argument: this._createInternalSyntaxTree(node.argument), + }; + break; + case "SpreadProperty": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.SpreadProperty, + argument: this._createInternalSyntaxTree(node.argument), + }; + break; + case "Super": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.Super + }; + break; + case "SwitchStatement": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.SwitchStatement, + discriminant: this._createInternalSyntaxTree(node.discriminant), + cases: node.cases.map(this._createInternalSyntaxTree, this) + }; + break; + case "SwitchCase": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.SwitchCase, + test: this._createInternalSyntaxTree(node.test), + consequent: node.consequent.map(this._createInternalSyntaxTree, this) + }; + break; + case "TaggedTemplateExpression": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.TaggedTemplateExpression, + tag: this._createInternalSyntaxTree(node.tag), + quasi: this._createInternalSyntaxTree(node.quasi) + }; + break; + case "TemplateElement": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.TemplateElement, + value: node.value, + tail: node.tail + }; + break; + case "TemplateLiteral": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.TemplateLiteral, + quasis: node.quasis.map(this._createInternalSyntaxTree, this), + expressions: node.expressions.map(this._createInternalSyntaxTree, this) + }; + break; + case "ThisExpression": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ThisExpression + }; + break; + case "ThrowStatement": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ThrowStatement, + argument: this._createInternalSyntaxTree(node.argument) + }; + break; + case "TryStatement": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.TryStatement, + block: this._createInternalSyntaxTree(node.block), + handler: this._createInternalSyntaxTree(node.handler), + finalizer: this._createInternalSyntaxTree(node.finalizer) + }; + break; + case "UnaryExpression": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.UnaryExpression, + operator: node.operator, + argument: this._createInternalSyntaxTree(node.argument) + }; + break; + case "UpdateExpression": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.UpdateExpression, + operator: node.operator, + prefix: node.prefix, + argument: this._createInternalSyntaxTree(node.argument) + }; + break; + case "VariableDeclaration": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.VariableDeclaration, + declarations: node.declarations.map(this._createInternalSyntaxTree, this), + kind: node.kind + }; + break; + case "VariableDeclarator": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.VariableDeclarator, + id: this._createInternalSyntaxTree(node.id), + init: this._createInternalSyntaxTree(node.init) + }; + break; + case "WhileStatement": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.WhileStatement, + test: this._createInternalSyntaxTree(node.test), + body: this._createInternalSyntaxTree(node.body) + }; + break; + case "WithStatement": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.WithStatement, + object: this._createInternalSyntaxTree(node.object), + body: this._createInternalSyntaxTree(node.body) + }; + break; + case "YieldExpression": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.YieldExpression, + argument: this._createInternalSyntaxTree(node.argument), + delegate: node.delegate + }; + break; + + // Modules. + + case "ExportAllDeclaration": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ExportAllDeclaration, + source: this._createInternalSyntaxTree(node.source), + }; + break; + case "ExportNamedDeclaration": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ExportNamedDeclaration, + declaration: this._createInternalSyntaxTree(node.declaration), + specifiers: node.specifiers.map(this._createInternalSyntaxTree, this), + source: this._createInternalSyntaxTree(node.source), + }; + break; + case "ExportDefaultDeclaration": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ExportDefaultDeclaration, + declaration: this._createInternalSyntaxTree(node.declaration), + }; + break; + case "ExportSpecifier": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ExportSpecifier, + local: this._createInternalSyntaxTree(node.local), + exported: this._createInternalSyntaxTree(node.exported), + }; + break; + case "Import": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.Import, + }; + break; + case "ImportDeclaration": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ImportDeclaration, + specifiers: node.specifiers.map(this._createInternalSyntaxTree, this), + source: this._createInternalSyntaxTree(node.source), + }; + break; + case "ImportDefaultSpecifier": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ImportDefaultSpecifier, + local: this._createInternalSyntaxTree(node.local), + }; + break; + case "ImportNamespaceSpecifier": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ImportNamespaceSpecifier, + local: this._createInternalSyntaxTree(node.local), + }; + break; + case "ImportSpecifier": + result = { + type: WebInspector.ScriptSyntaxTree.NodeType.ImportSpecifier, + imported: this._createInternalSyntaxTree(node.imported), + local: this._createInternalSyntaxTree(node.local), + }; + break; + + default: + console.error("Unsupported Syntax Tree Node: " + node.type, node); + return null; + } + + result.range = node.range; + // This is an object for which you can add fields to an AST node without worrying about polluting the syntax-related fields of the node. + result.attachments = {}; + + return result; + } +}; + +// This should be kept in sync with an enum in JavaSciptCore/runtime/TypeProfiler.h +WebInspector.ScriptSyntaxTree.TypeProfilerSearchDescriptor = { + NormalExpression: 1, + FunctionReturn: 2 +}; + +WebInspector.ScriptSyntaxTree.NodeType = { + ArrayExpression: Symbol("array-expression"), + ArrayPattern: Symbol("array-pattern"), + ArrowFunctionExpression: Symbol("arrow-function-expression"), + AssignmentExpression: Symbol("assignment-expression"), + AssignmentPattern: Symbol("assignment-pattern"), + AwaitExpression: Symbol("await-expression"), + BinaryExpression: Symbol("binary-expression"), + BlockStatement: Symbol("block-statement"), + BreakStatement: Symbol("break-statement"), + CallExpression: Symbol("call-expression"), + CatchClause: Symbol("catch-clause"), + ClassBody: Symbol("class-body"), + ClassDeclaration: Symbol("class-declaration"), + ClassExpression: Symbol("class-expression"), + ConditionalExpression: Symbol("conditional-expression"), + ContinueStatement: Symbol("continue-statement"), + DebuggerStatement: Symbol("debugger-statement"), + DoWhileStatement: Symbol("do-while-statement"), + EmptyStatement: Symbol("empty-statement"), + ExportAllDeclaration: Symbol("export-all-declaration"), + ExportDefaultDeclaration: Symbol("export-default-declaration"), + ExportNamedDeclaration: Symbol("export-named-declaration"), + ExportSpecifier: Symbol("export-specifier"), + ExpressionStatement: Symbol("expression-statement"), + ForInStatement: Symbol("for-in-statement"), + ForOfStatement: Symbol("for-of-statement"), + ForStatement: Symbol("for-statement"), + FunctionDeclaration: Symbol("function-declaration"), + FunctionExpression: Symbol("function-expression"), + Identifier: Symbol("identifier"), + IfStatement: Symbol("if-statement"), + Import: Symbol("import"), + ImportDeclaration: Symbol("import-declaration"), + ImportDefaultSpecifier: Symbol("import-default-specifier"), + ImportNamespaceSpecifier: Symbol("import-namespace-specifier"), + ImportSpecifier: Symbol("import-specifier"), + LabeledStatement: Symbol("labeled-statement"), + Literal: Symbol("literal"), + LogicalExpression: Symbol("logical-expression"), + MemberExpression: Symbol("member-expression"), + MetaProperty: Symbol("meta-property"), + MethodDefinition: Symbol("method-definition"), + NewExpression: Symbol("new-expression"), + ObjectExpression: Symbol("object-expression"), + ObjectPattern: Symbol("object-pattern"), + Program: Symbol("program"), + Property: Symbol("property"), + RestElement: Symbol("rest-element"), + RestProperty: Symbol("rest-property"), + ReturnStatement: Symbol("return-statement"), + SequenceExpression: Symbol("sequence-expression"), + SpreadElement: Symbol("spread-element"), + SpreadProperty: Symbol("spread-property"), + Super: Symbol("super"), + SwitchCase: Symbol("switch-case"), + SwitchStatement: Symbol("switch-statement"), + TaggedTemplateExpression: Symbol("tagged-template-expression"), + TemplateElement: Symbol("template-element"), + TemplateLiteral: Symbol("template-literal"), + ThisExpression: Symbol("this-expression"), + ThrowStatement: Symbol("throw-statement"), + TryStatement: Symbol("try-statement"), + UnaryExpression: Symbol("unary-expression"), + UpdateExpression: Symbol("update-expression"), + VariableDeclaration: Symbol("variable-declaration"), + VariableDeclarator: Symbol("variable-declarator"), + WhileStatement: Symbol("while-statement"), + WithStatement: Symbol("with-statement"), + YieldExpression: Symbol("yield-expression"), +}; |