<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[190184] trunk</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/190184">190184</a></dd>
<dt>Author</dt> <dd>sbarati@apple.com</dd>
<dt>Date</dt> <dd>2015-09-23 13:58:51 -0700 (Wed, 23 Sep 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>Web Inspector: Type bubbles missing for computed methods and methods on object literals
https://bugs.webkit.org/show_bug.cgi?id=148562
Reviewed by Joseph Pecoraro.
Source/WebInspectorUI:
This patch makes sure that computed methods are working
for both classes and object literals. Also, methods now
work on object literals. This patch also cleans up the
"isGetterOrSetter" and "getterOrSetterRange" fields.
Basically, we used this as a way to ask the type profiler
for the return types of a function. Now, we just have
a field called "typeProfilingReturnDivot" that is set
on all functions so we don't need to conditionally ask
if it's a getter or setter.
* UserInterface/Controllers/TypeTokenAnnotator.js:
(WebInspector.TypeTokenAnnotator.prototype._insertTypeToken):
* UserInterface/Models/ScriptSyntaxTree.js:
(WebInspector.ScriptSyntaxTree.functionReturnDivot):
(WebInspector.ScriptSyntaxTree.prototype._recurseArray):
(WebInspector.ScriptSyntaxTree.prototype._createInternalSyntaxTree):
(WebInspector.ScriptSyntaxTree):
LayoutTests:
* inspector/model/parse-script-syntax-tree-expected.txt:
* inspector/model/parse-script-syntax-tree.html:</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsinspectormodelparsescriptsyntaxtreeexpectedtxt">trunk/LayoutTests/inspector/model/parse-script-syntax-tree-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectormodelparsescriptsyntaxtreehtml">trunk/LayoutTests/inspector/model/parse-script-syntax-tree.html</a></li>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceControllersTypeTokenAnnotatorjs">trunk/Source/WebInspectorUI/UserInterface/Controllers/TypeTokenAnnotator.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceModelsScriptSyntaxTreejs">trunk/Source/WebInspectorUI/UserInterface/Models/ScriptSyntaxTree.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (190183 => 190184)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-09-23 20:34:18 UTC (rev 190183)
+++ trunk/LayoutTests/ChangeLog        2015-09-23 20:58:51 UTC (rev 190184)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2015-09-23 Saam barati <sbarati@apple.com>
+
+ Web Inspector: Type bubbles missing for computed methods and methods on object literals
+ https://bugs.webkit.org/show_bug.cgi?id=148562
+
+ Reviewed by Joseph Pecoraro.
+
+ * inspector/model/parse-script-syntax-tree-expected.txt:
+ * inspector/model/parse-script-syntax-tree.html:
+
</ins><span class="cx"> 2015-09-23 Beth Dakin <bdakin@apple.com>
</span><span class="cx">
</span><span class="cx"> accessibility/mac/aria-expanded-notifications.html is flaky
</span></span></pre></div>
<a id="trunkLayoutTestsinspectormodelparsescriptsyntaxtreeexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/model/parse-script-syntax-tree-expected.txt (190183 => 190184)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/model/parse-script-syntax-tree-expected.txt        2015-09-23 20:34:18 UTC (rev 190183)
+++ trunk/LayoutTests/inspector/model/parse-script-syntax-tree-expected.txt        2015-09-23 20:58:51 UTC (rev 190184)
</span><span class="lines">@@ -41,5 +41,8 @@
</span><span class="cx"> passed ClassStatement, Super, MetaProperty
</span><span class="cx"> passed AssignmentPattern
</span><span class="cx"> passed ArrowFunctionExpression
</span><ins>+passed computed method on object literal
+passed method on object literal
+passed computed method property on object literal
</ins><span class="cx"> passed ALL TESTS
</span><span class="cx">
</span></span></pre></div>
<a id="trunkLayoutTestsinspectormodelparsescriptsyntaxtreehtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/model/parse-script-syntax-tree.html (190183 => 190184)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/model/parse-script-syntax-tree.html        2015-09-23 20:34:18 UTC (rev 190183)
+++ trunk/LayoutTests/inspector/model/parse-script-syntax-tree.html        2015-09-23 20:58:51 UTC (rev 190184)
</span><span class="lines">@@ -193,13 +193,10 @@
</span><span class="cx"> InspectorTest.assert(node.params[1].type === WebInspector.ScriptSyntaxTree.NodeType.Identifier);
</span><span class="cx"> InspectorTest.assert(node.body);
</span><span class="cx"> InspectorTest.assert(node.body.type === WebInspector.ScriptSyntaxTree.NodeType.BlockStatement);
</span><del>- InspectorTest.assert(!node.isGetterOrSetter);
</del><span class="cx"> node = makeNode("x = {get foo(){return 20}}", true);
</span><span class="cx"> InspectorTest.assert(node.right.properties[0].value.type === WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression);
</span><del>- InspectorTest.assert(node.right.properties[0].value.isGetterOrSetter);
</del><span class="cx"> node = makeNode("x = {set foo(x){return 20}}", true);
</span><span class="cx"> InspectorTest.assert(node.right.properties[0].value.type === WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression);
</span><del>- InspectorTest.assert(node.right.properties[0].value.isGetterOrSetter);
</del><span class="cx"> InspectorTest.log("passed FunctionDeclaration");
</span><span class="cx">
</span><span class="cx"> node = makeNode("foo(function(x,y){})", true);
</span><span class="lines">@@ -496,6 +493,51 @@
</span><span class="cx"> InspectorTest.assert(node.body.type === WebInspector.ScriptSyntaxTree.NodeType.BlockStatement);
</span><span class="cx"> InspectorTest.log("passed ArrowFunctionExpression");
</span><span class="cx">
</span><ins>+ node = makeNode("var o = {['c']() { }};", false);
+ // ^
+ // type profiling return divot.
+ InspectorTest.assert(node.type === WebInspector.ScriptSyntaxTree.NodeType.VariableDeclaration);
+ InspectorTest.assert(node.declarations.length === 1);
+ InspectorTest.assert(node.declarations[0].type === WebInspector.ScriptSyntaxTree.NodeType.VariableDeclarator);
+ InspectorTest.assert(node.declarations[0].init.type === WebInspector.ScriptSyntaxTree.NodeType.ObjectExpression);
+ InspectorTest.assert(node.declarations[0].init.properties.length === 1);
+ InspectorTest.assert(node.declarations[0].init.properties[0].type === WebInspector.ScriptSyntaxTree.NodeType.Property);
+ InspectorTest.assert(!!node.declarations[0].init.properties[0].method);
+ InspectorTest.assert(!!node.declarations[0].init.properties[0].computed);
+ InspectorTest.assert(node.declarations[0].init.properties[0].value.type === WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression);
+ InspectorTest.assert(node.declarations[0].init.properties[0].value.typeProfilingReturnDivot === 9);
+ InspectorTest.log("passed computed method on object literal");
+
+ node = makeNode("var o = { m(){ } };", false);
+ // ^
+ // type profiling return divot.
+ InspectorTest.assert(node.type === WebInspector.ScriptSyntaxTree.NodeType.VariableDeclaration);
+ InspectorTest.assert(node.declarations.length === 1);
+ InspectorTest.assert(node.declarations[0].type === WebInspector.ScriptSyntaxTree.NodeType.VariableDeclarator);
+ InspectorTest.assert(node.declarations[0].init.type === WebInspector.ScriptSyntaxTree.NodeType.ObjectExpression);
+ InspectorTest.assert(node.declarations[0].init.properties.length === 1);
+ InspectorTest.assert(node.declarations[0].init.properties[0].type === WebInspector.ScriptSyntaxTree.NodeType.Property);
+ InspectorTest.assert(!!node.declarations[0].init.properties[0].method);
+ InspectorTest.assert(!node.declarations[0].init.properties[0].computed);
+ InspectorTest.assert(node.declarations[0].init.properties[0].value.type === WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression);
+ InspectorTest.assert(node.declarations[0].init.properties[0].value.typeProfilingReturnDivot === 10);
+ InspectorTest.log("passed method on object literal");
+
+ node = makeNode("var o = {['c']: function(){ } };", false);
+ // ^
+ // type profiling return divot.
+ InspectorTest.assert(node.type === WebInspector.ScriptSyntaxTree.NodeType.VariableDeclaration);
+ InspectorTest.assert(node.declarations.length === 1);
+ InspectorTest.assert(node.declarations[0].type === WebInspector.ScriptSyntaxTree.NodeType.VariableDeclarator);
+ InspectorTest.assert(node.declarations[0].init.type === WebInspector.ScriptSyntaxTree.NodeType.ObjectExpression);
+ InspectorTest.assert(node.declarations[0].init.properties.length === 1);
+ InspectorTest.assert(node.declarations[0].init.properties[0].type === WebInspector.ScriptSyntaxTree.NodeType.Property);
+ InspectorTest.assert(!node.declarations[0].init.properties[0].method);
+ InspectorTest.assert(!!node.declarations[0].init.properties[0].computed);
+ InspectorTest.assert(node.declarations[0].init.properties[0].value.type === WebInspector.ScriptSyntaxTree.NodeType.FunctionExpression);
+ InspectorTest.assert(node.declarations[0].init.properties[0].value.typeProfilingReturnDivot === 16);
+ InspectorTest.log("passed computed method property on object literal");
+
</ins><span class="cx"> InspectorTest.log("passed ALL TESTS");
</span><span class="cx"> InspectorTest.completeTest();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (190183 => 190184)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2015-09-23 20:34:18 UTC (rev 190183)
+++ trunk/Source/WebInspectorUI/ChangeLog        2015-09-23 20:58:51 UTC (rev 190184)
</span><span class="lines">@@ -1,3 +1,28 @@
</span><ins>+2015-09-23 Saam barati <sbarati@apple.com>
+
+ Web Inspector: Type bubbles missing for computed methods and methods on object literals
+ https://bugs.webkit.org/show_bug.cgi?id=148562
+
+ Reviewed by Joseph Pecoraro.
+
+ This patch makes sure that computed methods are working
+ for both classes and object literals. Also, methods now
+ work on object literals. This patch also cleans up the
+ "isGetterOrSetter" and "getterOrSetterRange" fields.
+ Basically, we used this as a way to ask the type profiler
+ for the return types of a function. Now, we just have
+ a field called "typeProfilingReturnDivot" that is set
+ on all functions so we don't need to conditionally ask
+ if it's a getter or setter.
+
+ * UserInterface/Controllers/TypeTokenAnnotator.js:
+ (WebInspector.TypeTokenAnnotator.prototype._insertTypeToken):
+ * UserInterface/Models/ScriptSyntaxTree.js:
+ (WebInspector.ScriptSyntaxTree.functionReturnDivot):
+ (WebInspector.ScriptSyntaxTree.prototype._recurseArray):
+ (WebInspector.ScriptSyntaxTree.prototype._createInternalSyntaxTree):
+ (WebInspector.ScriptSyntaxTree):
+
</ins><span class="cx"> 2015-09-22 Devin Rousso <dcrousso+webkit@gmail.com>
</span><span class="cx">
</span><span class="cx"> Web Inspector: The right sidebar always opens up on breakpoint
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceControllersTypeTokenAnnotatorjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/TypeTokenAnnotator.js (190183 => 190184)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Controllers/TypeTokenAnnotator.js        2015-09-23 20:34:18 UTC (rev 190183)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/TypeTokenAnnotator.js        2015-09-23 20:58:51 UTC (rev 190184)
</span><span class="lines">@@ -106,8 +106,7 @@
</span><span class="cx"> var scriptSyntaxTree = this._script._scriptSyntaxTree;
</span><span class="cx"> if (!node.attachments.__typeToken && (scriptSyntaxTree.containsNonEmptyReturnStatement(node.body) || !functionReturnType.typeSet.isContainedIn(WebInspector.TypeSet.TypeBit.Undefined))) {
</span><span class="cx"> var functionName = node.id ? node.id.name : null;
</span><del>- var offset = node.isGetterOrSetter ? node.getterOrSetterRange[0] : node.range[0];
- this._insertToken(offset, node, true, WebInspector.TypeTokenView.TitleType.ReturnStatement, functionName);
</del><ins>+ this._insertToken(node.typeProfilingReturnDivot, node, true, WebInspector.TypeTokenView.TitleType.ReturnStatement, functionName);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> if (node.attachments.__typeToken)
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceModelsScriptSyntaxTreejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Models/ScriptSyntaxTree.js (190183 => 190184)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Models/ScriptSyntaxTree.js        2015-09-23 20:34:18 UTC (rev 190183)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/ScriptSyntaxTree.js        2015-09-23 20:58:51 UTC (rev 190184)
</span><span class="lines">@@ -157,8 +157,9 @@
</span><span class="cx"> if (!DOMAgent.hasEvent("pseudoElementAdded"))
</span><span class="cx"> return node.body.range[0];
</span><span class="cx">
</span><del>- // "f" in function, "s" in set, "g" in get, first letter in any method name for classes.
- return node.isGetterOrSetter ? node.getterOrSetterRange[0] : node.range[0];
</del><ins>+ // "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;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> updateTypes(nodesToUpdate, callback)
</span><span class="lines">@@ -516,7 +517,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // This function translates from esprima's Abstract Syntax Tree to ours.
</span><del>- // Mostly, this is just the identity function. We've added an extra isGetterOrSetter property for functions.
</del><ins>+ // Mostly, this is just the identity function. We've added an extra typeProfilingReturnDivot property for functions/methods.
</ins><span class="cx"> // Our AST complies with the Mozilla parser API:
</span><span class="cx"> // https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/Parser_API
</span><span class="cx"> _createInternalSyntaxTree(node)
</span><span class="lines">@@ -546,7 +547,7 @@
</span><span class="cx"> defaults: node.defaults.map(this._createInternalSyntaxTree.bind(this)),
</span><span class="cx"> body: this._createInternalSyntaxTree(node.body),
</span><span class="cx"> expression: node.expression, // Boolean indicating if the body a single expression or a block statement.
</span><del>- isGetterOrSetter: false
</del><ins>+ typeProfilingReturnDivot: node.range[0]
</ins><span class="cx"> };
</span><span class="cx"> break;
</span><span class="cx"> case "AssignmentExpression":
</span><span class="lines">@@ -689,7 +690,7 @@
</span><span class="cx"> params: node.params.map(this._createInternalSyntaxTree.bind(this)),
</span><span class="cx"> defaults: node.defaults.map(this._createInternalSyntaxTree.bind(this)),
</span><span class="cx"> body: this._createInternalSyntaxTree(node.body),
</span><del>- isGetterOrSetter: false // This is obvious, but is convenient none the less b/c Declarations and Expressions are often intertwined.
</del><ins>+ typeProfilingReturnDivot: node.range[0]
</ins><span class="cx"> };
</span><span class="cx"> break;
</span><span class="cx"> case "FunctionExpression":
</span><span class="lines">@@ -699,7 +700,7 @@
</span><span class="cx"> params: node.params.map(this._createInternalSyntaxTree.bind(this)),
</span><span class="cx"> defaults: node.defaults.map(this._createInternalSyntaxTree.bind(this)),
</span><span class="cx"> body: this._createInternalSyntaxTree(node.body),
</span><del>- isGetterOrSetter: false // If true, it is set in the Property AST node.
</del><ins>+ typeProfilingReturnDivot: node.range[0] // This may be overridden in the Property AST node.
</ins><span class="cx"> };
</span><span class="cx"> break;
</span><span class="cx"> case "Identifier":
</span><span class="lines">@@ -763,14 +764,7 @@
</span><span class="cx"> kind: node.kind,
</span><span class="cx"> static: node.static
</span><span class="cx"> };
</span><del>- if (result.kind === "get" || result.kind === "set") {
- const length = result.key.range[1] - result.key.range[0];
- result.value.getterOrSetterRange = node.range;
- result.value.getterOrSetterRange[1] = node.range[0] + length;
- } else
- result.value.getterOrSetterRange = result.key.range;
- // FIXME: <https://webkit.org/b/143171> Web Inspector: Improve Type Profiler Support for ES6 Syntax
- result.value.isGetterOrSetter = true;
</del><ins>+ result.value.typeProfilingReturnDivot = node.range[0]; // "g" in "get" or "s" in "set" or "[" in "['computed']" or "m" in "methodName".
</ins><span class="cx"> break;
</span><span class="cx"> case "NewExpression":
</span><span class="cx"> result = {
</span><span class="lines">@@ -803,12 +797,12 @@
</span><span class="cx"> type: WebInspector.ScriptSyntaxTree.NodeType.Property,
</span><span class="cx"> key: this._createInternalSyntaxTree(node.key),
</span><span class="cx"> value: this._createInternalSyntaxTree(node.value),
</span><del>- kind: node.kind
</del><ins>+ kind: node.kind,
+ method: node.method,
+ computed: node.computed
</ins><span class="cx"> };
</span><del>- if (result.kind === "get" || result.kind === "set") {
- result.value.isGetterOrSetter = true;
- result.value.getterOrSetterRange = result.key.range;
- }
</del><ins>+ 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".
</ins><span class="cx"> break;
</span><span class="cx"> case "ReturnStatement":
</span><span class="cx"> result = {
</span></span></pre>
</div>
</div>
</body>
</html>