From bdc34fd7f7691def549a062439415eb76edd5c8b Mon Sep 17 00:00:00 2001 From: andjo403 Date: Tue, 9 Jan 2018 22:09:01 +0100 Subject: [PATCH 01/12] fix faulty comment --- src/librustc_trans/back/write.rs | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 4d1bcd9bf467d..034ed5aeeae6a 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -1363,15 +1363,10 @@ fn start_executing_work(tcx: TyCtxt, let sess = tcx.sess; // First up, convert our jobserver into a helper thread so we can use normal - // mpsc channels to manage our messages and such. Once we've got the helper - // thread then request `n-1` tokens because all of our work items are ready - // to go. - // - // Note that the `n-1` is here because we ourselves have a token (our - // process) and we'll use that token to execute at least one unit of work. - // - // After we've requested all these tokens then we'll, when we can, get - // tokens on `rx` above which will get managed in the main loop below. + // mpsc channels to manage our messages and such. + // After we've requested tokens then we'll, when we can, + // get tokens on `coordinator_receive` which will + // get managed in the main loop below. let coordinator_send2 = coordinator_send.clone(); let helper = jobserver.into_helper_thread(move |token| { drop(coordinator_send2.send(Box::new(Message::Token(token)))); From f7b48778b1472045bd8b7ee6aacdbf1487efe50b Mon Sep 17 00:00:00 2001 From: Mikko Rantanen Date: Fri, 12 Jan 2018 12:37:48 +0200 Subject: [PATCH 02/12] Report errors instead of panic!() --- src/tools/linkchecker/main.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/tools/linkchecker/main.rs b/src/tools/linkchecker/main.rs index 6458ec02669aa..f6eaa09f55d99 100644 --- a/src/tools/linkchecker/main.rs +++ b/src/tools/linkchecker/main.rs @@ -192,7 +192,17 @@ fn check(cache: &mut Cache, for part in Path::new(base).join(url).components() { match part { Component::Prefix(_) | - Component::RootDir => panic!(), + Component::RootDir => { + // Avoid absolute paths as they make the docs not + // relocatable by making assumptions on where the docs + // are hosted relative to the site root. + *errors = true; + println!("{}:{}: absolute path - {}", + pretty_file.display(), + i + 1, + Path::new(base).join(url).display()); + return; + } Component::CurDir => {} Component::ParentDir => { path.pop(); } Component::Normal(s) => { path.push(s); } From f31204662b6d5ab343b901d9684ecda71e777cc0 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 12 Jan 2018 22:47:31 +0100 Subject: [PATCH 03/12] Switch to pulldown as default markdown renderer --- src/librustdoc/lib.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 1740816ef6b16..8a3856db9b9ad 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -241,8 +241,8 @@ pub fn opts() -> Vec { or `#![doc(html_playground_url=...)]`", "URL") }), - unstable("enable-commonmark", |o| { - o.optflag("", "enable-commonmark", "to enable commonmark doc rendering/testing") + unstable("disable-commonmark", |o| { + o.optflag("", "disable-commonmark", "to disable commonmark doc rendering/testing") }), unstable("display-warnings", |o| { o.optflag("", "display-warnings", "to print code warnings when testing doc") @@ -346,10 +346,10 @@ pub fn main_args(args: &[String]) -> isize { let css_file_extension = matches.opt_str("e").map(|s| PathBuf::from(&s)); let cfgs = matches.opt_strs("cfg"); - let render_type = if matches.opt_present("enable-commonmark") { - RenderType::Pulldown - } else { + let render_type = if matches.opt_present("disable-commonmark") { RenderType::Hoedown + } else { + RenderType::Pulldown }; if let Some(ref p) = css_file_extension { From f18c52b2233b8d1142fea29551e140fd15d3ae70 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 12 Dec 2017 23:53:24 +0100 Subject: [PATCH 04/12] Start adding js tests --- src/bootstrap/check.rs | 35 ++++++++++++++++++++++++++++++++++ src/bootstrap/tool.rs | 1 + src/test/rustdoc-js/basic.js | 15 +++++++++++++++ src/tools/rustdoc-js/tester.js | 26 +++++++++++++++++++++++++ 4 files changed, 77 insertions(+) create mode 100644 src/test/rustdoc-js/basic.js create mode 100644 src/tools/rustdoc-js/tester.js diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index cc9be3cec3476..d4be0de6a1eae 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -424,6 +424,40 @@ fn path_for_cargo(builder: &Builder, compiler: Compiler) -> OsString { env::join_paths(iter::once(path).chain(env::split_paths(&old_path))).expect("") } +#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] +pub struct RustdocJS { + pub host: Interned, +} + +impl Step for RustdocJS { + type Output = PathBuf; + const DEFAULT: bool = true; + const ONLY_HOSTS: bool = true; + + fn should_run(run: ShouldRun) -> ShouldRun { + run.path("node") + } + + fn make_run(run: RunConfig) { + run.builder.ensure(RustdocJS { + host: run.host, + }); + } + + fn run(self, _: &Builder) { + let cmd = if cfg!(target_os = "windows") { + let command = Command::new("cmd"); + command.args(&["/C", "node src/tools/rustdoc-js/tester.js"]); + command + } else { + let command = Command::new("sh"); + command.args(&["-c", "node src/tools/rustdoc-js/tester.js"]); + command + }; + builder.run(cmd); + } +} + #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct Tidy { host: Interned, @@ -570,6 +604,7 @@ static HOST_COMPILETESTS: &[Test] = &[ }, Test { path: "src/test/run-make", mode: "run-make", suite: "run-make" }, Test { path: "src/test/rustdoc", mode: "rustdoc", suite: "rustdoc" }, + Test { path: "src/test/rustdoc-js", mode: "rustdoc-js", suite: "rustdoc-js" }, Test { path: "src/test/pretty", mode: "pretty", suite: "pretty" }, Test { path: "src/test/run-pass/pretty", mode: "pretty", suite: "run-pass" }, diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index ea055cb5d1b99..d80d7732ab266 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -260,6 +260,7 @@ tool!( BuildManifest, "src/tools/build-manifest", "build-manifest", Mode::Libstd; RemoteTestClient, "src/tools/remote-test-client", "remote-test-client", Mode::Libstd; RustInstaller, "src/tools/rust-installer", "fabricate", Mode::Libstd; + RustdocJS, "node", "node", Mode::Tool; ); #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] diff --git a/src/test/rustdoc-js/basic.js b/src/test/rustdoc-js/basic.js new file mode 100644 index 0000000000000..2eada17f0db69 --- /dev/null +++ b/src/test/rustdoc-js/basic.js @@ -0,0 +1,15 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const QUERY = 'String'; + +const EXPECTED = [ + {'all': ['std::string::String']}, +]; diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js new file mode 100644 index 0000000000000..9789c007d1600 --- /dev/null +++ b/src/tools/rustdoc-js/tester.js @@ -0,0 +1,26 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const fs = require('fs'); + +const TEST_FOLDER = 'src/test/rustdoc-js/'; + +function loadFile(filePath) { + var src = fs.readFileSync(filePath, 'utf8').split('\n').slice(15, -10).join('\n'); + var Module = module.constructor; + var m = new Module(); + m._compile(src, filePath); + return m; +} + +fs.readdirSync(TEST_FOLDER).forEach(function(file) { + var file = require(TEST_FOLDER + file); + const expected = file.EXPECTED; +}); From 53d8ec0ecb6e16e25d7646d6f6c143ac2d8f1819 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 7 Jan 2018 16:19:44 +0100 Subject: [PATCH 05/12] Prepare main.js for tests --- src/librustdoc/html/static/main.js | 82 ++++++++++++++---------------- 1 file changed, 39 insertions(+), 43 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index b4dbd76d0b4d0..a9a5bd5de0552 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -353,35 +353,33 @@ * This code is an unmodified version of the code written by Marco de Wit * and was found at http://stackoverflow.com/a/18514751/745719 */ - var levenshtein = (function() { - var row2 = []; - return function(s1, s2) { - if (s1 === s2) { - return 0; + var levenshtein_row2 = []; + function levenshtein(s1, s2) { + if (s1 === s2) { + return 0; + } + var s1_len = s1.length, s2_len = s2.length; + if (s1_len && s2_len) { + var i1 = 0, i2 = 0, a, b, c, c2, row = levenshtein_row2; + while (i1 < s1_len) { + row[i1] = ++i1; } - var s1_len = s1.length, s2_len = s2.length; - if (s1_len && s2_len) { - var i1 = 0, i2 = 0, a, b, c, c2, row = row2; - while (i1 < s1_len) { - row[i1] = ++i1; - } - while (i2 < s2_len) { - c2 = s2.charCodeAt(i2); - a = i2; - ++i2; - b = i2; - for (i1 = 0; i1 < s1_len; ++i1) { - c = a + (s1.charCodeAt(i1) !== c2 ? 1 : 0); - a = row[i1]; - b = b < a ? (b < c ? b + 1 : c) : (a < c ? a + 1 : c); - row[i1] = b; - } + while (i2 < s2_len) { + c2 = s2.charCodeAt(i2); + a = i2; + ++i2; + b = i2; + for (i1 = 0; i1 < s1_len; ++i1) { + c = a + (s1.charCodeAt(i1) !== c2 ? 1 : 0); + a = row[i1]; + b = b < a ? (b < c ? b + 1 : c) : (a < c ? a + 1 : c); + row[i1] = b; } - return b; } - return s1_len + s2_len; - }; - })(); + return b; + } + return s1_len + s2_len; + } function initSearch(rawSearchIndex) { var currentResults, index, searchIndex; @@ -400,12 +398,20 @@ /** * Executes the query and builds an index of results * @param {[Object]} query [The user query] - * @param {[type]} max [The maximum results returned] * @param {[type]} searchWords [The list of search words to query * against] * @return {[type]} [A search index of results] */ - function execQuery(query, max, searchWords) { + function execQuery(query, searchWords) { + function itemTypeFromName(typename) { + for (var i = 0; i < itemTypes.length; ++i) { + if (itemTypes[i] === typename) { + return i; + } + } + return -1; + } + var valLower = query.query.toLowerCase(), val = valLower, typeFilter = itemTypeFromName(query.type), @@ -1021,9 +1027,8 @@ return true; } - function getQuery() { - var matches, type, query, raw = - document.getElementsByClassName('search-input')[0].value; + function getQuery(raw) { + var matches, type, query; query = raw; matches = query.match(/^(fn|mod|struct|enum|trait|type|const|macro)\s*:\s*/i); @@ -1227,7 +1232,7 @@ } function showResults(results) { - var output, query = getQuery(); + var output, query = getQuery(document.getElementsByClassName('search-input')[0].value); currentResults = query.id; output = '

Results for ' + escape(query.query) + @@ -1271,7 +1276,7 @@ resultIndex; var params = getQueryStringParams(); - query = getQuery(); + query = getQuery(document.getElementsByClassName('search-input')[0].value); if (e) { e.preventDefault(); } @@ -1293,19 +1298,10 @@ } } - results = execQuery(query, 20000, index); + results = execQuery(query, index); showResults(results); } - function itemTypeFromName(typename) { - for (var i = 0; i < itemTypes.length; ++i) { - if (itemTypes[i] === typename) { - return i; - } - } - return -1; - } - function buildIndex(rawSearchIndex) { searchIndex = []; var searchWords = []; From 43acd233b396383a30860108e437829521eba114 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 7 Jan 2018 16:20:25 +0100 Subject: [PATCH 06/12] Add tester and a few tests --- src/test/rustdoc-js/basic.js | 18 ++- src/test/rustdoc-js/enum-option.js | 17 +++ src/test/rustdoc-js/fn-forget.js | 18 +++ src/test/rustdoc-js/from_u.js | 22 +++ src/test/rustdoc-js/macro-print.js | 20 +++ src/test/rustdoc-js/string-from_ut.js | 21 +++ src/test/rustdoc-js/struct-vec.js | 19 +++ src/tools/rustdoc-js/tester.js | 202 ++++++++++++++++++++++++-- 8 files changed, 324 insertions(+), 13 deletions(-) create mode 100644 src/test/rustdoc-js/enum-option.js create mode 100644 src/test/rustdoc-js/fn-forget.js create mode 100644 src/test/rustdoc-js/from_u.js create mode 100644 src/test/rustdoc-js/macro-print.js create mode 100644 src/test/rustdoc-js/string-from_ut.js create mode 100644 src/test/rustdoc-js/struct-vec.js diff --git a/src/test/rustdoc-js/basic.js b/src/test/rustdoc-js/basic.js index 2eada17f0db69..863437cac91d4 100644 --- a/src/test/rustdoc-js/basic.js +++ b/src/test/rustdoc-js/basic.js @@ -1,4 +1,4 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -10,6 +10,16 @@ const QUERY = 'String'; -const EXPECTED = [ - {'all': ['std::string::String']}, -]; +const EXPECTED = { + 'others': [ + { 'path': 'std::string', 'name': 'String' }, + { 'path': 'std::ffi', 'name': 'OsString' }, + { 'path': 'std::ffi', 'name': 'CString' }, + ], + 'in_args': [ + { 'path': 'std::str', 'name': 'eq' }, + ], + 'returned': [ + { 'path': 'std::string::String', 'name': 'add' }, + ], +}; diff --git a/src/test/rustdoc-js/enum-option.js b/src/test/rustdoc-js/enum-option.js new file mode 100644 index 0000000000000..3dac983b11b0e --- /dev/null +++ b/src/test/rustdoc-js/enum-option.js @@ -0,0 +1,17 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const QUERY = 'enum:Option'; + +const EXPECTED = { + 'others': [ + { 'path': 'std::option', 'name': 'Option' }, + ], +}; diff --git a/src/test/rustdoc-js/fn-forget.js b/src/test/rustdoc-js/fn-forget.js new file mode 100644 index 0000000000000..10310d5eaf7b9 --- /dev/null +++ b/src/test/rustdoc-js/fn-forget.js @@ -0,0 +1,18 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const QUERY = 'fn:forget'; + +const EXPECTED = { + 'others': [ + { 'path': 'std::mem', 'name': 'forget' }, + { 'path': 'std::fmt', 'name': 'format' }, + ], +}; diff --git a/src/test/rustdoc-js/from_u.js b/src/test/rustdoc-js/from_u.js new file mode 100644 index 0000000000000..920620a9aeed5 --- /dev/null +++ b/src/test/rustdoc-js/from_u.js @@ -0,0 +1,22 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const QUERY = 'from_u'; + +const EXPECTED = { + 'others': [ + { 'path': 'std::char', 'name': 'from_u32' }, + { 'path': 'std::str', 'name': 'from_utf8' }, + { 'path': 'std::string::String', 'name': 'from_utf8' }, + { 'path': 'std::boxed::Box', 'name': 'from_unique' }, + { 'path': 'std::i32', 'name': 'from_unsigned' }, + { 'path': 'std::i128', 'name': 'from_unsigned' }, + ], +}; diff --git a/src/test/rustdoc-js/macro-print.js b/src/test/rustdoc-js/macro-print.js new file mode 100644 index 0000000000000..811ba3474afa0 --- /dev/null +++ b/src/test/rustdoc-js/macro-print.js @@ -0,0 +1,20 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const QUERY = 'macro:print'; + +const EXPECTED = { + 'others': [ + { 'path': 'std', 'name': 'print' }, + { 'path': 'std', 'name': 'eprint' }, + { 'path': 'std', 'name': 'println' }, + { 'path': 'std', 'name': 'eprintln' }, + ], +}; diff --git a/src/test/rustdoc-js/string-from_ut.js b/src/test/rustdoc-js/string-from_ut.js new file mode 100644 index 0000000000000..3d08ee3736612 --- /dev/null +++ b/src/test/rustdoc-js/string-from_ut.js @@ -0,0 +1,21 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const QUERY = 'String::from_ut'; + +const EXPECTED = { + 'others': [ + { 'path': 'std::string::String', 'name': 'from_utf8' }, + { 'path': 'std::string::String', 'name': 'from_utf8' }, + { 'path': 'std::string::String', 'name': 'from_utf8_lossy' }, + { 'path': 'std::string::String', 'name': 'from_utf16_lossy' }, + { 'path': 'std::string::String', 'name': 'from_utf8_unchecked' }, + ], +}; diff --git a/src/test/rustdoc-js/struct-vec.js b/src/test/rustdoc-js/struct-vec.js new file mode 100644 index 0000000000000..a91bc2d0da288 --- /dev/null +++ b/src/test/rustdoc-js/struct-vec.js @@ -0,0 +1,19 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +const QUERY = 'struct:Vec'; + +const EXPECTED = { + 'others': [ + { 'path': 'std::vec', 'name': 'Vec' }, + { 'path': 'std::collections', 'name': 'VecDeque' }, + { 'path': 'alloc::raw_vec', 'name': 'RawVec' }, + ], +}; diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js index 9789c007d1600..9b7e151b1ffec 100644 --- a/src/tools/rustdoc-js/tester.js +++ b/src/tools/rustdoc-js/tester.js @@ -1,4 +1,4 @@ -// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -12,15 +12,199 @@ const fs = require('fs'); const TEST_FOLDER = 'src/test/rustdoc-js/'; -function loadFile(filePath) { - var src = fs.readFileSync(filePath, 'utf8').split('\n').slice(15, -10).join('\n'); +// Stupid function extractor based on indent. +function extractFunction(content, functionName) { + var x = content.split('\n'); + var in_func = false; + var indent = 0; + var lines = []; + + for (var i = 0; i < x.length; ++i) { + if (in_func === false) { + var splitter = "function " + functionName + "("; + if (x[i].trim().startsWith(splitter)) { + in_func = true; + indent = x[i].split(splitter)[0].length; + lines.push(x[i]); + } + } else { + lines.push(x[i]); + if (x[i].trim() === "}" && x[i].split("}")[0].length === indent) { + return lines.join("\n"); + } + } + } + return null; +} + +// Stupid function extractor for array. +function extractArrayVariable(content, arrayName) { + var x = content.split('\n'); + var found_var = false; + var lines = []; + + for (var i = 0; i < x.length; ++i) { + if (found_var === false) { + var splitter = "var " + arrayName + " = ["; + if (x[i].trim().startsWith(splitter)) { + found_var = true; + i -= 1; + } + } else { + lines.push(x[i]); + if (x[i].endsWith('];')) { + return lines.join("\n"); + } + } + } + return null; +} + +// Stupid function extractor for variable. +function extractVariable(content, varName) { + var x = content.split('\n'); + var found_var = false; + var lines = []; + + for (var i = 0; i < x.length; ++i) { + if (found_var === false) { + var splitter = "var " + varName + " = "; + if (x[i].trim().startsWith(splitter)) { + found_var = true; + i -= 1; + } + } else { + lines.push(x[i]); + if (x[i].endsWith(';')) { + return lines.join("\n"); + } + } + } + return null; +} + +function loadContent(content) { var Module = module.constructor; var m = new Module(); - m._compile(src, filePath); - return m; + m._compile(content, "tmp.js"); + return m.exports; +} + +function readFile(filePath) { + return fs.readFileSync(filePath, 'utf8'); +} + +function loadThings(thingsToLoad, kindOfLoad, funcToCall, fileContent) { + var content = ''; + for (var i = 0; i < thingsToLoad.length; ++i) { + var tmp = funcToCall(fileContent, thingsToLoad[i]); + if (tmp === null) { + console.error('enable to find ' + kindOfLoad + ' "' + thingsToLoad[i] + '"'); + process.exit(1); + } + content += tmp; + content += 'exports.' + thingsToLoad[i] + ' = ' + thingsToLoad[i] + ';'; + } + return content; +} + +function lookForEntry(entry, data) { + for (var i = 0; i < data.length; ++i) { + var allGood = true; + for (var key in entry) { + if (!entry.hasOwnProperty(key)) { + continue; + } + let value = data[i][key]; + // To make our life easier, if there is a "parent" type, we add it to the path. + if (key === 'path' && data[i]['parent'] !== undefined) { + if (value.length > 0) { + value += '::' + data[i]['parent']['name']; + } else { + value = data[i]['parent']['name']; + } + } + if (value !== entry[key]) { + allGood = false; + break; + } + } + if (allGood === true) { + return true; + } + } + return false; +} + +function main(argv) { + if (argv.length !== 3) { + console.error("Expected toolchain to check as argument (for example 'x86_64-apple-darwin'"); + return 1; + } + var toolchain = argv[2]; + + var mainJs = readFile("build/" + toolchain + "/doc/main.js"); + var searchIndex = readFile("build/" + toolchain + "/doc/search-index.js").split("\n"); + if (searchIndex[searchIndex.length - 1].length === 0) { + searchIndex.pop(); + } + searchIndex.pop(); + searchIndex = loadContent(searchIndex.join("\n") + '\nexports.searchIndex = searchIndex;'); + finalJS = ""; + + var arraysToLoad = ["itemTypes"]; + var variablesToLoad = ["MAX_LEV_DISTANCE", "MAX_RESULTS", "TY_PRIMITIVE", "levenshtein_row2"]; + // execQuery first parameter is built in getQuery (which takes in the search input). + // execQuery last parameter is built in buildIndex. + // buildIndex requires the hashmap from search-index. + var functionsToLoad = ["levenshtein", "validateResult", "getQuery", "buildIndex", "execQuery"]; + + finalJS += 'window = { "currentCrate": "std" };\n'; + finalJS += loadThings(arraysToLoad, 'array', extractArrayVariable, mainJs); + finalJS += loadThings(variablesToLoad, 'variable', extractVariable, mainJs); + finalJS += loadThings(functionsToLoad, 'function', extractFunction, mainJs); + + var loaded = loadContent(finalJS); + var index = loaded.buildIndex(searchIndex.searchIndex); + + var errors = 0; + + fs.readdirSync(TEST_FOLDER).forEach(function(file) { + var loadedFile = loadContent(readFile(TEST_FOLDER + file) + + 'exports.QUERY = QUERY;exports.EXPECTED = EXPECTED;'); + const expected = loadedFile.EXPECTED; + const query = loadedFile.QUERY; + var results = loaded.execQuery(loaded.getQuery(query), index); + process.stdout.write('Checking "' + file + '" ... '); + var error_text = []; + for (var key in expected) { + if (!expected.hasOwnProperty(key)) { + continue; + } + if (!results.hasOwnProperty(key)) { + error_text.push('==> Unknown key "' + key + '"'); + break; + } + var entry = expected[key]; + var found = false; + for (var i = 0; i < entry.length; ++i) { + if (lookForEntry(entry[i], results[key]) === true) { + found = true; + } else { + error_text.push("==> Result not found in '" + key + "': '" + + JSON.stringify(entry[i]) + "'"); + } + } + } + if (error_text.length !== 0) { + errors += 1; + console.error("FAILED"); + console.error(error_text.join("\n")); + } else { + console.log("OK"); + } + }); + return errors; } -fs.readdirSync(TEST_FOLDER).forEach(function(file) { - var file = require(TEST_FOLDER + file); - const expected = file.EXPECTED; -}); +process.exit(main(process.argv)); From 50bb6ba13eeb66e96db5455d0dc2a7cab5b02e1e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 8 Jan 2018 23:43:20 +0100 Subject: [PATCH 07/12] Move forward to add rustdoc test --- src/bootstrap/builder.rs | 4 +++- src/bootstrap/check.rs | 21 +++++++-------------- src/bootstrap/tool.rs | 2 +- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index ce30d1f4cec42..be62ce3bf3a0a 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -254,7 +254,9 @@ impl<'a> Builder<'a> { Kind::Test => describe!(check::Tidy, check::Bootstrap, check::DefaultCompiletest, check::HostCompiletest, check::Crate, check::CrateLibrustc, check::Rustdoc, check::Linkcheck, check::Cargotest, check::Cargo, check::Rls, check::Docs, - check::ErrorIndex, check::Distcheck, check::Rustfmt, check::Miri, check::Clippy), + check::ErrorIndex, check::Distcheck, check::Rustfmt, check::Miri, check::Clippy, + check::RustdocJS), + Kind::Bench => describe!(check::Crate, check::CrateLibrustc), Kind::Doc => describe!(doc::UnstableBook, doc::UnstableBookGen, doc::TheBook, doc::Standalone, doc::Std, doc::Test, doc::Rustc, doc::ErrorIndex, doc::Nomicon, diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index d4be0de6a1eae..265e7721a97c0 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -430,12 +430,12 @@ pub struct RustdocJS { } impl Step for RustdocJS { - type Output = PathBuf; + type Output = (); const DEFAULT: bool = true; const ONLY_HOSTS: bool = true; fn should_run(run: ShouldRun) -> ShouldRun { - run.path("node") + run.path("src/tests/rustdoc-js") } fn make_run(run: RunConfig) { @@ -444,17 +444,11 @@ impl Step for RustdocJS { }); } - fn run(self, _: &Builder) { - let cmd = if cfg!(target_os = "windows") { - let command = Command::new("cmd"); - command.args(&["/C", "node src/tools/rustdoc-js/tester.js"]); - command - } else { - let command = Command::new("sh"); - command.args(&["-c", "node src/tools/rustdoc-js/tester.js"]); - command - }; - builder.run(cmd); + fn run(self, builder: &Builder) { + let nodejs = builder.config.nodejs.clone(); + let mut command = Command::new(&nodejs.expect("no nodejs found")); + command.args(&["src/tools/rustdoc-js/tester.js", &*self.host]); + builder.run(&mut command); } } @@ -604,7 +598,6 @@ static HOST_COMPILETESTS: &[Test] = &[ }, Test { path: "src/test/run-make", mode: "run-make", suite: "run-make" }, Test { path: "src/test/rustdoc", mode: "rustdoc", suite: "rustdoc" }, - Test { path: "src/test/rustdoc-js", mode: "rustdoc-js", suite: "rustdoc-js" }, Test { path: "src/test/pretty", mode: "pretty", suite: "pretty" }, Test { path: "src/test/run-pass/pretty", mode: "pretty", suite: "run-pass" }, diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index d80d7732ab266..96947800d44b6 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -260,7 +260,7 @@ tool!( BuildManifest, "src/tools/build-manifest", "build-manifest", Mode::Libstd; RemoteTestClient, "src/tools/remote-test-client", "remote-test-client", Mode::Libstd; RustInstaller, "src/tools/rust-installer", "fabricate", Mode::Libstd; - RustdocJS, "node", "node", Mode::Tool; + RustdocJS, "rustdoc-js", "js-tests", Mode::Tool; ); #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] From 69521996c802e519f2b8f37d92259a7f389cde19 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 12 Jan 2018 23:40:00 +0100 Subject: [PATCH 08/12] End of rustdoc-js tool add into builder --- src/bootstrap/builder.rs | 3 ++- src/bootstrap/check.rs | 8 +++++++- src/bootstrap/doc.rs | 4 ++-- src/bootstrap/tool.rs | 1 - 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index be62ce3bf3a0a..4db522ebd137e 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -445,7 +445,8 @@ impl<'a> Builder<'a> { let out_dir = self.stage_out(compiler, mode); cargo.env("CARGO_TARGET_DIR", out_dir) .arg(cmd) - .arg("--target").arg(target); + .arg("--target") + .arg(target); // If we were invoked from `make` then that's already got a jobserver // set up for us so no need to tell Cargo about jobs all over again. diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 265e7721a97c0..bfc0009fcfb0d 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -427,6 +427,7 @@ fn path_for_cargo(builder: &Builder, compiler: Compiler) -> OsString { #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct RustdocJS { pub host: Interned, + pub target: Interned, } impl Step for RustdocJS { @@ -435,12 +436,13 @@ impl Step for RustdocJS { const ONLY_HOSTS: bool = true; fn should_run(run: ShouldRun) -> ShouldRun { - run.path("src/tests/rustdoc-js") + run.path("src/test/rustdoc-js") } fn make_run(run: RunConfig) { run.builder.ensure(RustdocJS { host: run.host, + target: run.target, }); } @@ -448,6 +450,10 @@ impl Step for RustdocJS { let nodejs = builder.config.nodejs.clone(); let mut command = Command::new(&nodejs.expect("no nodejs found")); command.args(&["src/tools/rustdoc-js/tester.js", &*self.host]); + builder.ensure(::doc::Std { + target: self.target, + stage: builder.top_stage, + }); builder.run(&mut command); } } diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 832da24c994db..0930bc15de131 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -418,8 +418,8 @@ impl Step for Standalone { #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Std { - stage: u32, - target: Interned, + pub stage: u32, + pub target: Interned, } impl Step for Std { diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 96947800d44b6..ea055cb5d1b99 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -260,7 +260,6 @@ tool!( BuildManifest, "src/tools/build-manifest", "build-manifest", Mode::Libstd; RemoteTestClient, "src/tools/remote-test-client", "remote-test-client", Mode::Libstd; RustInstaller, "src/tools/rust-installer", "fabricate", Mode::Libstd; - RustdocJS, "rustdoc-js", "js-tests", Mode::Tool; ); #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] From 026c7499895a7c251cc9f72345600195738f22fc Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 13 Jan 2018 22:35:41 +0100 Subject: [PATCH 09/12] Only run rustdoc-js test suite when nodejs is available --- src/bootstrap/check.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index bfc0009fcfb0d..25f2f6bc1d0f6 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -447,14 +447,17 @@ impl Step for RustdocJS { } fn run(self, builder: &Builder) { - let nodejs = builder.config.nodejs.clone(); - let mut command = Command::new(&nodejs.expect("no nodejs found")); - command.args(&["src/tools/rustdoc-js/tester.js", &*self.host]); - builder.ensure(::doc::Std { - target: self.target, - stage: builder.top_stage, - }); - builder.run(&mut command); + if let Some(ref nodejs) = builder.config.nodejs { + let mut command = Command::new(nodejs); + command.args(&["src/tools/rustdoc-js/tester.js", &*self.host]); + builder.ensure(::doc::Std { + target: self.target, + stage: builder.top_stage, + }); + builder.run(&mut command); + } else { + println!("No nodejs found, skipping \"src/test/rustdoc-js\" tests"); + } } } From e2bd0e15dc7c875750dfb5fc27b9a3afee5e9fca Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 15 Jan 2018 00:40:49 +0100 Subject: [PATCH 10/12] Update html-diff crate => fix unicode parsing and invalid paths --- src/Cargo.lock | 6 +++--- src/librustdoc/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 8fbf3535264fc..5b44f0ea34e04 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -838,7 +838,7 @@ dependencies = [ [[package]] name = "html-diff" -version = "0.0.5" +version = "0.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kuchiki 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2127,7 +2127,7 @@ version = "0.0.0" dependencies = [ "build_helper 0.1.0", "cc 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "html-diff 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "html-diff 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "pulldown-cmark 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2855,7 +2855,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum handlebars 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fb04af2006ea09d985fef82b81e0eb25337e51b691c76403332378a53d521edc" "checksum hex 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d6a22814455d41612f41161581c2883c0c6a1c41852729b17d5ed88f01e153aa" "checksum home 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9f25ae61099d8f3fee8b483df0bd4ecccf4b2731897aad40d50eca1b641fe6db" -"checksum html-diff 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9778743e3b3c3679f471f0ed1833c690f19f4a0919e33b281f12ef5f77ad64c6" +"checksum html-diff 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ee4cfdf62a484a3ac0d9b80f562d37f99366db08a63621b917ea3056565345f7" "checksum html5ever 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5bfb46978eb757a603b7dfe2dafb1c62cb4dee3428d8ac1de734d83d6b022d06" "checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d" "checksum if_chain 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "61bb90bdd39e3af69b0172dfc6130f6cd6332bf040fbb9bdd4401d37adbd48b8" diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index 1e574964b12dc..608adcb43d6c3 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -12,7 +12,7 @@ doctest = false [dependencies] pulldown-cmark = { version = "0.1.0", default-features = false } -html-diff = "0.0.5" +html-diff = "0.0.6" tempdir = "0.3" [build-dependencies] From ecd47a91c7c5eb22fba5fcdec7fa8d78a8bcac51 Mon Sep 17 00:00:00 2001 From: Ryan Cumming Date: Mon, 15 Jan 2018 08:08:22 +1100 Subject: [PATCH 11/12] Don't include bang in macro replacement suggestion When we suggest the replacement for a macro we include the "!" in the suggested replacement but the span only contains the name of the macro itself. Using that replacement would cause a duplicate "!" in the resulting code. I originally tried to extend the span to be replaced by 1 byte in rust-lang/rust#47424. However, @zackmdavis pointed out that there can be whitespace between the macro name and the bang. Instead, just remove the bang from the suggested replacement. Fixes #47418 --- src/librustc_resolve/macros.rs | 3 +-- src/test/ui-fulldeps/resolve-error.stderr | 6 +++--- src/test/ui/macros/macro-name-typo.stderr | 2 +- src/test/ui/macros/macro_undefined.stderr | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 2b0c839152ccb..ceb39aea108c8 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -691,8 +691,7 @@ impl<'a> Resolver<'a> { if let Some(suggestion) = suggestion { if suggestion != name { if let MacroKind::Bang = kind { - err.span_suggestion(span, "you could try the macro", - format!("{}!", suggestion)); + err.span_suggestion(span, "you could try the macro", suggestion.to_string()); } else { err.span_suggestion(span, "try", suggestion.to_string()); } diff --git a/src/test/ui-fulldeps/resolve-error.stderr b/src/test/ui-fulldeps/resolve-error.stderr index be7ebae70adf5..9121ce1720c98 100644 --- a/src/test/ui-fulldeps/resolve-error.stderr +++ b/src/test/ui-fulldeps/resolve-error.stderr @@ -38,13 +38,13 @@ error: cannot find macro `FooWithLongNama!` in this scope --> $DIR/resolve-error.rs:62:5 | 62 | FooWithLongNama!(); - | ^^^^^^^^^^^^^^^ help: you could try the macro: `FooWithLongNam!` + | ^^^^^^^^^^^^^^^ help: you could try the macro: `FooWithLongNam` error: cannot find macro `attr_proc_macra!` in this scope --> $DIR/resolve-error.rs:65:5 | 65 | attr_proc_macra!(); - | ^^^^^^^^^^^^^^^ help: you could try the macro: `attr_proc_mac!` + | ^^^^^^^^^^^^^^^ help: you could try the macro: `attr_proc_mac` error: cannot find macro `Dlona!` in this scope --> $DIR/resolve-error.rs:68:5 @@ -56,7 +56,7 @@ error: cannot find macro `bang_proc_macrp!` in this scope --> $DIR/resolve-error.rs:71:5 | 71 | bang_proc_macrp!(); - | ^^^^^^^^^^^^^^^ help: you could try the macro: `bang_proc_macro!` + | ^^^^^^^^^^^^^^^ help: you could try the macro: `bang_proc_macro` error: aborting due to 10 previous errors diff --git a/src/test/ui/macros/macro-name-typo.stderr b/src/test/ui/macros/macro-name-typo.stderr index 84851749c7074..ebe95356c26eb 100644 --- a/src/test/ui/macros/macro-name-typo.stderr +++ b/src/test/ui/macros/macro-name-typo.stderr @@ -2,7 +2,7 @@ error: cannot find macro `printlx!` in this scope --> $DIR/macro-name-typo.rs:12:5 | 12 | printlx!("oh noes!"); //~ ERROR cannot find - | ^^^^^^^ help: you could try the macro: `println!` + | ^^^^^^^ help: you could try the macro: `println` error: aborting due to previous error diff --git a/src/test/ui/macros/macro_undefined.stderr b/src/test/ui/macros/macro_undefined.stderr index 6cfb05e786703..8d6da6a4732fc 100644 --- a/src/test/ui/macros/macro_undefined.stderr +++ b/src/test/ui/macros/macro_undefined.stderr @@ -10,7 +10,7 @@ error: cannot find macro `k!` in this scope --> $DIR/macro_undefined.rs:21:5 | 21 | k!(); //~ ERROR cannot find - | ^ help: you could try the macro: `kl!` + | ^ help: you could try the macro: `kl` error: aborting due to 2 previous errors From 3a7e247acb6cd9c1bc9707d0b37ebba34f788006 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 16 Jan 2018 15:38:08 +0100 Subject: [PATCH 12/12] Fix for older JS versions --- src/tools/rustdoc-js/tester.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js index 9b7e151b1ffec..7c9ee2a49430b 100644 --- a/src/tools/rustdoc-js/tester.js +++ b/src/tools/rustdoc-js/tester.js @@ -115,7 +115,7 @@ function lookForEntry(entry, data) { if (!entry.hasOwnProperty(key)) { continue; } - let value = data[i][key]; + var value = data[i][key]; // To make our life easier, if there is a "parent" type, we add it to the path. if (key === 'path' && data[i]['parent'] !== undefined) { if (value.length > 0) {