Update js formatting

This commit is contained in:
Robert Masen 2018-06-15 12:55:37 -05:00
parent 19d6cf1488
commit 2d7e7cd73e
8 changed files with 2461 additions and 1390 deletions

31
.eslintrc.js Normal file
View File

@ -0,0 +1,31 @@
module.exports = {
env: {
es6: true,
browser: true,
commonjs: true,
node: true
},
extends: 'eslint:recommended',
parserOptions: {
sourceType: 'module'
},
rules: {
indent: ['error', 4],
'linebreak-style': [
'error',
'unix'
],
quotes: [
'error',
'single'
],
semi: [
'error',
'always'
],
'no-console': 0,
'no-undef':
'warn',
'no-unused-vars': 'warn'
}
};

View File

@ -11,7 +11,10 @@ matrix:
# Tests pass on nightly # Tests pass on nightly
- rust: nightly - rust: nightly
before_install: rustup target add wasm32-unknown-unknown before_install: rustup target add wasm32-unknown-unknown
script: cargo test script:
- cargo test
# Check JS output from all tests against eslint
- ./node_modules/.bin/eslint ./target/generated-tests/*/out*.js
env: RUST_BACKTRACE=1 env: RUST_BACKTRACE=1
# WebIDL tests pass on nightly # WebIDL tests pass on nightly

View File

@ -1,6 +1,6 @@
use failure::Error; use failure::Error;
use super::{indent, Context}; use super::Context;
use descriptor::{Descriptor, Function}; use descriptor::{Descriptor, Function};
/// Helper struct for manufacturing a shim in JS used to translate JS types to /// Helper struct for manufacturing a shim in JS used to translate JS types to
@ -305,7 +305,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
} }
Descriptor::Char => { Descriptor::Char => {
self.ret_ty = "string".to_string(); self.ret_ty = "string".to_string();
self.ret_expr = format!("return String.fromCodePoint(RET)") self.ret_expr = format!("return String.fromCodePoint(RET);")
} }
Descriptor::Anyref => { Descriptor::Anyref => {
self.ret_ty = "any".to_string(); self.ret_ty = "any".to_string();
@ -333,7 +333,7 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(", "); .join(", ");
let mut js = format!("{}({}) {{\n", prefix, js_args); let mut js = format!("{}({}) {{\n", prefix, js_args);
js.push_str(&indent(&self.prelude)); js.push_str(&self.prelude);
let rust_args = self.rust_arguments.join(", "); let rust_args = self.rust_arguments.join(", ");
let invoc = self.ret_expr.replace("RET", &format!("{}({})", invoc, rust_args)); let invoc = self.ret_expr.replace("RET", &format!("{}({})", invoc, rust_args));
@ -342,18 +342,17 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
} else { } else {
format!("\ format!("\
try {{\n\ try {{\n\
{}\ {}
}} finally {{\n\ \n}} finally {{\n\
{}\ {}
}}\n\ }}\n\
", ",
indent(&invoc), &invoc,
indent(&self.finally), &self.finally,
) )
}; };
js.push_str(&indent(&invoc)); js.push_str(&invoc);
js.push_str("}"); js.push_str("\n}");
let ts_args = self.js_arguments let ts_args = self.js_arguments
.iter() .iter()
.map(|s| format!("{}: {}", s.0, s.1)) .map(|s| format!("{}: {}", s.0, s.1))

View File

@ -55,7 +55,7 @@ pub struct SubContext<'a, 'b: 'a> {
impl<'a> Context<'a> { impl<'a> Context<'a> {
fn export(&mut self, name: &str, contents: &str, comments: Option<String>) { fn export(&mut self, name: &str, contents: &str, comments: Option<String>) {
let contents = deindent(contents); let contents = contents;
let contents = contents.trim(); let contents = contents.trim();
if let Some(ref c) = comments { if let Some(ref c) = comments {
self.globals.push_str(c); self.globals.push_str(c);
@ -110,8 +110,7 @@ impl<'a> Context<'a> {
me.expose_get_object(); me.expose_get_object();
let bump_cnt = if me.config.debug { let bump_cnt = if me.config.debug {
String::from(" String::from("
if (typeof(val) === 'number') if (typeof(val) === 'number') throw new Error('corrupt slab');
throw new Error('corrupt slab');
val.cnt += 1; val.cnt += 1;
") ")
} else { } else {
@ -120,8 +119,7 @@ impl<'a> Context<'a> {
Ok(format!(" Ok(format!("
function(idx) {{ function(idx) {{
// If this object is on the stack promote it to the heap. // If this object is on the stack promote it to the heap.
if ((idx & 1) === 1) if ((idx & 1) === 1) return addHeapObject(getObject(idx));
return addHeapObject(getObject(idx));
// Otherwise if the object is on the heap just bump the // Otherwise if the object is on the heap just bump the
// refcount and move on // refcount and move on
@ -134,7 +132,9 @@ impl<'a> Context<'a> {
self.bind("__wbindgen_object_drop_ref", &|me| { self.bind("__wbindgen_object_drop_ref", &|me| {
me.expose_drop_ref(); me.expose_drop_ref();
Ok("function(i) { dropRef(i); }".to_string()) Ok("function(i) {
dropRef(i);
}".to_string())
})?; })?;
self.bind("__wbindgen_string_new", &|me| { self.bind("__wbindgen_string_new", &|me| {
@ -149,7 +149,9 @@ impl<'a> Context<'a> {
self.bind("__wbindgen_number_new", &|me| { self.bind("__wbindgen_number_new", &|me| {
me.expose_add_heap_object(); me.expose_add_heap_object();
Ok(String::from("function(i) { return addHeapObject(i); }")) Ok(String::from("function(i) {
return addHeapObject(i);
}"))
})?; })?;
self.bind("__wbindgen_number_get", &|me| { self.bind("__wbindgen_number_get", &|me| {
@ -158,8 +160,7 @@ impl<'a> Context<'a> {
Ok(format!(" Ok(format!("
function(n, invalid) {{ function(n, invalid) {{
let obj = getObject(n); let obj = getObject(n);
if (typeof(obj) === 'number') if (typeof(obj) === 'number') return obj;
return obj;
getUint8Memory()[invalid] = 1; getUint8Memory()[invalid] = 1;
return 0; return 0;
}} }}
@ -168,7 +169,9 @@ impl<'a> Context<'a> {
self.bind("__wbindgen_undefined_new", &|me| { self.bind("__wbindgen_undefined_new", &|me| {
me.expose_add_heap_object(); me.expose_add_heap_object();
Ok(String::from("function() { return addHeapObject(undefined); }")) Ok(String::from("function() {
return addHeapObject(undefined);
}"))
})?; })?;
self.bind("__wbindgen_null_new", &|me| { self.bind("__wbindgen_null_new", &|me| {
@ -253,8 +256,7 @@ impl<'a> Context<'a> {
Ok(String::from(" Ok(String::from("
function(i, len_ptr) { function(i, len_ptr) {
let obj = getObject(i); let obj = getObject(i);
if (typeof(obj) !== 'string') if (typeof(obj) !== 'string') return 0;
return 0;
const [ptr, len] = passStringToWasm(obj); const [ptr, len] = passStringToWasm(obj);
getUint32Memory()[len_ptr / 4] = len; getUint32Memory()[len_ptr / 4] = len;
return ptr; return ptr;
@ -442,7 +444,7 @@ impl<'a> Context<'a> {
", class = name, constructor = constructor)); ", class = name, constructor = constructor));
} else { } else {
dst.push_str("throw new Error('you cannot invoke `new` directly without having a \ dst.push_str("throw new Error('you cannot invoke `new` directly without having a \
method annotated a constructor');"); method annotated a constructor');\n");
} }
dst.push_str("}"); dst.push_str("}");
@ -649,34 +651,28 @@ impl<'a> Context<'a> {
self.expose_global_slab_next(); self.expose_global_slab_next();
let validate_owned = if self.config.debug { let validate_owned = if self.config.debug {
String::from(" String::from("
if ((idx & 1) === 1) if ((idx & 1) === 1) throw new Error('cannot drop ref of stack objects');
throw new Error('cannot drop ref of stack objects');
") ")
} else { } else {
String::new() String::new()
}; };
let dec_ref = if self.config.debug { let dec_ref = if self.config.debug {
String::from(" String::from("
if (typeof(obj) === 'number') if (typeof(obj) === 'number') throw new Error('corrupt slab');
throw new Error('corrupt slab');
obj.cnt -= 1; obj.cnt -= 1;
if (obj.cnt > 0) if (obj.cnt > 0) return;
return;
") ")
} else { } else {
String::from(" String::from("
obj.cnt -= 1; obj.cnt -= 1;
if (obj.cnt > 0) if (obj.cnt > 0) return;
return;
") ")
}; };
self.global(&format!(" self.global(&format!("
function dropRef(idx) {{ function dropRef(idx) {{
{} {}
let obj = slab[idx >> 1]; let obj = slab[idx >> 1];
{} {}
// If we hit 0 then free up our space in the slab // If we hit 0 then free up our space in the slab
slab[idx >> 1] = slab_next; slab[idx >> 1] = slab_next;
slab_next = idx >> 1; slab_next = idx >> 1;
@ -694,8 +690,7 @@ impl<'a> Context<'a> {
if self.config.debug { if self.config.debug {
self.export("assertStackEmpty", " self.export("assertStackEmpty", "
function() { function() {
if (stack.length === 0) if (stack.length === 0) return;
return;
throw new Error('stack is not currently empty'); throw new Error('stack is not currently empty');
} }
", None); ", None);
@ -717,8 +712,7 @@ impl<'a> Context<'a> {
self.export("assertSlabEmpty", &format!(" self.export("assertSlabEmpty", &format!("
function() {{ function() {{
for (let i = {}; i < slab.length; i++) {{ for (let i = {}; i < slab.length; i++) {{
if (typeof(slab[i]) === 'number') if (typeof(slab[i]) === 'number') continue;
continue;
throw new Error('slab is not currently empty'); throw new Error('slab is not currently empty');
}} }}
}} }}
@ -745,8 +739,7 @@ impl<'a> Context<'a> {
let get_obj = if self.config.debug { let get_obj = if self.config.debug {
String::from(" String::from("
if (typeof(val) === 'number') if (typeof(val) === 'number') throw new Error('corrupt slab');
throw new Error('corrupt slab');
return val.obj; return val.obj;
") ")
} else { } else {
@ -772,8 +765,7 @@ impl<'a> Context<'a> {
} }
self.global(&format!(" self.global(&format!("
function _assertNum(n) {{ function _assertNum(n) {{
if (typeof(n) !== 'number') if (typeof(n) !== 'number') throw new Error('expected a number argument');
throw new Error('expected a number argument');
}} }}
")); "));
} }
@ -784,9 +776,10 @@ impl<'a> Context<'a> {
} }
self.global(&format!(" self.global(&format!("
function _assertBoolean(n) {{ function _assertBoolean(n) {{
if (typeof(n) !== 'boolean') if (typeof(n) !== 'boolean') {{
throw new Error('expected a boolean argument'); throw new Error('expected a boolean argument');
}} }}
}}
")); "));
} }
@ -799,8 +792,7 @@ impl<'a> Context<'a> {
self.expose_uint8_memory(); self.expose_uint8_memory();
let debug = if self.config.debug { let debug = if self.config.debug {
" "
if (typeof(arg) !== 'string') if (typeof(arg) !== 'string') throw new Error('expected a string argument');
throw new Error('expected a string argument');
" "
} else { } else {
"" ""
@ -946,7 +938,7 @@ impl<'a> Context<'a> {
const slice = mem.subarray(ptr / 4, ptr / 4 + len); const slice = mem.subarray(ptr / 4, ptr / 4 + len);
const result = []; const result = [];
for (let i = 0; i < slice.length; i++) {{ for (let i = 0; i < slice.length; i++) {{
result.push(takeObject(slice[i])) result.push(takeObject(slice[i]));
}} }}
return result; return result;
}} }}
@ -1119,9 +1111,9 @@ impl<'a> Context<'a> {
self.global(&format!(" self.global(&format!("
let cache{name} = null; let cache{name} = null;
function {name}() {{ function {name}() {{
if (cache{name} === null || if (cache{name} === null || cache{name}.buffer !== wasm.memory.buffer) {{
cache{name}.buffer !== wasm.memory.buffer)
cache{name} = new {js}(wasm.memory.buffer); cache{name} = new {js}(wasm.memory.buffer);
}}
return cache{name}; return cache{name};
}} }}
", ",
@ -1136,8 +1128,9 @@ impl<'a> Context<'a> {
} }
self.global(&format!(" self.global(&format!("
function _assertClass(instance, klass) {{ function _assertClass(instance, klass) {{
if (!(instance instanceof klass)) if (!(instance instanceof klass)) {{
throw new Error(`expected instance of ${{klass.name}}`); throw new Error(`expected instance of ${{klass.name}}`);
}}
return instance.ptr; return instance.ptr;
}} }}
")); "));
@ -1179,8 +1172,7 @@ impl<'a> Context<'a> {
self.expose_global_slab_next(); self.expose_global_slab_next();
let set_slab_next = if self.config.debug { let set_slab_next = if self.config.debug {
String::from(" String::from("
if (typeof(next) !== 'number') if (typeof(next) !== 'number') throw new Error('corrupt slab');
throw new Error('corrupt slab');
slab_next = next; slab_next = next;
") ")
} else { } else {
@ -1190,8 +1182,7 @@ impl<'a> Context<'a> {
}; };
self.global(&format!(" self.global(&format!("
function addHeapObject(obj) {{ function addHeapObject(obj) {{
if (slab_next === slab.length) if (slab_next === slab.length) slab.push(slab.length + 1);
slab.push(slab.length + 1);
const idx = slab_next; const idx = slab_next;
const next = slab[idx]; const next = slab[idx];
{} {}
@ -1329,8 +1320,9 @@ impl<'a> Context<'a> {
self.global(" self.global("
let cachedGlobalArgumentPtr = null; let cachedGlobalArgumentPtr = null;
function globalArgumentPtr() { function globalArgumentPtr() {
if (cachedGlobalArgumentPtr === null) if (cachedGlobalArgumentPtr === null) {{
cachedGlobalArgumentPtr = wasm.__wbindgen_global_argument_ptr(); cachedGlobalArgumentPtr = wasm.__wbindgen_global_argument_ptr();
}}
return cachedGlobalArgumentPtr; return cachedGlobalArgumentPtr;
} }
"); ");
@ -1357,7 +1349,7 @@ impl<'a> Context<'a> {
if (desc) return desc; if (desc) return desc;
obj = Object.getPrototypeOf(obj); obj = Object.getPrototypeOf(obj);
} }
throw \"descriptor not found\"; throw new Error('descriptor not found');
} }
"); ");
} }
@ -1408,7 +1400,7 @@ impl<'a> Context<'a> {
} }
fn global(&mut self, s: &str) { fn global(&mut self, s: &str) {
let s = deindent(s); let s = s;
let s = s.trim(); let s = s.trim();
// Ensure a blank line between adjacent items, and ensure everything is // Ensure a blank line between adjacent items, and ensure everything is
@ -1621,24 +1613,28 @@ impl<'a, 'b> SubContext<'a, 'b> {
let class = self.import_name(info, class)?; let class = self.import_name(info, class)?;
let target = if let Some(ref g) = import.getter { let target = if let Some(ref g) = import.getter {
if import.structural { if import.structural {
format!("function() {{ return this.{}; }}", g) format!("function() {{
return this.{};
}}", g)
} else { } else {
self.cx.expose_get_inherited_descriptor(); self.cx.expose_get_inherited_descriptor();
format!( format!(
"GetOwnOrInheritedPropertyDescriptor\ "GetOwnOrInheritedPropertyDescriptor\
({}.prototype, '{}').get;", ({}.prototype, '{}').get",
class, class,
g, g,
) )
} }
} else if let Some(ref s) = import.setter { } else if let Some(ref s) = import.setter {
if import.structural { if import.structural {
format!("function(y) {{ this.{} = y; }}", s) format!("function(y) {{
this.{} = y;
}}", s)
} else { } else {
self.cx.expose_get_inherited_descriptor(); self.cx.expose_get_inherited_descriptor();
format!( format!(
"GetOwnOrInheritedPropertyDescriptor\ "GetOwnOrInheritedPropertyDescriptor\
({}.prototype, '{}').set;", ({}.prototype, '{}').set",
class, class,
s, s,
) )
@ -1653,7 +1649,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
} }
drop(write!(s, "x{}", i)); drop(write!(s, "x{}", i));
} }
s.push_str(") { return this."); s.push_str(") { \nreturn this.");
s.push_str(&import.function.name); s.push_str(&import.function.name);
s.push_str("("); s.push_str("(");
for i in 0..nargs - 1 { for i in 0..nargs - 1 {
@ -1662,7 +1658,7 @@ impl<'a, 'b> SubContext<'a, 'b> {
} }
drop(write!(s, "x{}", i)); drop(write!(s, "x{}", i));
} }
s.push_str("); }"); s.push_str(");\n}");
s s
} else { } else {
format!("{}.prototype.{}", class, import.function.name) format!("{}.prototype.{}", class, import.function.name)
@ -1748,33 +1744,6 @@ impl<'a, 'b> SubContext<'a, 'b> {
} }
} }
fn indent(s: &str) -> String {
let mut ret = String::new();
for line in s.lines() {
ret.push_str(" ");
ret.push_str(line);
ret.push_str("\n");
}
return ret
}
fn deindent(s: &str) -> String {
let amt_to_strip = s.lines()
.filter(|l| !l.trim().is_empty())
.map(|s| s.len() - s.trim_left().len())
.min()
.unwrap_or(0);
let mut ret = String::new();
for line in s.lines() {
if !line.trim().is_empty() {
ret.push_str(&line[amt_to_strip..]);
}
ret.push_str("\n");
}
ret
}
fn format_doc_comments(comments: &Vec<String>) -> String { fn format_doc_comments(comments: &Vec<String>) -> String {
let body: String = comments.iter().map(|c| format!("*{}\n", c.trim_matches('"'))).collect(); let body: String = comments.iter().map(|c| format!("*{}\n", c.trim_matches('"'))).collect();
format!("/**\n{}*/\n", body) format!("/**\n{}*/\n", body)

