<!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>[205866] 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/205866">205866</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2016-09-13 11:37:12 -0700 (Tue, 13 Sep 2016)</dd>
</dl>
<h3>Log Message</h3>
<pre>Web Inspector: Should be able to pretty print module code (import / export statements)
https://bugs.webkit.org/show_bug.cgi?id=161891
<rdar://problem/28272784>
Patch by Joseph Pecoraro <pecoraro@apple.com> on 2016-09-13
Reviewed by Yusuke Suzuki.
Source/WebInspectorUI:
* Tools/Formatting/EsprimaFormatterDebug.js:
* Tools/Formatting/index.html:
Update the formatting tool to toggle between source type modes.
* UserInterface/Proxies/FormatterWorkerProxy.js:
* UserInterface/Workers/Formatter/FormatterWorker.js:
(FormatterWorker.prototype.formatJavaScript):
Provide a flag to parse the input as a module instead of a script/program.
* UserInterface/Views/TextEditor.js:
(WebInspector.TextEditor.prototype._startWorkerPrettyPrint):
Using the formatter here, we may have module scripts in the future.
* UserInterface/Views/SourceCodeTextEditor.js:
(WebInspector.SourceCodeTextEditor.prototype._showPopoverForFunction.didGetDetails):
Using the formatter for a function is not module source.
* UserInterface/Workers/Formatter/ESTreeWalker.js:
(ESTreeWalker.prototype._walkChildren):
Visit children of Export/Import nodes.
* UserInterface/Workers/Formatter/EsprimaFormatter.js:
(EsprimaFormatter.prototype._handleTokenAtNode):
Output tokens with appropriate whitespace.
LayoutTests:
* inspector/formatting/formatting-javascript-expected.txt:
* inspector/formatting/formatting-javascript.html:
* inspector/formatting/resources/javascript-tests/modules-expected.js: Added.
* inspector/formatting/resources/javascript-tests/modules.js: Added.
Include a new test for modules.
* inspector/formatting/formatting-json.html:
All of these are non-module source code.
* inspector/formatting/resources/utilities.js:
Determine if module or not based on the test name.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsinspectorformattingformattingjavascriptexpectedtxt">trunk/LayoutTests/inspector/formatting/formatting-javascript-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectorformattingformattingjavascripthtml">trunk/LayoutTests/inspector/formatting/formatting-javascript.html</a></li>
<li><a href="#trunkLayoutTestsinspectorformattingformattingjsonhtml">trunk/LayoutTests/inspector/formatting/formatting-json.html</a></li>
<li><a href="#trunkLayoutTestsinspectorformattingresourcesutilitiesjs">trunk/LayoutTests/inspector/formatting/resources/utilities.js</a></li>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUIToolsFormattingEsprimaFormatterDebugjs">trunk/Source/WebInspectorUI/Tools/Formatting/EsprimaFormatterDebug.js</a></li>
<li><a href="#trunkSourceWebInspectorUIToolsFormattingindexhtml">trunk/Source/WebInspectorUI/Tools/Formatting/index.html</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceProxiesFormatterWorkerProxyjs">trunk/Source/WebInspectorUI/UserInterface/Proxies/FormatterWorkerProxy.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsSourceCodeTextEditorjs">trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceViewsTextEditorjs">trunk/Source/WebInspectorUI/UserInterface/Views/TextEditor.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceWorkersFormatterESTreeWalkerjs">trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/ESTreeWalker.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceWorkersFormatterEsprimaFormatterjs">trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/EsprimaFormatter.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceWorkersFormatterFormatterWorkerjs">trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/FormatterWorker.js</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsinspectorformattingresourcesjavascripttestsmodulesexpectedjs">trunk/LayoutTests/inspector/formatting/resources/javascript-tests/modules-expected.js</a></li>
<li><a href="#trunkLayoutTestsinspectorformattingresourcesjavascripttestsmodulesjs">trunk/LayoutTests/inspector/formatting/resources/javascript-tests/modules.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (205865 => 205866)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-09-13 18:20:28 UTC (rev 205865)
+++ trunk/LayoutTests/ChangeLog        2016-09-13 18:37:12 UTC (rev 205866)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2016-09-13 Joseph Pecoraro <pecoraro@apple.com>
+
+ Web Inspector: Should be able to pretty print module code (import / export statements)
+ https://bugs.webkit.org/show_bug.cgi?id=161891
+ <rdar://problem/28272784>
+
+ Reviewed by Yusuke Suzuki.
+
+ * inspector/formatting/formatting-javascript-expected.txt:
+ * inspector/formatting/formatting-javascript.html:
+ * inspector/formatting/resources/javascript-tests/modules-expected.js: Added.
+ * inspector/formatting/resources/javascript-tests/modules.js: Added.
+ Include a new test for modules.
+
+ * inspector/formatting/formatting-json.html:
+ All of these are non-module source code.
+
+ * inspector/formatting/resources/utilities.js:
+ Determine if module or not based on the test name.
+
</ins><span class="cx"> 2016-09-13 Ryan Haddad <ryanhaddad@apple.com>
</span><span class="cx">
</span><span class="cx"> Marking http/tests/security/cross-origin-cached-scripts-parallel.html as flaky.
</span></span></pre></div>
<a id="trunkLayoutTestsinspectorformattingformattingjavascriptexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/formatting/formatting-javascript-expected.txt (205865 => 205866)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/formatting/formatting-javascript-expected.txt        2016-09-13 18:20:28 UTC (rev 205865)
+++ trunk/LayoutTests/inspector/formatting/formatting-javascript-expected.txt        2016-09-13 18:37:12 UTC (rev 205866)
</span><span class="lines">@@ -80,3 +80,6 @@
</span><span class="cx"> -- Running test case: EsprimaFormatter.JavaScript.with-statement.js
</span><span class="cx"> PASS
</span><span class="cx">
</span><ins>+-- Running test case: EsprimaFormatter.JavaScript.modules.js
+PASS
+
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorformattingformattingjavascripthtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/formatting/formatting-javascript.html (205865 => 205866)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/formatting/formatting-javascript.html        2016-09-13 18:20:28 UTC (rev 205865)
+++ trunk/LayoutTests/inspector/formatting/formatting-javascript.html        2016-09-13 18:37:12 UTC (rev 205866)
</span><span class="lines">@@ -35,6 +35,9 @@
</span><span class="cx"> "resources/javascript-tests/variable-declaration.js",
</span><span class="cx"> "resources/javascript-tests/while-statement.js",
</span><span class="cx"> "resources/javascript-tests/with-statement.js",
</span><ins>+
+ // Modules
+ "resources/javascript-tests/modules.js",
</ins><span class="cx"> ]);
</span><span class="cx">
</span><span class="cx"> suite.runTestCasesAndFinish();
</span></span></pre></div>
<a id="trunkLayoutTestsinspectorformattingformattingjsonhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/formatting/formatting-json.html (205865 => 205866)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/formatting/formatting-json.html        2016-09-13 18:20:28 UTC (rev 205865)
+++ trunk/LayoutTests/inspector/formatting/formatting-json.html        2016-09-13 18:37:12 UTC (rev 205866)
</span><span class="lines">@@ -34,7 +34,8 @@
</span><span class="cx">
</span><span class="cx"> let suite = InspectorTest.createAsyncSuite("EsprimaFormatter.JSON");
</span><span class="cx">
</span><del>- let indentString = " ";
</del><ins>+ const isModule = false;
+ const indentString = " ";
</ins><span class="cx"> let workerProxy = WebInspector.FormatterWorkerProxy.singleton();
</span><span class="cx">
</span><span class="cx"> suite.addTestCase({
</span><span class="lines">@@ -44,7 +45,7 @@
</span><span class="cx"> let validJSON = JSON.stringify({"a":123,"b":[1,2,3],"c":{"d":"e"}});
</span><span class="cx"> InspectorTest.log("JSON: " + doubleQuotedString(validJSON));
</span><span class="cx"> ensureJSON(validJSON, "valid");
</span><del>- workerProxy.formatJavaScript(validJSON, indentString, ({formattedText, sourceMapData}) => {
</del><ins>+ workerProxy.formatJavaScript(validJSON, isModule, indentString, ({formattedText, sourceMapData}) => {
</ins><span class="cx"> InspectorTest.log("FORMATTED:");
</span><span class="cx"> InspectorTest.log(formattedText);
</span><span class="cx"> resolve();
</span><span class="lines">@@ -60,7 +61,7 @@
</span><span class="cx"> InspectorTest.log("JSON: " + doubleQuotedString(invalidJSON));
</span><span class="cx"> ensureJSON(invalidJSON, "invalid");
</span><span class="cx"> ensureEval(invalidJSON, "object");
</span><del>- workerProxy.formatJavaScript(invalidJSON, indentString, ({formattedText, sourceMapData}) => {
</del><ins>+ workerProxy.formatJavaScript(invalidJSON, isModule, indentString, ({formattedText, sourceMapData}) => {
</ins><span class="cx"> InspectorTest.log("FORMATTED:");
</span><span class="cx"> InspectorTest.log(formattedText);
</span><span class="cx"> resolve();
</span><span class="lines">@@ -76,7 +77,7 @@
</span><span class="cx"> InspectorTest.log("JSON: " + doubleQuotedString(invalidJSON));
</span><span class="cx"> ensureJSON(invalidJSON, "invalid");
</span><span class="cx"> ensureEval(invalidJSON, "object");
</span><del>- workerProxy.formatJavaScript(invalidJSON, indentString, ({formattedText, sourceMapData}) => {
</del><ins>+ workerProxy.formatJavaScript(invalidJSON, isModule, indentString, ({formattedText, sourceMapData}) => {
</ins><span class="cx"> InspectorTest.log("FORMATTED:");
</span><span class="cx"> InspectorTest.log(formattedText);
</span><span class="cx"> resolve();
</span><span class="lines">@@ -92,7 +93,7 @@
</span><span class="cx"> InspectorTest.log("INPUT: " + doubleQuotedString(invalid));
</span><span class="cx"> ensureJSON(invalid, "invalid");
</span><span class="cx"> ensureEval(invalid, "bad");
</span><del>- workerProxy.formatJavaScript(invalid, indentString, ({formattedText, sourceMapData}) => {
</del><ins>+ workerProxy.formatJavaScript(invalid, isModule, indentString, ({formattedText, sourceMapData}) => {
</ins><span class="cx"> InspectorTest.expectThat(formattedText === null, "Response should be null.");
</span><span class="cx"> resolve();
</span><span class="cx"> });
</span></span></pre></div>
<a id="trunkLayoutTestsinspectorformattingresourcesjavascripttestsmodulesexpectedjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/formatting/resources/javascript-tests/modules-expected.js (0 => 205866)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/formatting/resources/javascript-tests/modules-expected.js         (rev 0)
+++ trunk/LayoutTests/inspector/formatting/resources/javascript-tests/modules-expected.js        2016-09-13 18:37:12 UTC (rev 205866)
</span><span class="lines">@@ -0,0 +1,40 @@
</span><ins>+import "module";
+import x from "module";
+import { x } from "module";
+import { a, b, c } from "module";
+import { a, b, c, } from "module";
+import { a as A } from "module";
+import { a, a as A, a } from "module";
+import { a as A, a as A } from "module";
+import a, { a } from "module";
+import a, { a as A } from "module";
+import x, * as A from "module";
+import * as A from "module";
+
+export { x };
+export let x;
+export var x;
+export const x = 1;
+export let x = 1,
+ y = 1;
+export let {x, y, z} = o;
+export let [x, y, z] = a;
+export { x as X };
+export { x as X, a as A };
+export * from "module";
+export { x } from "module";
+export { x, y } from "module";
+export { x as A } from "module";
+export { x as default };
+export default x;
+export default 1;
+export default {};
+export default (1);
+export default [1];
+export default /r/;
+export default function() {}
+export default function f() {}
+export default function* () {}
+export default function* f() {}
+export default class {}
+export default class X {}
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorformattingresourcesjavascripttestsmodulesjs"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/formatting/resources/javascript-tests/modules.js (0 => 205866)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/formatting/resources/javascript-tests/modules.js         (rev 0)
+++ trunk/LayoutTests/inspector/formatting/resources/javascript-tests/modules.js        2016-09-13 18:37:12 UTC (rev 205866)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+import"module";
+import x from"module";
+import{x}from"module";
+import{a,b,c}from"module";
+import{a,b,c,}from"module";
+import{a as A}from"module";
+import{a,a as A,a}from"module";
+import{a as A,a as A}from"module";
+import a,{a}from"module";
+import a,{a as A}from"module";
+import x,*as A from"module";
+import*as A from"module";
+
+export{x};
+export let x;
+export var x;
+export const x=1;
+export let x=1,y=1;
+export let{x,y,z}=o;
+export let[x,y,z]=a;
+export{x as X};
+export{x as X,a as A};
+export*from"module";
+export{x}from"module";
+export{x,y}from"module";
+export{x as A}from"module";
+export{x as default};
+export default x;
+export default 1;
+export default{};
+export default(1);
+export default[1];
+export default/r/;
+export default function(){}
+export default function f(){}
+export default function*(){}
+export default function*f(){}
+export default class{}
+export default class X{}
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorformattingresourcesutilitiesjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/formatting/resources/utilities.js (205865 => 205866)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/formatting/resources/utilities.js        2016-09-13 18:20:28 UTC (rev 205865)
+++ trunk/LayoutTests/inspector/formatting/resources/utilities.js        2016-09-13 18:37:12 UTC (rev 205866)
</span><span class="lines">@@ -15,7 +15,8 @@
</span><span class="cx"> return new Promise(function(resolve, reject) {
</span><span class="cx"> const indentString = " ";
</span><span class="cx"> let workerProxy = WebInspector.FormatterWorkerProxy.singleton();
</span><del>- workerProxy.formatJavaScript(testText, indentString, ({formattedText, sourceMapData}) => {
</del><ins>+ let isModule = /^module/.test(testName);
+ workerProxy.formatJavaScript(testText, isModule, indentString, ({formattedText, sourceMapData}) => {
</ins><span class="cx"> let pass = formattedText === expectedText;
</span><span class="cx"> InspectorTest.log(pass ? "PASS" : "FAIL");
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (205865 => 205866)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2016-09-13 18:20:28 UTC (rev 205865)
+++ trunk/Source/WebInspectorUI/ChangeLog        2016-09-13 18:37:12 UTC (rev 205866)
</span><span class="lines">@@ -1,3 +1,36 @@
</span><ins>+2016-09-13 Joseph Pecoraro <pecoraro@apple.com>
+
+ Web Inspector: Should be able to pretty print module code (import / export statements)
+ https://bugs.webkit.org/show_bug.cgi?id=161891
+ <rdar://problem/28272784>
+
+ Reviewed by Yusuke Suzuki.
+
+ * Tools/Formatting/EsprimaFormatterDebug.js:
+ * Tools/Formatting/index.html:
+ Update the formatting tool to toggle between source type modes.
+
+ * UserInterface/Proxies/FormatterWorkerProxy.js:
+ * UserInterface/Workers/Formatter/FormatterWorker.js:
+ (FormatterWorker.prototype.formatJavaScript):
+ Provide a flag to parse the input as a module instead of a script/program.
+
+ * UserInterface/Views/TextEditor.js:
+ (WebInspector.TextEditor.prototype._startWorkerPrettyPrint):
+ Using the formatter here, we may have module scripts in the future.
+
+ * UserInterface/Views/SourceCodeTextEditor.js:
+ (WebInspector.SourceCodeTextEditor.prototype._showPopoverForFunction.didGetDetails):
+ Using the formatter for a function is not module source.
+
+ * UserInterface/Workers/Formatter/ESTreeWalker.js:
+ (ESTreeWalker.prototype._walkChildren):
+ Visit children of Export/Import nodes.
+
+ * UserInterface/Workers/Formatter/EsprimaFormatter.js:
+ (EsprimaFormatter.prototype._handleTokenAtNode):
+ Output tokens with appropriate whitespace.
+
</ins><span class="cx"> 2016-09-13 Chris Dumez <cdumez@apple.com>
</span><span class="cx">
</span><span class="cx"> Drop support for <isindex>
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIToolsFormattingEsprimaFormatterDebugjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/Tools/Formatting/EsprimaFormatterDebug.js (205865 => 205866)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/Tools/Formatting/EsprimaFormatterDebug.js        2016-09-13 18:20:28 UTC (rev 205865)
+++ trunk/Source/WebInspectorUI/Tools/Formatting/EsprimaFormatterDebug.js        2016-09-13 18:37:12 UTC (rev 205866)
</span><span class="lines">@@ -1,8 +1,8 @@
</span><span class="cx"> EsprimaFormatterDebug = class EsprimaFormatterDebug
</span><span class="cx"> {
</span><del>- constructor(sourceText)
</del><ins>+ constructor(sourceText, sourceType)
</ins><span class="cx"> {
</span><del>- let tree = esprima.parse(sourceText, {attachComment: true, range: true, tokens: true});
</del><ins>+ let tree = esprima.parse(sourceText, {attachComment: true, range: true, tokens: true, sourceType});
</ins><span class="cx"> let walker = new ESTreeWalker(this._before.bind(this), this._after.bind(this));
</span><span class="cx">
</span><span class="cx"> this._statistics = {
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIToolsFormattingindexhtml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/Tools/Formatting/index.html (205865 => 205866)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/Tools/Formatting/index.html        2016-09-13 18:20:28 UTC (rev 205865)
+++ trunk/Source/WebInspectorUI/Tools/Formatting/index.html        2016-09-13 18:37:12 UTC (rev 205866)
</span><span class="lines">@@ -20,6 +20,10 @@
</span><span class="cx"> <!-- Controls -->
</span><span class="cx"> <button id="populate">Populate</button>
</span><span class="cx"> <select id="load-individual-test"><option>-- Load Test --</option></select>
</span><ins>+ <small>
+ <label><input id="program" type="radio" name="program-or-module"> Program</label>
+ <label><input id="module" type="radio" name="program-or-module" checked> Module</label>
+ </small>
</ins><span class="cx"> <button id="run-tests">Run All Tests</button>
</span><span class="cx"> <button id="clear">Clear</button>
</span><span class="cx"> <button id="select-output">Select Output</button>
</span><span class="lines">@@ -65,7 +69,7 @@
</span><span class="cx"> "sample-webinspector-object.js",
</span><span class="cx"> "sample-normal-utilities.js",
</span><span class="cx"> "sample-jquery.js",
</span><del>- // FIXME: Add a modules test when we support testing module source code.
</del><ins>+ "modules.js",
</ins><span class="cx"> ];
</span><span class="cx">
</span><span class="cx"> // Initial values from URL.
</span><span class="lines">@@ -83,6 +87,8 @@
</span><span class="cx"> let content = "(function(){let a=1;return a+1;})();";
</span><span class="cx"> if (queryParams.content)
</span><span class="cx"> content = queryParams.content || "";
</span><ins>+ if (queryParams.program)
+ document.getElementById("program").checked = true;
</ins><span class="cx">
</span><span class="cx"> // Setup CodeMirror.
</span><span class="cx"> let cm = CodeMirror.fromTextArea(document.getElementById("code"), {lineNumbers: true});
</span><span class="lines">@@ -110,6 +116,12 @@
</span><span class="cx"> option.value = test;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ // Program / Module checkboxes.
+ let programCheckbox = document.getElementById("program");
+ let moduleCheckbox = document.getElementById("module");
+ programCheckbox.addEventListener("change", refresh);
+ moduleCheckbox.addEventListener("change", refresh);
+
</ins><span class="cx"> // Run Tests button.
</span><span class="cx"> document.getElementById("run-tests").addEventListener("click", function(event) {
</span><span class="cx"> cm.setValue("/* Running Tests... */");
</span><span class="lines">@@ -140,7 +152,10 @@
</span><span class="cx"> // Save as URL button.
</span><span class="cx"> document.getElementById("save-as-url").addEventListener("click", function(event) {
</span><span class="cx"> let content = cm.getValue();
</span><del>- window.location.search = "?content=" + window.encodeURIComponent(content);
</del><ins>+ let queryString = "?content=" + window.encodeURIComponent(content);
+ if (programCheckbox.checked)
+ queryString += "&program";
+ window.location.search = queryString;
</ins><span class="cx"> });
</span><span class="cx">
</span><span class="cx"> // Refresh after changes after a short delay.
</span><span class="lines">@@ -160,6 +175,16 @@
</span><span class="cx"> let prettyPre = document.getElementById("pretty");
</span><span class="cx"> let debugPre = document.getElementById("debug");
</span><span class="cx">
</span><ins>+ // Current value of checkboxes.
+ function currentSourceType() {
+ if (programCheckbox.checked)
+ return EsprimaFormatter.SourceType.Script;
+ if (moduleCheckbox.checked)
+ return EsprimaFormatter.SourceType.Module;
+ console.assert(false, "Program or Module radio button should be checked");
+ return undefined;
+ }
+
</ins><span class="cx"> function refresh() {
</span><span class="cx"> if (timer)
</span><span class="cx"> clearTimeout(timer);
</span><span class="lines">@@ -166,13 +191,13 @@
</span><span class="cx">
</span><span class="cx"> // Time the formatter.
</span><span class="cx"> let startTime = Date.now();
</span><del>- let formatter = new EsprimaFormatter(cm.getValue());
</del><ins>+ let formatter = new EsprimaFormatter(cm.getValue(), currentSourceType());
</ins><span class="cx"> let endTime = Date.now();
</span><span class="cx">
</span><span class="cx"> // Show debug info.
</span><span class="cx"> let debugText;
</span><span class="cx"> try {
</span><del>- let debugFormatter = new EsprimaFormatterDebug(cm.getValue());
</del><ins>+ let debugFormatter = new EsprimaFormatterDebug(cm.getValue(), currentSourceType());
</ins><span class="cx"> debugText = debugFormatter.debugText;
</span><span class="cx"> } catch (error) {
</span><span class="cx"> debugText = "Parse error";
</span><span class="lines">@@ -188,6 +213,10 @@
</span><span class="cx">
</span><span class="cx"> // Testing.
</span><span class="cx">
</span><ins>+ function isModuleTest(test) {
+ return test === "modules.js";
+ }
+
</ins><span class="cx"> function loadIndividualTest(test) {
</span><span class="cx"> let testURL = testURLPrefix + test;
</span><span class="cx"> let xhr = new XMLHttpRequest;
</span><span class="lines">@@ -194,6 +223,11 @@
</span><span class="cx"> xhr.open("GET", testURL, true);
</span><span class="cx"> xhr.onload = () => { cm.setValue(xhr.responseText); setTimeout(refresh); }
</span><span class="cx"> xhr.send();
</span><ins>+
+ if (isModuleTest(test))
+ moduleCheckbox.checked = true;
+ else
+ programCheckbox.checked = true;
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> function runAllTests() {
</span><span class="lines">@@ -225,7 +259,8 @@
</span><span class="cx"> let expectedData = xhr2.responseText;
</span><span class="cx">
</span><span class="cx"> // Run the test.
</span><del>- let formatter = new EsprimaFormatter(testData);
</del><ins>+ let sourceType = isModuleTest(test) ? EsprimaFormatter.SourceType.Module : EsprimaFormatter.SourceType.Script;
+ let formatter = new EsprimaFormatter(testData, sourceType);
</ins><span class="cx">
</span><span class="cx"> // Compare results.
</span><span class="cx"> let pass = formatter.formattedText === expectedData;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceProxiesFormatterWorkerProxyjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Proxies/FormatterWorkerProxy.js (205865 => 205866)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Proxies/FormatterWorkerProxy.js        2016-09-13 18:20:28 UTC (rev 205865)
+++ trunk/Source/WebInspectorUI/UserInterface/Proxies/FormatterWorkerProxy.js        2016-09-13 18:37:12 UTC (rev 205866)
</span><span class="lines">@@ -47,7 +47,7 @@
</span><span class="cx">
</span><span class="cx"> // Actions
</span><span class="cx">
</span><del>- formatJavaScript(sourceText, indentString, includeSourceMapData)
</del><ins>+ formatJavaScript(sourceText, isModule, indentString, includeSourceMapData)
</ins><span class="cx"> {
</span><span class="cx"> this.performAction("formatJavaScript", ...arguments);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsSourceCodeTextEditorjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js (205865 => 205866)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js        2016-09-13 18:20:28 UTC (rev 205865)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SourceCodeTextEditor.js        2016-09-13 18:37:12 UTC (rev 205866)
</span><span class="lines">@@ -1523,8 +1523,9 @@
</span><span class="cx"> });
</span><span class="cx">
</span><span class="cx"> // FIXME: <rdar://problem/10593948> Provide a way to change the tab width in the Web Inspector
</span><ins>+ const isModule = false;
</ins><span class="cx"> let workerProxy = WebInspector.FormatterWorkerProxy.singleton();
</span><del>- workerProxy.formatJavaScript(data.description, " ", false, ({formattedText}) => {
</del><ins>+ workerProxy.formatJavaScript(data.description, isModule, " ", false, ({formattedText}) => {
</ins><span class="cx"> codeMirror.setValue(formattedText || data.description);
</span><span class="cx"> });
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceViewsTextEditorjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Views/TextEditor.js (205865 => 205866)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Views/TextEditor.js        2016-09-13 18:20:28 UTC (rev 205865)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/TextEditor.js        2016-09-13 18:37:12 UTC (rev 205866)
</span><span class="lines">@@ -792,8 +792,11 @@
</span><span class="cx"> let sourceText = this._codeMirror.getValue();
</span><span class="cx"> let includeSourceMapData = true;
</span><span class="cx">
</span><ins>+ // FIXME: Properly pass if this is a module or script.
+ const isModule = false;
+
</ins><span class="cx"> let workerProxy = WebInspector.FormatterWorkerProxy.singleton();
</span><del>- workerProxy.formatJavaScript(sourceText, indentString, includeSourceMapData, ({formattedText, sourceMapData}) => {
</del><ins>+ workerProxy.formatJavaScript(sourceText, isModule, indentString, includeSourceMapData, ({formattedText, sourceMapData}) => {
</ins><span class="cx"> // Handle if formatting failed, which is possible for invalid programs.
</span><span class="cx"> if (formattedText === null) {
</span><span class="cx"> callback();
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceWorkersFormatterESTreeWalkerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/ESTreeWalker.js (205865 => 205866)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/ESTreeWalker.js        2016-09-13 18:20:28 UTC (rev 205865)
+++ trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/ESTreeWalker.js        2016-09-13 18:37:12 UTC (rev 205866)
</span><span class="lines">@@ -240,6 +240,36 @@
</span><span class="cx"> this._walk(node.argument, node);
</span><span class="cx"> break;
</span><span class="cx">
</span><ins>+ case "ExportAllDeclaration":
+ this._walk(node.source, node);
+ break;
+ case "ExportNamedDeclaration":
+ this._walk(node.declaration, node);
+ this._walkArray(node.specifiers, node);
+ this._walk(node.source, node);
+ break;
+ case "ExportDefaultDeclaration":
+ this._walk(node.declaration, node);
+ break;
+ case "ExportSpecifier":
+ this._walk(node.local, node);
+ this._walk(node.exported, node);
+ break;
+ case "ImportDeclaration":
+ this._walkArray(node.specifiers, node);
+ this._walk(node.source, node);
+ break;
+ case "ImportDefaultSpecifier":
+ this._walk(node.local, node);
+ break;
+ case "ImportNamespaceSpecifier":
+ this._walk(node.local, node);
+ break;
+ case "ImportSpecifier":
+ this._walk(node.imported, node);
+ this._walk(node.local, node);
+ break;
+
</ins><span class="cx"> // Special case. We want to walk in program order,
</span><span class="cx"> // so walk quasi, expression, quasi, expression, etc.
</span><span class="cx"> case "TemplateLiteral":
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceWorkersFormatterEsprimaFormatterjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/EsprimaFormatter.js (205865 => 205866)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/EsprimaFormatter.js        2016-09-13 18:20:28 UTC (rev 205865)
+++ trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/EsprimaFormatter.js        2016-09-13 18:37:12 UTC (rev 205866)
</span><span class="lines">@@ -29,14 +29,13 @@
</span><span class="cx">
</span><span class="cx"> EsprimaFormatter = class EsprimaFormatter
</span><span class="cx"> {
</span><del>- constructor(sourceText, indentString = " ")
</del><ins>+ constructor(sourceText, sourceType, indentString = " ")
</ins><span class="cx"> {
</span><span class="cx"> this._success = false;
</span><span class="cx">
</span><span class="cx"> let tree = (function() {
</span><span class="cx"> try {
</span><del>- // FIXME: Support "module" sourceType as well.
- return esprima.parse(sourceText, {attachComment: true, range: true, tokens: true});
</del><ins>+ return esprima.parse(sourceText, {attachComment: true, range: true, tokens: true, sourceType});
</ins><span class="cx"> } catch (error) {
</span><span class="cx"> return null;
</span><span class="cx"> }
</span><span class="lines">@@ -738,7 +737,8 @@
</span><span class="cx">
</span><span class="cx"> if (nodeType === "ClassBody") {
</span><span class="cx"> if (tokenValue === "{") {
</span><del>- builder.appendSpace();
</del><ins>+ if (node.parent.id)
+ builder.appendSpace();
</ins><span class="cx"> builder.appendToken(tokenValue, tokenOffset);
</span><span class="cx"> if (node.body.length)
</span><span class="cx"> builder.appendNewline();
</span><span class="lines">@@ -778,6 +778,30 @@
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ if (nodeType === "ImportDeclaration" || nodeType === "ExportNamedDeclaration") {
+ if (tokenValue === "}" || (tokenType === "Identifier" && tokenValue === "from"))
+ builder.appendSpace();
+ builder.appendToken(tokenValue, tokenOffset);
+ if (tokenValue !== "}")
+ builder.appendSpace();
+ return;
+ }
+
+ if (nodeType === "ExportSpecifier" || nodeType === "ImportSpecifier") {
+ if (tokenType === "Identifier" && tokenValue === "as")
+ builder.appendSpace();
+ builder.appendToken(tokenValue, tokenOffset);
+ builder.appendSpace();
+ return;
+ }
+
+ if (nodeType === "ExportAllDeclaration" || nodeType === "ExportDefaultDeclaration" || nodeType === "ImportDefaultSpecifier" || nodeType === "ImportNamespaceSpecifier") {
+ builder.appendToken(tokenValue, tokenOffset);
+ if (tokenValue !== "(" && tokenValue !== ")")
+ builder.appendSpace();
+ return;
+ }
+
</ins><span class="cx"> // Include these here so we get only get warnings about unhandled nodes.
</span><span class="cx"> if (nodeType === "ExpressionStatement"
</span><span class="cx"> || nodeType === "SpreadElement"
</span><span class="lines">@@ -876,3 +900,8 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx"> };
</span><ins>+
+EsprimaFormatter.SourceType = {
+ Script: "script",
+ Module: "module",
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceWorkersFormatterFormatterWorkerjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/FormatterWorker.js (205865 => 205866)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/FormatterWorker.js        2016-09-13 18:20:28 UTC (rev 205865)
+++ trunk/Source/WebInspectorUI/UserInterface/Workers/Formatter/FormatterWorker.js        2016-09-13 18:37:12 UTC (rev 205866)
</span><span class="lines">@@ -40,10 +40,12 @@
</span><span class="cx">
</span><span class="cx"> // Actions
</span><span class="cx">
</span><del>- formatJavaScript(sourceText, indentString, includeSourceMapData)
</del><ins>+ formatJavaScript(sourceText, isModule, indentString, includeSourceMapData)
</ins><span class="cx"> {
</span><ins>+ let sourceType = isModule ? EsprimaFormatter.SourceType.Module : EsprimaFormatter.SourceType.Script;
+
</ins><span class="cx"> // Format a JavaScript program.
</span><del>- let formatter = new EsprimaFormatter(sourceText, indentString);
</del><ins>+ let formatter = new EsprimaFormatter(sourceText, sourceType, indentString);
</ins><span class="cx"> if (formatter.success) {
</span><span class="cx"> let result = {formattedText: formatter.formattedText};
</span><span class="cx"> if (includeSourceMapData) {
</span><span class="lines">@@ -74,7 +76,7 @@
</span><span class="cx"> // Likewise, an unnamed function's toString() produces a "function() { ... }", which is not
</span><span class="cx"> // a valid program on its own. Wrap it in parenthesis to make it a function expression,
</span><span class="cx"> // which is a valid program.
</span><del>- let invalidJSONFormatter = new EsprimaFormatter("(" + sourceText + ")", indentString);
</del><ins>+ let invalidJSONFormatter = new EsprimaFormatter("(" + sourceText + ")", sourceType, indentString);
</ins><span class="cx"> if (invalidJSONFormatter.success) {
</span><span class="cx"> let formattedTextWithParens = invalidJSONFormatter.formattedText;
</span><span class="cx"> let result = {formattedText: formattedTextWithParens.substring(1, formattedTextWithParens.length - 2)}; // Remove "(" and ")\n".
</span></span></pre>
</div>
</div>
</body>
</html>