<!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
&lt;rdar://problem/28272784&gt;

Patch by Joseph Pecoraro &lt;pecoraro@apple.com&gt; 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  &lt;pecoraro@apple.com&gt;
+
+        Web Inspector: Should be able to pretty print module code (import / export statements)
+        https://bugs.webkit.org/show_bug.cgi?id=161891
+        &lt;rdar://problem/28272784&gt;
+
+        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  &lt;ryanhaddad@apple.com&gt;
</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">         &quot;resources/javascript-tests/variable-declaration.js&quot;,
</span><span class="cx">         &quot;resources/javascript-tests/while-statement.js&quot;,
</span><span class="cx">         &quot;resources/javascript-tests/with-statement.js&quot;,
</span><ins>+
+        // Modules
+        &quot;resources/javascript-tests/modules.js&quot;,
</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(&quot;EsprimaFormatter.JSON&quot;);
</span><span class="cx"> 
</span><del>-    let indentString = &quot;    &quot;;
</del><ins>+    const isModule = false;
+    const indentString = &quot;    &quot;;
</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({&quot;a&quot;:123,&quot;b&quot;:[1,2,3],&quot;c&quot;:{&quot;d&quot;:&quot;e&quot;}});
</span><span class="cx">             InspectorTest.log(&quot;JSON: &quot; + doubleQuotedString(validJSON));
</span><span class="cx">             ensureJSON(validJSON, &quot;valid&quot;);
</span><del>-            workerProxy.formatJavaScript(validJSON, indentString, ({formattedText, sourceMapData}) =&gt; {
</del><ins>+            workerProxy.formatJavaScript(validJSON, isModule, indentString, ({formattedText, sourceMapData}) =&gt; {
</ins><span class="cx">                 InspectorTest.log(&quot;FORMATTED:&quot;);
</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(&quot;JSON: &quot; + doubleQuotedString(invalidJSON));
</span><span class="cx">             ensureJSON(invalidJSON, &quot;invalid&quot;);
</span><span class="cx">             ensureEval(invalidJSON, &quot;object&quot;);
</span><del>-            workerProxy.formatJavaScript(invalidJSON, indentString, ({formattedText, sourceMapData}) =&gt; {
</del><ins>+            workerProxy.formatJavaScript(invalidJSON, isModule, indentString, ({formattedText, sourceMapData}) =&gt; {
</ins><span class="cx">                 InspectorTest.log(&quot;FORMATTED:&quot;);
</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(&quot;JSON: &quot; + doubleQuotedString(invalidJSON));
</span><span class="cx">             ensureJSON(invalidJSON, &quot;invalid&quot;);
</span><span class="cx">             ensureEval(invalidJSON, &quot;object&quot;);
</span><del>-            workerProxy.formatJavaScript(invalidJSON, indentString, ({formattedText, sourceMapData}) =&gt; {
</del><ins>+            workerProxy.formatJavaScript(invalidJSON, isModule, indentString, ({formattedText, sourceMapData}) =&gt; {
</ins><span class="cx">                 InspectorTest.log(&quot;FORMATTED:&quot;);
</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(&quot;INPUT: &quot; + doubleQuotedString(invalid));
</span><span class="cx">             ensureJSON(invalid, &quot;invalid&quot;);
</span><span class="cx">             ensureEval(invalid, &quot;bad&quot;);
</span><del>-            workerProxy.formatJavaScript(invalid, indentString, ({formattedText, sourceMapData}) =&gt; {
</del><ins>+            workerProxy.formatJavaScript(invalid, isModule, indentString, ({formattedText, sourceMapData}) =&gt; {
</ins><span class="cx">                 InspectorTest.expectThat(formattedText === null, &quot;Response should be null.&quot;);
</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 &quot;module&quot;;
+import x from &quot;module&quot;;
+import { x } from &quot;module&quot;;
+import { a, b, c } from &quot;module&quot;;
+import { a, b, c,  } from &quot;module&quot;;
+import { a as A } from &quot;module&quot;;
+import { a, a as A, a } from &quot;module&quot;;
+import { a as A, a as A } from &quot;module&quot;;
+import a, { a } from &quot;module&quot;;
+import a, { a as A } from &quot;module&quot;;
+import x, * as A from &quot;module&quot;;
+import * as A from &quot;module&quot;;
+
+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 &quot;module&quot;;
+export { x } from &quot;module&quot;;
+export { x, y } from &quot;module&quot;;
+export { x as A } from &quot;module&quot;;
+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&quot;module&quot;;
+import x from&quot;module&quot;;
+import{x}from&quot;module&quot;;
+import{a,b,c}from&quot;module&quot;;
+import{a,b,c,}from&quot;module&quot;;
+import{a as A}from&quot;module&quot;;
+import{a,a as A,a}from&quot;module&quot;;
+import{a as A,a as A}from&quot;module&quot;;
+import a,{a}from&quot;module&quot;;
+import a,{a as A}from&quot;module&quot;;
+import x,*as A from&quot;module&quot;;
+import*as A from&quot;module&quot;;
+
+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&quot;module&quot;;
+export{x}from&quot;module&quot;;
+export{x,y}from&quot;module&quot;;
+export{x as A}from&quot;module&quot;;
+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 = &quot;    &quot;;
</span><span class="cx">                 let workerProxy = WebInspector.FormatterWorkerProxy.singleton();
</span><del>-                workerProxy.formatJavaScript(testText, indentString, ({formattedText, sourceMapData}) =&gt; {
</del><ins>+                let isModule = /^module/.test(testName);
+                workerProxy.formatJavaScript(testText, isModule, indentString, ({formattedText, sourceMapData}) =&gt; {
</ins><span class="cx">                     let pass = formattedText === expectedText;
</span><span class="cx">                     InspectorTest.log(pass ? &quot;PASS&quot; : &quot;FAIL&quot;);
</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  &lt;pecoraro@apple.com&gt;
+
+        Web Inspector: Should be able to pretty print module code (import / export statements)
+        https://bugs.webkit.org/show_bug.cgi?id=161891
+        &lt;rdar://problem/28272784&gt;
+
+        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  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Drop support for &lt;isindex&gt;
</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">     &lt;!-- Controls --&gt;
</span><span class="cx">     &lt;button id=&quot;populate&quot;&gt;Populate&lt;/button&gt;
</span><span class="cx">     &lt;select id=&quot;load-individual-test&quot;&gt;&lt;option&gt;-- Load Test --&lt;/option&gt;&lt;/select&gt;
</span><ins>+    &lt;small&gt;
+        &lt;label&gt;&lt;input id=&quot;program&quot; type=&quot;radio&quot; name=&quot;program-or-module&quot;&gt; Program&lt;/label&gt;
+        &lt;label&gt;&lt;input id=&quot;module&quot; type=&quot;radio&quot; name=&quot;program-or-module&quot; checked&gt; Module&lt;/label&gt;
+    &lt;/small&gt;
</ins><span class="cx">     &lt;button id=&quot;run-tests&quot;&gt;Run All Tests&lt;/button&gt;
</span><span class="cx">     &lt;button id=&quot;clear&quot;&gt;Clear&lt;/button&gt;
</span><span class="cx">     &lt;button id=&quot;select-output&quot;&gt;Select Output&lt;/button&gt;
</span><span class="lines">@@ -65,7 +69,7 @@
</span><span class="cx">         &quot;sample-webinspector-object.js&quot;,
</span><span class="cx">         &quot;sample-normal-utilities.js&quot;,
</span><span class="cx">         &quot;sample-jquery.js&quot;,
</span><del>-        // FIXME: Add a modules test when we support testing module source code.
</del><ins>+        &quot;modules.js&quot;,
</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 = &quot;(function(){let a=1;return a+1;})();&quot;;
</span><span class="cx">     if (queryParams.content)
</span><span class="cx">         content = queryParams.content || &quot;&quot;;
</span><ins>+    if (queryParams.program)
+        document.getElementById(&quot;program&quot;).checked = true;
</ins><span class="cx"> 
</span><span class="cx">     // Setup CodeMirror.
</span><span class="cx">     let cm = CodeMirror.fromTextArea(document.getElementById(&quot;code&quot;), {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(&quot;program&quot;);
+    let moduleCheckbox = document.getElementById(&quot;module&quot;);
+    programCheckbox.addEventListener(&quot;change&quot;, refresh);
+    moduleCheckbox.addEventListener(&quot;change&quot;, refresh);
+
</ins><span class="cx">     // Run Tests button.
</span><span class="cx">     document.getElementById(&quot;run-tests&quot;).addEventListener(&quot;click&quot;, function(event) {
</span><span class="cx">         cm.setValue(&quot;/* Running Tests... */&quot;);
</span><span class="lines">@@ -140,7 +152,10 @@
</span><span class="cx">     // Save as URL button.
</span><span class="cx">     document.getElementById(&quot;save-as-url&quot;).addEventListener(&quot;click&quot;, function(event) {
</span><span class="cx">         let content = cm.getValue();
</span><del>-        window.location.search = &quot;?content=&quot; + window.encodeURIComponent(content);
</del><ins>+        let queryString = &quot;?content=&quot; + window.encodeURIComponent(content);
+        if (programCheckbox.checked)
+            queryString += &quot;&amp;program&quot;;
+        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(&quot;pretty&quot;);
</span><span class="cx">     let debugPre = document.getElementById(&quot;debug&quot;);
</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, &quot;Program or Module radio button should be checked&quot;);
+        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 = &quot;Parse error&quot;;
</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 === &quot;modules.js&quot;;
+    }
+
</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(&quot;GET&quot;, testURL, true);
</span><span class="cx">         xhr.onload = () =&gt; { 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(&quot;formatJavaScript&quot;, ...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: &lt;rdar://problem/10593948&gt; 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, &quot;    &quot;, false, ({formattedText}) =&gt; {
</del><ins>+            workerProxy.formatJavaScript(data.description, isModule, &quot;    &quot;, false, ({formattedText}) =&gt; {
</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}) =&gt; {
</del><ins>+        workerProxy.formatJavaScript(sourceText, isModule, indentString, includeSourceMapData, ({formattedText, sourceMapData}) =&gt; {
</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 &quot;ExportAllDeclaration&quot;:
+            this._walk(node.source, node);
+            break;
+        case &quot;ExportNamedDeclaration&quot;:
+            this._walk(node.declaration, node);
+            this._walkArray(node.specifiers, node);
+            this._walk(node.source, node);
+            break;
+        case &quot;ExportDefaultDeclaration&quot;:
+            this._walk(node.declaration, node);
+            break;
+        case &quot;ExportSpecifier&quot;:
+            this._walk(node.local, node);
+            this._walk(node.exported, node);
+            break;
+        case &quot;ImportDeclaration&quot;:
+            this._walkArray(node.specifiers, node);
+            this._walk(node.source, node);
+            break;
+        case &quot;ImportDefaultSpecifier&quot;:
+            this._walk(node.local, node);
+            break;
+        case &quot;ImportNamespaceSpecifier&quot;:
+            this._walk(node.local, node);
+            break;
+        case &quot;ImportSpecifier&quot;:
+            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 &quot;TemplateLiteral&quot;:
</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 = &quot;    &quot;)
</del><ins>+    constructor(sourceText, sourceType, indentString = &quot;    &quot;)
</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 &quot;module&quot; 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 === &quot;ClassBody&quot;) {
</span><span class="cx">             if (tokenValue === &quot;{&quot;) {
</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 === &quot;ImportDeclaration&quot; || nodeType === &quot;ExportNamedDeclaration&quot;) {
+            if (tokenValue === &quot;}&quot; || (tokenType === &quot;Identifier&quot; &amp;&amp; tokenValue === &quot;from&quot;))
+                builder.appendSpace();
+            builder.appendToken(tokenValue, tokenOffset);
+            if (tokenValue !== &quot;}&quot;)
+                builder.appendSpace();
+            return;
+        }
+
+        if (nodeType === &quot;ExportSpecifier&quot; || nodeType === &quot;ImportSpecifier&quot;) {
+            if (tokenType === &quot;Identifier&quot; &amp;&amp; tokenValue === &quot;as&quot;)
+                builder.appendSpace();
+            builder.appendToken(tokenValue, tokenOffset);
+            builder.appendSpace();
+            return;            
+        }
+
+        if (nodeType === &quot;ExportAllDeclaration&quot; || nodeType === &quot;ExportDefaultDeclaration&quot; || nodeType === &quot;ImportDefaultSpecifier&quot; || nodeType === &quot;ImportNamespaceSpecifier&quot;) {
+            builder.appendToken(tokenValue, tokenOffset);
+            if (tokenValue !== &quot;(&quot; &amp;&amp; tokenValue !== &quot;)&quot;)
+                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 === &quot;ExpressionStatement&quot;
</span><span class="cx">             || nodeType === &quot;SpreadElement&quot;
</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: &quot;script&quot;,
+    Module: &quot;module&quot;,
+};
</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 &quot;function() { ... }&quot;, 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(&quot;(&quot; + sourceText + &quot;)&quot;, indentString);
</del><ins>+        let invalidJSONFormatter = new EsprimaFormatter(&quot;(&quot; + sourceText + &quot;)&quot;, 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 &quot;(&quot; and &quot;)\n&quot;.
</span></span></pre>
</div>
</div>

</body>
</html>