View File

@ -1,7 +1,7 @@
use failure::Error; use failure::Error;
use descriptor::{Descriptor, Function}; use descriptor::{Descriptor, Function};
use super::{indent, Context, Js2Rust}; use super::{Context, Js2Rust};
/// Helper struct for manufacturing a shim in JS used to translate Rust types to /// Helper struct for manufacturing a shim in JS used to translate Rust types to
/// JS, then invoking an imported JS function. /// JS, then invoking an imported JS function.
@ -202,7 +202,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
if (idx{0} === 0xffffffff) {{\n\ if (idx{0} === 0xffffffff) {{\n\
{1}\ {1}\
}}\n\ }}\n\
", abi, indent(&reset_idx))); ", abi, &reset_idx));
self.cx.expose_get_object(); self.cx.expose_get_object();
self.js_arguments.push(format!("getObject(idx{})", abi)); self.js_arguments.push(format!("getObject(idx{})", abi));
return Ok(()) return Ok(())
@ -272,7 +272,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
} }
self.ret_expr = match *ty { self.ret_expr = match *ty {
Descriptor::Boolean => "return JS ? 1 : 0;".to_string(), Descriptor::Boolean => "return JS ? 1 : 0;".to_string(),
Descriptor::Char => "return JS.codePointAt(0)".to_string(), Descriptor::Char => "return JS.codePointAt(0);".to_string(),
Descriptor::Anyref => { Descriptor::Anyref => {
self.cx.expose_add_heap_object(); self.cx.expose_add_heap_object();
"return addHeapObject(JS);".to_string() "return addHeapObject(JS);".to_string()
@ -293,7 +293,7 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
ret.push_str("exnptr"); ret.push_str("exnptr");
} }
ret.push_str(") {\n"); ret.push_str(") {\n");
ret.push_str(&indent(&self.prelude)); ret.push_str(&self.prelude);
let mut invoc = self.ret_expr.replace( let mut invoc = self.ret_expr.replace(
"JS", "JS",
@ -308,25 +308,25 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
invoc = format!("\ invoc = format!("\
try {{\n\ try {{\n\
{}\ {}
}} catch (e) {{\n\ }} catch (e) {{\n\
{}\ {}
}}\ }}\
", indent(&invoc), indent(catch)); ", &invoc, catch);
}; };
if self.finally.len() > 0 { if self.finally.len() > 0 {
invoc = format!("\ invoc = format!("\
try {{\n\ try {{\n\
{}\ {}
}} finally {{\n\ }} finally {{\n\
{}\ {}
}}\ }}\
", indent(&invoc), indent(&self.finally)); ", &invoc, &self.finally);
} }
ret.push_str(&indent(&invoc)); ret.push_str(&invoc);
ret.push_str("}\n"); ret.push_str("\n}\n");
return ret return ret
} }

