diff --git a/website/css/style.css b/website/css/style.css index c2bb98cf9..c1b92c894 100644 --- a/website/css/style.css +++ b/website/css/style.css @@ -630,29 +630,63 @@ img.nav-logo { .legend-header { text-align: center; - align: center; } .legend-table { text-align: center; - align: center; margin: 0 auto; padding-bottom: 3%; border-spacing: 5%; } -.repl, .error { +.repl { width: 100%; height: 100%; } -.error { - padding: 10px; +.messagesContainer { + width: 100%; + height: auto; + position: absolute; + bottom: 0; + z-index: 5; /* one more than ace_gutter */ + overflow-x: scroll; + overflow-y: hidden; +} + +.messages { + display: inline-block; + min-width: 100%; + height: 100%; font-family: "Operator Mono", "Fira Code", "Ubuntu Mono", "Droid Sans Mono", "Liberation Mono", "Source Code Pro", Menlo, Monaco, Consolas, "Courier New", monospace; - color: #c7254e; white-space: pre; } +.message { + width: 100%; + padding: 10px; +} + +.message.error { + color: #c7254e; + background-color:#ffefee; + border-top: 1px solid #ffe1e0; +} + +.message.error > .line-link { + color: red; +} + +.message.warning { + color: #8a6f40; + background-color:#fffae5; + border-top: 1px solid #fff6cc; +} + +.message.warning > .line-link { + color: #7d7d7d; +} + .align-left { text-align: left; } diff --git a/website/js/repl-worker.js b/website/js/repl-worker.js index 898939922..05279274d 100644 --- a/website/js/repl-worker.js +++ b/website/js/repl-worker.js @@ -1,5 +1,11 @@ self.importScripts('prepack.min.js'); +function onlyWarnings(buffer) { + return buffer.every(function(error) { + return error.severity === "Warning" || error.severity === "Information"; + }); +} + onmessage = function(e) { let buffer = []; @@ -33,9 +39,11 @@ onmessage = function(e) { options[property] = e.data.options[property]; } } + let result = Prepack.prepackSources(sources, options); - if (result && !buffer.length) { - postMessage({ type: 'success', data: result.code, graph: result.heapGraph }); + let noErrors = onlyWarnings(buffer); + if (result && noErrors) { + postMessage({ type: 'success', data: result.code, graph: result.heapGraph, messages: buffer }); } else { // A well-defined error occurred. postMessage({ type: 'error', data: buffer }); diff --git a/website/js/repl.js b/website/js/repl.js index 515f8d710..030f87191 100644 --- a/website/js/repl.js +++ b/website/js/repl.js @@ -94,7 +94,7 @@ function generateDemosSelect(obj, dom) { var worker; var debounce; -var errorOutput = document.querySelector('.output .error'); +var messagesOutput = document.querySelector('.input .messages'); var replOutput = document.querySelector('.output .repl'); var isEmpty = /^\s*$/; @@ -106,34 +106,76 @@ function terminateWorker() { } } -function processError(errorOutput, error) { - let errorWikiLink = document.createElement('a'); - errorWikiLink.href = 'https://github.com/facebook/prepack/wiki/' + encodeURIComponent(error.errorCode); - errorWikiLink.text = error.errorCode; - errorWikiLink.setAttribute('target', '_blank'); +function createWikiLink(code) { + const wikiLink = document.createElement('a'); + wikiLink.href = 'https://github.com/facebook/prepack/wiki/' + encodeURIComponent(code); + wikiLink.text = code; + wikiLink.setAttribute('target', '_blank'); + + return wikiLink; +} + +function createLineLink(location) { + const lineLink = document.createElement('a'); + let lineNumber = location.start ? location.start.line : location.line; + let colNumber = location.start ? location.start.column : location.column; + colNumber++; + let lineText = lineNumber + ':' + colNumber; + + lineLink.href = ''; + lineLink.onclick = function() { + input.gotoLine(lineNumber); + return false; + }; + lineLink.text = lineText; + lineLink.classList.add("line-link"); + + return lineLink; +} + +function processMessage(messageNode, data) { // TODO: syntax errors need their location stripped - if (error.location) { - let errorLineLink = document.createElement('a'); - let lineNumber = error.location.start ? error.location.start.line : error.location.line; - let colNumber = error.location.start ? error.location.start.column : error.location.column; - colNumber++; - let lineText = lineNumber + ':' + colNumber; - errorLineLink.href = ''; - errorLineLink.onclick = function() { - input.gotoLine(lineNumber); - return false; - }; - errorLineLink.text = lineText; - errorLineLink.style.color = 'red'; - errorOutput.appendChild(errorWikiLink); - errorOutput.appendChild(document.createTextNode(' (')); - errorOutput.appendChild(errorLineLink); - errorOutput.appendChild(document.createTextNode('): ' + error.message + '\n')); - } else if (!error.code) { - errorOutput.appendChild(document.createTextNode(error.message + '\n')); + if (data.location) { + const wikiLink = createWikiLink(data.errorCode); + const lineLink = createLineLink(data.location); + messageNode.appendChild(wikiLink); + messageNode.appendChild(document.createTextNode(' (')); + messageNode.appendChild(lineLink); + messageNode.appendChild(document.createTextNode('): ' + data.message + '\n')); + } else if (!data.code) { + messageNode.appendChild(document.createTextNode(data.message + '\n')); } else { - errorOutput.appendChild(errorWikiLink); - errorOutput.appendChild(document.createTextNode(': ' + error.message + '\n')); + const wikiLink = createWikiLink(data.errorCode); + messageNode.appendChild(wikiLink); + messageNode.appendChild(document.createTextNode(': ' + data.message + '\n')); + } +} + +function getMessageClassType(severity) { + switch(severity) { + case "FatalError": + return "error"; + case "RecoverableError": + return "error"; + case "Warning": + return "warning"; + case "Information": + return "warning"; + default: + return "error"; + } +} + +function showMessages(messages) { + messagesOutput.style.display = 'inline-block'; + + for (var i in messages) { + const message = document.createElement('div'); + message.classList.add("message", getMessageClassType(messages[i].severity)); + + processMessage(message, messages[i]); + + messagesOutput.appendChild(message); } } @@ -151,12 +193,37 @@ function makeDemoSharable() { history.replaceState(undefined, undefined, `#${encoded}`); } +function showGeneratedCode(code) { + if (isEmpty.test(code) && !isEmpty.test(input.getValue())) { + code = + '// Your code was all dead code and thus eliminated.\n' + '// Try storing a property on the global object.'; + } + output.setValue(code, -1); +} + +function showGenerationGraph(graph) { + drawGraphCallback = () => { + if (graph) { + var graphData = JSON.parse(graph); + var visData = { + nodes: graphData.nodes, + edges: graphData.edges, + }; + + var visOptions = {}; + var boxNetwork = new vis.Network(graphBox, visData, visOptions); + } + }; + + if (showGraphDiv) drawGraphCallback(); +} + function compile() { clearTimeout(debounce); terminateWorker(); - errorOutput.innerHTML = ''; - errorOutput.style.display = 'none'; + messagesOutput.innerHTML = ''; + messagesOutput.style.display = 'none'; replOutput.style.display = 'block'; output.setValue('// Compiling...', -1); @@ -164,42 +231,16 @@ function compile() { debounce = setTimeout(function() { worker = new Worker('js/repl-worker.js'); worker.onmessage = function(e) { - // turn off compiling - - var result = e.data; + const result = e.data; if (result.type === 'success') { - var code = result.data; - if (isEmpty.test(code) && !isEmpty.test(input.getValue())) { - code = - '// Your code was all dead code and thus eliminated.\n' + '// Try storing a property on the global object.'; - } - drawGraphCallback = () => { - var graphData = JSON.parse(result.graph); - var visData = { - nodes: graphData.nodes, - edges: graphData.edges - } - - var visOptions = {}; - var boxNetwork = new vis.Network(graphBox, visData, visOptions); - } - if (showGraphDiv) { - drawGraphCallback(); - } - output.setValue(code, -1); + const { data, graph, messages } = result; + showGeneratedCode(data); + showGenerationGraph(graph); + showMessages(messages); } else if (result.type === 'error') { - let errors = result.data; - if (typeof errors === 'string') { - errorOutput.style.display = 'block'; - replOutput.style.display = 'none'; - errorOutput.textContent = errors; - } else { - errorOutput.style.display = 'block'; - replOutput.style.display = 'none'; - for (var i in errors) { - processError(errorOutput, errors[i]); - } - } + const errors = result.data; + showMessages(errors); + output.setValue('// Prepack is unable to produce output for this input.\n// Please check the left pane for diagnostic information.', -1); } terminateWorker(); }; @@ -234,7 +275,6 @@ input.on('change', compile); input.on('change', makeDemoSharable); /**record **/ - var selectRecord = document.querySelector('select.select-record'); var optionsRecord = document.querySelector('#optionsMenuRecord'); var selectInput = document.querySelector('#recordName'); diff --git a/website/repl.html b/website/repl.html index 7c70a44b8..f6fa05592 100644 --- a/website/repl.html +++ b/website/repl.html @@ -67,11 +67,13 @@