View File

@ -158,7 +158,7 @@ impl Bindgen {
let js_path = out_dir.join(stem).with_extension("js"); let js_path = out_dir.join(stem).with_extension("js");
File::create(&js_path) File::create(&js_path)
.and_then(|mut f| f.write_all(js.as_bytes())) .and_then(|mut f| f.write_all(reset_indentation(&js).as_bytes()))
.with_context(|_| format!("failed to write `{}`", js_path.display()))?; .with_context(|_| format!("failed to write `{}`", js_path.display()))?;
if self.typescript { if self.typescript {
@ -207,7 +207,7 @@ impl Bindgen {
module.exports = wasmInstance.exports; module.exports = wasmInstance.exports;
", path.file_name().unwrap().to_str().unwrap())); ", path.file_name().unwrap().to_str().unwrap()));
shim reset_indentation(&shim)
} }
} }
@ -380,3 +380,32 @@ impl fmt::Display for MyError {
self.0.fmt(f) self.0.fmt(f)
} }
} }
fn reset_indentation(s: &str) -> String {
indent_recurse(s.lines(), 0)
}
fn indent_recurse(mut lines: ::std::str::Lines, current_indent: usize) -> String {
if let Some(line) = lines.next() {
let mut trimmed = line.trim().to_owned();
let mut next_indent = current_indent;
let mut current_indent = current_indent;
if trimmed.ends_with('{') {
next_indent += 1;
}
if trimmed.starts_with('}') || trimmed.ends_with('}') {
if current_indent > 0 {
current_indent -= 1;
}
if next_indent > 0 {
next_indent -= 1;
}
}
if trimmed.starts_with('?') || trimmed.starts_with(':') {
current_indent += 1;
}
format!("\n{}{}{}", " ".repeat(current_indent), &trimmed, &indent_recurse(lines, next_indent))
} else {
String::new()
}
}

3609
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -8,6 +8,7 @@
"ts-loader": "^4.0.1", "ts-loader": "^4.0.1",
"typescript": "^2.7.2", "typescript": "^2.7.2",
"webpack": "^4.11.1", "webpack": "^4.11.1",
"webpack-cli": "^2.0.10" "webpack-cli": "^2.0.10",
"eslint": "^4.19.1"
} }
} }