From 4b5638af5ab3cd6c31b41a36f50542fd0cc16835 Mon Sep 17 00:00:00 2001 From: Ted Campbell Date: Wed, 17 Jun 2020 13:57:07 +0000 Subject: [PATCH] Bug 1642708 - Remove BinAST Rust modules r=arai,emilio Differential Revision: https://phabricator.services.mozilla.com/D77947 --- Cargo.lock | 52 - Cargo.toml | 1 - js/src/frontend/binast/Cargo.toml | 18 - js/src/frontend/binast/README.md | 16 - js/src/frontend/binast/build.sh | 41 - js/src/frontend/binast/moz.build | 7 - js/src/frontend/binast/src/main.rs | 3601 ----------------- js/src/frontend/binast/src/refgraph.rs | 96 - .../rust/Inflector/.cargo-checksum.json | 1 - third_party/rust/Inflector/Cargo.toml | 42 - third_party/rust/Inflector/README.md | 136 - .../rust/Inflector/src/cases/camelcase/mod.rs | 370 -- .../rust/Inflector/src/cases/case/mod.rs | 303 -- .../rust/Inflector/src/cases/classcase/mod.rs | 393 -- .../rust/Inflector/src/cases/kebabcase/mod.rs | 262 -- third_party/rust/Inflector/src/cases/mod.rs | 52 - .../Inflector/src/cases/pascalcase/mod.rs | 360 -- .../src/cases/screamingsnakecase/mod.rs | 253 -- .../Inflector/src/cases/sentencecase/mod.rs | 313 -- .../rust/Inflector/src/cases/snakecase/mod.rs | 334 -- .../rust/Inflector/src/cases/tablecase/mod.rs | 271 -- .../rust/Inflector/src/cases/titlecase/mod.rs | 308 -- .../rust/Inflector/src/cases/traincase/mod.rs | 320 -- third_party/rust/Inflector/src/lib.rs | 332 -- .../Inflector/src/numbers/deordinalize/mod.rs | 117 - third_party/rust/Inflector/src/numbers/mod.rs | 9 - .../Inflector/src/numbers/ordinalize/mod.rs | 147 - .../Inflector/src/string/constants/mod.rs | 225 - .../Inflector/src/string/deconstantize/mod.rs | 50 - .../Inflector/src/string/demodulize/mod.rs | 46 - third_party/rust/Inflector/src/string/mod.rs | 23 - .../Inflector/src/string/pluralize/mod.rs | 194 - .../Inflector/src/string/singularize/mod.rs | 189 - .../Inflector/src/suffix/foreignkey/mod.rs | 139 - third_party/rust/Inflector/src/suffix/mod.rs | 5 - third_party/rust/Inflector/tests/lib.rs | 162 - .../rust/ansi_term/.cargo-checksum.json | 1 - third_party/rust/ansi_term/Cargo.toml | 27 - third_party/rust/ansi_term/LICENCE | 21 - third_party/rust/ansi_term/README.md | 174 - .../rust/ansi_term/examples/colours.rs | 13 - third_party/rust/ansi_term/src/ansi.rs | 258 -- third_party/rust/ansi_term/src/debug.rs | 122 - third_party/rust/ansi_term/src/difference.rs | 179 - third_party/rust/ansi_term/src/display.rs | 279 -- third_party/rust/ansi_term/src/lib.rs | 205 - third_party/rust/ansi_term/src/style.rs | 259 -- third_party/rust/ansi_term/src/windows.rs | 40 - third_party/rust/ansi_term/src/write.rs | 40 - .../rust/binjs_meta/.cargo-checksum.json | 1 - third_party/rust/binjs_meta/Cargo.lock | 315 -- third_party/rust/binjs_meta/Cargo.toml | 46 - third_party/rust/binjs_meta/README.md | 7 - .../examples/generate_spidermonkey.rs | 1668 -------- third_party/rust/binjs_meta/src/export.rs | 531 --- third_party/rust/binjs_meta/src/import.rs | 358 -- third_party/rust/binjs_meta/src/lib.rs | 21 - third_party/rust/binjs_meta/src/spec.rs | 1209 ------ third_party/rust/binjs_meta/src/util.rs | 535 --- third_party/rust/weedle/.cargo-checksum.json | 1 - third_party/rust/weedle/Cargo.toml | 27 - third_party/rust/weedle/LICENSE.md | 15 - third_party/rust/weedle/README.md | 49 - third_party/rust/weedle/src/argument.rs | 76 - third_party/rust/weedle/src/attribute.rs | 99 - third_party/rust/weedle/src/common.rs | 208 - third_party/rust/weedle/src/dictionary.rs | 33 - third_party/rust/weedle/src/interface.rs | 202 - third_party/rust/weedle/src/lib.rs | 425 -- third_party/rust/weedle/src/literal.rs | 281 -- third_party/rust/weedle/src/macros.rs | 614 --- third_party/rust/weedle/src/mixin.rs | 60 - third_party/rust/weedle/src/namespace.rs | 52 - third_party/rust/weedle/src/term.rs | 690 ---- third_party/rust/weedle/src/types.rs | 380 -- third_party/rust/weedle/src/whitespace.rs | 31 - third_party/rust/weedle/tests/defs/dom.webidl | 549 --- .../rust/weedle/tests/defs/html.webidl | 2410 ----------- .../tests/defs/interface-constructor.webidl | 4 - .../tests/defs/mediacapture-streams.webidl | 246 -- third_party/rust/weedle/tests/webidl.rs | 99 - tools/lint/clippy.yml | 1 - 82 files changed, 22049 deletions(-) delete mode 100644 js/src/frontend/binast/Cargo.toml delete mode 100644 js/src/frontend/binast/README.md delete mode 100755 js/src/frontend/binast/build.sh delete mode 100644 js/src/frontend/binast/moz.build delete mode 100644 js/src/frontend/binast/src/main.rs delete mode 100644 js/src/frontend/binast/src/refgraph.rs delete mode 100644 third_party/rust/Inflector/.cargo-checksum.json delete mode 100644 third_party/rust/Inflector/Cargo.toml delete mode 100644 third_party/rust/Inflector/README.md delete mode 100644 third_party/rust/Inflector/src/cases/camelcase/mod.rs delete mode 100644 third_party/rust/Inflector/src/cases/case/mod.rs delete mode 100644 third_party/rust/Inflector/src/cases/classcase/mod.rs delete mode 100644 third_party/rust/Inflector/src/cases/kebabcase/mod.rs delete mode 100644 third_party/rust/Inflector/src/cases/mod.rs delete mode 100644 third_party/rust/Inflector/src/cases/pascalcase/mod.rs delete mode 100644 third_party/rust/Inflector/src/cases/screamingsnakecase/mod.rs delete mode 100644 third_party/rust/Inflector/src/cases/sentencecase/mod.rs delete mode 100644 third_party/rust/Inflector/src/cases/snakecase/mod.rs delete mode 100644 third_party/rust/Inflector/src/cases/tablecase/mod.rs delete mode 100644 third_party/rust/Inflector/src/cases/titlecase/mod.rs delete mode 100644 third_party/rust/Inflector/src/cases/traincase/mod.rs delete mode 100644 third_party/rust/Inflector/src/lib.rs delete mode 100644 third_party/rust/Inflector/src/numbers/deordinalize/mod.rs delete mode 100644 third_party/rust/Inflector/src/numbers/mod.rs delete mode 100644 third_party/rust/Inflector/src/numbers/ordinalize/mod.rs delete mode 100644 third_party/rust/Inflector/src/string/constants/mod.rs delete mode 100644 third_party/rust/Inflector/src/string/deconstantize/mod.rs delete mode 100644 third_party/rust/Inflector/src/string/demodulize/mod.rs delete mode 100644 third_party/rust/Inflector/src/string/mod.rs delete mode 100644 third_party/rust/Inflector/src/string/pluralize/mod.rs delete mode 100644 third_party/rust/Inflector/src/string/singularize/mod.rs delete mode 100644 third_party/rust/Inflector/src/suffix/foreignkey/mod.rs delete mode 100644 third_party/rust/Inflector/src/suffix/mod.rs delete mode 100644 third_party/rust/Inflector/tests/lib.rs delete mode 100644 third_party/rust/ansi_term/.cargo-checksum.json delete mode 100644 third_party/rust/ansi_term/Cargo.toml delete mode 100644 third_party/rust/ansi_term/LICENCE delete mode 100644 third_party/rust/ansi_term/README.md delete mode 100644 third_party/rust/ansi_term/examples/colours.rs delete mode 100644 third_party/rust/ansi_term/src/ansi.rs delete mode 100644 third_party/rust/ansi_term/src/debug.rs delete mode 100644 third_party/rust/ansi_term/src/difference.rs delete mode 100644 third_party/rust/ansi_term/src/display.rs delete mode 100644 third_party/rust/ansi_term/src/lib.rs delete mode 100644 third_party/rust/ansi_term/src/style.rs delete mode 100644 third_party/rust/ansi_term/src/windows.rs delete mode 100644 third_party/rust/ansi_term/src/write.rs delete mode 100644 third_party/rust/binjs_meta/.cargo-checksum.json delete mode 100644 third_party/rust/binjs_meta/Cargo.lock delete mode 100644 third_party/rust/binjs_meta/Cargo.toml delete mode 100644 third_party/rust/binjs_meta/README.md delete mode 100644 third_party/rust/binjs_meta/examples/generate_spidermonkey.rs delete mode 100644 third_party/rust/binjs_meta/src/export.rs delete mode 100644 third_party/rust/binjs_meta/src/import.rs delete mode 100644 third_party/rust/binjs_meta/src/lib.rs delete mode 100644 third_party/rust/binjs_meta/src/spec.rs delete mode 100644 third_party/rust/binjs_meta/src/util.rs delete mode 100644 third_party/rust/weedle/.cargo-checksum.json delete mode 100644 third_party/rust/weedle/Cargo.toml delete mode 100644 third_party/rust/weedle/LICENSE.md delete mode 100644 third_party/rust/weedle/README.md delete mode 100644 third_party/rust/weedle/src/argument.rs delete mode 100644 third_party/rust/weedle/src/attribute.rs delete mode 100644 third_party/rust/weedle/src/common.rs delete mode 100644 third_party/rust/weedle/src/dictionary.rs delete mode 100644 third_party/rust/weedle/src/interface.rs delete mode 100644 third_party/rust/weedle/src/lib.rs delete mode 100644 third_party/rust/weedle/src/literal.rs delete mode 100644 third_party/rust/weedle/src/macros.rs delete mode 100644 third_party/rust/weedle/src/mixin.rs delete mode 100644 third_party/rust/weedle/src/namespace.rs delete mode 100644 third_party/rust/weedle/src/term.rs delete mode 100644 third_party/rust/weedle/src/types.rs delete mode 100644 third_party/rust/weedle/src/whitespace.rs delete mode 100644 third_party/rust/weedle/tests/defs/dom.webidl delete mode 100644 third_party/rust/weedle/tests/defs/html.webidl delete mode 100644 third_party/rust/weedle/tests/defs/interface-constructor.webidl delete mode 100644 third_party/rust/weedle/tests/defs/mediacapture-streams.webidl delete mode 100644 third_party/rust/weedle/tests/webidl.rs diff --git a/Cargo.lock b/Cargo.lock index d0563340d2ec..b464d0213b08 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,11 +1,5 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -[[package]] -name = "Inflector" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" - [[package]] name = "adler32" version = "1.0.4" @@ -27,15 +21,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "ansi_term" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -dependencies = [ - "winapi 0.3.7", -] - [[package]] name = "anyhow" version = "1.0.30" @@ -257,19 +242,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff" -[[package]] -name = "binast" -version = "0.2.0" -dependencies = [ - "Inflector", - "binjs_meta", - "clap", - "env_logger", - "itertools", - "log", - "yaml-rust", -] - [[package]] name = "bincode" version = "1.2.1" @@ -300,18 +272,6 @@ dependencies = [ "shlex", ] -[[package]] -name = "binjs_meta" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d535cc5246fd9035268770420afd76c05f87e68b83ebed0ac94e8258e88fc353" -dependencies = [ - "Inflector", - "itertools", - "log", - "weedle", -] - [[package]] name = "bitflags" version = "1.2.0" @@ -610,14 +570,11 @@ version = "2.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536" dependencies = [ - "ansi_term", - "atty", "bitflags", "strsim", "term_size", "textwrap", "unicode-width", - "vec_map", ] [[package]] @@ -5561,15 +5518,6 @@ dependencies = [ "url", ] -[[package]] -name = "weedle" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7d4f9feb723a800d8f7b74edc9fa44ff35cb0b2ec64886714362f423427f37" -dependencies = [ - "nom", -] - [[package]] name = "wgpu-core" version = "0.5.0" diff --git a/Cargo.toml b/Cargo.toml index a5ec89a1d7db..0b7ec008b8e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,7 +8,6 @@ members = [ "js/rust", "js/src", "js/src/frontend/smoosh", - "js/src/frontend/binast", # Code generator. "js/src/rust", "js/src/wasm/cranelift", "netwerk/test/http3server", diff --git a/js/src/frontend/binast/Cargo.toml b/js/src/frontend/binast/Cargo.toml deleted file mode 100644 index 16c4296eef5a..000000000000 --- a/js/src/frontend/binast/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "binast" -version = "0.2.0" -authors = ["David Teller "] -autobins = false - -[dependencies] -binjs_meta = "^0.5.2" -clap = "^2" -env_logger = "^0.6" -Inflector = { version="^0.11", default-features=false } -itertools = "^0.8" -log = "0.4" -yaml-rust = "^0.4.2" - -[[bin]] -name = "binast" -path = "src/main.rs" diff --git a/js/src/frontend/binast/README.md b/js/src/frontend/binast/README.md deleted file mode 100644 index daa8484d418c..000000000000 --- a/js/src/frontend/binast/README.md +++ /dev/null @@ -1,16 +0,0 @@ -A parser generator used to generate the following files: - -- js/src/frontend/BinASTParser.h -- js/src/frontend/BinASTParser.cpp -- js/src/frontend/BinASTToken.h - -from the following files: - -- js/src/frontend/BinAST.webidl_ (specifications of BinAST) -- js/src/frontend/BinAST.yaml (parser generator driver) - -To use it: -```sh -$ cd $(topsrcdir)/js/src/frontend/binast -% ./build.sh -``` diff --git a/js/src/frontend/binast/build.sh b/js/src/frontend/binast/build.sh deleted file mode 100755 index 22a07d13c411..000000000000 --- a/js/src/frontend/binast/build.sh +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/sh - -cargo run -- \ - ../BinAST.webidl_ \ - ../BinAST.yaml \ - --out-class ../BinASTParser-tmp.h \ - --out-impl ../BinASTParser-tmp.cpp \ - --out-enum ../BinASTEnum-tmp.h \ - --out-token ../BinASTToken-tmp.h - - -( - cd ../../../../; - ./mach clang-format -p \ - js/src/frontend/BinASTParser-tmp.h \ - js/src/frontend/BinASTParser-tmp.cpp \ - js/src/frontend/BinASTEnum-tmp.h \ - js/src/frontend/BinASTToken-tmp.h -) - -# Usage: update SRC DST -# -# If SRC file and DST file have different content, move SRC file to DST file. -# If not, remove SRC file. -update() { - SRC=$1 - DST=$2 - - if diff -q ${SRC} ${DST} > /dev/null; then - echo "SKIPPED: ${DST} was not modified" - rm ${SRC} - else - echo "UPDATED: ${DST} was modified" - mv ${SRC} ${DST} - fi -} - -update ../BinASTParser-tmp.h ../BinASTParser.h -update ../BinASTParser-tmp.cpp ../BinASTParser.cpp -update ../BinASTEnum-tmp.h ../BinASTEnum.h -update ../BinASTToken-tmp.h ../BinASTToken.h diff --git a/js/src/frontend/binast/moz.build b/js/src/frontend/binast/moz.build deleted file mode 100644 index a3e8a14877ed..000000000000 --- a/js/src/frontend/binast/moz.build +++ /dev/null @@ -1,7 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -HOST_RUST_PROGRAMS += ['binast'] diff --git a/js/src/frontend/binast/src/main.rs b/js/src/frontend/binast/src/main.rs deleted file mode 100644 index 40f0c84a2666..000000000000 --- a/js/src/frontend/binast/src/main.rs +++ /dev/null @@ -1,3601 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -extern crate binjs_meta; -extern crate clap; -extern crate env_logger; -extern crate inflector; -extern crate itertools; -#[macro_use] -extern crate log; -extern crate yaml_rust; - -use binjs_meta::export::{ToWebidl, TypeDeanonymizer, TypeName}; -use binjs_meta::import::Importer; -use binjs_meta::spec::*; -use binjs_meta::util::{Reindentable, ToCases, ToStr}; - -mod refgraph; - -use refgraph::ReferenceGraph; - -use std::borrow::Cow; -use std::collections::{HashMap, HashSet}; -use std::fs::*; -use std::io::{Read, Write}; -use std::rc::Rc; - -use clap::{App, Arg}; - -use itertools::Itertools; - -/// An extension of `ToCases` to produce macro-style names, e.g. `FOO_BAR` -/// from `FooBar` or `foo_bar`. -trait ToCases2: ToCases { - fn to_cpp_macro_case(&self) -> String { - use inflector::cases::screamingsnakecase::to_screaming_snake_case; - to_screaming_snake_case(&self.to_cpp_enum_case()) - } -} -impl ToCases2 for T {} - -/// Rules for generating the code for parsing a single field -/// of a node. -/// -/// Extracted from the yaml file. -#[derive(Clone, Default)] -struct FieldRules { - /// Declaring the variable to hold the contents of that field. - declare: Option, - - /// Replace the declaration and assignation. - replace: Option, - - /// Things to add before the field, typically for checking invariants. - before_field: Option, - - /// Things to add after the field, typically for checking invariants. - after_field: Option, - - /// Things to add before the field, as part of a block, typically for - /// putting guard values on the stack. - block_before_field: Option, - - /// Things to add before the field, as part of a block, typically for - /// cleanup. - block_after_field: Option, - - /// Extra arguments passed to the method when parsing this field. - extra_args: Option>, -} - -#[derive(Clone, Default)] -struct SumRules { - after_arm: Option, - - // Disable this arm (false by default). - disabled: bool, -} - -/// Rules for generating the code for parsing a full node -/// of a node. -/// -/// Extracted from the yaml file. -#[derive(Clone, Default)] -struct NodeRules { - /// This node inherits from another node. - inherits: Option, - - /// Override the result type for the method. - type_ok: Option>, - - /// Default value for the optional field. - default_value: Option>, - - /// Extra parameters for the method. - extra_params: Option>, - - /// Extra arguments passed to the method when parsing this interface. - /// For ListOf* interfaces, this arguments are passed to each item. - /// For sum interface, this arguments are passed to each interface. - extra_args: Option>, - - /// Things to add before calling the method when the optional field has - /// value. - some_before: Option>, - - /// Things to add after calling the method when the optional field has - /// value. - some_after: Option>, - - /// Replace the assignment when the option field has no value. - none_replace: Option>, - - /// Stuff to add at start. - init: Option, - - /// How to append to a list. Used only for lists. - append: Option, - - /// Custom per-field treatment. Used only for interfaces. - by_field: HashMap, - - by_sum: HashMap, - - /// How to build the result, eventually. - build_result: Option, -} - -/// Rules for generating entire files. -/// -/// Extracted from the yaml file. -#[derive(Default)] -struct GlobalRules { - /// C++ class name of the parser class. - parser_class_name: Rc, - - /// The template part of the parser class. - parser_class_template: Rc, - - /// The return value of each method. - parser_type_ok: Rc, - - /// Default value for the optional field. - parser_default_value: Rc, - - /// Code to append the list item. - parser_list_append: Option>, - - /// Header to add at the start of the .cpp file. - cpp_header: Option, - - /// Header to add at the end of the .cpp file. - cpp_footer: Option, - - /// Header to add at the start of the .hpp file. - /// defining the class. - hpp_class_header: Option, - - /// Footer to add at the end of the .hpp file - /// defining the class. - hpp_class_footer: Option, - - /// Header to add at the start of the .hpp file. - /// defining the enums. - hpp_enums_header: Option, - - /// Footer to add at the end of the .hpp file - /// defining the enums. - hpp_enums_footer: Option, - - /// Header to add at the start of the .hpp file. - /// defining the tokens. - hpp_tokens_header: Option, - - /// Footer to add at the start of the .hpp file. - /// defining the tokens. - hpp_tokens_footer: Option, - - /// Documentation for the `BinASTKind` class enum. - hpp_tokens_kind_doc: Option, - - /// Documentation for the `BinASTField` class enum. - hpp_tokens_field_doc: Option, - - /// Documentation for the `BinASTVariant` class enum. - hpp_tokens_variants_doc: Option, - - /// Per-node rules. - per_node: HashMap, -} -impl GlobalRules { - fn new(syntax: &Spec, yaml: &yaml_rust::yaml::Yaml) -> Self { - let rules = yaml.as_hash().expect("Rules are not a dictionary"); - - let mut parser_class_name = None; - let mut parser_class_template = None; - let mut parser_type_ok = None; - let mut parser_default_value = None; - let mut parser_list_append = None; - let mut cpp_header = None; - let mut cpp_footer = None; - let mut hpp_class_header = None; - let mut hpp_class_footer = None; - let mut hpp_enums_header = None; - let mut hpp_enums_footer = None; - let mut hpp_tokens_header = None; - let mut hpp_tokens_footer = None; - let mut hpp_tokens_kind_doc = None; - let mut hpp_tokens_field_doc = None; - let mut hpp_tokens_variants_doc = None; - let mut per_node = HashMap::new(); - - for (node_key, node_entries) in rules.iter() { - let node_key = node_key - .as_str() - .expect("Could not convert node_key to string"); - - match node_key { - "parser" => { - update_rule_rc(&mut parser_class_name, &node_entries["class-name"]) - .unwrap_or_else(|_| panic!("Rule parser.class-name must be a string")); - update_rule(&mut parser_class_template, &node_entries["class-template"]) - .unwrap_or_else(|_| panic!("Rule parser.class-template must be a string")); - update_rule_rc(&mut parser_type_ok, &node_entries["type-ok"]) - .unwrap_or_else(|_| panic!("Rule parser.type-ok must be a string")); - update_rule_rc(&mut parser_default_value, &node_entries["default-value"]) - .unwrap_or_else(|_| panic!("Rule parser.default-value must be a string")); - update_rule_rc(&mut parser_list_append, &node_entries["list"]["append"]) - .unwrap_or_else(|_| panic!("Rule parser.list.append must be a string")); - continue; - } - "cpp" => { - update_rule(&mut cpp_header, &node_entries["header"]) - .unwrap_or_else(|_| panic!("Rule cpp.header must be a string")); - update_rule(&mut cpp_footer, &node_entries["footer"]) - .unwrap_or_else(|_| panic!("Rule cpp.footer must be a string")); - continue; - } - "hpp" => { - update_rule(&mut hpp_class_header, &node_entries["class"]["header"]) - .unwrap_or_else(|_| panic!("Rule hpp.class.header must be a string")); - update_rule(&mut hpp_class_footer, &node_entries["class"]["footer"]) - .unwrap_or_else(|_| panic!("Rule hpp.class.footer must be a string")); - update_rule(&mut hpp_enums_header, &node_entries["enums"]["header"]) - .unwrap_or_else(|_| panic!("Rule hpp.enum.header must be a string")); - update_rule(&mut hpp_enums_footer, &node_entries["enums"]["footer"]) - .unwrap_or_else(|_| panic!("Rule hpp.enum.footer must be a string")); - update_rule(&mut hpp_tokens_header, &node_entries["tokens"]["header"]) - .unwrap_or_else(|_| panic!("Rule hpp.tokens.header must be a string")); - update_rule(&mut hpp_tokens_footer, &node_entries["tokens"]["footer"]) - .unwrap_or_else(|_| panic!("Rule hpp.tokens.footer must be a string")); - update_rule( - &mut hpp_tokens_kind_doc, - &node_entries["tokens"]["kind"]["doc"], - ) - .unwrap_or_else(|_| panic!("Rule hpp.tokens.kind.doc must be a string")); - update_rule( - &mut hpp_tokens_field_doc, - &node_entries["tokens"]["field"]["doc"], - ) - .unwrap_or_else(|_| panic!("Rule hpp.tokens.field.doc must be a string")); - update_rule( - &mut hpp_tokens_variants_doc, - &node_entries["tokens"]["variants"]["doc"], - ) - .unwrap_or_else(|_| panic!("Rule hpp.tokens.variants.doc must be a string")); - continue; - } - _ => {} - } - - let node_name = syntax - .get_node_name(&node_key) - .unwrap_or_else(|| panic!("Unknown node name {}", node_key)); - - let hash = node_entries - .as_hash() - .unwrap_or_else(|| panic!("Node {} isn't a dictionary")); - - let mut node_rule = NodeRules::default(); - for (node_item_key, node_item_entry) in hash { - let as_string = node_item_key - .as_str() - .unwrap_or_else(|| panic!("Keys for rule {} must be strings", node_key)); - match as_string { - "inherits" => { - let name = node_item_entry.as_str().unwrap_or_else(|| { - panic!("Rule {}.{} must be a string", node_key, as_string) - }); - let inherits = syntax - .get_node_name(name) - .unwrap_or_else(|| panic!("Unknown node name {}", name)); - node_rule.inherits = Some(inherits).cloned(); - } - "extra-params" => { - update_rule_rc(&mut node_rule.extra_params, node_item_entry) - .unwrap_or_else(|()| { - panic!("Rule {}.{} must be a string", node_key, as_string) - }); - } - "extra-args" => { - update_rule_rc(&mut node_rule.extra_args, node_item_entry).unwrap_or_else( - |()| panic!("Rule {}.{} must be a string", node_key, as_string), - ); - } - "some" => { - update_rule_rc(&mut node_rule.some_before, &node_item_entry["before"]) - .unwrap_or_else(|()| { - panic!("Rule {}.{}.before must be a string", node_key, as_string) - }); - update_rule_rc(&mut node_rule.some_after, &node_item_entry["after"]) - .unwrap_or_else(|()| { - panic!("Rule {}.{}.after must be a string", node_key, as_string) - }); - } - "none" => { - update_rule_rc(&mut node_rule.none_replace, &node_item_entry["replace"]) - .unwrap_or_else(|()| { - panic!("Rule {}.{}.replace must be a string", node_key, as_string) - }); - } - "init" => { - update_rule(&mut node_rule.init, node_item_entry).unwrap_or_else(|()| { - panic!("Rule {}.{} must be a string", node_key, as_string) - }); - } - "build" => { - update_rule(&mut node_rule.build_result, node_item_entry).unwrap_or_else( - |()| panic!("Rule {}.{} must be a string", node_key, as_string), - ); - } - "append" => { - update_rule(&mut node_rule.append, node_item_entry).unwrap_or_else(|()| { - panic!("Rule {}.{} must be a string", node_key, as_string) - }); - } - "type-ok" => { - update_rule_rc(&mut node_rule.type_ok, node_item_entry).unwrap_or_else( - |()| panic!("Rule {}.{} must be a string", node_key, as_string), - ); - } - "default-value" => { - update_rule_rc(&mut node_rule.default_value, node_item_entry) - .unwrap_or_else(|()| { - panic!("Rule {}.{} must be a string", node_key, as_string) - }); - } - "fields" => { - let fields = node_item_entry.as_hash().unwrap_or_else(|| { - panic!( - "Rule {}.fields must be a hash, got {:?}", - node_key, node_entries["fields"] - ) - }); - for (field_key, field_entry) in fields { - let field_key = field_key - .as_str() - .unwrap_or_else(|| { - panic!( - "In rule {}, field entries must be field names", - node_key - ) - }) - .to_string(); - let field_name = - syntax.get_field_name(&field_key).unwrap_or_else(|| { - panic!("In rule {}, can't find field {}", node_key, field_key) - }); - - let mut field_rule = FieldRules::default(); - for (field_config_key, field_config_entry) in - field_entry.as_hash().unwrap_or_else(|| { - panic!("Rule {}.fields.{} must be a hash", node_key, field_key) - }) - { - let field_config_key = field_config_key - .as_str() - .expect("Expected a string as a key"); - match field_config_key { - "block" => { - update_rule( - &mut field_rule.declare, - &field_config_entry["declare"], - ) - .unwrap_or_else( - |()| { - panic!( - "Rule {}.fields.{}.{}.{} must be a string", - node_key, - field_key, - field_config_key, - "declare" - ) - }, - ); - - update_rule( - &mut field_rule.replace, - &field_config_entry["replace"], - ) - .unwrap_or_else( - |()| { - panic!( - "Rule {}.fields.{}.{}.{} must be a string", - node_key, - field_key, - field_config_key, - "replace" - ) - }, - ); - - update_rule( - &mut field_rule.block_before_field, - &field_config_entry["before"], - ) - .unwrap_or_else( - |()| { - panic!( - "Rule {}.fields.{}.{}.{} must be a string", - node_key, field_key, field_config_key, "before" - ) - }, - ); - - update_rule( - &mut field_rule.block_after_field, - &field_config_entry["after"], - ) - .unwrap_or_else( - |()| { - panic!( - "Rule {}.fields.{}.{}.{} must be a string", - node_key, field_key, field_config_key, "after" - ) - }, - ); - } - "before" => { - update_rule( - &mut field_rule.before_field, - &field_config_entry, - ) - .unwrap_or_else( - |()| { - panic!( - "Rule {}.fields.{}.{} must be a string", - node_key, field_key, field_config_key - ) - }, - ); - } - "after" => { - update_rule( - &mut field_rule.after_field, - &field_config_entry, - ) - .unwrap_or_else( - |()| { - panic!( - "Rule {}.fields.{}.{} must be a string", - node_key, field_key, field_config_key - ) - }, - ); - } - "extra-args" => { - update_rule_rc( - &mut field_rule.extra_args, - &field_config_entry, - ) - .unwrap_or_else( - |()| { - panic!( - "Rule {}.fields.{}.{} must be a string", - node_key, field_key, field_config_key - ) - }, - ); - } - _ => panic!( - "Unexpected {}.fields.{}.{}", - node_key, field_key, field_config_key - ), - } - } - node_rule.by_field.insert(field_name.clone(), field_rule); - } - } - "sum-arms" => { - let arms = node_item_entry.as_hash().unwrap_or_else(|| { - panic!( - "Rule {}.sum-arms must be a hash, got {:?}", - node_key, node_entries["sum-arms"] - ) - }); - for (sum_arm_key, sum_arm_entry) in arms { - let sum_arm_key = sum_arm_key.as_str().unwrap_or_else(|| { - panic!("In rule {}, sum arms must be interface names") - }); - let sum_arm_name = - syntax.get_node_name(&sum_arm_key).unwrap_or_else(|| { - panic!( - "In rule {}. cannot find interface {}", - node_key, sum_arm_key - ) - }); - - let mut sum_rule = SumRules::default(); - for (arm_config_key, arm_config_entry) in - sum_arm_entry.as_hash().unwrap_or_else(|| { - panic!( - "Rule {}.sum-arms.{} must be a hash", - node_key, sum_arm_key - ) - }) - { - let arm_config_key = - arm_config_key.as_str().expect("Expected a string as a key"); - match arm_config_key { - "after" => { - update_rule(&mut sum_rule.after_arm, arm_config_entry) - .unwrap_or_else(|()| { - panic!( - "Rule {}.sum-arms.{}.{} must be a string", - node_key, sum_arm_key, arm_config_key - ) - }); - } - "disabled" => { - if let Some(disabled) = arm_config_entry.as_bool() { - if disabled { - sum_rule.disabled = true; - } - } else { - panic!( - "Rule {}.sum-arms.{}.{} must be a bool", - node_key, sum_arm_key, arm_config_key - ); - } - } - _ => { - panic!( - "Unexpected {}.sum-arms.{}.{}", - node_key, sum_arm_key, arm_config_key - ); - } - } - } - node_rule.by_sum.insert(sum_arm_name.clone(), sum_rule); - } - } - _ => panic!("Unexpected node_item_key {}.{}", node_key, as_string), - } - } - - per_node.insert(node_name.clone(), node_rule); - } - - Self { - parser_class_name: parser_class_name.expect("parser.class-name should be specified"), - parser_class_template: Rc::new(if parser_class_template.is_some() { - format!("{} ", parser_class_template.unwrap()) - } else { - "".to_string() - }), - parser_type_ok: parser_type_ok.expect("parser.type-ok should be specified"), - parser_default_value: parser_default_value - .expect("parser.default-value should be specified"), - parser_list_append, - cpp_header, - cpp_footer, - hpp_class_header, - hpp_class_footer, - hpp_enums_header, - hpp_enums_footer, - hpp_tokens_header, - hpp_tokens_footer, - hpp_tokens_kind_doc, - hpp_tokens_field_doc, - hpp_tokens_variants_doc, - per_node, - } - } - fn get(&self, name: &NodeName) -> NodeRules { - let mut rules = self.per_node.get(name).cloned().unwrap_or_default(); - if let Some(ref parent) = rules.inherits { - let NodeRules { - inherits: _, - type_ok, - default_value, - extra_params, - extra_args, - some_before, - some_after, - none_replace, - init, - append, - by_field, - by_sum, - build_result, - } = self.get(parent); - if rules.type_ok.is_none() { - rules.type_ok = type_ok; - } - if rules.default_value.is_none() { - rules.default_value = default_value; - } - if rules.extra_params.is_none() { - rules.extra_params = extra_params; - } - if rules.extra_args.is_none() { - rules.extra_args = extra_args; - } - if rules.some_before.is_none() { - rules.some_before = some_before; - } - if rules.some_after.is_none() { - rules.some_after = some_after; - } - if rules.none_replace.is_none() { - rules.none_replace = none_replace; - } - if rules.init.is_none() { - rules.init = init; - } - if rules.append.is_none() { - rules.append = append; - } - if rules.build_result.is_none() { - rules.build_result = build_result; - } - for (key, value) in by_field { - rules.by_field.entry(key).or_insert(value); - } - for (key, value) in by_sum { - rules.by_sum.entry(key).or_insert(value); - } - } - rules - } -} - -/// The inforamtion used to generate a list parser. -#[derive(Clone, Debug)] -struct ListParserData { - /// Name of the node. - name: NodeName, - - /// If `true`, supports empty lists. - supports_empty: bool, - - /// Name of the elements in the list. - elements: NodeName, -} - -/// The inforamtion used to generate a parser for an optional data structure. -struct OptionParserData { - /// Name of the node. - name: NodeName, - - /// Name of the element that may be contained. - elements: NodeName, -} - -/// What to use when calling the method to store the result value. -enum MethodCallKind { - /// Use BINJS_MOZ_TRY_DECL if the result type is not "Ok", - /// use MOZ_TRY otherwise. - Decl, - - /// Always use MOZ_TRY_DECL regardless of the result type. - AlwaysDecl, - - /// Use MOZ_TRY_VAR if the result type is not "Ok", - /// use MOZ_TRY otherwise. - Var, - - /// Always use MOZ_TRY_VAR regardless of the result type. - AlwaysVar, -} - -/// Fixed parameter of interface method. -const INTERFACE_PARAMS: &str = "const size_t start"; - -/// Fixed arguments of interface method. -const INTERFACE_ARGS: &str = "start"; - -/// Fixed parameter of sum interface method. -const SUM_INTERFACE_PARAMS: &str = "const size_t start, const BinASTKind kind"; - -/// Fixed arguments of sum interface method. -const SUM_INTERFACE_ARGS: &str = "start, kind"; - -/// The name of the toplevel interface for the script. -const TOPLEVEL_INTERFACE: &str = "Program"; - -/// In which context an interface appears. -#[derive(Clone, Debug, PartialEq)] -struct LookupContext { - /// In root of parsing. - in_root: bool, - - /// In list element. - in_list: bool, - - /// In interface field. - in_field: bool, -} -impl LookupContext { - fn empty() -> Self { - Self { - in_root: false, - in_list: false, - in_field: false, - } - } - - fn root() -> Self { - Self { - in_root: true, - in_list: false, - in_field: false, - } - } - - fn list() -> Self { - Self { - in_root: false, - in_list: true, - in_field: false, - } - } - - fn field() -> Self { - Self { - in_root: false, - in_list: false, - in_field: true, - } - } - - fn is_root(&self) -> bool { - self.in_root && !self.in_list && !self.in_field - } - - fn is_list(&self) -> bool { - !self.in_root && self.in_list && !self.in_field - } - - fn is_field(&self) -> bool { - !self.in_root && !self.in_list && self.in_field - } - - fn is_field_and_list(&self) -> bool { - !self.in_root && self.in_list && self.in_field - } - - fn is_field_and_root(&self) -> bool { - self.in_root && !self.in_list && self.in_field - } - - fn is_single(&self) -> bool { - self.is_root() || self.is_list() || self.is_field() - } - - fn is_valid_double(&self) -> bool { - self.is_field_and_root() || self.is_field_and_list() - } - - fn add(&mut self, rhs: Self) { - self.in_root |= rhs.in_root; - self.in_list |= rhs.in_list; - self.in_field |= rhs.in_field; - } -} - -type ContextMap = HashMap, LookupContext>; - -/// The actual exporter. -struct CPPExporter { - /// The syntax to export. - syntax: Spec, - - /// Rules, as specified in yaml. - rules: GlobalRules, - - /// Reference graph of the method call. - refgraph: ReferenceGraph, - - context_map: ContextMap, - - /// All parsers of lists. - list_parsers_to_generate: Vec, - - /// All parsers of options. - option_parsers_to_generate: Vec, - - /// A subset of `list_parsers_to_generate` guaranteed to have - /// a single representative for each list type, regardless - /// of typedefs. - /// - /// Indexed by the contents of the list. - canonical_list_parsers: HashMap, - - /// A mapping from symbol (e.g. `+`, `-`, `instanceof`, ...) to the - /// name of the symbol as part of `enum class BinASTVariant` - /// (e.g. `UnaryOperatorDelete`). - variants_by_symbol: HashMap, - - // A map from enum class names to the type. - enum_types: HashMap>, -} - -impl CPPExporter { - fn new(syntax: Spec, rules: GlobalRules) -> Self { - let mut list_parsers_to_generate = vec![]; - let mut option_parsers_to_generate = vec![]; - let mut canonical_list_parsers = HashMap::new(); - for (parser_node_name, typedef) in syntax.typedefs_by_name() { - if typedef.is_optional() { - let content_name = TypeName::type_spec(typedef.spec()); - let content_node_name = syntax - .get_node_name(&content_name) - .unwrap_or_else(|| { - panic!( - "While generating an option parser, could not find node name \"{}\"", - content_name - ) - }) - .clone(); - debug!(target: "generate_spidermonkey", "CPPExporter::new adding optional typedef {:?} => {:?} => {:?}", - parser_node_name, - content_name, - content_node_name); - option_parsers_to_generate.push(OptionParserData { - name: parser_node_name.clone(), - elements: content_node_name, - }); - } else if let TypeSpec::Array { - ref contents, - ref supports_empty, - } = *typedef.spec() - { - use std::collections::hash_map::Entry::*; - let content_name = TypeName::type_(&**contents); - let content_node_name = syntax - .get_node_name(&content_name) - .unwrap_or_else(|| { - panic!( - "While generating an array parser, could not find node name {}", - content_name - ) - }) - .clone(); - debug!(target: "generate_spidermonkey", "CPPExporter::new adding list typedef {:?} => {:?} => {:?}", - parser_node_name, - content_name, - content_node_name); - let data = ListParserData { - name: parser_node_name.clone(), - supports_empty: *supports_empty, - elements: content_node_name, - }; - - match canonical_list_parsers.entry(data.elements.clone()) { - Occupied(mut entry) => { - debug!(target: "generate_spidermonkey", "lists: Comparing existing entry {existing:?} and {new:?}", - existing = entry.get(), - new = data); - // HACK: We assume that a parser with name `ListXXX` is more canonical than doesn't start with `List`. - if data.name.to_str().starts_with("List") { - entry.insert(data.clone()); - } - } - Vacant(entry) => { - debug!(target: "generate_spidermonkey", "lists: Inserting {new:?}", - new = data); - entry.insert(data.clone()); - } - } - - list_parsers_to_generate.push(data); - } - } - list_parsers_to_generate.sort_by(|a, b| str::cmp(a.name.to_str(), b.name.to_str())); - option_parsers_to_generate.sort_by(|a, b| str::cmp(a.name.to_str(), b.name.to_str())); - - // Prepare variant_by_symbol, which will let us lookup the BinASTVariant name of - // a symbol. Since some symbols can appear in several enums (e.g. "+" - // is both a unary and a binary operator), we need to collect all the - // string enums that contain each symbol and come up with a unique name - // (note that there is no guarantee of unicity – if collisions show up, - // we may need to tweak the name generation algorithm). - let mut enum_by_string: HashMap> = HashMap::new(); - let mut enum_types: HashMap> = HashMap::new(); - for (name, enum_) in syntax.string_enums_by_name().iter() { - let type_ = format!( - "typename {parser_class_name}::{kind}", - parser_class_name = rules.parser_class_name, - kind = name.to_class_cases() - ); - enum_types.insert(name.clone(), Rc::new(type_)); - for string in enum_.strings().iter() { - let vec = enum_by_string - .entry(string.clone()) - .or_insert_with(|| vec![]); - vec.push(name.clone()); - } - } - let variants_by_symbol = enum_by_string - .drain() - .map(|(string, names)| { - let expanded = format!( - "{names}{symbol}", - names = names - .iter() - .map(NodeName::to_str) - .sorted() - .into_iter() - .format("Or"), - symbol = string.to_cpp_enum_case() - ); - (string, expanded) - }) - .collect(); - - // This is just a placeholder to instantiate the CPPExporter struct. - // The field will be overwritten later in generate_reference_graph. - let refgraph = ReferenceGraph::new(); - - let context_map = HashMap::new(); - - CPPExporter { - syntax, - rules, - refgraph, - context_map, - list_parsers_to_generate, - option_parsers_to_generate, - canonical_list_parsers, - variants_by_symbol, - enum_types, - } - } - - /// Return NamedType for given NodeName. - /// Panic if NodeName is not NamedType - fn get_named_implementation(&self, name: &NodeName) -> NamedType { - if let Some(NamedType::Typedef(ref typedef)) = self.syntax.get_type_by_name(name) { - assert!(typedef.is_optional()); - if let TypeSpec::NamedType(ref named) = *typedef.spec() { - self.syntax.get_type_by_name(named).unwrap_or_else(|| { - panic!( - "Internal error: Could not find type {}, which should have been generated.", - named.to_str() - ) - }) - } else { - panic!( - "Internal error: In {}, type {:?} should have been a named type", - name.to_str(), - typedef - ); - } - } else { - panic!( - "Internal error: In {}, there should be a type with that name", - name.to_str() - ); - } - } - - /// Generate a reference graph of methods. - fn generate_reference_graph(&mut self) { - let mut refgraph = ReferenceGraph::new(); - - // FIXME: Reflect `replace` rule in yaml file for each interface to - // the reference (bug 1504595). - - // 1. Typesums - let sums_of_interfaces = self.syntax.resolved_sums_of_interfaces_by_name(); - for (name, nodes) in sums_of_interfaces { - let rules_for_this_sum = self.rules.get(name); - - let mut edges: HashSet> = HashSet::new(); - edges.insert(Rc::new(format!("Sum{}", name))); - refgraph.insert(name.to_rc_string().clone(), edges); - - let mut sum_edges: HashSet> = HashSet::new(); - for node in nodes { - let rule_for_this_arm = rules_for_this_sum - .by_sum - .get(&node) - .cloned() - .unwrap_or_default(); - - // If this arm is disabled, we emit raiseError instead of - // call to parseInterface*. Do not add edge in that case. - if rule_for_this_arm.disabled { - continue; - } - - sum_edges.insert(Rc::new(format!("Interface{}", node.to_string()))); - } - refgraph.insert(Rc::new(format!("Sum{}", name.to_string())), sum_edges); - } - - // 2. Single interfaces - let interfaces_by_name = self.syntax.interfaces_by_name(); - for (name, interface) in interfaces_by_name { - let rules_for_this_interface = self.rules.get(name); - let is_implemented = rules_for_this_interface.build_result.is_some(); - // If this interafce is not implemented, parse* method should - // not be called nor referenced in the graph. - if is_implemented { - let mut edges: HashSet> = HashSet::new(); - edges.insert(Rc::new(format!("Interface{}", name))); - refgraph.insert(name.to_rc_string().clone(), edges); - } - - let mut interface_edges: HashSet> = HashSet::new(); - // If this interface is not implemented, we emit raiseError in - // parseInterface* method, instead of parse* for each fields. - // There can be reference to parseInterface* of this interface - // from sum interface, and this node needs to be represented in - // the reference graph. - if is_implemented { - for field in interface.contents().fields() { - match field.type_().get_primitive(&self.syntax) { - Some(IsNullable { - is_nullable: _, - content: Primitive::Interface(_), - }) - | None => { - let typename = TypeName::type_(field.type_()); - interface_edges.insert(Rc::new(typename.to_string())); - } - - // Don't have to handle other type of fields (string, - // number, bool, etc). - _ => {} - } - } - } - refgraph.insert(Rc::new(format!("Interface{}", name)), interface_edges); - } - - // 3. String Enums - for (kind, _) in self.syntax.string_enums_by_name() { - refgraph.insert(kind.to_rc_string().clone(), HashSet::new()); - } - - // 4. Lists - for parser in &self.list_parsers_to_generate { - let name = &parser.name; - let rules_for_this_list = self.rules.get(name); - let is_implemented = rules_for_this_list.init.is_some(); - // If this list is not implemented, this method should not be - // called nor referenced in the graph. - if !is_implemented { - continue; - } - - let mut edges: HashSet> = HashSet::new(); - edges.insert(parser.elements.to_rc_string().clone()); - refgraph.insert(name.to_rc_string().clone(), edges); - } - - // 5. Optional values - for parser in &self.option_parsers_to_generate { - let mut edges: HashSet> = HashSet::new(); - let named_implementation = self.get_named_implementation(&parser.name); - match named_implementation { - NamedType::Interface(_) => { - edges.insert(Rc::new(format!("Interface{}", parser.elements.to_string()))); - } - NamedType::Typedef(ref type_) => match type_.spec() { - &TypeSpec::TypeSum(_) => { - edges.insert(Rc::new(format!("Sum{}", parser.elements.to_string()))); - } - _ => {} - }, - _ => {} - } - refgraph.insert(parser.name.to_rc_string().clone(), edges); - } - - // 6. Primitive values. - refgraph.insert(Rc::new("IdentifierName".to_string()), HashSet::new()); - refgraph.insert(Rc::new("PropertyKey".to_string()), HashSet::new()); - - self.refgraph = refgraph; - } - - /// Trace the reference graph from the node with `name and mark all nodes - /// as used. `name` is the name of the method, without leading "parse". - fn trace(&mut self, name: Rc) { - self.refgraph.trace(name) - } - - /// Collect context information for each interface to determine - /// which *Context type each method should receive. - fn collect_context(&mut self) { - fn add_context(map: &mut ContextMap, name: Rc, context: LookupContext) { - let entry = map.entry(name).or_insert(LookupContext::empty()); - (*entry).add(context); - } - - // 1. Root - add_context( - &mut self.context_map, - Rc::new("Program".to_string()), - LookupContext::root(), - ); - add_context( - &mut self.context_map, - Rc::new("FunctionExpressionContents".to_string()), - LookupContext::root(), - ); - add_context( - &mut self.context_map, - Rc::new("FunctionOrMethodContents".to_string()), - LookupContext::root(), - ); - - // 2. Interface fields - // XXX => XXX.field - for (name, interface) in self.syntax.interfaces_by_name() { - let inner_prefix = "Interface"; - let inner_name = Rc::new(format!("{}{}", inner_prefix, name)); - if !self.refgraph.is_used(inner_name) { - continue; - } - - for field in interface.contents().fields() { - match field.type_().get_primitive(&self.syntax) { - Some(IsNullable { - is_nullable: _, - content: Primitive::Interface(_), - }) - | None => { - let typename = TypeName::type_(field.type_()); - add_context( - &mut self.context_map, - Rc::new(typename), - LookupContext::field(), - ); - } - _ => {} - } - } - } - - // 3. List contents - // ListXXX => XXX - for parser in &self.list_parsers_to_generate { - if !self.refgraph.is_used(parser.name.to_rc_string().clone()) { - continue; - } - - add_context( - &mut self.context_map, - Rc::new(parser.elements.to_class_cases()), - LookupContext::list(), - ); - } - - fn propagate_context(map: &mut ContextMap, from: Rc, to: Rc) { - let opt_context = match map.get(&from) { - Some(opt_context) => opt_context.clone(), - _ => { - return; - } - }; - let entry = map.entry(to).or_insert(LookupContext::empty()); - (*entry).add(opt_context); - } - - // 4. Propagate Optional - // OptionalXXX => XXX - for parser in &self.option_parsers_to_generate { - if !self.refgraph.is_used(parser.name.to_rc_string().clone()) { - continue; - } - - let named_implementation = self.get_named_implementation(&parser.name); - match named_implementation { - NamedType::Interface(_) => { - propagate_context( - &mut self.context_map, - Rc::new(parser.name.to_class_cases()), - Rc::new(format!("Interface{}", parser.elements.to_class_cases())), - ); - } - NamedType::Typedef(ref type_) => match type_.spec() { - &TypeSpec::TypeSum(_) => { - propagate_context( - &mut self.context_map, - Rc::new(parser.name.to_class_cases()), - Rc::new(format!("Sum{}", parser.elements.to_class_cases())), - ); - } - _ => {} - }, - _ => {} - } - } - - // 5. Propagate Sum - // XXX => SumXXX - // SumXXX => each arm - let sums_of_interfaces = self.syntax.resolved_sums_of_interfaces_by_name(); - for (name, nodes) in sums_of_interfaces { - if !self.refgraph.is_used(name.to_rc_string().clone()) { - continue; - } - - propagate_context( - &mut self.context_map, - Rc::new(name.to_class_cases()), - Rc::new(format!("Sum{}", name.to_class_cases())), - ); - - for node in nodes { - propagate_context( - &mut self.context_map, - Rc::new(format!("Sum{}", name.to_class_cases())), - Rc::new(format!("Interface{}", node.to_class_cases())), - ); - } - } - - // 6. Propagate Interface - // XXX => InterfaceXXX - // InterfaceXXX => XXX - for (name, _) in self.syntax.interfaces_by_name() { - let inner_prefix = "Interface"; - let inner_name = Rc::new(format!("{}{}", inner_prefix, name)); - if !self.refgraph.is_used(inner_name) { - continue; - } - - propagate_context( - &mut self.context_map, - Rc::new(name.to_class_cases()), - Rc::new(format!("Interface{}", name.to_class_cases())), - ); - propagate_context( - &mut self.context_map, - Rc::new(format!("Interface{}", name.to_class_cases())), - Rc::new(name.to_class_cases()), - ); - } - } - - // ----- Generating the header - - /// Get the type representing a success for parsing this node. - fn get_type_ok(&self, name: &NodeName) -> Rc { - // enum has its own rule. - if self.enum_types.contains_key(name) { - return self.enum_types.get(name).unwrap().clone(); - } - - let rules_for_this_interface = self.rules.get(name); - // If the override is provided, use it. - if let Some(type_ok) = rules_for_this_interface.type_ok { - return type_ok; - } - self.rules.parser_type_ok.clone() - } - fn get_default_value(&self, name: &NodeName) -> Rc { - let rules_for_this_interface = self.rules.get(name); - // If the override is provided, use it. - if let Some(default_value) = rules_for_this_interface.default_value { - return default_value; - } - if let Some(type_ok) = rules_for_this_interface.type_ok { - if type_ok.as_str() == "Ok" { - return Rc::new("Ok()".to_string()); - } - } - self.rules.parser_default_value.clone() - } - - fn get_context_param(&self, name: &NodeName, prefix: &str) -> String { - let context = - match self - .context_map - .get(&Rc::new(format!("{}{}", prefix, name.to_rc_string()))) - { - Some(context) => context.clone(), - _ => { - panic!("{}{} doesn't have context", prefix, name.to_rc_string()); - } - }; - if context.is_root() { - return "const RootContext& context".to_string(); - } - if context.is_list() { - return "const ListContext& context".to_string(); - } - if context.is_field() { - return "const FieldContext& context".to_string(); - } - if context.is_field_and_list() { - return "const FieldOrListContext& context".to_string(); - } - if context.is_field_and_root() { - return "const FieldOrRootContext& context".to_string(); - } - - panic!("unexpected context"); - } - - fn get_method_signature( - &self, - name: &NodeName, - prefix: &str, - args: &str, - extra_params: &Option>, - ) -> String { - let type_ok = self.get_type_ok(name); - let kind = name.to_class_cases(); - let extra = match extra_params { - Some(s) => format!( - "{}\n{}", - if args.len() > 0 { "," } else { "" }, - s.reindent(" ") - ), - _ => "".to_string(), - }; - format!( - " JS::Result<{type_ok}> parse{prefix}{kind}({args}{extra}{before_context}{context}); -", - prefix = prefix, - type_ok = type_ok, - kind = kind, - args = args, - extra = extra, - before_context = if args.len() > 0 || extra_params.is_some() { - ", " - } else { - "" - }, - context = self.get_context_param(name, prefix), - ) - } - - fn get_method_definition_start( - &self, - name: &NodeName, - prefix: &str, - args: &str, - extra_params: &Option>, - ) -> String { - let type_ok = self.get_type_ok(name); - let kind = name.to_class_cases(); - let extra = match extra_params { - Some(s) => format!( - "{}\n{}", - if args.len() > 0 { "," } else { "" }, - s.reindent(" ") - ), - _ => "".to_string(), - }; - format!( - "{parser_class_template}JS::Result<{type_ok}> -{parser_class_name}::parse{prefix}{kind}({args}{extra}{before_context}{context})", - parser_class_template = self.rules.parser_class_template, - prefix = prefix, - type_ok = type_ok, - parser_class_name = self.rules.parser_class_name, - kind = kind, - args = args, - extra = extra, - before_context = if args.len() > 0 || extra_params.is_some() { - ", " - } else { - "" - }, - context = self.get_context_param(name, prefix), - ) - } - - fn get_context_param_for_sum(&self, sum: &NodeName, arm: &NodeName, context: &str) -> String { - let sum_name = format!("Sum{}", sum); - let arm_name = format!("Interface{}", arm); - - let sum_context = match self.context_map.get(&sum_name) { - Some(context) => context.clone(), - _ => panic!("no context"), - }; - let arm_context = match self.context_map.get(&arm_name) { - Some(context) => context.clone(), - _ => panic!("no context"), - }; - - if sum_context == arm_context { - return context.to_string(); - } - - assert!(sum_context.is_single()); - assert!(arm_context.is_valid_double()); - - if arm_context.is_field_and_root() { - return format!("FieldOrRootContext({})", context); - } - - return format!("FieldOrListContext({})", context); - } - - fn get_context_param_for_optional( - &self, - optional: &NodeName, - body_prefix: &str, - body: &NodeName, - context: &str, - ) -> String { - let optional_name = optional.to_string().clone(); - let body_name = format!("{}{}", body_prefix, body); - - let optional_context = match self.context_map.get(&optional_name) { - Some(context) => context.clone(), - _ => panic!("no context"), - }; - let body_context = match self.context_map.get(&body_name) { - Some(context) => context.clone(), - _ => panic!("no context"), - }; - - if optional_context == body_context { - return context.to_string(); - } - - assert!(optional_context.is_single()); - assert!(body_context.is_valid_double()); - - if body_context.is_field_and_root() { - return format!("FieldOrRootContext({})", context); - } - - return format!("FieldOrListContext({})", context); - } - - fn get_context_param_for_list(&self, element: &NodeName, context: &str) -> String { - let element_name = element.to_string().clone(); - - let element_context = match self.context_map.get(&element_name) { - Some(context) => context.clone(), - _ => panic!("no context"), - }; - - if element_context.is_list() { - return context.to_string(); - } - - assert!(element_context.is_field_and_list()); - - return format!("FieldOrListContext({})", context); - } - - fn get_context_param_for_field(&self, field: &NodeName, context: &str) -> String { - let field_name = field.to_string().clone(); - - let field_context = match self.context_map.get(&field_name) { - Some(context) => context.clone(), - _ => panic!("no context"), - }; - - if field_context.is_field() { - return context.to_string(); - } - - assert!(field_context.is_valid_double()); - - if field_context.is_field_and_root() { - return format!("FieldOrRootContext({})", context); - } - - return format!("FieldOrListContext({})", context); - } - - fn get_method_call( - &self, - var_name: &str, - name: &NodeName, - prefix: &str, - args: &str, - extra_params: &Option>, - context_name: String, - call_kind: MethodCallKind, - ) -> String { - let type_ok_is_ok = match call_kind { - MethodCallKind::Decl | MethodCallKind::Var => self.get_type_ok(name).to_str() == "Ok", - MethodCallKind::AlwaysDecl | MethodCallKind::AlwaysVar => false, - }; - let extra = match extra_params { - Some(s) => format!( - "{}\n{}", - if args.len() > 0 { "," } else { "" }, - s.reindent(" ") - ), - _ => "".to_string(), - }; - let call = format!( - "parse{prefix}{name}({args}{extra}{before_context}{context})", - prefix = prefix, - name = name.to_class_cases(), - args = args, - extra = extra, - before_context = if extra_params.is_some() || args.len() > 0 { - ", " - } else { - "" - }, - context = context_name - ); - - if type_ok_is_ok { - // Special case: `Ok` means that we shouldn't bind the return value. - format!("MOZ_TRY({call});", call = call) - } else { - match call_kind { - MethodCallKind::Decl | MethodCallKind::AlwaysDecl => format!( - "BINJS_MOZ_TRY_DECL({var_name}, {call});", - var_name = var_name, - call = call - ), - MethodCallKind::Var | MethodCallKind::AlwaysVar => format!( - "MOZ_TRY_VAR({var_name}, {call});", - var_name = var_name, - call = call - ), - } - } - } - - /// Auxiliary function: get a name for a field type. - fn get_field_type_name( - canonical_list_parsers: &HashMap, - _typedef: Option<&str>, - spec: &Spec, - type_: &Type, - make_optional: bool, - ) -> Cow<'static, str> { - let optional = make_optional || type_.is_optional(); - match *type_.spec() { - TypeSpec::Boolean if optional => Cow::from("PRIMITIVE(MaybeBoolean)"), - TypeSpec::Boolean => Cow::from("PRIMITIVE(Boolean)"), - TypeSpec::String if optional => Cow::from("PRIMITIVE(MaybeString)"), - TypeSpec::String => Cow::from("PRIMITIVE(String)"), - TypeSpec::Number if optional => Cow::from("PRIMITIVE(MaybeNumber)"), - TypeSpec::Number => Cow::from("PRIMITIVE(Number)"), - TypeSpec::UnsignedLong if optional => Cow::from("PRIMITIVE(MaybeUnsignedLong)"), - TypeSpec::UnsignedLong => Cow::from("PRIMITIVE(UnsignedLong)"), - TypeSpec::Offset if optional => Cow::from("PRIMITIVE(MaybeLazy)"), - TypeSpec::Offset => Cow::from("PRIMITIVE(Lazy)"), - TypeSpec::Void if optional => Cow::from("PRIMITIVE(MaybeVoid)"), - TypeSpec::Void => Cow::from("PRIMITIVE(Void)"), - TypeSpec::IdentifierName if optional => Cow::from("PRIMITIVE(MaybeIdentifierName)"), - TypeSpec::IdentifierName => Cow::from("PRIMITIVE(IdentifierName)"), - TypeSpec::PropertyKey if optional => Cow::from("PRIMITIVE(MaybePropertyKey)"), - TypeSpec::PropertyKey => Cow::from("PRIMITIVE(PropertyKey)"), - TypeSpec::Array { ref contents, .. } => { - let typename = TypeName::type_(contents); - let node_name = spec.get_node_name(&typename).unwrap(); - let ref name = canonical_list_parsers.get(node_name).unwrap().name; - let contents = - Self::get_field_type_name(canonical_list_parsers, None, spec, contents, false); - debug!(target: "generate_spidermonkey", "get_field_type_name for LIST {name}", - name = name); - Cow::from(format!( - "LIST({name}, {contents})", - name = name, - contents = contents - )) - } - TypeSpec::NamedType(ref name) => { - debug!(target: "generate_spidermonkey", "get_field_type_name for named type {name} ({optional})", - name = name, - optional = if optional { "optional" } else { "required" }); - match spec - .get_type_by_name(name) - .expect("By now, all types MUST exist") - { - NamedType::Typedef(alias_type) => { - if alias_type.is_optional() { - return Self::get_field_type_name( - canonical_list_parsers, - Some(name.to_str()), - spec, - alias_type.as_ref(), - true, - ); - } - // Keep the simple name of sums and lists if there is one. - match *alias_type.spec() { - TypeSpec::TypeSum(_) => { - if optional { - Cow::from(format!( - "OPTIONAL_SUM({name})", - name = name.to_cpp_enum_case() - )) - } else { - Cow::from(format!( - "SUM({name})", - name = name.to_cpp_enum_case() - )) - } - } - TypeSpec::Array { ref contents, .. } => { - debug!(target: "generate_spidermonkey", "It's an array {:?}", contents); - let typename = TypeName::type_(contents); - let node_name = spec.get_node_name(&typename).unwrap(); - let ref name = canonical_list_parsers.get(node_name).unwrap().name; - let contents = Self::get_field_type_name( - canonical_list_parsers, - None, - spec, - contents, - false, - ); - debug!(target: "generate_spidermonkey", "get_field_type_name for typedefed LIST {name}", - name = name); - if optional { - Cow::from(format!( - "OPTIONAL_LIST({name}, {contents})", - name = name.to_cpp_enum_case(), - contents = contents - )) - } else { - Cow::from(format!( - "LIST({name}, {contents})", - name = name.to_cpp_enum_case(), - contents = contents - )) - } - } - _ => Self::get_field_type_name( - canonical_list_parsers, - Some(name.to_str()), - spec, - alias_type.as_ref(), - optional, - ), - } - } - NamedType::StringEnum(_) if type_.is_optional() => Cow::from(format!( - "OPTIONAL_STRING_ENUM({name})", - name = TypeName::type_(type_) - )), - NamedType::StringEnum(_) => Cow::from(format!( - "STRING_ENUM({name})", - name = TypeName::type_(type_) - )), - NamedType::Interface(ref interface) if type_.is_optional() => { - Cow::from(format!( - "OPTIONAL_INTERFACE({name})", - name = interface.name().to_class_cases() - )) - } - NamedType::Interface(ref interface) => Cow::from(format!( - "INTERFACE({name})", - name = interface.name().to_class_cases() - )), - } - } - TypeSpec::TypeSum(ref contents) if type_.is_optional() => { - // We need to make sure that we don't count the `optional` part twice. - // FIXME: The problem seems to only show up in this branch, but it looks like - // it might (should?) appear in other branches, too. - let non_optional_type = Type::sum(contents.types()).required(); - let name = TypeName::type_(&non_optional_type); - Cow::from(format!("OPTIONAL_SUM({name})", name = name)) - } - TypeSpec::TypeSum(_) => { - Cow::from(format!("SUM({name})", name = TypeName::type_(type_))) - } - } - } - - /// Declaring enums for kinds and fields. - fn export_declare_kinds_and_fields_enums(&self, buffer: &mut String) { - buffer.push_str(&self.rules.hpp_tokens_header.reindent("")); - - buffer.push_str("\n\n"); - if self.rules.hpp_tokens_kind_doc.is_some() { - buffer.push_str(&self.rules.hpp_tokens_kind_doc.reindent("")); - } - - let node_names = self - .syntax - .interfaces_by_name() - .keys() - .map(|n| n.to_string()) - .sorted() - .collect_vec(); - let kind_limit = node_names.len(); - buffer.push_str(&format!( - " -#define FOR_EACH_BIN_KIND(F) \\ - F(_Uninitialized, \"Uninitialized\", UNINITIALIZED) \\ -{nodes} -", - nodes = node_names - .iter() - .map(|name| format!( - " F({enum_name}, \"{spec_name}\", {macro_name})", - enum_name = name.to_cpp_enum_case(), - spec_name = name, - macro_name = name.to_cpp_macro_case() - )) - .format(" \\\n") - )); - buffer.push_str( - " -enum class BinASTKind: uint16_t { -#define EMIT_ENUM(name, _1, _2) name, - FOR_EACH_BIN_KIND(EMIT_ENUM) -#undef EMIT_ENUM -}; -", - ); - - buffer.push_str(&format!( - " -// The number of distinct values of BinASTKind. -const size_t BINASTKIND_LIMIT = {}; - -", - kind_limit - )); - if self.rules.hpp_tokens_field_doc.is_some() { - buffer.push_str(&self.rules.hpp_tokens_field_doc.reindent("")); - } - - let field_names = self.syntax.field_names().keys().sorted().collect_vec(); - let field_limit = field_names.len(); - buffer.push_str(&format!( - " -#define FOR_EACH_BIN_FIELD(F) \\ -{nodes} -", - nodes = field_names - .iter() - .map(|name| format!( - " F({enum_name}, \"{spec_name}\")", - spec_name = name, - enum_name = name.to_cpp_enum_case() - )) - .format(" \\\n") - )); - buffer.push_str( - " -enum class BinASTField: uint16_t { -#define EMIT_ENUM(name, _) name, - FOR_EACH_BIN_FIELD(EMIT_ENUM) -#undef EMIT_ENUM -}; -", - ); - buffer.push_str(&format!( - " -// The number of distinct values of BinASTField. -const size_t BINASTFIELD_LIMIT = {}; - -", - field_limit - )); - - buffer.push_str(&format!(" - -#define FOR_EACH_BIN_INTERFACE_AND_FIELD(F) \\ -{nodes} -", - nodes = self.syntax.interfaces_by_name() - .iter() - .sorted_by_key(|a| a.0) - .into_iter() - .flat_map(|(interface_name, interface)| { - let interface_enum_name = interface_name.to_cpp_enum_case(); - let interface_spec_name = interface_name.clone(); - interface.contents().fields() - .iter() - .map(move |field| format!(" F({interface_enum_name}__{field_enum_name}, \"{interface_spec_name}::{field_spec_name}\")", - interface_enum_name = interface_enum_name, - field_enum_name = field.name().to_cpp_enum_case(), - interface_spec_name = interface_spec_name, - field_spec_name = field.name().to_str(), - ) - ) - }) - .format(" \\\n"))); - buffer.push_str( - " -enum class BinASTInterfaceAndField: uint16_t { -#define EMIT_ENUM(name, _) name, - FOR_EACH_BIN_INTERFACE_AND_FIELD(EMIT_ENUM) -#undef EMIT_ENUM -}; -", - ); - - for (sum_name, sum) in self - .syntax - .resolved_sums_of_interfaces_by_name() - .iter() - .sorted_by_key(|a| a.0) - { - let sum_enum_name = sum_name.to_cpp_enum_case(); - let sum_macro_name = sum_name.to_cpp_macro_case(); - buffer.push_str(&format!(" -// Iteration through the interfaces of sum {sum_enum_name} -#define FOR_EACH_BIN_INTERFACE_IN_SUM_{sum_macro_name}(F) \\ -{nodes} - -const size_t BINAST_SUM_{sum_macro_name}_LIMIT = {limit}; - - ", - sum_enum_name = sum_enum_name.clone(), - sum_macro_name = sum_macro_name, - limit = sum.len(), - nodes = sum.iter() - .sorted() - .into_iter() - .enumerate() - .map(move |(i, interface_name)| { - let interface_macro_name = interface_name.to_cpp_macro_case(); - let interface_enum_name = interface_name.to_cpp_enum_case(); - format!(" F({sum_enum_name}, {index}, {interface_enum_name}, {interface_macro_name}, \"{sum_spec_name}::{interface_spec_name}\")", - sum_enum_name = sum_enum_name, - index = i, - interface_enum_name = interface_enum_name, - interface_macro_name = interface_macro_name, - sum_spec_name = sum_name, - interface_spec_name = interface_name, - ) - }) - .format(" \\\n"))); - } - - buffer.push_str(" -// Strongly typed iterations through the fields of interfaces. -// -// Each of these macros accepts the following arguments: -// - F: callback -// - PRIMITIVE: wrapper for primitive type names - called as `PRIMITIVE(typename)` -// - INTERFACE: wrapper for non-optional interface type names - called as `INTERFACE(typename)` -// - OPTIONAL_INTERFACE: wrapper for optional interface type names - called as `OPTIONAL_INTERFACE(typename)` where -// `typename` is the name of the interface (e.g. no `Maybe` prefix) -// - LIST: wrapper for list types - called as `LIST(list_typename, element_typename)` -// - SUM: wrapper for non-optional type names - called as `SUM(typename)` -// - OPTIONAL_SUM: wrapper for optional sum type names - called as `OPTIONAL_SUM(typename)` where -// `typename` is the name of the sum (e.g. no `Maybe` prefix) -// - STRING_ENUM: wrapper for non-optional string enum types - called as `STRING_ENUNM(typename)` -// - OPTIONAL_STRING_ENUM: wrapper for optional string enum type names - called as `OPTIONAL_STRING_ENUM(typename)` where -// `typename` is the name of the string enum (e.g. no `Maybe` prefix) -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_UNINITIALIZED( \ - F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, \ - STRING_ENUM, OPTIONAL_STRING_ENUM) -"); - for (interface_name, interface) in self - .syntax - .interfaces_by_name() - .iter() - .sorted_by_key(|a| a.0) - { - let interface_enum_name = interface_name.to_cpp_enum_case(); - let interface_spec_name = interface_name.clone(); - let interface_macro_name = interface.name().to_cpp_macro_case(); - buffer.push_str(&format!(" - -// Strongly typed iteration through the fields of interface {interface_enum_name}. -#define FOR_EACH_BIN_FIELD_IN_INTERFACE_{interface_macro_name}(F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, STRING_ENUM, OPTIONAL_STRING_ENUM) \\ -{nodes} -", - interface_macro_name = interface_macro_name, - interface_enum_name = interface_enum_name.clone(), - nodes = interface.contents().fields() - .iter() - .enumerate() - .map(|(i, field)| { - let field_type_name = Self::get_field_type_name(&self.canonical_list_parsers, None, &self.syntax, field.type_(), false); - format!(" F({interface_enum_name}, {field_enum_name}, {field_index}, {field_type}, \"{interface_spec_name}::{field_spec_name}\")", - interface_enum_name = interface_enum_name, - field_enum_name = field.name().to_cpp_enum_case(), - field_index = i, - interface_spec_name = interface_spec_name, - field_spec_name = field.name().to_str(), - field_type = field_type_name - ) - }) - .format(" \\\n"))); - buffer.push_str(&format!( - " -// The number of fields of interface {interface_spec_name}. -const size_t BINAST_NUMBER_OF_FIELDS_IN_INTERFACE_{interface_macro_name} = {len};", - interface_spec_name = interface_spec_name, - interface_macro_name = interface_macro_name, - len = interface.contents().fields().len() - )); - } - - let total_number_of_fields: usize = self - .syntax - .interfaces_by_name() - .values() - .map(|interface| interface.contents().fields().len()) - .sum(); - buffer.push_str(&format!(" -// The total number of fields across all interfaces. Used typically to maintain a probability table per field. -const size_t BINAST_INTERFACE_AND_FIELD_LIMIT = {number}; - -// Create parameters list to pass mozilla::Array constructor. -// The number of parameters equals to BINAST_INTERFACE_AND_FIELD_LIMIT. -#define BINAST_PARAM_NUMBER_OF_INTERFACE_AND_FIELD(X) {param} - -", number=total_number_of_fields, param=(0..total_number_of_fields) - .map(|_| "(X)") - .format(","))); - - if self.rules.hpp_tokens_variants_doc.is_some() { - buffer.push_str(&self.rules.hpp_tokens_variants_doc.reindent("")); - } - let enum_variants: Vec<_> = self - .variants_by_symbol - .iter() - .sorted_by_key(|a| a.0) - .collect_vec(); - let variants_limit = enum_variants.len(); - - buffer.push_str(&format!( - " -#define FOR_EACH_BIN_VARIANT(F) \\ -{nodes} -", - nodes = enum_variants - .into_iter() - .map(|(symbol, name)| format!( - " F({variant_name}, \"{spec_name}\")", - spec_name = symbol, - variant_name = name - )) - .format(" \\\n") - )); - - buffer.push_str( - " -enum class BinASTVariant: uint16_t { -#define EMIT_ENUM(name, _) name, - FOR_EACH_BIN_VARIANT(EMIT_ENUM) -#undef EMIT_ENUM -}; -", - ); - buffer.push_str(&format!( - " -// The number of distinct values of BinASTVariant. -const size_t BINASTVARIANT_LIMIT = {}; - -", - variants_limit - )); - - buffer.push_str(&format!( - " -#define FOR_EACH_BIN_STRING_ENUM(F) \\ -{nodes} -", - nodes = self - .syntax - .string_enums_by_name() - .keys() - .sorted() - .into_iter() - .map(|name| format!( - " F({enum_name}, \"{spec_name}\", {macro_name})", - enum_name = name.to_cpp_enum_case(), - spec_name = name.to_str(), - macro_name = name.to_cpp_macro_case() - )) - .format(" \\\n") - )); - - buffer.push_str( - " -enum class BinASTStringEnum: uint16_t { -#define EMIT_ENUM(NAME, _HUMAN_NAME, _MACRO_NAME) NAME, - FOR_EACH_BIN_STRING_ENUM(EMIT_ENUM) -#undef EMIT_ENUM -}; -", - ); - buffer.push_str(&format!( - " -// The number of distinct values of BinASTStringEnum. -const size_t BINASTSTRINGENUM_LIMIT = {}; - -", - self.syntax.string_enums_by_name().len() - )); - - for (name, enum_) in self - .syntax - .string_enums_by_name() - .iter() - .sorted_by_key(|kv| kv.0) - .into_iter() - { - let enum_name = name.to_str().to_class_cases(); - let enum_macro_name = name.to_cpp_macro_case(); - buffer.push_str(&format!( - " -#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_{enum_macro_name}_BY_STRING_ORDER(F) \\ - {variants} -", - enum_macro_name = enum_macro_name, - variants = enum_ - .strings() - .iter() - .sorted() - .into_iter() - .map(|variant_string| { - format!( - " F({enum_name}, {variant_name}, \"{variant_string}\")", - enum_name = enum_name, - variant_name = self.variants_by_symbol.get(variant_string).unwrap(), - variant_string = variant_string - ) - }) - .format("\\\n") - )); - buffer.push_str(&format!( - " -#define FOR_EACH_BIN_VARIANT_IN_STRING_ENUM_{enum_macro_name}_BY_WEBIDL_ORDER(F) \\ - {variants} -", - enum_macro_name = enum_macro_name, - variants = enum_ - .strings() - .iter() - .map(|variant_string| { - format!( - " F({enum_name}, {variant_name}, \"{variant_string}\")", - enum_name = enum_name, - variant_name = self.variants_by_symbol.get(variant_string).unwrap(), - variant_string = variant_string - ) - }) - .format("\\\n") - )); - buffer.push_str(&format!( - " - -const size_t BIN_AST_STRING_ENUM_{enum_macro_name}_LIMIT = {len}; -", - enum_macro_name = enum_macro_name, - len = enum_.strings().len(), - )); - } - - buffer.push_str(&format!(" -// This macro accepts the following arguments: -// - F: callback -// - PRIMITIVE: wrapper for primitive type names - called as `PRIMITIVE(typename)` -// - INTERFACE: wrapper for non-optional interface type names - called as `INTERFACE(typename)` -// - OPTIONAL_INTERFACE: wrapper for optional interface type names - called as `OPTIONAL_INTERFACE(typename)` where -// `typename` is the name of the interface (e.g. no `Maybe` prefix) -// - LIST: wrapper for list types - called as `LIST(list_typename, element_typename)` -// - SUM: wrapper for non-optional type names - called as `SUM(typename)` -// - OPTIONAL_SUM: wrapper for optional sum type names - called as `OPTIONAL_SUM(typename)` where -// `typename` is the name of the sum (e.g. no `Maybe` prefix) -// - STRING_ENUM: wrapper for non-optional string enum types - called as `STRING_ENUNM(typename)` -// - OPTIONAL_STRING_ENUM: wrapper for optional string enum type names - called as `OPTIONAL_STRING_ENUM(typename)` where -// `typename` is the name of the string enum (e.g. no `Maybe` prefix) -#define FOR_EACH_BIN_LIST(F, PRIMITIVE, INTERFACE, OPTIONAL_INTERFACE, LIST, SUM, OPTIONAL_SUM, STRING_ENUM, OPTIONAL_STRING_ENUM) \\ -{nodes} -", - nodes = self.canonical_list_parsers.values() - .sorted_by_key(|data| &data.name) - .into_iter() - .map(|data| { - debug!(target: "generate_spidermonkey", "Generating FOR_EACH_BIN_LIST case {list_name} => {type_name:?}", - list_name = data.name, - type_name = self.syntax.typedefs_by_name().get(&data.name).unwrap()); - format!(" F({list_name}, {content_name}, \"{spec_name}\", {type_name})", - list_name = data.name.to_cpp_enum_case(), - content_name = data.elements.to_cpp_enum_case(), - spec_name = data.name.to_str(), - type_name = Self::get_field_type_name(&self.canonical_list_parsers, Some(data.name.to_str()), &self.syntax, self.syntax.typedefs_by_name().get(&data.name).unwrap(), false)) - }) - .format(" \\\n"))); - buffer.push_str(" -enum class BinASTList: uint16_t { -#define NOTHING(_) -#define EMIT_ENUM(name, _content, _user, _type_name) name, - FOR_EACH_BIN_LIST(EMIT_ENUM, NOTHING, NOTHING, NOTHING, NOTHING, NOTHING, NOTHING, NOTHING, NOTHING) -#undef EMIT_ENUM -#undef NOTHING -}; -"); - - let number_of_lists = self.list_parsers_to_generate.len(); - - buffer.push_str(&format!(" -// The number of distinct list types in the grammar. Used typically to maintain a probability table per list type. -const size_t BINAST_NUMBER_OF_LIST_TYPES = {number}; - -// Create parameters list to pass mozilla::Array constructor. -// The number of parameters equals to BINAST_NUMBER_OF_LIST_TYPES. -#define BINAST_PARAM_NUMBER_OF_LIST_TYPES(X) {param} - -", number=number_of_lists, param=(0..number_of_lists) - .map(|_| "(X)") - .format(","))); - - buffer.push_str(&format!( - " -#define FOR_EACH_BIN_SUM(F) \\ -{nodes} -", - nodes = self - .syntax - .resolved_sums_of_interfaces_by_name() - .iter() - .sorted_by_key(|a| a.0) - .into_iter() - .map(|(name, _)| format!( - " F({name}, \"{spec_name}\", {macro_name}, {type_name})", - name = name.to_cpp_enum_case(), - spec_name = name.to_str(), - macro_name = name.to_cpp_macro_case(), - type_name = Self::get_field_type_name( - &self.canonical_list_parsers, - Some(name.to_str()), - &self.syntax, - self.syntax.typedefs_by_name().get(name).unwrap(), - false - ) - )) - .format(" \\\n") - )); - buffer.push_str( - " -enum class BinASTSum: uint16_t { -#define EMIT_ENUM(name, _user, _macro, _type) name, - FOR_EACH_BIN_SUM(EMIT_ENUM) -#undef EMIT_ENUM -}; -", - ); - buffer.push_str(&format!(" -// The number of distinct sum types in the grammar. Used typically to maintain a probability table per sum type. -const size_t BINAST_NUMBER_OF_SUM_TYPES = {}; - -", - self.syntax.resolved_sums_of_interfaces_by_name().len())); - - buffer.push_str(&self.rules.hpp_tokens_footer.reindent("")); - buffer.push_str("\n"); - } - - /// Declare string enums - fn export_declare_string_enums(&self, buffer: &mut String) { - buffer.push_str( - " -// ----- Declaring string enums (by lexicographical order) -", - ); - let string_enums_by_name = self - .syntax - .string_enums_by_name() - .iter() - .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str())); - for (name, enum_) in string_enums_by_name { - let rendered_cases = enum_ - .strings() - .iter() - .map(|str| { - format!( - " // \"{original}\" - {case},", - case = str.to_cpp_enum_case(), - original = str - ) - }) - .format("\n"); - let rendered = format!( - " -enum class {name} {{ -{cases} -}}; -", - cases = rendered_cases, - name = name.to_class_cases() - ); - buffer.push_str(&rendered); - } - } - - fn export_declare_sums_of_interface_methods(&self, buffer: &mut String) { - let sums_of_interfaces = self - .syntax - .resolved_sums_of_interfaces_by_name() - .iter() - .sorted_by(|a, b| a.0.cmp(&b.0)) - .collect_vec(); - buffer.push_str( - " - // ----- Sums of interfaces (by lexicographical order) - // `ParseNode*` may never be nullptr -", - ); - for &(ref name, _) in &sums_of_interfaces { - if !self.refgraph.is_used(name.to_rc_string().clone()) { - continue; - } - - let rules_for_this_sum = self.rules.get(name); - let extra_params = rules_for_this_sum.extra_params; - let rendered = self.get_method_signature(name, "", "", &extra_params); - buffer.push_str(&rendered.reindent(" ").newline_if_not_empty()); - } - for (name, _) in sums_of_interfaces { - let prefix = "Sum"; - if !self - .refgraph - .is_used(Rc::new(format!("{}{}", prefix, name))) - { - continue; - } - - let rules_for_this_sum = self.rules.get(name); - let extra_params = rules_for_this_sum.extra_params; - let rendered = - self.get_method_signature(name, prefix, SUM_INTERFACE_PARAMS, &extra_params); - buffer.push_str(&rendered.reindent(" ").newline_if_not_empty()); - } - } - - fn export_declare_single_interface_methods(&self, buffer: &mut String) { - buffer.push_str( - " - // ----- Interfaces (by lexicographical order) - // `ParseNode*` may never be nullptr -", - ); - let interfaces_by_name = self - .syntax - .interfaces_by_name() - .iter() - .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str())) - .collect_vec(); - - let mut outer_parsers = Vec::with_capacity(interfaces_by_name.len()); - let mut inner_parsers = Vec::with_capacity(interfaces_by_name.len()); - - for &(name, _) in &interfaces_by_name { - let rules_for_this_interface = self.rules.get(name); - let extra_params = rules_for_this_interface.extra_params; - - if self.refgraph.is_used(name.to_rc_string().clone()) { - let outer = self.get_method_signature(name, "", "", &extra_params); - outer_parsers.push(outer.reindent(" ")); - } - - let inner_prefix = "Interface"; - if !self - .refgraph - .is_used(Rc::new(format!("{}{}", inner_prefix, name))) - { - continue; - } - let inner = - self.get_method_signature(name, inner_prefix, INTERFACE_PARAMS, &extra_params); - inner_parsers.push(inner.reindent(" ")); - } - - for parser in outer_parsers.drain(..) { - buffer.push_str(&parser); - buffer.push_str("\n"); - } - - for parser in inner_parsers.drain(..) { - buffer.push_str(&parser); - buffer.push_str("\n"); - } - } - - fn export_declare_string_enums_methods(&self, buffer: &mut String) { - buffer.push_str( - " - // ----- String enums (by lexicographical order) -", - ); - let string_enums_by_name = self - .syntax - .string_enums_by_name() - .iter() - .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str())); - for (kind, _) in string_enums_by_name { - if !self.refgraph.is_used(kind.to_rc_string().clone()) { - continue; - } - - let rendered = self.get_method_signature(kind, "", "", &None); - buffer.push_str(&rendered.reindent(" ")); - buffer.push_str("\n"); - } - } - - fn export_declare_list_methods(&self, buffer: &mut String) { - buffer.push_str( - " - // ----- Lists (by lexicographical order) -", - ); - for parser in &self.list_parsers_to_generate { - if !self.refgraph.is_used(parser.name.to_rc_string().clone()) { - continue; - } - - let rules_for_this_node = self.rules.get(&parser.name); - let extra_params = rules_for_this_node.extra_params; - let rendered = self.get_method_signature(&parser.name, "", "", &extra_params); - buffer.push_str(&rendered.reindent(" ")); - buffer.push_str("\n"); - } - } - - fn export_declare_option_methods(&self, buffer: &mut String) { - buffer.push_str( - " - // ----- Default values (by lexicographical order) -", - ); - for parser in &self.option_parsers_to_generate { - if !self.refgraph.is_used(parser.name.to_rc_string().clone()) { - continue; - } - - let rules_for_this_node = self.rules.get(&parser.name); - let extra_params = rules_for_this_node.extra_params; - let rendered = self.get_method_signature(&parser.name, "", "", &extra_params); - buffer.push_str(&rendered.reindent(" ")); - buffer.push_str("\n"); - } - } - - fn generate_autogenerated_warning(&self) -> String { - let warning = format!( - "// This file was autogenerated by binjs_generate_spidermonkey, -// please DO NOT EDIT BY HAND. -" - ); - warning - } - - /// Generate C++ headers for SpiderMonkey - fn to_spidermonkey_token_hpp(&self) -> String { - let mut buffer = String::new(); - - buffer.push_str(&self.generate_autogenerated_warning()); - - self.export_declare_kinds_and_fields_enums(&mut buffer); - - buffer.push_str("\n"); - buffer - } - fn to_spidermonkey_class_hpp(&self) -> String { - let mut buffer = String::new(); - - buffer.push_str(&self.generate_autogenerated_warning()); - - buffer.push_str(&self.rules.hpp_class_header.reindent("")); - buffer.push_str("\n"); - - self.export_declare_sums_of_interface_methods(&mut buffer); - self.export_declare_single_interface_methods(&mut buffer); - self.export_declare_string_enums_methods(&mut buffer); - self.export_declare_list_methods(&mut buffer); - self.export_declare_option_methods(&mut buffer); - - buffer.push_str("\n"); - buffer.push_str(&self.rules.hpp_class_footer.reindent("")); - buffer.push_str("\n"); - buffer - } - - fn to_spidermonkey_enum_hpp(&self) -> String { - let mut buffer = String::new(); - - buffer.push_str(&self.generate_autogenerated_warning()); - - buffer.push_str(&self.rules.hpp_enums_header.reindent("")); - buffer.push_str("\n"); - - self.export_declare_string_enums(&mut buffer); - - buffer.push_str("\n"); - buffer.push_str(&self.rules.hpp_enums_footer.reindent("")); - buffer.push_str("\n"); - buffer - } -} - -impl CPPExporter { - /// Generate implementation of a single typesum. - fn generate_implement_sum( - &self, - buffer: &mut String, - name: &NodeName, - nodes: &HashSet, - ) { - // Generate comments (FIXME: We should use the actual webidl, not the resolved sum) - let rules_for_this_sum = self.rules.get(name); - let extra_params = rules_for_this_sum.extra_params; - let extra_args = rules_for_this_sum.extra_args; - let nodes = nodes.iter().sorted().collect_vec(); - let kind = name.to_class_cases(); - - if self.refgraph.is_used(name.to_rc_string().clone()) { - let rendered_bnf = format!( - "/* -{name} ::= {nodes} -*/", - nodes = nodes.iter().format("\n "), - name = name.to_str() - ); - - // Generate outer method - buffer.push_str(&format!( - "{bnf} -{first_line} -{{ - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - guard.init(); - MOZ_TRY(tokenizer_->enterSum(kind, context)); - -{call} - - MOZ_TRY(guard.done()); - return result; -}} -", - bnf = rendered_bnf, - call = self - .get_method_call( - "result", - name, - "Sum", - SUM_INTERFACE_ARGS, - &extra_args, - "context".to_string(), - MethodCallKind::AlwaysDecl - ) - .reindent(" "), - first_line = self.get_method_definition_start(name, "", "", &extra_params) - )); - } - - let inner_prefix = "Sum"; - if !self - .refgraph - .is_used(Rc::new(format!("{}{}", inner_prefix, name))) - { - return; - } - - // Generate inner method - let mut buffer_cases = String::new(); - for node in nodes { - let rule_for_this_arm = rules_for_this_sum - .by_sum - .get(&node) - .cloned() - .unwrap_or_default(); - - if rule_for_this_arm.disabled { - buffer_cases.push_str(&format!(" - case BinASTKind::{variant_name}: - return raiseError(\"FIXME: Not implemented yet in this preview release ({variant_name})\");", - variant_name = node.to_cpp_enum_case())); - continue; - } - - buffer_cases.push_str(&format!( - " - case BinASTKind::{variant_name}: -{call} -{arm_after} break;", - call = self - .get_method_call( - "result", - node, - "Interface", - INTERFACE_ARGS, - &extra_args, - self.get_context_param_for_sum(name, node, "context"), - MethodCallKind::AlwaysVar - ) - .reindent(" "), - variant_name = node.to_cpp_enum_case(), - arm_after = rule_for_this_arm - .after_arm - .reindent(" ") - .newline_if_not_empty() - )); - } - buffer.push_str(&format!( - " - -{first_line} -{{ - {type_ok} result; - switch (kind) {{{cases} - default: - if (isInvalidKindPossible()) {{ - return raiseInvalidKind(\"{kind}\", kind); - }} else {{ - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE(\"invalid BinASTKind should not appear\"); - }} - }} - return result; -}} - -", - kind = kind, - cases = buffer_cases, - first_line = self.get_method_definition_start( - name, - inner_prefix, - SUM_INTERFACE_PARAMS, - &extra_params - ), - type_ok = self.get_type_ok(name) - )); - } - - /// Generate the implementation of a single list parser - fn generate_implement_list(&self, buffer: &mut String, parser: &ListParserData) { - if !self.refgraph.is_used(parser.name.to_rc_string().clone()) { - return; - } - - let rules_for_this_list = self.rules.get(&parser.name); - let extra_params = rules_for_this_list.extra_params; - let extra_args = rules_for_this_list.extra_args; - - // Warn if some rules are unused. - for &(condition, name) in &[ - (rules_for_this_list.build_result.is_some(), "build:"), - (rules_for_this_list.type_ok.is_some(), "type-ok:"), - (rules_for_this_list.by_field.len() > 0, "fields:"), - (rules_for_this_list.by_sum.len() > 0, "sum-arms:"), - ] { - if condition { - warn!( - "In {}, rule `{}` was specified but is ignored.", - parser.name, name - ); - } - } - - let kind = parser.name.to_class_cases(); - let first_line = self.get_method_definition_start(&parser.name, "", "", &extra_params); - - let init = match rules_for_this_list.init { - Some(str) => str.reindent(" "), - None => { - // We cannot generate the method if we don't know how to initialize the list. - let rendered = format!( - " -{first_line} -{{ - return raiseError(\"FIXME: Not implemented yet in this preview release ({kind})\"); -}} -", - first_line = first_line, - kind = kind, - ); - buffer.push_str(&rendered); - return; - } - }; - let append = match rules_for_this_list.append { - Some(str) => str.reindent(" ").newline_if_not_empty(), - None => match self.rules.parser_list_append { - Some(ref str) => str.reindent(" ").newline_if_not_empty(), - None => "".to_string(), - }, - }; - - let rendered = format!( - " - -{first_line} -{{ - uint32_t length; - AutoList guard(*tokenizer_); - - const auto start = tokenizer_->offset(); - const auto childContext = ListContext(context.position_, BinASTList::{content_kind}); - guard.init(); - MOZ_TRY(tokenizer_->enterList(length, childContext));{empty_check} -{init} - - for (uint32_t i = 0; i < length; ++i) {{ -{call} -{append} }} - - MOZ_TRY(guard.done()); - return result; -}} -", - first_line = first_line, - content_kind = self - .canonical_list_parsers - .get(&parser.elements) - .unwrap() // Each list parser has a deduplicated representative - .name - .to_class_cases(), - empty_check = if parser.supports_empty { - "".to_string() - } else { - format!( - " - if (MOZ_UNLIKELY(length == 0)) {{ - return raiseEmpty(\"{kind}\"); - }} -", - kind = kind - ) - }, - call = self - .get_method_call( - "item", - &parser.elements, - "", - "", - &extra_args, - self.get_context_param_for_list(&parser.elements, "childContext"), - MethodCallKind::Decl - ) - .reindent(" "), - init = init, - append = append - ); - buffer.push_str(&rendered); - } - - fn generate_implement_option(&self, buffer: &mut String, parser: &OptionParserData) { - debug!(target: "generate_spidermonkey", "Implementing optional value {} backed by {}", - parser.name.to_str(), parser.elements.to_str()); - - if !self.refgraph.is_used(parser.name.to_rc_string().clone()) { - return; - } - - let rules_for_this_node = self.rules.get(&parser.name); - let extra_params = rules_for_this_node.extra_params; - let extra_args = rules_for_this_node.extra_args; - - // Warn if some rules are unused. - for &(condition, name) in &[ - (rules_for_this_node.build_result.is_some(), "build:"), - (rules_for_this_node.append.is_some(), "append:"), - (rules_for_this_node.by_field.len() > 0, "fields:"), - (rules_for_this_node.by_sum.len() > 0, "sum-arms:"), - ] { - if condition { - warn!( - "In {}, rule `{}` was specified but is ignored.", - parser.name, name - ); - } - } - - let type_ok = self.get_type_ok(&parser.name); - let default_value = self.get_default_value(&parser.name); - - // At this stage, thanks to deanonymization, `contents` - // is something like `OptionalFooBar`. - let named_implementation = if let Some(NamedType::Typedef(ref typedef)) = - self.syntax.get_type_by_name(&parser.name) - { - assert!(typedef.is_optional()); - if let TypeSpec::NamedType(ref named) = *typedef.spec() { - self.syntax.get_type_by_name(named).unwrap_or_else(|| { - panic!( - "Internal error: Could not find type {}, which should have been generated.", - named.to_str() - ) - }) - } else { - panic!( - "Internal error: In {}, type {:?} should have been a named type", - parser.name.to_str(), - typedef - ); - } - } else { - panic!( - "Internal error: In {}, there should be a type with that name", - parser.name.to_str() - ); - }; - match named_implementation { - NamedType::Interface(_) => { - buffer.push_str(&format!( - "{first_line} -{{ - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterOptionalInterface(kind, context)); - {type_ok} result; - if (kind == BinASTKind::{null}) {{ -{none_block} - }} else if (!isInvalidKindPossible() || kind == BinASTKind::{kind}) {{ - const auto start = tokenizer_->offset(); -{before}{call}{after} - }} else {{ - if (isInvalidKindPossible()) {{ - return raiseInvalidKind(\"{kind}\", kind); - }} else {{ - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE(\"invalid BinASTKind should not appear\"); - }} - }} - MOZ_TRY(guard.done()); - - return result; -}} - -", - first_line = - self.get_method_definition_start(&parser.name, "", "", &extra_params), - null = self.syntax.get_null_name().to_cpp_enum_case(), - call = self - .get_method_call( - "result", - &parser.elements, - "Interface", - INTERFACE_ARGS, - &extra_args, - self.get_context_param_for_optional( - &parser.name, - "Interface", - &parser.elements, - "context" - ), - MethodCallKind::AlwaysVar - ) - .reindent(" "), - before = rules_for_this_node.some_before.map_or_else( - || "".to_string(), - |s| s.reindent(" ").newline_if_not_empty() - ), - after = rules_for_this_node.some_after.map_or_else( - || "".to_string(), - |s| s.reindent(" ").newline_if_not_empty() - ), - none_block = rules_for_this_node.none_replace.map_or_else( - || format!("result = {default_value};", default_value = default_value) - .reindent(" "), - |s| s.reindent(" ") - ), - type_ok = type_ok, - kind = parser.elements.to_cpp_enum_case(), - )); - } - NamedType::Typedef(ref type_) => match type_.spec() { - &TypeSpec::TypeSum(_) => { - buffer.push_str(&format!( - "{first_line} -{{ - BinASTKind kind = BinASTKind::_Uninitialized; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterSum(kind, context)); - {type_ok} result; - if (kind == BinASTKind::{null}) {{ -{none_block} - }} else {{ - const auto start = tokenizer_->offset(); -{before}{call}{after} - }} - MOZ_TRY(guard.done()); - - return result; -}} - -", - first_line = - self.get_method_definition_start(&parser.name, "", "", &extra_params), - call = self - .get_method_call( - "result", - &parser.elements, - "Sum", - SUM_INTERFACE_ARGS, - &extra_args, - self.get_context_param_for_optional( - &parser.name, - "Sum", - &parser.elements, - "context" - ), - MethodCallKind::AlwaysVar - ) - .reindent(" "), - before = rules_for_this_node.some_before.map_or_else( - || "".to_string(), - |s| s.reindent(" ").newline_if_not_empty() - ), - after = rules_for_this_node.some_after.map_or_else( - || "".to_string(), - |s| s.reindent(" ").newline_if_not_empty() - ), - none_block = rules_for_this_node.none_replace.map_or_else( - || format!("result = {default_value};", default_value = default_value) - .reindent(" "), - |s| s.reindent(" ") - ), - type_ok = type_ok, - null = self.syntax.get_null_name().to_cpp_enum_case(), - )); - } - &TypeSpec::String => { - let build_result = rules_for_this_node.init.reindent(" "); - let first_line = - self.get_method_definition_start(&parser.name, "", "", &extra_params); - if build_result.len() == 0 { - buffer.push_str(&format!( - "{first_line} -{{ - return raiseError(\"FIXME: Not implemented yet in this preview release ({kind})\"); -}} - -", - first_line = first_line, - kind = parser.name.to_str() - )); - } else { - buffer.push_str(&format!( - "{first_line} -{{ - BINJS_MOZ_TRY_DECL(result, tokenizer_->readMaybeAtom(context)); - -{build} - - return result; -}} - -", - first_line = first_line, - build = build_result, - )); - } - } - &TypeSpec::IdentifierName => { - let build_result = rules_for_this_node.init.reindent(" "); - let first_line = - self.get_method_definition_start(&parser.name, "", "", &extra_params); - if build_result.len() == 0 { - buffer.push_str(&format!( - "{first_line} -{{ - return raiseError(\"FIXME: Not implemented yet in this preview release ({kind})\"); -}} - -", - first_line = first_line, - kind = parser.name.to_str() - )); - } else { - buffer.push_str(&format!( - "{first_line} -{{ - BINJS_MOZ_TRY_DECL(result, tokenizer_->readMaybeIdentifierName(context)); - -{build} - - return result; -}} - -", - first_line = first_line, - build = build_result, - )); - } - } - &TypeSpec::PropertyKey => { - debug!(target: "generate_spidermonkey", "Generating method for PropertyKey: {:?}", parser.name); - let build_result = rules_for_this_node.init.reindent(" "); - let first_line = - self.get_method_definition_start(&parser.name, "", "", &extra_params); - if build_result.len() == 0 { - buffer.push_str(&format!( - "{first_line} -{{ - return raiseError(\"FIXME: Not implemented yet in this preview release ({kind})\"); -}} - -", - first_line = first_line, - kind = parser.name.to_str() - )); - } else { - panic!("PropertyKey shouldn't be optional"); - } - } - _else => unimplemented!("{:?}", _else), - }, - NamedType::StringEnum(_) => unimplemented!(), - } - } - - fn generate_implement_interface( - &self, - buffer: &mut String, - name: &NodeName, - interface: &Interface, - ) { - let rules_for_this_interface = self.rules.get(name); - let extra_params = rules_for_this_interface.extra_params; - let extra_args = rules_for_this_interface.extra_args; - - for &(condition, rule_name) in &[(rules_for_this_interface.append.is_some(), "build:")] { - if condition { - warn!( - "In {}, rule `{}` was specified but is ignored.", - name, rule_name - ); - } - } - - if self.refgraph.is_used(name.to_rc_string().clone()) { - // Generate comments - let comment = format!( - " -/* -{}*/ -", - ToWebidl::interface(interface, "", " ") - ); - buffer.push_str(&comment); - - // Generate public method - buffer.push_str(&format!( - "{first_line} -{{ - BinASTKind kind = BinASTKind::{kind}; - AutoTaggedTuple guard(*tokenizer_); - - guard.init(); - MOZ_TRY(tokenizer_->enterInterface(kind, context)); - const auto start = tokenizer_->offset(); -{call} - MOZ_TRY(guard.done()); - - return result; -}} - -", - first_line = self.get_method_definition_start(name, "", "", &extra_params), - kind = name.to_cpp_enum_case(), - call = self - .get_method_call( - "result", - name, - "Interface", - INTERFACE_ARGS, - &extra_args, - "context".to_string(), - MethodCallKind::AlwaysDecl - ) - .reindent(" ") - )); - } - - let inner_prefix = "Interface"; - if !self - .refgraph - .is_used(Rc::new(format!("{}{}", inner_prefix, name))) - { - return; - } - - // Generate aux method - let first_line = - self.get_method_definition_start(name, inner_prefix, INTERFACE_PARAMS, &extra_params); - - let mut fields_implem = String::new(); - for field in interface.contents().fields() { - let context = format!( - "FieldContext(BinASTInterfaceAndField::{kind}__{field})", - kind = name.to_cpp_enum_case(), - field = field.name().to_cpp_enum_case() - ); - - let rules_for_this_field = rules_for_this_interface - .by_field - .get(field.name()) - .cloned() - .unwrap_or_default(); - let needs_block = rules_for_this_field.block_before_field.is_some() - || rules_for_this_field.block_after_field.is_some(); - - let var_name = field.name().to_cpp_field_case(); - let (decl_var, parse_var) = match field.type_().get_primitive(&self.syntax) { - Some(IsNullable { - is_nullable: false, - content: Primitive::Number, - }) => { - if needs_block { - ( - Some(format!("double {var_name};", var_name = var_name)), - Some(format!( - "MOZ_TRY_VAR({var_name}, tokenizer_->readDouble({context}));", - var_name = var_name, - context = context - )), - ) - } else { - (None, - Some(format!("BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readDouble({context}));", - var_name = var_name, - context = context))) - } - } - Some(IsNullable { - is_nullable: false, - content: Primitive::UnsignedLong, - }) => { - if needs_block { - ( - Some(format!("uint32_t {var_name};", var_name = var_name)), - Some(format!( - "MOZ_TRY_VAR({var_name}, tokenizer_->readUnsignedLong({context}));", - var_name = var_name, - context = context - )), - ) - } else { - (None, - Some(format!("BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readUnsignedLong({context}));", - var_name = var_name, - context = context))) - } - } - Some(IsNullable { - is_nullable: false, - content: Primitive::Boolean, - }) => { - if needs_block { - ( - Some(format!("bool {var_name};", var_name = var_name)), - Some(format!( - "MOZ_TRY_VAR({var_name}, tokenizer_->readBool({context}));", - var_name = var_name, - context = context - )), - ) - } else { - ( - None, - Some(format!( - "BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readBool({context}));", - var_name = var_name, - context = context - )), - ) - } - } - Some(IsNullable { - is_nullable: false, - content: Primitive::Offset, - }) => { - if needs_block { - (Some(format!("BinASTTokenReaderBase::SkippableSubTree {var_name};", var_name = var_name)), - Some(format!("MOZ_TRY_VAR({var_name}, tokenizer_->readSkippableSubTree({context}));", - var_name = var_name, - context = context))) - } else { - (None, - Some(format!("BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readSkippableSubTree({context}));", - var_name = var_name, - context = context))) - } - } - Some(IsNullable { - content: Primitive::Void, - .. - }) => { - warn!("Internal error: We shouldn't have any `void` types at this stage."); - ( - Some(format!("// Skipping void field {}", field.name().to_str())), - None, - ) - } - Some(IsNullable { - is_nullable: false, - content: Primitive::String, - }) => ( - Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)), - Some(format!( - "MOZ_TRY_VAR({var_name}, tokenizer_->readAtom({context}));", - var_name = var_name, - context = context - )), - ), - Some(IsNullable { - is_nullable: false, - content: Primitive::IdentifierName, - }) => ( - Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)), - Some(format!( - "MOZ_TRY_VAR({var_name}, tokenizer_->readIdentifierName({context}));", - var_name = var_name, - context = context - )), - ), - Some(IsNullable { - is_nullable: false, - content: Primitive::PropertyKey, - }) => ( - Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)), - Some(format!( - "MOZ_TRY_VAR({var_name}, tokenizer_->readPropertyKey({context}));", - var_name = var_name, - context = context - )), - ), - Some(IsNullable { - is_nullable: true, - content: Primitive::String, - }) => ( - Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)), - Some(format!( - "MOZ_TRY_VAR({var_name}, tokenizer_->readMaybeAtom({context}));", - var_name = var_name, - context = context - )), - ), - Some(IsNullable { - is_nullable: true, - content: Primitive::IdentifierName, - }) => ( - Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)), - Some(format!( - "MOZ_TRY_VAR({var_name}, tokenizer_->readMaybeIdentifierName({context}));", - var_name = var_name, - context = context - )), - ), - Some(IsNullable { - is_nullable: true, - content: Primitive::PropertyKey, - }) => { - panic!("PropertyKey shouldn't be optional"); - } - _else => { - let typename = TypeName::type_(field.type_()); - let name = self - .syntax - .get_node_name(typename.to_str()) - .expect("NodeName for the field type should exist."); - let field_extra_args = rules_for_this_field.extra_args; - - let (decl_var, call_kind) = if needs_block { - ( - Some(format!( - "{typename} {var_name};", - var_name = var_name, - typename = typename - )), - MethodCallKind::Var, - ) - } else { - (None, MethodCallKind::Decl) - }; - - ( - decl_var, - Some(self.get_method_call( - var_name.to_str(), - &name, - "", - "", - &field_extra_args, - self.get_context_param_for_field(name, &context), - call_kind, - )), - ) - } - }; - let rendered = { - if rules_for_this_field.replace.is_some() { - for &(condition, rule_name) in &[ - (rules_for_this_field.before_field.is_some(), "before:"), - (rules_for_this_field.after_field.is_some(), "after:"), - (rules_for_this_field.declare.is_some(), "declare:"), - ] { - if condition { - warn!("In {}, rule `{}` was specified but is ignored because `replace:` is also specified.", name, rule_name); - } - } - rules_for_this_field.replace.reindent(" ").newline() - } else { - let before_field = rules_for_this_field.before_field.reindent(" "); - let after_field = rules_for_this_field.after_field.reindent(" "); - let decl_var = if rules_for_this_field.declare.is_some() { - rules_for_this_field.declare.reindent(" ") - } else { - decl_var.reindent(" ") - }; - if needs_block { - let parse_var = parse_var.reindent(" "); - format!( - " -{before_field}{decl_var} {{ -{block_before_field}{parse_var}{block_after_field} - }} -{after_field}", - before_field = before_field.reindent(" ").newline_if_not_empty(), - decl_var = decl_var.reindent(" ").newline_if_not_empty(), - block_before_field = rules_for_this_field - .block_before_field - .reindent(" ") - .newline_if_not_empty(), - parse_var = parse_var.reindent(" ").newline_if_not_empty(), - block_after_field = - rules_for_this_field.block_after_field.reindent(" "), - after_field = after_field.reindent(" "), - ) - } else { - // We have a before_field and an after_field. This will create newlines - // for them. - format!( - " -{before_field}{decl_var}{parse_var}{after_field}", - before_field = before_field.reindent(" ").newline_if_not_empty(), - decl_var = decl_var.reindent(" ").newline_if_not_empty(), - parse_var = parse_var.reindent(" ").newline_if_not_empty(), - after_field = after_field.reindent(" ") - ) - } - } - }; - fields_implem.push_str(&rendered); - } - - let init = rules_for_this_interface.init.reindent(" "); - let build_result = rules_for_this_interface.build_result.reindent(" "); - - if build_result == "" { - buffer.push_str(&format!( - "{first_line} -{{ - return raiseError(\"FIXME: Not implemented yet in this preview release ({class_name})\"); -}} - -", - class_name = name.to_class_cases(), - first_line = first_line, - )); - } else { - buffer.push_str(&format!( - "{first_line} -{{ - BINJS_TRY(CheckRecursionLimit(cx_)); -{pre}{fields_implem} -{post} return result; -}} - -", - fields_implem = fields_implem, - pre = init.newline_if_not_empty(), - post = build_result.newline_if_not_empty(), - first_line = first_line, - )); - } - } - - /// Generate C++ code for SpiderMonkey - fn to_spidermonkey_cpp(&self) -> String { - let mut buffer = String::new(); - - buffer.push_str(&self.generate_autogenerated_warning()); - - // 0. Header - buffer.push_str(&self.rules.cpp_header.reindent("")); - buffer.push_str("\n"); - - // 1. Typesums - buffer.push_str( - " - -// ----- Sums of interfaces (autogenerated, by lexicographical order) -", - ); - buffer.push_str( - "// Sums of sums are flattened. -", - ); - - let sums_of_interfaces = self - .syntax - .resolved_sums_of_interfaces_by_name() - .iter() - .sorted_by(|a, b| a.0.cmp(&b.0)); - - for (name, nodes) in sums_of_interfaces { - self.generate_implement_sum(&mut buffer, name, nodes); - } - - // 2. Single interfaces - buffer.push_str( - " - -// ----- Interfaces (autogenerated, by lexicographical order) -", - ); - buffer.push_str("// When fields have a non-trivial type, implementation is deanonymized and delegated to another parser. -"); - let interfaces_by_name = self - .syntax - .interfaces_by_name() - .iter() - .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str())); - - for (name, interface) in interfaces_by_name { - self.generate_implement_interface(&mut buffer, name, interface); - } - - // 3. String Enums - buffer.push_str( - " - -// ----- String enums (autogenerated, by lexicographical order) -", - ); - { - let string_enums_by_name = self - .syntax - .string_enums_by_name() - .iter() - .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str())); - for (kind, enum_) in string_enums_by_name { - if !self.refgraph.is_used(kind.to_rc_string().clone()) { - continue; - } - - let convert = format!( - " switch (variant) {{ -{cases} - default: - if (isInvalidVariantPossible()) {{ - return raiseInvalidVariant(\"{kind}\", variant); - }} else {{ - MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE(\"invalid BinASTVariant should not appear\"); - }} - }}", - kind = kind, - cases = enum_ - .strings() - .iter() - .map(|symbol| { - format!( - " case BinASTVariant::{binastvariant_variant}: - return {kind}::{specialized_variant};", - kind = kind, - specialized_variant = symbol.to_cpp_enum_case(), - binastvariant_variant = - self.variants_by_symbol.get(symbol).unwrap() - ) - }) - .format("\n") - ); - - let rendered_doc = format!( - "/* -enum {kind} {{ -{cases} -}}; -*/ -", - kind = kind, - cases = enum_ - .strings() - .iter() - .map(|s| format!(" \"{}\"", s)) - .format(",\n") - ); - buffer.push_str(&format!( - "{rendered_doc}{first_line} -{{ - BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant(context)); - -{convert} -}} - -", - rendered_doc = rendered_doc, - convert = convert, - first_line = self.get_method_definition_start(kind, "", "", &None) - )); - } - } - - // 4. Lists - buffer.push_str( - " - -// ----- Lists (autogenerated, by lexicographical order) -", - ); - for parser in &self.list_parsers_to_generate { - self.generate_implement_list(&mut buffer, parser); - } - - // 5. Optional values - buffer.push_str( - " - - // ----- Default values (by lexicographical order) -", - ); - for parser in &self.option_parsers_to_generate { - self.generate_implement_option(&mut buffer, parser); - } - - buffer.push_str("\n"); - buffer.push_str(&self.rules.cpp_footer.reindent("")); - buffer.push_str("\n"); - - buffer - } -} - -fn update_rule(rule: &mut Option, entry: &yaml_rust::Yaml) -> Result, ()> { - if entry.is_badvalue() { - return Ok(None); - } else if let Some(as_str) = entry.as_str() { - *rule = Some(as_str.to_string()); - Ok(Some(())) - } else { - Err(()) - } -} -fn update_rule_rc( - rule: &mut Option>, - entry: &yaml_rust::Yaml, -) -> Result, ()> { - let mut value = None; - let ret = update_rule(&mut value, entry)?; - if let Some(s) = value { - *rule = Some(Rc::new(s)); - } - Ok(ret) -} - -fn main() { - env_logger::init(); - - let matches = App::new("BinAST C++ parser generator") - .author("David Teller, ") - .about("Converts an webidl syntax definition and a yaml set of rules into the C++ source code of a parser.") - .args(&[ - Arg::with_name("INPUT.webidl") - .required(true) - .help("Input webidl file to use. Must be a webidl source file."), - Arg::with_name("INPUT.yaml") - .required(true) - .help("Input rules file to use. Must be a yaml source file."), - Arg::with_name("OUT_HEADER_CLASS_FILE") - .long("out-class") - .required(true) - .takes_value(true) - .help("Output header file for class (.h)"), - Arg::with_name("OUT_HEADER_ENUM_FILE") - .long("out-enum") - .required(true) - .takes_value(true) - .help("Output header file for enum (.h)"), - Arg::with_name("OUT_TOKEN_FILE") - .long("out-token") - .required(true) - .takes_value(true) - .help("Output token file (.h)"), - Arg::with_name("OUT_IMPL_FILE") - .long("out-impl") - .required(true) - .takes_value(true) - .help("Output implementation file (.cpp)"), - ]) - .get_matches(); - - let source_path = matches - .value_of("INPUT.webidl") - .expect("Expected INPUT.webidl"); - - let mut file = File::open(source_path).expect("Could not open source"); - let mut source = String::new(); - file.read_to_string(&mut source) - .expect("Could not read source"); - - println!("...verifying grammar"); - let mut builder = Importer::import(vec![source.as_ref()]).expect("Invalid grammar"); - let fake_root = builder.node_name("@@ROOT@@"); // Unused - let null = builder.node_name(""); // Used - builder.add_interface(&null).unwrap(); - let syntax = builder.into_spec(SpecOptions { - root: &fake_root, - null: &null, - }); - - let deanonymizer = TypeDeanonymizer::new(&syntax); - let syntax_options = SpecOptions { - root: &fake_root, - null: &null, - }; - let new_syntax = deanonymizer.into_spec(syntax_options); - - let rules_source_path = matches.value_of("INPUT.yaml").unwrap(); - println!("...generating rules"); - let mut file = File::open(rules_source_path).expect("Could not open rules"); - let mut data = String::new(); - file.read_to_string(&mut data) - .expect("Could not read rules"); - - let yaml = yaml_rust::YamlLoader::load_from_str(&data).expect("Could not parse rules"); - assert_eq!(yaml.len(), 1); - - let global_rules = GlobalRules::new(&new_syntax, &yaml[0]); - let mut exporter = CPPExporter::new(new_syntax, global_rules); - - exporter.generate_reference_graph(); - exporter.trace(Rc::new(TOPLEVEL_INTERFACE.to_string())); - exporter.collect_context(); - - let write_to = |description, arg, data: &String| { - let dest_path = matches.value_of(arg).unwrap(); - print!( - "...exporting {description}: {path} ... ", - description = description, - path = dest_path - ); - - let mut dest = File::create(&dest_path).unwrap_or_else(|e| { - panic!( - "Could not create {description} at {path}: {error}", - description = description, - path = dest_path, - error = e - ) - }); - dest.write_all(data.as_bytes()).unwrap_or_else(|e| { - panic!( - "Could not write {description} at {path}: {error}", - description = description, - path = dest_path, - error = e - ) - }); - - println!("done"); - }; - - write_to( - "C++ class header code", - "OUT_HEADER_CLASS_FILE", - &exporter.to_spidermonkey_class_hpp(), - ); - write_to( - "C++ enum header code", - "OUT_HEADER_ENUM_FILE", - &exporter.to_spidermonkey_enum_hpp(), - ); - write_to( - "C++ token header code", - "OUT_TOKEN_FILE", - &exporter.to_spidermonkey_token_hpp(), - ); - write_to( - "C++ token implementation code", - "OUT_IMPL_FILE", - &exporter.to_spidermonkey_cpp(), - ); - - println!("...done"); -} diff --git a/js/src/frontend/binast/src/refgraph.rs b/js/src/frontend/binast/src/refgraph.rs deleted file mode 100644 index 534e3420dc62..000000000000 --- a/js/src/frontend/binast/src/refgraph.rs +++ /dev/null @@ -1,96 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -use std::cell::RefCell; -use std::collections::{HashMap, HashSet}; -use std::rc::Rc; - -/// A node in the reference graph -struct ReferenceGraphNode { - /// True if this node is used. - used: RefCell, - - /// The set of method names which node uses. - edges: HashSet>, -} -impl ReferenceGraphNode { - fn new(edges: HashSet>) -> Self { - ReferenceGraphNode { - used: RefCell::new(false), - edges, - } - } -} - -/// A reference graph of the method call. -/// -/// Each auto-generated method has corresponding node in this reference graph, -/// and the method definition/declaration are written to the file only if the -/// method is marked as used. -/// -/// This is necessary for the following reason: -/// * we generate parseX and parseInterfaceX for `interface X` -/// * parseX is not used if `interface X` appears only in sum interface -pub struct ReferenceGraph { - /// The map from the node name to node struct. - /// Node name is the method name without leading "parse". - refnodes: HashMap, Rc>, -} -impl ReferenceGraph { - pub fn new() -> Self { - ReferenceGraph { - refnodes: HashMap::new(), - } - } - - /// Trace the reference graph from the node with `name and mark all nodes - /// as used. `name` is the name of the method, without leading "parse". - pub fn trace(&mut self, name: Rc) { - // The set of edges to trace in the current iteration. - let mut edges: HashSet> = HashSet::new(); - edges.insert(name); - - // Iterate over the remaining edges until all edges are traced. - loop { - // The set of edges to trace in the next iteration. - let mut next_edges: HashSet> = HashSet::new(); - - for edge in edges { - let refnode = self.refnodes.get(&edge).unwrap_or_else(|| { - panic!("While computing dependencies, node {} doesn't exist", edge) - }); - if *refnode.used.borrow() { - continue; - } - - refnode.used.replace(true); - - for next_edge in refnode.edges.iter() { - next_edges.insert(next_edge.clone()); - } - } - - if next_edges.len() == 0 { - break; - } - - edges = next_edges; - } - } - - /// Return true if the method named `name` (without leading "parse") is - /// used. - pub fn is_used(&self, name: Rc) -> bool { - match self.refnodes.get(&name) { - Some(refnode) => *refnode.used.borrow(), - None => false, - } - } - - /// Insert a node with `name` to the graph. - pub fn insert(&mut self, name: Rc, edges: HashSet>) { - self.refnodes - .insert(name, Rc::new(ReferenceGraphNode::new(edges))); - } -} diff --git a/third_party/rust/Inflector/.cargo-checksum.json b/third_party/rust/Inflector/.cargo-checksum.json deleted file mode 100644 index 16741f50fd79..000000000000 --- a/third_party/rust/Inflector/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"Cargo.toml":"8fb633b01ea17947fd1f76e0a447b027ddf48c019671f09e39c1338ab715605d","README.md":"3c7136fc446143eecf9668e6daf7f096eb5eb3a3e312cc674571719cb4c83bcc","src/cases/camelcase/mod.rs":"8e65fca78ea88acb32c0f214cafde39b849aef253253c3681e316f2559b26977","src/cases/case/mod.rs":"16323191c983d316debd50af11f94f4c525bb70d4d1a02db06a9aed67d4ba2a9","src/cases/classcase/mod.rs":"5b6b74530a2a693bf1ac89342f1b25f58f39336b1ee3242547c3d6ef468a878f","src/cases/kebabcase/mod.rs":"b317ebd42f22daab4b23bb4b83ce85f053d7088680d3a32eecbd13bd5331587a","src/cases/mod.rs":"e272853bcc1c5f6eb02594038febb9dcebb6eca8eac744d6e503db5082e585c6","src/cases/pascalcase/mod.rs":"a44feed6d8877fd8a31160076befe826960aa001d859587aef2dddc1aedc397b","src/cases/screamingsnakecase/mod.rs":"21582eb1ec2170d379bf3536c6ffb39b8bdc096efe2d493674458ee27b86e985","src/cases/sentencecase/mod.rs":"eb21d7d5bf0b23e1325d429dfdc149081d233a8b950c1fdfe04b4bebcc2c0ddb","src/cases/snakecase/mod.rs":"369739e37e700c028022f308aa78504873c10a5e88768f05249c1c8481b30c9d","src/cases/tablecase/mod.rs":"a6a50a397059d775a517d5dce6ba612b107919e209a9eb56871a5c1d42314664","src/cases/titlecase/mod.rs":"3f0dac5e5b434da9234d6c389f67bb2d3c8f138dc521fa29dbe3791f8eaf5341","src/cases/traincase/mod.rs":"4e2493d6594d3c505de293c69390b3f672c0fd4d35603ae1a1aae48166bc18c2","src/lib.rs":"6c5cf60f5c2f8778a3ad7638f37064527b8a86f164117d867b8b6532e2cc655e","src/numbers/deordinalize/mod.rs":"a3930b0315d20d2d86747bc4ae653a0fb7f7d80de497b0aaa9873aadd1459d18","src/numbers/mod.rs":"fed4e090f8b64a34ae64ddcb68d899cfa4dd8e8422a060be01a70dbdb71b85e0","src/numbers/ordinalize/mod.rs":"ce0d88977efaa50792e7311c0e0a73a3115928f9f7be77f914824c3d80eab66c","src/string/constants/mod.rs":"38de3d5060a5d224d28d184eab8af02203c65d74c1d380720c3260ea205f3e05","src/string/deconstantize/mod.rs":"c79f2170dc41bd6abb89a6e74fbdd87bf011f62cfe1f34d8886fda0724ade6fa","src/string/demodulize/mod.rs":"bbcb5314473e4ca02feee4903e31a332caaa912ed2cbca0f49c2fe411a826215","src/string/mod.rs":"570f7ea4dd646f2d633ddd67079db922cc2cadf916719fa19c2f59b4d522ee89","src/string/pluralize/mod.rs":"5f07fab8b5f4e7af546f1e907426724714b9b27af1ecb59a91e57dccd0833a6e","src/string/singularize/mod.rs":"9c2d833cbcdc1489013642de22578d51f558a31e8d2fea4536a27f8fa1114169","src/suffix/foreignkey/mod.rs":"e7ad9a9a0a21fcb53becb36306a15eedf67958e2da18ae928ae592177e70e7a3","src/suffix/mod.rs":"f6f99ce6fc8794d5411d91533b67be5d4a2bc5994317d32f405b2fa3c5ec660d","tests/lib.rs":"e1cfcea8a146291396ff72b0a2e84c2b9ddaa0103717442c4921c165a2ab470d"},"package":"fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3"} \ No newline at end of file diff --git a/third_party/rust/Inflector/Cargo.toml b/third_party/rust/Inflector/Cargo.toml deleted file mode 100644 index 553f00f6de36..000000000000 --- a/third_party/rust/Inflector/Cargo.toml +++ /dev/null @@ -1,42 +0,0 @@ -# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO -# -# When uploading crates to the registry Cargo will automatically -# "normalize" Cargo.toml files for maximal compatibility -# with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies -# -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) - -[package] -name = "Inflector" -version = "0.11.4" -authors = ["Josh Teeter"] -include = ["**/*.rs", "Cargo.toml", "README.md"] -description = "Adds String based inflections for Rust. Snake, kebab, camel, sentence, class, title and table cases as well as ordinalize, deordinalize, demodulize, foreign key, and pluralize/singularize are supported as both traits and pure functions acting on String types.\n" -homepage = "https://github.com/whatisinternet/inflector" -documentation = "https://docs.rs/Inflector" -readme = "README.md" -keywords = ["pluralize", "Inflector", "camel", "snake", "inflection"] -categories = ["text-processing", "value-formatting"] -license = "BSD-2-Clause" -repository = "https://github.com/whatisinternet/inflector" - -[lib] -name = "inflector" -[dependencies.lazy_static] -version = "1.2.0" -optional = true - -[dependencies.regex] -version = "1.1" -optional = true - -[features] -default = ["heavyweight"] -heavyweight = ["regex", "lazy_static"] -unstable = [] -[badges.travis-ci] -repository = "whatisinternet/Inflector" diff --git a/third_party/rust/Inflector/README.md b/third_party/rust/Inflector/README.md deleted file mode 100644 index db8de0992d01..000000000000 --- a/third_party/rust/Inflector/README.md +++ /dev/null @@ -1,136 +0,0 @@ -# Rust Inflector - - -[![Build Status](https://travis-ci.org/whatisinternet/Inflector.svg?branch=master)](https://travis-ci.org/whatisinternet/Inflector) [![Crates.io](https://img.shields.io/crates/v/Inflector.svg)](https://crates.io/crates/inflector)[![Crate downloads](https://img.shields.io/crates/d/Inflector.svg)](https://crates.io/crates/inflector) - - -Adds String based inflections for Rust. Snake, kebab, train, camel, -sentence, class, and title cases as well as ordinalize, -deordinalize, demodulize, deconstantize, foreign key, table case, and pluralize/singularize are supported as both traits and pure functions -acting on &str and String types. - ------ -## Documentation: - -Documentation can be found here at the README or via rust docs below. - -[Rust docs with examples](https://docs.rs/Inflector) - ------ - -## Installation: - -### As a [crate](http://crates.io) - -```toml -[dependencies] -Inflector = "*" -``` - -### Compile yourself: - -1. Install [Rust and cargo](http://doc.crates.io/) -2. git clone https://github.com/whatisinternet/Inflector -3. Library: cd inflector && cargo build --release --lib -4. You can find the library in target/release - -## Usage / Example: - -```rust -... -// to use methods like String.to_lower_case(); -extern crate inflector; -use inflector::Inflector; -... -fn main() { -... - let camel_case_string: String = "some_string".to_camel_case(); -... -} - -``` - -Or - -```rust -... -// to use methods like to_snake_case(&str); -extern crate inflector; - -// use inflector::cases::classcase::to_class_case; -// use inflector::cases::classcase::is_class_case; - -// use inflector::cases::camelcase::to_camel_case; -// use inflector::cases::camelcase::is_camel_case; - -// use inflector::cases::pascalcase::to_pascal_case; -// use inflector::cases::pascalcase::is_pascal_case; - -// use inflector::cases::screamingsnakecase::to_screamingsnake_case; -// use inflector::cases::screamingsnakecase::is_screamingsnake_case; - -// use inflector::cases::snakecase::to_snake_case; -// use inflector::cases::snakecase::is_snake_case; - -// use inflector::cases::kebabcase::to_kebab_case; -// use inflector::cases::kebabcase::is_kebab_case; - -// use inflector::cases::traincase::to_train_case; -// use inflector::cases::traincase::is_train_case; - -// use inflector::cases::sentencecase::to_sentence_case; -// use inflector::cases::sentencecase::is_sentence_case; - -// use inflector::cases::titlecase::to_title_case; -// use inflector::cases::titlecase::is_title_case; - -// use inflector::cases::tablecase::to_table_case; -// use inflector::cases::tablecase::is_table_case; - -// use inflector::numbers::ordinalize::ordinalize; -// use inflector::numbers::deordinalize::deordinalize; - -// use inflector::suffix::foreignkey::to_foreign_key; -// use inflector::suffix::foreignkey::is_foreign_key; - -// use inflector::string::demodulize::demodulize; -// use inflector::string::deconstantize::deconstantize; - -// use inflector::string::pluralize::to_plural; -// use inflector::string::singularize::to_singular; -... -fn main() { -... - let camel_case_string: String = to_camel_case("some_string"); -... -} - -``` - -## Advanced installation and usage: - -If the project doesn't require singularize, pluralize, class, table, demodulize, -deconstantize. Then in your `cargo.toml` you may wish to specify: - -```toml -[dependencies.Inflector] -version = "*" -default-features = false -``` - -Or - -```toml -Inflector = {version="*", default-features=false} - -``` - -To test this crate locally with features off try: - -```shell -cargo test --no-default-features -``` - -## [Contributing](CONTRIBUTING.md) - -This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct. diff --git a/third_party/rust/Inflector/src/cases/camelcase/mod.rs b/third_party/rust/Inflector/src/cases/camelcase/mod.rs deleted file mode 100644 index b09ddc65b2f5..000000000000 --- a/third_party/rust/Inflector/src/cases/camelcase/mod.rs +++ /dev/null @@ -1,370 +0,0 @@ -#![deny(warnings)] -use cases::case::*; - -/// Converts a `&str` to camelCase `String` -/// -/// ``` -/// use inflector::cases::camelcase::to_camel_case; -/// let mock_string: &str = "fooBar"; -/// let expected_string: String = "fooBar".to_string(); -/// let asserted_string: String = to_camel_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::camelcase::to_camel_case; -/// let mock_string: &str = "FOO_BAR"; -/// let expected_string: String = "fooBar".to_string(); -/// let asserted_string: String = to_camel_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::camelcase::to_camel_case; -/// let mock_string: &str = "Foo Bar"; -/// let expected_string: String = "fooBar".to_string(); -/// let asserted_string: String = to_camel_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::camelcase::to_camel_case; -/// let mock_string: &str = "foo_bar"; -/// let expected_string: String = "fooBar".to_string(); -/// let asserted_string: String = to_camel_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::camelcase::to_camel_case; -/// let mock_string: &str = "Foo bar"; -/// let expected_string: String = "fooBar".to_string(); -/// let asserted_string: String = to_camel_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::camelcase::to_camel_case; -/// let mock_string: &str = "foo-bar"; -/// let expected_string: String = "fooBar".to_string(); -/// let asserted_string: String = to_camel_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::camelcase::to_camel_case; -/// let mock_string: &str = "FooBar"; -/// let expected_string: String = "fooBar".to_string(); -/// let asserted_string: String = to_camel_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::camelcase::to_camel_case; -/// let mock_string: &str = "FooBar3"; -/// let expected_string: String = "fooBar3".to_string(); -/// let asserted_string: String = to_camel_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::camelcase::to_camel_case; -/// let mock_string: &str = "Foo-Bar"; -/// let expected_string: String = "fooBar".to_string(); -/// let asserted_string: String = to_camel_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -pub fn to_camel_case(non_camelized_string: &str) -> String { - let options = CamelOptions { - new_word: false, - last_char: ' ', - first_word: false, - injectable_char: ' ', - has_seperator: false, - inverted: false, - }; - to_case_camel_like(&non_camelized_string, options) -} - -/// Determines if a `&str` is camelCase bool`` -/// -/// ``` -/// use inflector::cases::camelcase::is_camel_case; -/// let mock_string: &str = "Foo"; -/// let asserted_bool: bool = is_camel_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// -/// ``` -/// ``` -/// use inflector::cases::camelcase::is_camel_case; -/// let mock_string: &str = "foo"; -/// let asserted_bool: bool = is_camel_case(mock_string); -/// assert!(asserted_bool == true); -/// -/// -/// ``` -/// ``` -/// use inflector::cases::camelcase::is_camel_case; -/// let mock_string: &str = "foo-bar-string-that-is-really-really-long"; -/// let asserted_bool: bool = is_camel_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// -/// ``` -/// ``` -/// use inflector::cases::camelcase::is_camel_case; -/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; -/// let asserted_bool: bool = is_camel_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// -/// ``` -/// ``` -/// use inflector::cases::camelcase::is_camel_case; -/// let mock_string: &str = "fooBarIsAReallyReally3LongString"; -/// let asserted_bool: bool = is_camel_case(mock_string); -/// assert!(asserted_bool == true); -/// -/// -/// ``` -/// ``` -/// use inflector::cases::camelcase::is_camel_case; -/// let mock_string: &str = "fooBarIsAReallyReallyLongString"; -/// let asserted_bool: bool = is_camel_case(mock_string); -/// assert!(asserted_bool == true); -/// -/// -/// ``` -/// ``` -/// use inflector::cases::camelcase::is_camel_case; -/// let mock_string: &str = "FOO_BAR_STRING_THAT_IS_REALLY_REALLY_LONG"; -/// let asserted_bool: bool = is_camel_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// -/// ``` -/// ``` -/// use inflector::cases::camelcase::is_camel_case; -/// let mock_string: &str = "foo_bar_string_that_is_really_really_long"; -/// let asserted_bool: bool = is_camel_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// -/// ``` -/// ``` -/// use inflector::cases::camelcase::is_camel_case; -/// let mock_string: &str = "Foo bar string that is really really long"; -/// let asserted_bool: bool = is_camel_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// -/// ``` -/// ``` -/// use inflector::cases::camelcase::is_camel_case; -/// let mock_string: &str = "Foo Bar Is A Really Really Long String"; -/// let asserted_bool: bool = is_camel_case(mock_string); -/// assert!(asserted_bool == false); -/// ``` -pub fn is_camel_case(test_string: &str) -> bool { - to_camel_case(&test_string.clone()) == test_string -} - -#[cfg(all(feature = "unstable", test))] -mod benchmarks { - extern crate test; - use self::test::Bencher; - - #[bench] - fn bench_camel0(b: &mut Bencher) { - b.iter(|| { - let test_string = "Foo bar"; - super::to_camel_case(test_string) - }); - } - - #[bench] - fn bench_camel1(b: &mut Bencher) { - b.iter(|| { - let test_string = "foo_bar"; - super::to_camel_case(test_string) - }); - } - - #[bench] - fn bench_camel2(b: &mut Bencher) { - b.iter(|| { - let test_string = "fooBar"; - super::to_camel_case(test_string) - }); - } - - #[bench] - fn bench_is_camel(b: &mut Bencher) { - b.iter(|| { - let test_string: &str = "Foo bar"; - super::is_camel_case(test_string) - }); - } -} - -#[cfg(test)] -mod tests { - use ::to_camel_case; - use ::is_camel_case; - - #[test] - fn from_camel_case() { - let convertable_string: String = "fooBar".to_owned(); - let expected: String = "fooBar".to_owned(); - assert_eq!(to_camel_case(&convertable_string), expected) - } - - #[test] - fn from_pascal_case() { - let convertable_string: String = "FooBar".to_owned(); - let expected: String = "fooBar".to_owned(); - assert_eq!(to_camel_case(&convertable_string), expected) - } - - #[test] - fn from_kebab_case() { - let convertable_string: String = "foo-bar".to_owned(); - let expected: String = "fooBar".to_owned(); - assert_eq!(to_camel_case(&convertable_string), expected) - } - - #[test] - fn from_sentence_case() { - let convertable_string: String = "Foo bar".to_owned(); - let expected: String = "fooBar".to_owned(); - assert_eq!(to_camel_case(&convertable_string), expected) - } - - #[test] - fn from_title_case() { - let convertable_string: String = "Foo Bar".to_owned(); - let expected: String = "fooBar".to_owned(); - assert_eq!(to_camel_case(&convertable_string), expected) - } - - #[test] - fn from_train_case() { - let convertable_string: String = "Foo-Bar".to_owned(); - let expected: String = "fooBar".to_owned(); - assert_eq!(to_camel_case(&convertable_string), expected) - } - - #[test] - fn from_screaming_snake_case() { - let convertable_string: String = "FOO_BAR".to_owned(); - let expected: String = "fooBar".to_owned(); - assert_eq!(to_camel_case(&convertable_string), expected) - } - - #[test] - fn from_snake_case() { - let convertable_string: String = "foo_bar".to_owned(); - let expected: String = "fooBar".to_owned(); - assert_eq!(to_camel_case(&convertable_string), expected) - } - - #[test] - fn from_case_with_loads_of_space() { - let convertable_string: String = "foo bar".to_owned(); - let expected: String = "fooBar".to_owned(); - assert_eq!(to_camel_case(&convertable_string), expected) - } - - #[test] - fn a_name_with_a_dot() { - let convertable_string: String = "Robert C. Martin".to_owned(); - let expected: String = "robertCMartin".to_owned(); - assert_eq!(to_camel_case(&convertable_string), expected) - } - - #[test] - fn random_text_with_bad_chars() { - let convertable_string: String = "Random text with *(bad) chars".to_owned(); - let expected: String = "randomTextWithBadChars".to_owned(); - assert_eq!(to_camel_case(&convertable_string), expected) - } - - #[test] - fn trailing_bad_chars() { - let convertable_string: String = "trailing bad_chars*(()())".to_owned(); - let expected: String = "trailingBadChars".to_owned(); - assert_eq!(to_camel_case(&convertable_string), expected) - } - - #[test] - fn leading_bad_chars() { - let convertable_string: String = "-!#$%leading bad chars".to_owned(); - let expected: String = "leadingBadChars".to_owned(); - assert_eq!(to_camel_case(&convertable_string), expected) - } - - #[test] - fn wrapped_in_bad_chars() { - let convertable_string: String = "-!#$%wrapped in bad chars&*^*&(&*^&(<>><>))".to_owned(); - let expected: String = "wrappedInBadChars".to_owned(); - assert_eq!(to_camel_case(&convertable_string), expected) - } - - #[test] - fn has_a_sign() { - let convertable_string: String = "has a + sign".to_owned(); - let expected: String = "hasASign".to_owned(); - assert_eq!(to_camel_case(&convertable_string), expected) - } - - #[test] - fn is_correct_from_camel_case() { - let convertable_string: String = "fooBar".to_owned(); - assert_eq!(is_camel_case(&convertable_string), true) - } - - #[test] - fn is_correct_from_pascal_case() { - let convertable_string: String = "FooBar".to_owned(); - assert_eq!(is_camel_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_kebab_case() { - let convertable_string: String = "foo-bar".to_owned(); - assert_eq!(is_camel_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_sentence_case() { - let convertable_string: String = "Foo bar".to_owned(); - assert_eq!(is_camel_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_title_case() { - let convertable_string: String = "Foo Bar".to_owned(); - assert_eq!(is_camel_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_train_case() { - let convertable_string: String = "Foo-Bar".to_owned(); - assert_eq!(is_camel_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_screaming_snake_case() { - let convertable_string: String = "FOO_BAR".to_owned(); - assert_eq!(is_camel_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_snake_case() { - let convertable_string: String = "foo_bar".to_owned(); - assert_eq!(is_camel_case(&convertable_string), false) - } -} - diff --git a/third_party/rust/Inflector/src/cases/case/mod.rs b/third_party/rust/Inflector/src/cases/case/mod.rs deleted file mode 100644 index bb4c3d2e3347..000000000000 --- a/third_party/rust/Inflector/src/cases/case/mod.rs +++ /dev/null @@ -1,303 +0,0 @@ -#![deny(warnings)] -#[allow(unknown_lints)] -#[allow(unused_imports)] -use std::ascii::*; - -pub struct CamelOptions { - pub new_word: bool, - pub last_char: char, - pub first_word: bool, - pub injectable_char: char, - pub has_seperator: bool, - pub inverted: bool, -} - -pub fn to_case_snake_like(convertable_string: &str, replace_with: &str, case: &str) -> String { - let mut first_character: bool = true; - let mut result: String = String::with_capacity(convertable_string.len() * 2); - for char_with_index in trim_right(convertable_string).char_indices() { - if char_is_seperator(&char_with_index.1) { - if !first_character { - first_character = true; - result.push(replace_with.chars().nth(0).unwrap_or('_')); - } - } else if requires_seperator(char_with_index, first_character, &convertable_string) { - first_character = false; - result = snake_like_with_seperator(result, replace_with, &char_with_index.1, case) - } else { - first_character = false; - result = snake_like_no_seperator(result, &char_with_index.1, case) - } - } - result -} - -pub fn to_case_camel_like(convertable_string: &str, camel_options: CamelOptions) -> String { - let mut new_word: bool = camel_options.new_word; - let mut first_word: bool = camel_options.first_word; - let mut last_char: char = camel_options.last_char; - let mut found_real_char: bool = false; - let mut result: String = String::with_capacity(convertable_string.len() * 2); - for character in trim_right(convertable_string).chars() { - if char_is_seperator(&character) && found_real_char { - new_word = true; - } else if !found_real_char && is_not_alphanumeric(character) { - continue; - } else if character.is_numeric() { - found_real_char = true; - new_word = true; - result.push(character); - } else if last_char_lower_current_is_upper_or_new_word(new_word, last_char, character) { - found_real_char = true; - new_word = false; - result = append_on_new_word(result, first_word, character, &camel_options); - first_word = false; - } else { - found_real_char = true; - last_char = character; - result.push(character.to_ascii_lowercase()); - } - } - result -} - -#[inline] -fn append_on_new_word(mut result: String, first_word: bool, character: char, camel_options: &CamelOptions) -> String { - if not_first_word_and_has_seperator(first_word, camel_options.has_seperator) { - result.push(camel_options.injectable_char); - } - if first_word_or_not_inverted(first_word, camel_options.inverted) { - result.push(character.to_ascii_uppercase()); - } else { - result.push(character.to_ascii_lowercase()); - } - result -} - -fn not_first_word_and_has_seperator(first_word: bool, has_seperator: bool) -> bool { - has_seperator && !first_word -} - -fn first_word_or_not_inverted(first_word: bool, inverted: bool) -> bool { - !inverted || first_word -} - - -fn last_char_lower_current_is_upper_or_new_word(new_word: bool, last_char: char, character: char) -> bool{ - new_word || - ((last_char.is_lowercase() && character.is_uppercase()) && - (last_char != ' ')) -} - -fn char_is_seperator(character: &char) -> bool { - is_not_alphanumeric(*character) -} - -fn trim_right(convertable_string: &str) -> &str { - convertable_string.trim_end_matches(is_not_alphanumeric) -} - -fn is_not_alphanumeric(character: char) -> bool { - !character.is_alphanumeric() -} - -#[inline] -fn requires_seperator(char_with_index: (usize, char), first_character: bool, convertable_string: &str) -> bool { - !first_character && - char_is_uppercase(char_with_index.1) && - next_or_previous_char_is_lowercase(convertable_string, char_with_index.0) -} - -#[inline] -fn snake_like_no_seperator(mut accumlator: String, current_char: &char, case: &str) -> String { - if case == "lower" { - accumlator.push(current_char.to_ascii_lowercase()); - accumlator - } else { - accumlator.push(current_char.to_ascii_uppercase()); - accumlator - } -} - -#[inline] -fn snake_like_with_seperator(mut accumlator: String, replace_with: &str, current_char: &char, case: &str) -> String { - if case == "lower" { - accumlator.push(replace_with.chars().nth(0).unwrap_or('_')); - accumlator.push(current_char.to_ascii_lowercase()); - accumlator - } else { - accumlator.push(replace_with.chars().nth(0).unwrap_or('_')); - accumlator.push(current_char.to_ascii_uppercase()); - accumlator - } -} - -fn next_or_previous_char_is_lowercase(convertable_string: &str, char_with_index: usize) -> bool { - convertable_string.chars().nth(char_with_index + 1).unwrap_or('A').is_lowercase() || - convertable_string.chars().nth(char_with_index - 1).unwrap_or('A').is_lowercase() -} - -fn char_is_uppercase(test_char: char) -> bool { - test_char == test_char.to_ascii_uppercase() -} - -#[test] -fn test_trim_bad_chars() { - assert_eq!("abc", trim_right("abc----^")) -} - -#[test] -fn test_trim_bad_chars_when_none_are_bad() { - assert_eq!("abc", trim_right("abc")) -} - -#[test] -fn test_is_not_alphanumeric_on_is_alphanumeric() { - assert!(!is_not_alphanumeric('a')) -} - -#[test] -fn test_is_not_alphanumeric_on_is_not_alphanumeric() { - assert!(is_not_alphanumeric('_')) -} - - -#[test] -fn test_char_is_uppercase_when_it_is() { - assert_eq!(char_is_uppercase('A'), true) -} - -#[test] -fn test_char_is_uppercase_when_it_is_not() { - assert_eq!(char_is_uppercase('a'), false) -} - -#[test] -fn test_next_or_previous_char_is_lowercase_true() { - assert_eq!(next_or_previous_char_is_lowercase("TestWWW", 3), true) -} - -#[test] -fn test_next_or_previous_char_is_lowercase_false() { - assert_eq!(next_or_previous_char_is_lowercase("TestWWW", 5), false) -} - -#[test] -fn snake_like_with_seperator_lowers() { - assert_eq!(snake_like_with_seperator("".to_owned(), "^", &'c', "lower"), "^c".to_string()) -} - -#[test] -fn snake_like_with_seperator_upper() { - assert_eq!(snake_like_with_seperator("".to_owned(), "^", &'c', "upper"), "^C".to_string()) -} - -#[test] -fn snake_like_no_seperator_lower() { - assert_eq!(snake_like_no_seperator("".to_owned(), &'C', "lower"), "c".to_string()) -} - -#[test] -fn snake_like_no_seperator_upper() { - assert_eq!(snake_like_no_seperator("".to_owned(), &'c', "upper"), "C".to_string()) -} - -#[test] -fn requires_seperator_upper_not_first_wrap_is_safe_current_upper() { - assert_eq!(requires_seperator((2, 'C'), false, "test"), true) -} - -#[test] -fn requires_seperator_upper_not_first_wrap_is_safe_current_lower() { - assert_eq!(requires_seperator((2, 'c'), false, "test"), false) -} - -#[test] -fn requires_seperator_upper_first_wrap_is_safe_current_upper() { - assert_eq!(requires_seperator((0, 'T'), true, "Test"), false) -} - -#[test] -fn requires_seperator_upper_first_wrap_is_safe_current_lower() { - assert_eq!(requires_seperator((0, 't'), true, "Test"), false) -} - -#[test] -fn requires_seperator_upper_first_wrap_is_safe_current_lower_next_is_too() { - assert_eq!(requires_seperator((0, 't'), true, "test"), false) -} - -#[test] -fn test_char_is_seperator_dash() { - assert_eq!(char_is_seperator(&'-'), true) -} - -#[test] -fn test_char_is_seperator_underscore() { - assert_eq!(char_is_seperator(&'_'), true) -} - -#[test] -fn test_char_is_seperator_space() { - assert_eq!(char_is_seperator(&' '), true) -} - -#[test] -fn test_char_is_seperator_when_not() { - assert_eq!(char_is_seperator(&'A'), false) -} - -#[test] -fn test_last_char_lower_current_is_upper_or_new_word_with_new_word() { - assert_eq!(last_char_lower_current_is_upper_or_new_word(true, ' ', '-'), true) -} - -#[test] -fn test_last_char_lower_current_is_upper_or_new_word_last_char_space() { - assert_eq!(last_char_lower_current_is_upper_or_new_word(false, ' ', '-'), false) -} - -#[test] -fn test_last_char_lower_current_is_upper_or_new_word_last_char_lower_current_upper() { - assert_eq!(last_char_lower_current_is_upper_or_new_word(false, 'a', 'A'), true) -} - -#[test] -fn test_last_char_lower_current_is_upper_or_new_word_last_char_upper_current_upper() { - assert_eq!(last_char_lower_current_is_upper_or_new_word(false, 'A', 'A'), false) -} - -#[test] -fn test_last_char_lower_current_is_upper_or_new_word_last_char_upper_current_lower() { - assert_eq!(last_char_lower_current_is_upper_or_new_word(false, 'A', 'a'), false) -} - -#[test] -fn test_first_word_or_not_inverted_with_first_word() { - assert_eq!(first_word_or_not_inverted(true, false), true) -} - -#[test] -fn test_first_word_or_not_inverted_not_first_word_not_inverted() { - assert_eq!(first_word_or_not_inverted(false, false), true) -} - -#[test] -fn test_first_word_or_not_inverted_not_first_word_is_inverted() { - assert_eq!(first_word_or_not_inverted(false, true), false) -} - -#[test] -fn test_not_first_word_and_has_seperator_is_first_and_not_seperator() { - assert_eq!(not_first_word_and_has_seperator(true, false), false) -} - -#[test] -fn test_not_first_word_and_has_seperator_not_first_and_not_seperator() { - assert_eq!(not_first_word_and_has_seperator(false, false), false) -} - -#[test] -fn test_not_first_word_and_has_seperator_not_first_and_has_seperator() { - assert_eq!(not_first_word_and_has_seperator(false, true), true) -} diff --git a/third_party/rust/Inflector/src/cases/classcase/mod.rs b/third_party/rust/Inflector/src/cases/classcase/mod.rs deleted file mode 100644 index e0b6ef6f48b4..000000000000 --- a/third_party/rust/Inflector/src/cases/classcase/mod.rs +++ /dev/null @@ -1,393 +0,0 @@ -#![deny(warnings)] -use cases::case::*; -#[cfg(feature = "heavyweight")] -use string::singularize::to_singular; -#[cfg(feature = "heavyweight")] -/// Converts a `&str` to `ClassCase` `String` -/// -/// ``` -/// use inflector::cases::classcase::to_class_case; -/// let mock_string: &str = "FooBar"; -/// let expected_string: String = "FooBar".to_string(); -/// let asserted_string: String = to_class_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::classcase::to_class_case; -/// let mock_string: &str = "FooBars"; -/// let expected_string: String = "FooBar".to_string(); -/// let asserted_string: String = to_class_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::classcase::to_class_case; -/// let mock_string: &str = "Foo Bar"; -/// let expected_string: String = "FooBar".to_string(); -/// let asserted_string: String = to_class_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::classcase::to_class_case; -/// let mock_string: &str = "foo-bar"; -/// let expected_string: String = "FooBar".to_string(); -/// let asserted_string: String = to_class_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::classcase::to_class_case; -/// let mock_string: &str = "fooBar"; -/// let expected_string: String = "FooBar".to_string(); -/// let asserted_string: String = to_class_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::classcase::to_class_case; -/// let mock_string: &str = "FOO_BAR"; -/// let expected_string: String = "FooBar".to_string(); -/// let asserted_string: String = to_class_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::classcase::to_class_case; -/// let mock_string: &str = "foo_bar"; -/// let expected_string: String = "FooBar".to_string(); -/// let asserted_string: String = to_class_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::classcase::to_class_case; -/// let mock_string: &str = "foo_bars"; -/// let expected_string: String = "FooBar".to_string(); -/// let asserted_string: String = to_class_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::classcase::to_class_case; -/// let mock_string: &str = "Foo bar"; -/// let expected_string: String = "FooBar".to_string(); -/// let asserted_string: String = to_class_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -pub fn to_class_case(non_class_case_string: &str) -> String { - let options = CamelOptions { - new_word: true, - last_char: ' ', - first_word: false, - injectable_char: ' ', - has_seperator: false, - inverted: false, - }; - let class_plural = to_case_camel_like(non_class_case_string, options); - let split: (&str, &str) = - class_plural.split_at(class_plural.rfind(char::is_uppercase).unwrap_or(0)); - format!("{}{}", split.0, to_singular(split.1)) -} - -#[cfg(feature = "heavyweight")] -/// Determines if a `&str` is `ClassCase` `bool` -/// -/// ``` -/// use inflector::cases::classcase::is_class_case; -/// let mock_string: &str = "Foo"; -/// let asserted_bool: bool = is_class_case(mock_string); -/// assert!(asserted_bool == true); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::classcase::is_class_case; -/// let mock_string: &str = "foo"; -/// let asserted_bool: bool = is_class_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::classcase::is_class_case; -/// let mock_string: &str = "FooBarIsAReallyReallyLongStrings"; -/// let asserted_bool: bool = is_class_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// -/// -/// ``` -/// use inflector::cases::classcase::is_class_case; -/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; -/// let asserted_bool: bool = is_class_case(mock_string); -/// assert!(asserted_bool == true); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::classcase::is_class_case; -/// let mock_string: &str = "foo-bar-string-that-is-really-really-long"; -/// let asserted_bool: bool = is_class_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::classcase::is_class_case; -/// let mock_string: &str = "foo_bar_is_a_really_really_long_strings"; -/// let asserted_bool: bool = is_class_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// -/// -/// ``` -/// use inflector::cases::classcase::is_class_case; -/// let mock_string: &str = "fooBarIsAReallyReallyLongString"; -/// let asserted_bool: bool = is_class_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::classcase::is_class_case; -/// let mock_string: &str = "FOO_BAR_STRING_THAT_IS_REALLY_REALLY_LONG"; -/// let asserted_bool: bool = is_class_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::classcase::is_class_case; -/// let mock_string: &str = "foo_bar_string_that_is_really_really_long"; -/// let asserted_bool: bool = is_class_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::classcase::is_class_case; -/// let mock_string: &str = "Foo bar string that is really really long"; -/// let asserted_bool: bool = is_class_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::classcase::is_class_case; -/// let mock_string: &str = "Foo Bar Is A Really Really Long String"; -/// let asserted_bool: bool = is_class_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -pub fn is_class_case(test_string: &str) -> bool { - to_class_case(&test_string.clone()) == test_string -} - -#[cfg(all(feature = "unstable", test))] -#[cfg(feature = "heavyweight")] -mod benchmarks { - extern crate test; - use self::test::Bencher; - - #[bench] - fn bench_class_case(b: &mut Bencher) { - b.iter(|| super::to_class_case("Foo bar")); - } - - #[bench] - fn bench_is_class(b: &mut Bencher) { - b.iter(|| super::is_class_case("Foo bar")); - } - - #[bench] - fn bench_class_from_snake(b: &mut Bencher) { - b.iter(|| super::to_class_case("foo_bar")); - } -} - -#[cfg(test)] -#[cfg(feature = "heavyweight")] -mod tests { - use ::to_class_case; - use ::is_class_case; - - #[test] - fn from_camel_case() { - let convertable_string: String = "fooBar".to_owned(); - let expected: String = "FooBar".to_owned(); - assert_eq!(to_class_case(&convertable_string), expected) - } - - #[test] - fn from_pascal_case() { - let convertable_string: String = "FooBar".to_owned(); - let expected: String = "FooBar".to_owned(); - assert_eq!(to_class_case(&convertable_string), expected) - } - - #[test] - fn from_kebab_case() { - let convertable_string: String = "foo-bar".to_owned(); - let expected: String = "FooBar".to_owned(); - assert_eq!(to_class_case(&convertable_string), expected) - } - - #[test] - fn from_sentence_case() { - let convertable_string: String = "Foo bar".to_owned(); - let expected: String = "FooBar".to_owned(); - assert_eq!(to_class_case(&convertable_string), expected) - } - - #[test] - fn from_title_case() { - let convertable_string: String = "Foo Bar".to_owned(); - let expected: String = "FooBar".to_owned(); - assert_eq!(to_class_case(&convertable_string), expected) - } - - #[test] - fn from_train_case() { - let convertable_string: String = "Foo-Bar".to_owned(); - let expected: String = "FooBar".to_owned(); - assert_eq!(to_class_case(&convertable_string), expected) - } - - #[test] - fn from_screaming_class_case() { - let convertable_string: String = "FOO_BAR".to_owned(); - let expected: String = "FooBar".to_owned(); - assert_eq!(to_class_case(&convertable_string), expected) - } - - #[test] - fn from_snake_case() { - let convertable_string: String = "foo_bar".to_owned(); - let expected: String = "FooBar".to_owned(); - assert_eq!(to_class_case(&convertable_string), expected) - } - - #[test] - fn from_table_case() { - let convertable_string: String = "foo_bars".to_owned(); - let expected: String = "FooBar".to_owned(); - assert_eq!(to_class_case(&convertable_string), expected) - } - - #[test] - fn from_case_with_loads_of_space() { - let convertable_string: String = "foo bar".to_owned(); - let expected: String = "FooBar".to_owned(); - assert_eq!(to_class_case(&convertable_string), expected) - } - - #[test] - fn a_name_with_a_dot() { - let convertable_string: String = "Robert C. Martin".to_owned(); - let expected: String = "RobertCMartin".to_owned(); - assert_eq!(to_class_case(&convertable_string), expected) - } - - #[test] - fn random_text_with_bad_chars() { - let convertable_string: String = "Random text with *(bad) chars".to_owned(); - let expected: String = "RandomTextWithBadChar".to_owned(); - assert_eq!(to_class_case(&convertable_string), expected) - } - - #[test] - fn trailing_bad_chars() { - let convertable_string: String = "trailing bad_chars*(()())".to_owned(); - let expected: String = "TrailingBadChar".to_owned(); - assert_eq!(to_class_case(&convertable_string), expected) - } - - #[test] - fn leading_bad_chars() { - let convertable_string: String = "-!#$%leading bad chars".to_owned(); - let expected: String = "LeadingBadChar".to_owned(); - assert_eq!(to_class_case(&convertable_string), expected) - } - - #[test] - fn wrapped_in_bad_chars() { - let convertable_string: String = "-!#$%wrapped in bad chars&*^*&(&*^&(<>><>))".to_owned(); - let expected: String = "WrappedInBadChar".to_owned(); - assert_eq!(to_class_case(&convertable_string), expected) - } - - #[test] - fn has_a_sign() { - let convertable_string: String = "has a + sign".to_owned(); - let expected: String = "HasASign".to_owned(); - assert_eq!(to_class_case(&convertable_string), expected) - } - - #[test] - fn is_correct_from_class_case() { - let convertable_string: String = "fooBar".to_owned(); - assert_eq!(is_class_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_pascal_case() { - let convertable_string: String = "FooBar".to_owned(); - assert_eq!(is_class_case(&convertable_string), true) - } - - #[test] - fn is_correct_from_kebab_case() { - let convertable_string: String = "foo-bar".to_owned(); - assert_eq!(is_class_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_sentence_case() { - let convertable_string: String = "Foo bar".to_owned(); - assert_eq!(is_class_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_title_case() { - let convertable_string: String = "Foo Bar".to_owned(); - assert_eq!(is_class_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_train_case() { - let convertable_string: String = "Foo-Bar".to_owned(); - assert_eq!(is_class_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_screaming_snake_case() { - let convertable_string: String = "FOO_BAR".to_owned(); - assert_eq!(is_class_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_snake_case() { - let convertable_string: String = "foo_bar".to_owned(); - assert_eq!(is_class_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_table_case() { - let convertable_string: String = "FooBar".to_owned(); - assert_eq!(is_class_case(&convertable_string), true) - } -} - diff --git a/third_party/rust/Inflector/src/cases/kebabcase/mod.rs b/third_party/rust/Inflector/src/cases/kebabcase/mod.rs deleted file mode 100644 index d79f27362a88..000000000000 --- a/third_party/rust/Inflector/src/cases/kebabcase/mod.rs +++ /dev/null @@ -1,262 +0,0 @@ -#![deny(warnings)] -use cases::case::*; -/// Determines if a `&str` is `kebab-case` -/// -/// ``` -/// use inflector::cases::kebabcase::is_kebab_case; -/// let mock_string: &str = "foo-bar-string-that-is-really-really-long"; -/// let asserted_bool: bool = is_kebab_case(mock_string); -/// assert!(asserted_bool == true); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::kebabcase::is_kebab_case; -/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; -/// let asserted_bool: bool = is_kebab_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::kebabcase::is_kebab_case; -/// let mock_string: &str = "fooBarIsAReallyReallyLongString"; -/// let asserted_bool: bool = is_kebab_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::kebabcase::is_kebab_case; -/// let mock_string: &str = "FOO_BAR_STRING_THAT_IS_REALLY_REALLY_LONG"; -/// let asserted_bool: bool = is_kebab_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::kebabcase::is_kebab_case; -/// let mock_string: &str = "foo_bar_string_that_is_really_really_long"; -/// let asserted_bool: bool = is_kebab_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::kebabcase::is_kebab_case; -/// let mock_string: &str = "Foo bar string that is really really long"; -/// let asserted_bool: bool = is_kebab_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::kebabcase::is_kebab_case; -/// let mock_string: &str = "Foo Bar Is A Really Really Long String"; -/// let asserted_bool: bool = is_kebab_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -pub fn is_kebab_case(test_string: &str) -> bool { - test_string == to_kebab_case(test_string.clone()) -} - -/// Converts a `&str` to `kebab-case` `String` -/// -/// ``` -/// use inflector::cases::kebabcase::to_kebab_case; -/// let mock_string: &str = "foo-bar"; -/// let expected_string: String = "foo-bar".to_string(); -/// let asserted_string: String = to_kebab_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::kebabcase::to_kebab_case; -/// let mock_string: &str = "FOO_BAR"; -/// let expected_string: String = "foo-bar".to_string(); -/// let asserted_string: String = to_kebab_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::kebabcase::to_kebab_case; -/// let mock_string: &str = "foo_bar"; -/// let expected_string: String = "foo-bar".to_string(); -/// let asserted_string: String = to_kebab_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::kebabcase::to_kebab_case; -/// let mock_string: &str = "Foo Bar"; -/// let expected_string: String = "foo-bar".to_string(); -/// let asserted_string: String = to_kebab_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::kebabcase::to_kebab_case; -/// let mock_string: &str = "Foo bar"; -/// let expected_string: String = "foo-bar".to_string(); -/// let asserted_string: String = to_kebab_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::kebabcase::to_kebab_case; -/// let mock_string: &str = "FooBar"; -/// let expected_string: String = "foo-bar".to_string(); -/// let asserted_string: String = to_kebab_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::kebabcase::to_kebab_case; -/// let mock_string: &str = "fooBar"; -/// let expected_string: String = "foo-bar".to_string(); -/// let asserted_string: String = to_kebab_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -pub fn to_kebab_case(non_kebab_case_string: &str) -> String { - to_case_snake_like(non_kebab_case_string, "-", "lower") -} - -#[cfg(all(feature = "unstable", test))] -mod benchmarks { - extern crate test; - use self::test::Bencher; - - #[bench] - fn bench_kebab(b: &mut Bencher) { - b.iter(|| super::to_kebab_case("Foo bar")); - } - - #[bench] - fn bench_is_kebab(b: &mut Bencher) { - b.iter(|| super::is_kebab_case("Foo bar")); - } - - #[bench] - fn bench_kebab_from_snake(b: &mut Bencher) { - b.iter(|| super::to_kebab_case("test_test_test")); - } -} - -#[cfg(test)] -mod tests { - use ::to_kebab_case; - use ::is_kebab_case; - - #[test] - fn from_camel_case() { - let convertable_string: String = "fooBar".to_owned(); - let expected: String = "foo-bar".to_owned(); - assert_eq!(to_kebab_case(&convertable_string), expected) - } - - #[test] - fn from_pascal_case() { - let convertable_string: String = "FooBar".to_owned(); - let expected: String = "foo-bar".to_owned(); - assert_eq!(to_kebab_case(&convertable_string), expected) - } - - #[test] - fn from_kebab_case() { - let convertable_string: String = "foo-bar".to_owned(); - let expected: String = "foo-bar".to_owned(); - assert_eq!(to_kebab_case(&convertable_string), expected) - } - - #[test] - fn from_sentence_case() { - let convertable_string: String = "Foo bar".to_owned(); - let expected: String = "foo-bar".to_owned(); - assert_eq!(to_kebab_case(&convertable_string), expected) - } - - #[test] - fn from_title_case() { - let convertable_string: String = "Foo Bar".to_owned(); - let expected: String = "foo-bar".to_owned(); - assert_eq!(to_kebab_case(&convertable_string), expected) - } - - #[test] - fn from_train_case() { - let convertable_string: String = "Foo-Bar".to_owned(); - let expected: String = "foo-bar".to_owned(); - assert_eq!(to_kebab_case(&convertable_string), expected) - } - - #[test] - fn from_screaming_snake_case() { - let convertable_string: String = "FOO_BAR".to_owned(); - let expected: String = "foo-bar".to_owned(); - assert_eq!(to_kebab_case(&convertable_string), expected) - } - - #[test] - fn from_snake_case() { - let convertable_string: String = "foo_bar".to_owned(); - let expected: String = "foo-bar".to_owned(); - assert_eq!(to_kebab_case(&convertable_string), expected) - } - - #[test] - fn is_correct_from_camel_case() { - let convertable_string: String = "fooBar".to_owned(); - assert_eq!(is_kebab_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_pascal_case() { - let convertable_string: String = "FooBar".to_owned(); - assert_eq!(is_kebab_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_kebab_case() { - let convertable_string: String = "foo-bar".to_owned(); - assert_eq!(is_kebab_case(&convertable_string), true) - } - - #[test] - fn is_correct_from_sentence_case() { - let convertable_string: String = "Foo bar".to_owned(); - assert_eq!(is_kebab_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_title_case() { - let convertable_string: String = "Foo Bar".to_owned(); - assert_eq!(is_kebab_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_train_case() { - let convertable_string: String = "Foo-Bar".to_owned(); - assert_eq!(is_kebab_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_screaming_snake_case() { - let convertable_string: String = "FOO_BAR".to_owned(); - assert_eq!(is_kebab_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_snake_case() { - let convertable_string: String = "foo_bar".to_owned(); - assert_eq!(is_kebab_case(&convertable_string), false) - } -} - diff --git a/third_party/rust/Inflector/src/cases/mod.rs b/third_party/rust/Inflector/src/cases/mod.rs deleted file mode 100644 index dfa772e80161..000000000000 --- a/third_party/rust/Inflector/src/cases/mod.rs +++ /dev/null @@ -1,52 +0,0 @@ -mod case; -/// Provides conversion to and detection of class case strings. -/// -/// This version singularizes strings. -/// -/// Example string `ClassCase` -pub mod classcase; - -/// Provides conversion to and detection of camel case strings. -/// -/// Example string `camelCase` -pub mod camelcase; - -/// Provides conversion to and detection of snake case strings. -/// -/// Example string `snake_case` -pub mod snakecase; - -/// Provides conversion to and detection of screaming snake case strings. -/// -/// Example string `SCREAMING_SNAKE_CASE` -pub mod screamingsnakecase; - -/// Provides conversion to and detection of kebab case strings. -/// -/// Example string `kebab-case` -pub mod kebabcase; - -/// Provides conversion to and detection of train case strings. -/// -/// Example string `Train-Case` -pub mod traincase; - -/// Provides conversion to and detection of sentence case strings. -/// -/// Example string `Sentence case` -pub mod sentencecase; - -/// Provides conversion to and detection of title case strings. -/// -/// Example string `Title Case` -pub mod titlecase; - -/// Provides conversion to and detection of table case strings. -/// -/// Example string `table_cases` -pub mod tablecase; - -/// Provides conversion to pascal case strings. -/// -/// Example string `PascalCase` -pub mod pascalcase; diff --git a/third_party/rust/Inflector/src/cases/pascalcase/mod.rs b/third_party/rust/Inflector/src/cases/pascalcase/mod.rs deleted file mode 100644 index 248f91ab4389..000000000000 --- a/third_party/rust/Inflector/src/cases/pascalcase/mod.rs +++ /dev/null @@ -1,360 +0,0 @@ -#![deny(warnings)] -use cases::case::*; -/// Converts a `&str` to pascalCase `String` -/// -/// ``` -/// use inflector::cases::pascalcase::to_pascal_case; -/// let mock_string: &str = "fooBar"; -/// let expected_string: String = "FooBar".to_string(); -/// let asserted_string: String = to_pascal_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::pascalcase::to_pascal_case; -/// let mock_string: &str = "FOO_BAR"; -/// let expected_string: String = "FooBar".to_string(); -/// let asserted_string: String = to_pascal_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::pascalcase::to_pascal_case; -/// let mock_string: &str = "Foo Bar"; -/// let expected_string: String = "FooBar".to_string(); -/// let asserted_string: String = to_pascal_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::pascalcase::to_pascal_case; -/// let mock_string: &str = "foo_bar"; -/// let expected_string: String = "FooBar".to_string(); -/// let asserted_string: String = to_pascal_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::pascalcase::to_pascal_case; -/// let mock_string: &str = "Foo bar"; -/// let expected_string: String = "FooBar".to_string(); -/// let asserted_string: String = to_pascal_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::pascalcase::to_pascal_case; -/// let mock_string: &str = "foo-bar"; -/// let expected_string: String = "FooBar".to_string(); -/// let asserted_string: String = to_pascal_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::pascalcase::to_pascal_case; -/// let mock_string: &str = "FooBar"; -/// let expected_string: String = "FooBar".to_string(); -/// let asserted_string: String = to_pascal_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::pascalcase::to_pascal_case; -/// let mock_string: &str = "FooBar3"; -/// let expected_string: String = "FooBar3".to_string(); -/// let asserted_string: String = to_pascal_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -pub fn to_pascal_case(non_pascalized_string: &str) -> String { - let options = CamelOptions { - new_word: true, - last_char: ' ', - first_word: false, - injectable_char: ' ', - has_seperator: false, - inverted: false, - }; - to_case_camel_like(non_pascalized_string, options) -} - -/// Determines if a `&str` is pascalCase bool`` -/// -/// ``` -/// use inflector::cases::pascalcase::is_pascal_case; -/// let mock_string: &str = "Foo"; -/// let asserted_bool: bool = is_pascal_case(mock_string); -/// assert!(asserted_bool == true); -/// -/// -/// ``` -/// ``` -/// use inflector::cases::pascalcase::is_pascal_case; -/// let mock_string: &str = "foo"; -/// let asserted_bool: bool = is_pascal_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// -/// ``` -/// ``` -/// use inflector::cases::pascalcase::is_pascal_case; -/// let mock_string: &str = "foo-bar-string-that-is-really-really-long"; -/// let asserted_bool: bool = is_pascal_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// -/// ``` -/// ``` -/// use inflector::cases::pascalcase::is_pascal_case; -/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; -/// let asserted_bool: bool = is_pascal_case(mock_string); -/// assert!(asserted_bool == true); -/// -/// -/// ``` -/// ``` -/// use inflector::cases::pascalcase::is_pascal_case; -/// let mock_string: &str = "FooBarIsAReallyReally3LongString"; -/// let asserted_bool: bool = is_pascal_case(mock_string); -/// assert!(asserted_bool == true); -/// -/// -/// ``` -/// ``` -/// use inflector::cases::pascalcase::is_pascal_case; -/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; -/// let asserted_bool: bool = is_pascal_case(mock_string); -/// assert!(asserted_bool == true); -/// -/// -/// ``` -/// ``` -/// use inflector::cases::pascalcase::is_pascal_case; -/// let mock_string: &str = "FOO_BAR_STRING_THAT_IS_REALLY_REALLY_LONG"; -/// let asserted_bool: bool = is_pascal_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// -/// ``` -/// ``` -/// use inflector::cases::pascalcase::is_pascal_case; -/// let mock_string: &str = "foo_bar_string_that_is_really_really_long"; -/// let asserted_bool: bool = is_pascal_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// -/// ``` -/// ``` -/// use inflector::cases::pascalcase::is_pascal_case; -/// let mock_string: &str = "Foo bar string that is really really long"; -/// let asserted_bool: bool = is_pascal_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// -/// ``` -/// ``` -/// use inflector::cases::pascalcase::is_pascal_case; -/// let mock_string: &str = "Foo Bar Is A Really Really Long String"; -/// let asserted_bool: bool = is_pascal_case(mock_string); -/// assert!(asserted_bool == false); -/// ``` -pub fn is_pascal_case(test_string: &str) -> bool { - to_pascal_case(test_string.clone()) == test_string -} - -#[cfg(all(feature = "unstable", test))] -mod benchmarks { - extern crate test; - use self::test::Bencher; - - #[bench] - fn bench_pascal0(b: &mut Bencher) { - b.iter(|| { - let test_string = "Foo bar"; - super::to_pascal_case(test_string) - }); - } - - #[bench] - fn bench_pascal1(b: &mut Bencher) { - b.iter(|| { - let test_string = "foo_bar"; - super::to_pascal_case(test_string) - }); - } - - #[bench] - fn bench_pascal2(b: &mut Bencher) { - b.iter(|| { - let test_string = "fooBar"; - super::to_pascal_case(test_string) - }); - } - - #[bench] - fn bench_is_pascal(b: &mut Bencher) { - b.iter(|| { - let test_string: &str = "Foo bar"; - super::is_pascal_case(test_string) - }); - } -} - -#[cfg(test)] -mod tests { - use ::to_pascal_case; - use ::is_pascal_case; - - #[test] - fn from_camel_case() { - let convertable_string: String = "fooBar".to_owned(); - let expected: String = "FooBar".to_owned(); - assert_eq!(to_pascal_case(&convertable_string), expected) - } - - #[test] - fn from_pascal_case() { - let convertable_string: String = "FooBar".to_owned(); - let expected: String = "FooBar".to_owned(); - assert_eq!(to_pascal_case(&convertable_string), expected) - } - - #[test] - fn from_kebab_case() { - let convertable_string: String = "foo-bar".to_owned(); - let expected: String = "FooBar".to_owned(); - assert_eq!(to_pascal_case(&convertable_string), expected) - } - - #[test] - fn from_sentence_case() { - let convertable_string: String = "Foo bar".to_owned(); - let expected: String = "FooBar".to_owned(); - assert_eq!(to_pascal_case(&convertable_string), expected) - } - - #[test] - fn from_title_case() { - let convertable_string: String = "Foo Bar".to_owned(); - let expected: String = "FooBar".to_owned(); - assert_eq!(to_pascal_case(&convertable_string), expected) - } - - #[test] - fn from_train_case() { - let convertable_string: String = "Foo-Bar".to_owned(); - let expected: String = "FooBar".to_owned(); - assert_eq!(to_pascal_case(&convertable_string), expected) - } - - #[test] - fn from_screaming_snake_case() { - let convertable_string: String = "FOO_BAR".to_owned(); - let expected: String = "FooBar".to_owned(); - assert_eq!(to_pascal_case(&convertable_string), expected) - } - - #[test] - fn from_snake_case() { - let convertable_string: String = "foo_bar".to_owned(); - let expected: String = "FooBar".to_owned(); - assert_eq!(to_pascal_case(&convertable_string), expected) - } - - #[test] - fn from_case_with_loads_of_space() { - let convertable_string: String = "foo bar".to_owned(); - let expected: String = "FooBar".to_owned(); - assert_eq!(to_pascal_case(&convertable_string), expected) - } - - #[test] - fn a_name_with_a_dot() { - let convertable_string: String = "Robert C. Martin".to_owned(); - let expected: String = "RobertCMartin".to_owned(); - assert_eq!(to_pascal_case(&convertable_string), expected) - } - - #[test] - fn random_text_with_bad_chars() { - let convertable_string: String = "Random text with *(bad) chars".to_owned(); - let expected: String = "RandomTextWithBadChars".to_owned(); - assert_eq!(to_pascal_case(&convertable_string), expected) - } - - #[test] - fn trailing_bad_chars() { - let convertable_string: String = "trailing bad_chars*(()())".to_owned(); - let expected: String = "TrailingBadChars".to_owned(); - assert_eq!(to_pascal_case(&convertable_string), expected) - } - - #[test] - fn leading_bad_chars() { - let convertable_string: String = "-!#$%leading bad chars".to_owned(); - let expected: String = "LeadingBadChars".to_owned(); - assert_eq!(to_pascal_case(&convertable_string), expected) - } - - #[test] - fn wrapped_in_bad_chars() { - let convertable_string: String = "-!#$%wrapped in bad chars&*^*&(&*^&(<>><>))".to_owned(); - let expected: String = "WrappedInBadChars".to_owned(); - assert_eq!(to_pascal_case(&convertable_string), expected) - } - - #[test] - fn has_a_sign() { - let convertable_string: String = "has a + sign".to_owned(); - let expected: String = "HasASign".to_owned(); - assert_eq!(to_pascal_case(&convertable_string), expected) - } - - #[test] - fn is_correct_from_camel_case() { - let convertable_string: String = "fooBar".to_owned(); - assert_eq!(is_pascal_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_pascal_case() { - let convertable_string: String = "FooBar".to_owned(); - assert_eq!(is_pascal_case(&convertable_string), true) - } - - #[test] - fn is_correct_from_kebab_case() { - let convertable_string: String = "foo-bar".to_owned(); - assert_eq!(is_pascal_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_sentence_case() { - let convertable_string: String = "Foo bar".to_owned(); - assert_eq!(is_pascal_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_title_case() { - let convertable_string: String = "Foo Bar".to_owned(); - assert_eq!(is_pascal_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_train_case() { - let convertable_string: String = "Foo-Bar".to_owned(); - assert_eq!(is_pascal_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_screaming_snake_case() { - let convertable_string: String = "FOO_BAR".to_owned(); - assert_eq!(is_pascal_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_snake_case() { - let convertable_string: String = "foo_bar".to_owned(); - assert_eq!(is_pascal_case(&convertable_string), false) - } -} diff --git a/third_party/rust/Inflector/src/cases/screamingsnakecase/mod.rs b/third_party/rust/Inflector/src/cases/screamingsnakecase/mod.rs deleted file mode 100644 index 9bec7a5536a6..000000000000 --- a/third_party/rust/Inflector/src/cases/screamingsnakecase/mod.rs +++ /dev/null @@ -1,253 +0,0 @@ -#![deny(warnings)] -use cases::case::*; -/// Converts a `&str` to `SCREAMING_SNAKE_CASE` `String` -/// -/// ``` -/// use inflector::cases::screamingsnakecase::to_screaming_snake_case; -/// let mock_string: &str = "foo_bar"; -/// let expected_string: String = "FOO_BAR".to_string(); -/// let asserted_string: String = to_screaming_snake_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::screamingsnakecase::to_screaming_snake_case; -/// let mock_string: &str = "HTTP Foo bar"; -/// let expected_string: String = "HTTP_FOO_BAR".to_string(); -/// let asserted_string: String = to_screaming_snake_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::screamingsnakecase::to_screaming_snake_case; -/// let mock_string: &str = "Foo bar"; -/// let expected_string: String = "FOO_BAR".to_string(); -/// let asserted_string: String = to_screaming_snake_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::screamingsnakecase::to_screaming_snake_case; -/// let mock_string: &str = "Foo Bar"; -/// let expected_string: String = "FOO_BAR".to_string(); -/// let asserted_string: String = to_screaming_snake_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::screamingsnakecase::to_screaming_snake_case; -/// let mock_string: &str = "FooBar"; -/// let expected_string: String = "FOO_BAR".to_string(); -/// let asserted_string: String = to_screaming_snake_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::screamingsnakecase::to_screaming_snake_case; -/// let mock_string: &str = "fooBar"; -/// let expected_string: String = "FOO_BAR".to_string(); -/// let asserted_string: String = to_screaming_snake_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::screamingsnakecase::to_screaming_snake_case; -/// let mock_string: &str = "fooBar3"; -/// let expected_string: String = "FOO_BAR_3".to_string(); -/// let asserted_string: String = to_screaming_snake_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -pub fn to_screaming_snake_case(non_snake_case_string: &str) -> String { - to_case_snake_like(non_snake_case_string, "_", "upper") -} - -/// Determines of a `&str` is `SCREAMING_SNAKE_CASE` -/// -/// ``` -/// use inflector::cases::screamingsnakecase::is_screaming_snake_case; -/// let mock_string: &str = "Foo bar string that is really really long"; -/// let asserted_bool: bool = is_screaming_snake_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::screamingsnakecase::is_screaming_snake_case; -/// let mock_string: &str = "foo-bar-string-that-is-really-really-long"; -/// let asserted_bool: bool = is_screaming_snake_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::screamingsnakecase::is_screaming_snake_case; -/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; -/// let asserted_bool: bool = is_screaming_snake_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::screamingsnakecase::is_screaming_snake_case; -/// let mock_string: &str = "Foo Bar Is A Really Really Long String"; -/// let asserted_bool: bool = is_screaming_snake_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::screamingsnakecase::is_screaming_snake_case; -/// let mock_string: &str = "fooBarIsAReallyReallyLongString"; -/// let asserted_bool: bool = is_screaming_snake_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::screamingsnakecase::is_screaming_snake_case; -/// let mock_string: &str = "FOO_BAR_STRING_THAT_IS_REALLY_REALLY_LONG"; -/// let asserted_bool: bool = is_screaming_snake_case(mock_string); -/// assert!(asserted_bool == true); -/// -/// ``` -/// ``` -/// use inflector::cases::screamingsnakecase::is_screaming_snake_case; -/// let mock_string: &str = "FOO_BAR1_STRING_THAT_IS_REALLY_REALLY_LONG"; -/// let asserted_bool: bool = is_screaming_snake_case(mock_string); -/// assert!(asserted_bool == true); -/// -/// ``` -/// ``` -/// use inflector::cases::screamingsnakecase::is_screaming_snake_case; -/// let mock_string: &str = "FOO_BAR_1_STRING_THAT_IS_REALLY_REALLY_LONG"; -/// let asserted_bool: bool = is_screaming_snake_case(mock_string); -/// assert!(asserted_bool == true); -/// -/// ``` -pub fn is_screaming_snake_case(test_string: &str) -> bool { - test_string == to_screaming_snake_case(test_string.clone()) -} - - -#[cfg(all(feature = "unstable", test))] -mod benchmarks { - extern crate test; - use self::test::Bencher; - - #[bench] - fn bench_screaming_snake(b: &mut Bencher) { - b.iter(|| super::to_screaming_snake_case("Foo bar")); - } - - #[bench] - fn bench_is_screaming_snake(b: &mut Bencher) { - b.iter(|| super::is_screaming_snake_case("Foo bar")); - } - -} - -#[cfg(test)] -mod tests { - use ::to_screaming_snake_case; - use ::is_screaming_snake_case; - - #[test] - fn from_camel_case() { - let convertable_string: String = "fooBar".to_owned(); - let expected: String = "FOO_BAR".to_owned(); - assert_eq!(to_screaming_snake_case(&convertable_string), expected) - } - - #[test] - fn from_pascal_case() { - let convertable_string: String = "FooBar".to_owned(); - let expected: String = "FOO_BAR".to_owned(); - assert_eq!(to_screaming_snake_case(&convertable_string), expected) - } - - #[test] - fn from_kebab_case() { - let convertable_string: String = "foo-bar".to_owned(); - let expected: String = "FOO_BAR".to_owned(); - assert_eq!(to_screaming_snake_case(&convertable_string), expected) - } - - #[test] - fn from_sentence_case() { - let convertable_string: String = "Foo bar".to_owned(); - let expected: String = "FOO_BAR".to_owned(); - assert_eq!(to_screaming_snake_case(&convertable_string), expected) - } - - #[test] - fn from_title_case() { - let convertable_string: String = "Foo Bar".to_owned(); - let expected: String = "FOO_BAR".to_owned(); - assert_eq!(to_screaming_snake_case(&convertable_string), expected) - } - - #[test] - fn from_train_case() { - let convertable_string: String = "Foo-Bar".to_owned(); - let expected: String = "FOO_BAR".to_owned(); - assert_eq!(to_screaming_snake_case(&convertable_string), expected) - } - - #[test] - fn from_screaming_screaming_snake_case() { - let convertable_string: String = "FOO_BAR".to_owned(); - let expected: String = "FOO_BAR".to_owned(); - assert_eq!(to_screaming_snake_case(&convertable_string), expected) - } - - #[test] - fn from_snake_case() { - let convertable_string: String = "foo_bar".to_owned(); - let expected: String = "FOO_BAR".to_owned(); - assert_eq!(to_screaming_snake_case(&convertable_string), expected) - } - - #[test] - fn is_correct_from_camel_case() { - let convertable_string: String = "fooBar".to_owned(); - assert_eq!(is_screaming_snake_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_pascal_case() { - let convertable_string: String = "FooBar".to_owned(); - assert_eq!(is_screaming_snake_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_kebab_case() { - let convertable_string: String = "foo-bar".to_owned(); - assert_eq!(is_screaming_snake_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_sentence_case() { - let convertable_string: String = "Foo bar".to_owned(); - assert_eq!(is_screaming_snake_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_title_case() { - let convertable_string: String = "Foo Bar".to_owned(); - assert_eq!(is_screaming_snake_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_train_case() { - let convertable_string: String = "Foo-Bar".to_owned(); - assert_eq!(is_screaming_snake_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_screaming_screaming_snake_case() { - let convertable_string: String = "FOO_BAR".to_owned(); - assert_eq!(is_screaming_snake_case(&convertable_string), true) - } - - #[test] - fn is_correct_from_snake_case() { - let convertable_string: String = "foo_bar".to_owned(); - assert_eq!(is_screaming_snake_case(&convertable_string), false) - } -} diff --git a/third_party/rust/Inflector/src/cases/sentencecase/mod.rs b/third_party/rust/Inflector/src/cases/sentencecase/mod.rs deleted file mode 100644 index 5a99d217f427..000000000000 --- a/third_party/rust/Inflector/src/cases/sentencecase/mod.rs +++ /dev/null @@ -1,313 +0,0 @@ -#![deny(warnings)] -use cases::case::*; -/// Converts a `&str` to `Sentence case` `String` -/// -/// ``` -/// use inflector::cases::sentencecase::to_sentence_case; -/// let mock_string: &str = "Foo bar"; -/// let expected_string: String = "Foo bar".to_string(); -/// let asserted_string: String = to_sentence_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::sentencecase::to_sentence_case; -/// let mock_string: &str = "FooBar"; -/// let expected_string: String = "Foo bar".to_string(); -/// let asserted_string: String = to_sentence_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::sentencecase::to_sentence_case; -/// let mock_string: &str = "fooBar"; -/// let expected_string: String = "Foo bar".to_string(); -/// let asserted_string: String = to_sentence_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::sentencecase::to_sentence_case; -/// let mock_string: &str = "FOO_BAR"; -/// let expected_string: String = "Foo bar".to_string(); -/// let asserted_string: String = to_sentence_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::sentencecase::to_sentence_case; -/// let mock_string: &str = "foo_bar"; -/// let expected_string: String = "Foo bar".to_string(); -/// let asserted_string: String = to_sentence_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::sentencecase::to_sentence_case; -/// let mock_string: &str = "foo-bar"; -/// let expected_string: String = "Foo bar".to_string(); -/// let asserted_string: String = to_sentence_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -pub fn to_sentence_case(non_sentence_case_string: &str) -> String { - let options = CamelOptions { - new_word: true, - last_char: ' ', - first_word: true, - injectable_char: ' ', - has_seperator: true, - inverted: true, - }; - to_case_camel_like(non_sentence_case_string, options) -} -/// Determines of a `&str` is `Sentence case` -/// -/// ``` -/// use inflector::cases::sentencecase::is_sentence_case; -/// let mock_string: &str = "foo-bar-string-that-is-really-really-long"; -/// let asserted_bool: bool = is_sentence_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::sentencecase::is_sentence_case; -/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; -/// let asserted_bool: bool = is_sentence_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::sentencecase::is_sentence_case; -/// let mock_string: &str = "fooBarIsAReallyReallyLongString"; -/// let asserted_bool: bool = is_sentence_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::sentencecase::is_sentence_case; -/// let mock_string: &str = "Foo Bar Is A Really Really Long String"; -/// let asserted_bool: bool = is_sentence_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::sentencecase::is_sentence_case; -/// let mock_string: &str = "FOO_BAR_STRING_THAT_IS_REALLY_REALLY_LONG"; -/// let asserted_bool: bool = is_sentence_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::sentencecase::is_sentence_case; -/// let mock_string: &str = "foo_bar_string_that_is_really_really_long"; -/// let asserted_bool: bool = is_sentence_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::sentencecase::is_sentence_case; -/// let mock_string: &str = "Foo"; -/// let asserted_bool: bool = is_sentence_case(mock_string); -/// assert!(asserted_bool == true); -/// -/// ``` -/// ``` -/// use inflector::cases::sentencecase::is_sentence_case; -/// let mock_string: &str = "foo"; -/// let asserted_bool: bool = is_sentence_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::sentencecase::is_sentence_case; -/// let mock_string: &str = "Foo bar string that is really really long"; -/// let asserted_bool: bool = is_sentence_case(mock_string); -/// assert!(asserted_bool == true); -/// -/// ``` -pub fn is_sentence_case(test_string: &str) -> bool { - test_string == to_sentence_case(test_string.clone()) -} - -#[cfg(all(feature = "unstable", test))] -mod benchmarks { - extern crate test; - use self::test::Bencher; - - #[bench] - fn bench_sentence(b: &mut Bencher) { - b.iter(|| super::to_sentence_case("Foo BAR")); - } - - #[bench] - fn bench_is_sentence(b: &mut Bencher) { - b.iter(|| super::is_sentence_case("Foo bar")); - } - - #[bench] - fn bench_sentence_from_snake(b: &mut Bencher) { - b.iter(|| super::to_sentence_case("foo_bar")); - } - -} - -#[cfg(test)] -mod tests { - use ::to_sentence_case; - use ::is_sentence_case; - - #[test] - fn from_camel_case() { - let convertable_string: String = "fooBar".to_owned(); - let expected: String = "Foo bar".to_owned(); - assert_eq!(to_sentence_case(&convertable_string), expected) - } - - #[test] - fn from_pascal_case() { - let convertable_string: String = "FooBar".to_owned(); - let expected: String = "Foo bar".to_owned(); - assert_eq!(to_sentence_case(&convertable_string), expected) - } - - #[test] - fn from_kebab_case() { - let convertable_string: String = "foo-bar".to_owned(); - let expected: String = "Foo bar".to_owned(); - assert_eq!(to_sentence_case(&convertable_string), expected) - } - - #[test] - fn from_sentence_case() { - let convertable_string: String = "Foo bar".to_owned(); - let expected: String = "Foo bar".to_owned(); - assert_eq!(to_sentence_case(&convertable_string), expected) - } - - #[test] - fn from_title_case() { - let convertable_string: String = "Foo Bar".to_owned(); - let expected: String = "Foo bar".to_owned(); - assert_eq!(to_sentence_case(&convertable_string), expected) - } - - #[test] - fn from_train_case() { - let convertable_string: String = "Foo-Bar".to_owned(); - let expected: String = "Foo bar".to_owned(); - assert_eq!(to_sentence_case(&convertable_string), expected) - } - - #[test] - fn from_screaming_snake_case() { - let convertable_string: String = "FOO_BAR".to_owned(); - let expected: String = "Foo bar".to_owned(); - assert_eq!(to_sentence_case(&convertable_string), expected) - } - - #[test] - fn from_snake_case() { - let convertable_string: String = "foo_bar".to_owned(); - let expected: String = "Foo bar".to_owned(); - assert_eq!(to_sentence_case(&convertable_string), expected) - } - - #[test] - fn from_case_with_loads_of_space() { - let convertable_string: String = "foo bar".to_owned(); - let expected: String = "Foo bar".to_owned(); - assert_eq!(to_sentence_case(&convertable_string), expected) - } - - #[test] - fn a_name_with_a_dot() { - let convertable_string: String = "Robert C. Martin".to_owned(); - let expected: String = "Robert c martin".to_owned(); - assert_eq!(to_sentence_case(&convertable_string), expected) - } - - #[test] - fn random_text_with_bad_chars() { - let convertable_string: String = "Random text with *(bad) chars".to_owned(); - let expected: String = "Random text with bad chars".to_owned(); - assert_eq!(to_sentence_case(&convertable_string), expected) - } - - #[test] - fn trailing_bad_chars() { - let convertable_string: String = "trailing bad_chars*(()())".to_owned(); - let expected: String = "Trailing bad chars".to_owned(); - assert_eq!(to_sentence_case(&convertable_string), expected) - } - - #[test] - fn leading_bad_chars() { - let convertable_string: String = "-!#$%leading bad chars".to_owned(); - let expected: String = "Leading bad chars".to_owned(); - assert_eq!(to_sentence_case(&convertable_string), expected) - } - - #[test] - fn wrapped_in_bad_chars() { - let convertable_string: String = "-!#$%wrapped in bad chars&*^*&(&*^&(<>><>))".to_owned(); - let expected: String = "Wrapped in bad chars".to_owned(); - assert_eq!(to_sentence_case(&convertable_string), expected) - } - - #[test] - fn has_a_sign() { - let convertable_string: String = "has a + sign".to_owned(); - let expected: String = "Has a sign".to_owned(); - assert_eq!(to_sentence_case(&convertable_string), expected) - } - - - #[test] - fn is_correct_from_camel_case() { - let convertable_string: String = "fooBar".to_owned(); - assert_eq!(is_sentence_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_pascal_case() { - let convertable_string: String = "FooBar".to_owned(); - assert_eq!(is_sentence_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_kebab_case() { - let convertable_string: String = "foo-bar".to_owned(); - assert_eq!(is_sentence_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_sentence_case() { - let convertable_string: String = "Foo bar".to_owned(); - assert_eq!(is_sentence_case(&convertable_string), true) - } - - #[test] - fn is_correct_from_title_case() { - let convertable_string: String = "Foo Bar".to_owned(); - assert_eq!(is_sentence_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_train_case() { - let convertable_string: String = "Foo-Bar".to_owned(); - assert_eq!(is_sentence_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_screaming_snake_case() { - let convertable_string: String = "FOO_BAR".to_owned(); - assert_eq!(is_sentence_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_snake_case() { - let convertable_string: String = "foo_bar".to_owned(); - assert_eq!(is_sentence_case(&convertable_string), false) - } -} diff --git a/third_party/rust/Inflector/src/cases/snakecase/mod.rs b/third_party/rust/Inflector/src/cases/snakecase/mod.rs deleted file mode 100644 index a56894b1a1f9..000000000000 --- a/third_party/rust/Inflector/src/cases/snakecase/mod.rs +++ /dev/null @@ -1,334 +0,0 @@ -#![deny(warnings)] -use cases::case::*; -/// Converts a `&str` to `snake_case` `String` -/// -/// ``` -/// use inflector::cases::snakecase::to_snake_case; -/// let mock_string: &str = "foo_bar"; -/// let expected_string: String = "foo_bar".to_string(); -/// let asserted_string: String = to_snake_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::snakecase::to_snake_case; -/// let mock_string: &str = "HTTP Foo bar"; -/// let expected_string: String = "http_foo_bar".to_string(); -/// let asserted_string: String = to_snake_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::snakecase::to_snake_case; -/// let mock_string: &str = "HTTPFooBar"; -/// let expected_string: String = "http_foo_bar".to_string(); -/// let asserted_string: String = to_snake_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::snakecase::to_snake_case; -/// let mock_string: &str = "Foo bar"; -/// let expected_string: String = "foo_bar".to_string(); -/// let asserted_string: String = to_snake_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::snakecase::to_snake_case; -/// let mock_string: &str = "Foo Bar"; -/// let expected_string: String = "foo_bar".to_string(); -/// let asserted_string: String = to_snake_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::snakecase::to_snake_case; -/// let mock_string: &str = "FooBar"; -/// let expected_string: String = "foo_bar".to_string(); -/// let asserted_string: String = to_snake_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::snakecase::to_snake_case; -/// let mock_string: &str = "FOO_BAR"; -/// let expected_string: String = "foo_bar".to_string(); -/// let asserted_string: String = to_snake_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::snakecase::to_snake_case; -/// let mock_string: &str = "fooBar"; -/// let expected_string: String = "foo_bar".to_string(); -/// let asserted_string: String = to_snake_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::snakecase::to_snake_case; -/// let mock_string: &str = "fooBar3"; -/// let expected_string: String = "foo_bar_3".to_string(); -/// let asserted_string: String = to_snake_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -pub fn to_snake_case(non_snake_case_string: &str) -> String { - to_case_snake_like(non_snake_case_string, "_", "lower") -} - -/// Determines of a `&str` is `snake_case` -/// -/// ``` -/// use inflector::cases::snakecase::is_snake_case; -/// let mock_string: &str = "Foo bar string that is really really long"; -/// let asserted_bool: bool = is_snake_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::snakecase::is_snake_case; -/// let mock_string: &str = "foo-bar-string-that-is-really-really-long"; -/// let asserted_bool: bool = is_snake_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::snakecase::is_snake_case; -/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; -/// let asserted_bool: bool = is_snake_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::snakecase::is_snake_case; -/// let mock_string: &str = "Foo Bar Is A Really Really Long String"; -/// let asserted_bool: bool = is_snake_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::snakecase::is_snake_case; -/// let mock_string: &str = "FOO_BAR_IS_A_REALLY_REALLY_LONG_STRING"; -/// let asserted_bool: bool = is_snake_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::snakecase::is_snake_case; -/// let mock_string: &str = "fooBarIsAReallyReallyLongString"; -/// let asserted_bool: bool = is_snake_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::snakecase::is_snake_case; -/// let mock_string: &str = "foo_bar_string_that_is_really_really_long"; -/// let asserted_bool: bool = is_snake_case(mock_string); -/// assert!(asserted_bool == true); -/// -/// ``` -/// ``` -/// use inflector::cases::snakecase::is_snake_case; -/// let mock_string: &str = "foo_bar1_string_that_is_really_really_long"; -/// let asserted_bool: bool = is_snake_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::snakecase::is_snake_case; -/// let mock_string: &str = "foo_bar_1_string_that_is_really_really_long"; -/// let asserted_bool: bool = is_snake_case(mock_string); -/// assert!(asserted_bool == true); -/// -/// ``` -pub fn is_snake_case(test_string: &str) -> bool { - test_string == to_snake_case(test_string.clone()) -} - -#[cfg(all(feature = "unstable", test))] -mod benchmarks { - extern crate test; - use self::test::Bencher; - - #[bench] - fn bench_snake_from_title(b: &mut Bencher) { - b.iter(|| super::to_snake_case("Foo bar")); - } - - #[bench] - fn bench_snake_from_camel(b: &mut Bencher) { - b.iter(|| super::to_snake_case("fooBar")); - } - - #[bench] - fn bench_snake_from_snake(b: &mut Bencher) { - b.iter(|| super::to_snake_case("foo_bar_bar_bar")); - } - - #[bench] - fn bench_is_snake(b: &mut Bencher) { - b.iter(|| super::is_snake_case("Foo bar")); - } - -} - -#[cfg(test)] -mod tests { - use ::to_snake_case; - use ::is_snake_case; - - #[test] - fn from_camel_case() { - let convertable_string: String = "fooBar".to_owned(); - let expected: String = "foo_bar".to_owned(); - assert_eq!(to_snake_case(&convertable_string), expected) - } - - #[test] - fn from_pascal_case() { - let convertable_string: String = "FooBar".to_owned(); - let expected: String = "foo_bar".to_owned(); - assert_eq!(to_snake_case(&convertable_string), expected) - } - - #[test] - fn from_kebab_case() { - let convertable_string: String = "foo-bar".to_owned(); - let expected: String = "foo_bar".to_owned(); - assert_eq!(to_snake_case(&convertable_string), expected) - } - - #[test] - fn from_sentence_case() { - let convertable_string: String = "Foo bar".to_owned(); - let expected: String = "foo_bar".to_owned(); - assert_eq!(to_snake_case(&convertable_string), expected) - } - - #[test] - fn from_title_case() { - let convertable_string: String = "Foo Bar".to_owned(); - let expected: String = "foo_bar".to_owned(); - assert_eq!(to_snake_case(&convertable_string), expected) - } - - #[test] - fn from_train_case() { - let convertable_string: String = "Foo-Bar".to_owned(); - let expected: String = "foo_bar".to_owned(); - assert_eq!(to_snake_case(&convertable_string), expected) - } - - #[test] - fn from_screaming_snake_case() { - let convertable_string: String = "FOO_BAR".to_owned(); - let expected: String = "foo_bar".to_owned(); - assert_eq!(to_snake_case(&convertable_string), expected) - } - - #[test] - fn from_snake_case() { - let convertable_string: String = "foo_bar".to_owned(); - let expected: String = "foo_bar".to_owned(); - assert_eq!(to_snake_case(&convertable_string), expected) - } - - #[test] - fn from_case_with_loads_of_space() { - let convertable_string: String = "foo bar".to_owned(); - let expected: String = "foo_bar".to_owned(); - assert_eq!(to_snake_case(&convertable_string), expected) - } - - #[test] - fn a_name_with_a_dot() { - let convertable_string: String = "Robert C. Martin".to_owned(); - let expected: String = "robert_c_martin".to_owned(); - assert_eq!(to_snake_case(&convertable_string), expected) - } - - #[test] - fn random_text_with_bad_chars() { - let convertable_string: String = "Random text with *(bad) chars".to_owned(); - let expected: String = "random_text_with_bad_chars".to_owned(); - assert_eq!(to_snake_case(&convertable_string), expected) - } - - #[test] - fn trailing_bad_chars() { - let convertable_string: String = "trailing bad_chars*(()())".to_owned(); - let expected: String = "trailing_bad_chars".to_owned(); - assert_eq!(to_snake_case(&convertable_string), expected) - } - - #[test] - fn leading_bad_chars() { - let convertable_string: String = "-!#$%leading bad chars".to_owned(); - let expected: String = "leading_bad_chars".to_owned(); - assert_eq!(to_snake_case(&convertable_string), expected) - } - - #[test] - fn wrapped_in_bad_chars() { - let convertable_string: String = "-!#$%wrapped in bad chars&*^*&(&*^&(<>><>))".to_owned(); - let expected: String = "wrapped_in_bad_chars".to_owned(); - assert_eq!(to_snake_case(&convertable_string), expected) - } - - #[test] - fn has_a_sign() { - let convertable_string: String = "has a + sign".to_owned(); - let expected: String = "has_a_sign".to_owned(); - assert_eq!(to_snake_case(&convertable_string), expected) - } - - #[test] - fn is_correct_from_camel_case() { - let convertable_string: String = "fooBar".to_owned(); - assert_eq!(is_snake_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_pascal_case() { - let convertable_string: String = "FooBar".to_owned(); - assert_eq!(is_snake_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_kebab_case() { - let convertable_string: String = "foo-bar".to_owned(); - assert_eq!(is_snake_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_sentence_case() { - let convertable_string: String = "Foo bar".to_owned(); - assert_eq!(is_snake_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_title_case() { - let convertable_string: String = "Foo Bar".to_owned(); - assert_eq!(is_snake_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_train_case() { - let convertable_string: String = "Foo-Bar".to_owned(); - assert_eq!(is_snake_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_screaming_snake_case() { - let convertable_string: String = "FOO_BAR".to_owned(); - assert_eq!(is_snake_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_snake_case() { - let convertable_string: String = "foo_bar".to_owned(); - assert_eq!(is_snake_case(&convertable_string), true) - } -} diff --git a/third_party/rust/Inflector/src/cases/tablecase/mod.rs b/third_party/rust/Inflector/src/cases/tablecase/mod.rs deleted file mode 100644 index 7224cc439be7..000000000000 --- a/third_party/rust/Inflector/src/cases/tablecase/mod.rs +++ /dev/null @@ -1,271 +0,0 @@ -#![deny(warnings)] -#[cfg(feature = "heavyweight")] -use string::pluralize::to_plural; -#[cfg(feature = "heavyweight")] -use cases::case::*; -#[cfg(feature = "heavyweight")] -/// Converts a `&str` to `table-case` `String` -/// -/// ``` -/// use inflector::cases::tablecase::to_table_case; -/// let mock_string: &str = "foo-bar"; -/// let expected_string: String = "foo_bars".to_string(); -/// let asserted_string: String = to_table_case(mock_string); -/// assert!(asserted_string == expected_string); -/// ``` -/// -/// ``` -/// use inflector::cases::tablecase::to_table_case; -/// let mock_string: &str = "FOO_BAR"; -/// let expected_string: String = "foo_bars".to_string(); -/// let asserted_string: String = to_table_case(mock_string); -/// assert!(asserted_string == expected_string); -/// ``` -/// -/// ``` -/// use inflector::cases::tablecase::to_table_case; -/// let mock_string: &str = "foo_bar"; -/// let expected_string: String = "foo_bars".to_string(); -/// let asserted_string: String = to_table_case(mock_string); -/// assert!(asserted_string == expected_string); -/// ``` -/// -/// ``` -/// use inflector::cases::tablecase::to_table_case; -/// let mock_string: &str = "Foo Bar"; -/// let expected_string: String = "foo_bars".to_string(); -/// let asserted_string: String = to_table_case(mock_string); -/// assert!(asserted_string == expected_string); -/// ``` -/// -/// ``` -/// use inflector::cases::tablecase::to_table_case; -/// let mock_string: &str = "Foo bar"; -/// let expected_string: String = "foo_bars".to_string(); -/// let asserted_string: String = to_table_case(mock_string); -/// assert!(asserted_string == expected_string); -/// ``` -/// -/// ``` -/// use inflector::cases::tablecase::to_table_case; -/// let mock_string: &str = "FooBar"; -/// let expected_string: String = "foo_bars".to_string(); -/// let asserted_string: String = to_table_case(mock_string); -/// assert!(asserted_string == expected_string); -/// ``` -/// -/// ``` -/// use inflector::cases::tablecase::to_table_case; -/// let mock_string: &str = "fooBar"; -/// let expected_string: String = "foo_bars".to_string(); -/// let asserted_string: String = to_table_case(mock_string); -/// assert!(asserted_string == expected_string); -/// ``` -pub fn to_table_case(non_table_case_string: &str) -> String { - let snaked: String = to_case_snake_like(non_table_case_string, "_", "lower"); - let split: (&str, &str) = snaked.split_at(snaked.rfind('_').unwrap_or(0)); - format!("{}{}", split.0, to_plural(split.1)) -} - -#[cfg(feature = "heavyweight")] -/// Determines if a `&str` is `table-case` -/// -/// ``` -/// use inflector::cases::tablecase::is_table_case; -/// let mock_string: &str = "foo_bar_strings"; -/// let asserted_bool: bool = is_table_case(mock_string); -/// assert!(asserted_bool == true); -/// ``` -/// -/// ``` -/// use inflector::cases::tablecase::is_table_case; -/// let mock_string: &str = "foo-bar-string-that-is-really-really-long"; -/// let asserted_bool: bool = is_table_case(mock_string); -/// assert!(asserted_bool == false); -/// ``` -/// -/// ``` -/// use inflector::cases::tablecase::is_table_case; -/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; -/// let asserted_bool: bool = is_table_case(mock_string); -/// assert!(asserted_bool == false); -/// ``` -/// -/// ``` -/// use inflector::cases::tablecase::is_table_case; -/// let mock_string: &str = "fooBarIsAReallyReallyLongString"; -/// let asserted_bool: bool = is_table_case(mock_string); -/// assert!(asserted_bool == false); -/// ``` -/// -/// ``` -/// use inflector::cases::tablecase::is_table_case; -/// let mock_string: &str = "FOO_BAR_STRING_THAT_IS_REALLY_REALLY_LONG"; -/// let asserted_bool: bool = is_table_case(mock_string); -/// assert!(asserted_bool == false); -/// ``` -/// -/// ``` -/// use inflector::cases::tablecase::is_table_case; -/// let mock_string: &str = "foo_bar_string_that_is_really_really_long"; -/// let asserted_bool: bool = is_table_case(mock_string); -/// assert!(asserted_bool == false); -/// ``` -/// -/// ``` -/// use inflector::cases::tablecase::is_table_case; -/// let mock_string: &str = "Foo bar string that is really really long"; -/// let asserted_bool: bool = is_table_case(mock_string); -/// assert!(asserted_bool == false); -/// ``` -/// -/// ``` -/// use inflector::cases::tablecase::is_table_case; -/// let mock_string: &str = "Foo Bar Is A Really Really Long String"; -/// let asserted_bool: bool = is_table_case(mock_string); -/// assert!(asserted_bool == false); -/// ``` -pub fn is_table_case(test_string: &str) -> bool { - to_table_case(&test_string.clone()) == test_string -} - -#[cfg(all(feature = "unstable", test))] -#[cfg(feature = "heavyweight")] -mod benchmarks { - extern crate test; - use self::test::Bencher; - - #[bench] - fn bench_table_case(b: &mut Bencher) { - b.iter(|| super::to_table_case("Foo bar")); - } - - #[bench] - fn bench_is_table_case(b: &mut Bencher) { - b.iter(|| super::is_table_case("Foo bar")); - } -} - -#[cfg(test)] -#[cfg(feature = "heavyweight")] -mod tests { - use ::to_table_case; - use ::is_table_case; - - #[test] - fn from_camel_case() { - let convertable_string: String = "fooBar".to_owned(); - let expected: String = "foo_bars".to_owned(); - assert_eq!(to_table_case(&convertable_string), expected) - } - - #[test] - fn from_pascal_case() { - let convertable_string: String = "FooBar".to_owned(); - let expected: String = "foo_bars".to_owned(); - assert_eq!(to_table_case(&convertable_string), expected) - } - - #[test] - fn from_kebab_case() { - let convertable_string: String = "foo-bar".to_owned(); - let expected: String = "foo_bars".to_owned(); - assert_eq!(to_table_case(&convertable_string), expected) - } - - #[test] - fn from_sentence_case() { - let convertable_string: String = "Foo bar".to_owned(); - let expected: String = "foo_bars".to_owned(); - assert_eq!(to_table_case(&convertable_string), expected) - } - - #[test] - fn from_title_case() { - let convertable_string: String = "Foo Bar".to_owned(); - let expected: String = "foo_bars".to_owned(); - assert_eq!(to_table_case(&convertable_string), expected) - } - - #[test] - fn from_train_case() { - let convertable_string: String = "Foo-Bar".to_owned(); - let expected: String = "foo_bars".to_owned(); - assert_eq!(to_table_case(&convertable_string), expected) - } - - #[test] - fn from_screaming_snake_case() { - let convertable_string: String = "FOO_BAR".to_owned(); - let expected: String = "foo_bars".to_owned(); - assert_eq!(to_table_case(&convertable_string), expected) - } - - #[test] - fn from_snake_case() { - let convertable_string: String = "foo_bar".to_owned(); - let expected: String = "foo_bars".to_owned(); - assert_eq!(to_table_case(&convertable_string), expected) - } - - #[test] - fn from_table_case() { - let convertable_string: String = "foo_bars".to_owned(); - let expected: String = "foo_bars".to_owned(); - assert_eq!(to_table_case(&convertable_string), expected) - } - - #[test] - fn is_correct_from_camel_case() { - let convertable_string: String = "fooBar".to_owned(); - assert_eq!(is_table_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_pascal_case() { - let convertable_string: String = "FooBar".to_owned(); - assert_eq!(is_table_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_kebab_case() { - let convertable_string: String = "foo-bar".to_owned(); - assert_eq!(is_table_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_sentence_case() { - let convertable_string: String = "Foo bar".to_owned(); - assert_eq!(is_table_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_title_case() { - let convertable_string: String = "Foo Bar".to_owned(); - assert_eq!(is_table_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_train_case() { - let convertable_string: String = "Foo-Bar".to_owned(); - assert_eq!(is_table_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_screaming_snake_case() { - let convertable_string: String = "FOO_BAR".to_owned(); - assert_eq!(is_table_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_snake_case() { - let convertable_string: String = "foo_bar".to_owned(); - assert_eq!(is_table_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_table_case() { - let convertable_string: String = "foo_bars".to_owned(); - assert_eq!(is_table_case(&convertable_string), true) - } -} diff --git a/third_party/rust/Inflector/src/cases/titlecase/mod.rs b/third_party/rust/Inflector/src/cases/titlecase/mod.rs deleted file mode 100644 index eb0de2574484..000000000000 --- a/third_party/rust/Inflector/src/cases/titlecase/mod.rs +++ /dev/null @@ -1,308 +0,0 @@ -#![deny(warnings)] -use cases::case::*; -/// Converts a `&str` to `Title Case` `String` -/// -/// ``` -/// use inflector::cases::titlecase::to_title_case; -/// let mock_string: &str = "Foo bar"; -/// let expected_string: String = "Foo Bar".to_string(); -/// let asserted_string: String = to_title_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::titlecase::to_title_case; -/// let mock_string: &str = "FooBar"; -/// let expected_string: String = "Foo Bar".to_string(); -/// let asserted_string: String = to_title_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::titlecase::to_title_case; -/// let mock_string: &str = "fooBar"; -/// let expected_string: String = "Foo Bar".to_string(); -/// let asserted_string: String = to_title_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::titlecase::to_title_case; -/// let mock_string: &str = "FOO_BAR"; -/// let expected_string: String = "Foo Bar".to_string(); -/// let asserted_string: String = to_title_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::titlecase::to_title_case; -/// let mock_string: &str = "foo_bar"; -/// let expected_string: String = "Foo Bar".to_string(); -/// let asserted_string: String = to_title_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::cases::titlecase::to_title_case; -/// let mock_string: &str = "foo-bar"; -/// let expected_string: String = "Foo Bar".to_string(); -/// let asserted_string: String = to_title_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -pub fn to_title_case(non_title_case_string: &str) -> String { - let options = CamelOptions { - new_word: true, - last_char: ' ', - first_word: true, - injectable_char: ' ', - has_seperator: true, - inverted: false, - }; - to_case_camel_like(non_title_case_string, options) -} - -/// Determines if a `&str` is `Title Case` -/// -/// ``` -/// use inflector::cases::titlecase::is_title_case; -/// let mock_string: &str = "foo-bar-string-that-is-really-really-long"; -/// let asserted_bool: bool = is_title_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::titlecase::is_title_case; -/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; -/// let asserted_bool: bool = is_title_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::titlecase::is_title_case; -/// let mock_string: &str = "fooBarIsAReallyReallyLongString"; -/// let asserted_bool: bool = is_title_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::titlecase::is_title_case; -/// let mock_string: &str = "FOO_BAR_STRING_THAT_IS_REALLY_REALLY_LONG"; -/// let asserted_bool: bool = is_title_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::titlecase::is_title_case; -/// let mock_string: &str = "foo_bar_string_that_is_really_really_long"; -/// let asserted_bool: bool = is_title_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::titlecase::is_title_case; -/// let mock_string: &str = "Foo bar string that is really really long"; -/// let asserted_bool: bool = is_title_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::titlecase::is_title_case; -/// let mock_string: &str = "foo"; -/// let asserted_bool: bool = is_title_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::cases::titlecase::is_title_case; -/// let mock_string: &str = "Foo Bar String That Is Really Really Long"; -/// let asserted_bool: bool = is_title_case(mock_string); -/// assert!(asserted_bool == true); -/// -/// ``` -pub fn is_title_case(test_string: &str) -> bool { - test_string == to_title_case(test_string.clone()) -} - -#[cfg(all(feature = "unstable", test))] -mod benchmarks { - extern crate test; - use self::test::Bencher; - - #[bench] - fn bench_title(b: &mut Bencher) { - b.iter(|| super::to_title_case("Foo BAR")); - } - - #[bench] - fn bench_is_title(b: &mut Bencher) { - b.iter(|| super::is_title_case("Foo bar")); - } - - #[bench] - fn bench_title_from_snake(b: &mut Bencher) { - b.iter(|| super::to_title_case("foo_bar")); - } - -} - - -#[cfg(test)] -mod tests { - use ::to_title_case; - use ::is_title_case; - - #[test] - fn from_camel_case() { - let convertable_string: String = "fooBar".to_owned(); - let expected: String = "Foo Bar".to_owned(); - assert_eq!(to_title_case(&convertable_string), expected) - } - - #[test] - fn from_pascal_case() { - let convertable_string: String = "FooBar".to_owned(); - let expected: String = "Foo Bar".to_owned(); - assert_eq!(to_title_case(&convertable_string), expected) - } - - #[test] - fn from_kebab_case() { - let convertable_string: String = "foo-bar".to_owned(); - let expected: String = "Foo Bar".to_owned(); - assert_eq!(to_title_case(&convertable_string), expected) - } - - #[test] - fn from_sentence_case() { - let convertable_string: String = "Foo bar".to_owned(); - let expected: String = "Foo Bar".to_owned(); - assert_eq!(to_title_case(&convertable_string), expected) - } - - #[test] - fn from_title_case() { - let convertable_string: String = "Foo Bar".to_owned(); - let expected: String = "Foo Bar".to_owned(); - assert_eq!(to_title_case(&convertable_string), expected) - } - - #[test] - fn from_train_case() { - let convertable_string: String = "Foo-Bar".to_owned(); - let expected: String = "Foo Bar".to_owned(); - assert_eq!(to_title_case(&convertable_string), expected) - } - - #[test] - fn from_screaming_snake_case() { - let convertable_string: String = "FOO_BAR".to_owned(); - let expected: String = "Foo Bar".to_owned(); - assert_eq!(to_title_case(&convertable_string), expected) - } - - #[test] - fn from_snake_case() { - let convertable_string: String = "foo_bar".to_owned(); - let expected: String = "Foo Bar".to_owned(); - assert_eq!(to_title_case(&convertable_string), expected) - } - - #[test] - fn from_case_with_loads_of_space() { - let convertable_string: String = "foo bar".to_owned(); - let expected: String = "Foo Bar".to_owned(); - assert_eq!(to_title_case(&convertable_string), expected) - } - - #[test] - fn a_name_with_a_dot() { - let convertable_string: String = "Robert C. Martin".to_owned(); - let expected: String = "Robert C Martin".to_owned(); - assert_eq!(to_title_case(&convertable_string), expected) - } - - #[test] - fn random_text_with_bad_chars() { - let convertable_string: String = "Random text with *(bad) chars".to_owned(); - let expected: String = "Random Text With Bad Chars".to_owned(); - assert_eq!(to_title_case(&convertable_string), expected) - } - - #[test] - fn trailing_bad_chars() { - let convertable_string: String = "trailing bad_chars*(()())".to_owned(); - let expected: String = "Trailing Bad Chars".to_owned(); - assert_eq!(to_title_case(&convertable_string), expected) - } - - #[test] - fn leading_bad_chars() { - let convertable_string: String = "-!#$%leading bad chars".to_owned(); - let expected: String = "Leading Bad Chars".to_owned(); - assert_eq!(to_title_case(&convertable_string), expected) - } - - #[test] - fn wrapped_in_bad_chars() { - let convertable_string: String = "-!#$%wrapped in bad chars&*^*&(&*^&(<>><>))".to_owned(); - let expected: String = "Wrapped In Bad Chars".to_owned(); - assert_eq!(to_title_case(&convertable_string), expected) - } - - #[test] - fn has_a_sign() { - let convertable_string: String = "has a + sign".to_owned(); - let expected: String = "Has A Sign".to_owned(); - assert_eq!(to_title_case(&convertable_string), expected) - } - - #[test] - fn is_correct_from_camel_case() { - let convertable_string: String = "fooBar".to_owned(); - assert_eq!(is_title_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_pascal_case() { - let convertable_string: String = "FooBar".to_owned(); - assert_eq!(is_title_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_kebab_case() { - let convertable_string: String = "foo-bar".to_owned(); - assert_eq!(is_title_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_sentence_case() { - let convertable_string: String = "Foo bar".to_owned(); - assert_eq!(is_title_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_title_case() { - let convertable_string: String = "Foo Bar".to_owned(); - assert_eq!(is_title_case(&convertable_string), true) - } - - #[test] - fn is_correct_from_train_case() { - let convertable_string: String = "Foo-Bar".to_owned(); - assert_eq!(is_title_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_screaming_snake_case() { - let convertable_string: String = "FOO_BAR".to_owned(); - assert_eq!(is_title_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_snake_case() { - let convertable_string: String = "foo_bar".to_owned(); - assert_eq!(is_title_case(&convertable_string), false) - } -} - diff --git a/third_party/rust/Inflector/src/cases/traincase/mod.rs b/third_party/rust/Inflector/src/cases/traincase/mod.rs deleted file mode 100644 index cb2e88281868..000000000000 --- a/third_party/rust/Inflector/src/cases/traincase/mod.rs +++ /dev/null @@ -1,320 +0,0 @@ -#![deny(warnings)] -use cases::case::*; -/// Determines if a `&str` is `Train-Case` -/// -/// ``` -/// use inflector::cases::traincase::is_train_case; -/// let mock_string: &str = "Foo-Bar-String-That-Is-Really-Really-Long"; -/// let asserted_bool: bool = is_train_case(mock_string); -/// assert!(asserted_bool == true); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::traincase::is_train_case; -/// let mock_string: &str = "foo-bar-string-that-is-really-really-long"; -/// let asserted_bool: bool = is_train_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::traincase::is_train_case; -/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; -/// let asserted_bool: bool = is_train_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::traincase::is_train_case; -/// let mock_string: &str = "fooBarIsAReallyReallyLongString"; -/// let asserted_bool: bool = is_train_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::traincase::is_train_case; -/// let mock_string: &str = "foo_bar_string_that_is_really_really_long"; -/// let asserted_bool: bool = is_train_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::traincase::is_train_case; -/// let mock_string: &str = "Foo bar string that is really really long"; -/// let asserted_bool: bool = is_train_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::traincase::is_train_case; -/// let mock_string: &str = "Foo Bar Is A Really Really Long String"; -/// let asserted_bool: bool = is_train_case(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -pub fn is_train_case(test_string: &str) -> bool { - test_string == to_train_case(test_string.clone()) -} - - -/// Converts a `&str` to `Train-Case` `String` -/// -/// ``` -/// use inflector::cases::traincase::to_train_case; -/// let mock_string: &str = "foo-bar"; -/// let expected_string: String = "Foo-Bar".to_string(); -/// let asserted_string: String = to_train_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::traincase::to_train_case; -/// let mock_string: &str = "FOO_BAR"; -/// let expected_string: String = "Foo-Bar".to_string(); -/// let asserted_string: String = to_train_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::traincase::to_train_case; -/// let mock_string: &str = "foo_bar"; -/// let expected_string: String = "Foo-Bar".to_string(); -/// let asserted_string: String = to_train_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::traincase::to_train_case; -/// let mock_string: &str = "Foo Bar"; -/// let expected_string: String = "Foo-Bar".to_string(); -/// let asserted_string: String = to_train_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::traincase::to_train_case; -/// let mock_string: &str = "Foo bar"; -/// let expected_string: String = "Foo-Bar".to_string(); -/// let asserted_string: String = to_train_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::traincase::to_train_case; -/// let mock_string: &str = "FooBar"; -/// let expected_string: String = "Foo-Bar".to_string(); -/// let asserted_string: String = to_train_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// -/// ``` -/// use inflector::cases::traincase::to_train_case; -/// let mock_string: &str = "fooBar"; -/// let expected_string: String = "Foo-Bar".to_string(); -/// let asserted_string: String = to_train_case(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -pub fn to_train_case(non_train_case_string: &str) -> String { - let options = CamelOptions { - new_word: true, - last_char: ' ', - first_word: true, - injectable_char: '-', - has_seperator: true, - inverted: false, - }; - to_case_camel_like(non_train_case_string, options) -} - -#[cfg(all(feature = "unstable", test))] -mod benchmarks { - extern crate test; - use self::test::Bencher; - - #[bench] - fn bench_train(b: &mut Bencher) { - b.iter(|| super::to_train_case("Foo bar")); - } - - #[bench] - fn bench_is_train(b: &mut Bencher) { - b.iter(|| super::is_train_case("Foo bar")); - } - - #[bench] - fn bench_train_from_snake(b: &mut Bencher) { - b.iter(|| super::to_train_case("test_test_test")); - } - -} - -#[cfg(test)] -mod tests { - use ::to_train_case; - use ::is_train_case; - - #[test] - fn from_camel_case() { - let convertable_string: String = "fooBar".to_owned(); - let expected: String = "Foo-Bar".to_owned(); - assert_eq!(to_train_case(&convertable_string), expected) - } - - #[test] - fn from_pascal_case() { - let convertable_string: String = "FooBar".to_owned(); - let expected: String = "Foo-Bar".to_owned(); - assert_eq!(to_train_case(&convertable_string), expected) - } - - #[test] - fn from_kebab_case() { - let convertable_string: String = "foo-bar".to_owned(); - let expected: String = "Foo-Bar".to_owned(); - assert_eq!(to_train_case(&convertable_string), expected) - } - - #[test] - fn from_sentence_case() { - let convertable_string: String = "Foo bar".to_owned(); - let expected: String = "Foo-Bar".to_owned(); - assert_eq!(to_train_case(&convertable_string), expected) - } - - #[test] - fn from_title_case() { - let convertable_string: String = "Foo Bar".to_owned(); - let expected: String = "Foo-Bar".to_owned(); - assert_eq!(to_train_case(&convertable_string), expected) - } - - #[test] - fn from_train_case() { - let convertable_string: String = "Foo-Bar".to_owned(); - let expected: String = "Foo-Bar".to_owned(); - assert_eq!(to_train_case(&convertable_string), expected) - } - - #[test] - fn from_screaming_snake_case() { - let convertable_string: String = "FOO_BAR".to_owned(); - let expected: String = "Foo-Bar".to_owned(); - assert_eq!(to_train_case(&convertable_string), expected) - } - - #[test] - fn from_snake_case() { - let convertable_string: String = "foo_bar".to_owned(); - let expected: String = "Foo-Bar".to_owned(); - assert_eq!(to_train_case(&convertable_string), expected) - } - - #[test] - fn from_case_with_loads_of_space() { - let convertable_string: String = "foo bar".to_owned(); - let expected: String = "Foo-Bar".to_owned(); - assert_eq!(to_train_case(&convertable_string), expected) - } - - #[test] - fn a_name_with_a_dot() { - let convertable_string: String = "Robert C. Martin".to_owned(); - let expected: String = "Robert-C-Martin".to_owned(); - assert_eq!(to_train_case(&convertable_string), expected) - } - - #[test] - fn random_text_with_bad_chars() { - let convertable_string: String = "Random text with *(bad) chars".to_owned(); - let expected: String = "Random-Text-With-Bad-Chars".to_owned(); - assert_eq!(to_train_case(&convertable_string), expected) - } - - #[test] - fn trailing_bad_chars() { - let convertable_string: String = "trailing bad_chars*(()())".to_owned(); - let expected: String = "Trailing-Bad-Chars".to_owned(); - assert_eq!(to_train_case(&convertable_string), expected) - } - - #[test] - fn leading_bad_chars() { - let convertable_string: String = "-!#$%leading bad chars".to_owned(); - let expected: String = "Leading-Bad-Chars".to_owned(); - assert_eq!(to_train_case(&convertable_string), expected) - } - - #[test] - fn wrapped_in_bad_chars() { - let convertable_string: String = "-!#$%wrapped in bad chars&*^*&(&*^&(<>><>))".to_owned(); - let expected: String = "Wrapped-In-Bad-Chars".to_owned(); - assert_eq!(to_train_case(&convertable_string), expected) - } - - #[test] - fn has_a_sign() { - let convertable_string: String = "has a + sign".to_owned(); - let expected: String = "Has-A-Sign".to_owned(); - assert_eq!(to_train_case(&convertable_string), expected) - } - - #[test] - fn is_correct_from_camel_case() { - let convertable_string: String = "fooBar".to_owned(); - assert_eq!(is_train_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_pascal_case() { - let convertable_string: String = "FooBar".to_owned(); - assert_eq!(is_train_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_kebab_case() { - let convertable_string: String = "foo-bar".to_owned(); - assert_eq!(is_train_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_sentence_case() { - let convertable_string: String = "Foo bar".to_owned(); - assert_eq!(is_train_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_title_case() { - let convertable_string: String = "Foo Bar".to_owned(); - assert_eq!(is_train_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_train_case() { - let convertable_string: String = "Foo-Bar".to_owned(); - assert_eq!(is_train_case(&convertable_string), true) - } - - #[test] - fn is_correct_from_screaming_snake_case() { - let convertable_string: String = "FOO_BAR".to_owned(); - assert_eq!(is_train_case(&convertable_string), false) - } - - #[test] - fn is_correct_from_snake_case() { - let convertable_string: String = "foo_bar".to_owned(); - assert_eq!(is_train_case(&convertable_string), false) - } -} diff --git a/third_party/rust/Inflector/src/lib.rs b/third_party/rust/Inflector/src/lib.rs deleted file mode 100644 index f52ea29f40f2..000000000000 --- a/third_party/rust/Inflector/src/lib.rs +++ /dev/null @@ -1,332 +0,0 @@ -#![deny(warnings, unused_variables, missing_docs, unsafe_code, unused_extern_crates)] -#![cfg_attr(feature = "unstable", feature(test))] - -//! Adds String based inflections for Rust. Snake, kebab, train, camel, -//! sentence, class, and title cases as well as ordinalize, -//! deordinalize, demodulize, deconstantize, and foreign key are supported as -//! both traits and pure functions acting on String types. -//! ```rust -//! use inflector::Inflector; -//! let camel_case_string: String = "some_string".to_camel_case(); -//! let is_camel_cased: bool= camel_case_string.is_camel_case(); -//! assert!(is_camel_cased == true); -//! ``` - -#[cfg(feature = "heavyweight")] -extern crate regex; - -#[cfg(feature = "heavyweight")] -#[macro_use] extern crate lazy_static; - -/// Provides case inflections -/// - Camel case -/// - Class case -/// - Kebab case -/// - Train case -/// - Screaming snake case -/// - Table case -/// - Sentence case -/// - Snake case -/// - Pascal case -pub mod cases; -/// Provides number inflections -/// - Ordinalize -/// - Deordinalize -pub mod numbers; -/// Provides suffix inflections -/// - Foreign key -pub mod suffix; -/// Provides string inflections -/// - Deconstantize -/// - Demodulize -/// - Pluralize -/// - Singularize -#[cfg(feature = "heavyweight")] -pub mod string; - - -#[cfg(feature = "heavyweight")] -use cases::classcase::to_class_case; -#[cfg(feature = "heavyweight")] -use cases::classcase::is_class_case; - -use cases::camelcase::to_camel_case; -use cases::camelcase::is_camel_case; - -use cases::pascalcase::to_pascal_case; -use cases::pascalcase::is_pascal_case; - -use cases::snakecase::to_snake_case; -use cases::snakecase::is_snake_case; - -use cases::screamingsnakecase::to_screaming_snake_case; -use cases::screamingsnakecase::is_screaming_snake_case; - -use cases::kebabcase::to_kebab_case; -use cases::kebabcase::is_kebab_case; - -use cases::traincase::to_train_case; -use cases::traincase::is_train_case; - -use cases::sentencecase::to_sentence_case; -use cases::sentencecase::is_sentence_case; - -use cases::titlecase::to_title_case; -use cases::titlecase::is_title_case; - -#[cfg(feature = "heavyweight")] -use cases::tablecase::to_table_case; -#[cfg(feature = "heavyweight")] -use cases::tablecase::is_table_case; - -use numbers::ordinalize::ordinalize; -use numbers::deordinalize::deordinalize; - -use suffix::foreignkey::to_foreign_key; -use suffix::foreignkey::is_foreign_key; - -#[cfg(feature = "heavyweight")] -use string::demodulize::demodulize; -#[cfg(feature = "heavyweight")] -use string::deconstantize::deconstantize; - -#[cfg(feature = "heavyweight")] -use string::pluralize::to_plural; -#[cfg(feature = "heavyweight")] -use string::singularize::to_singular; - -#[allow(missing_docs)] -pub trait Inflector { - - fn to_camel_case(&self) -> String; - fn is_camel_case(&self) -> bool; - - fn to_pascal_case(&self) -> String; - fn is_pascal_case(&self) -> bool; - - fn to_snake_case(&self) -> String; - fn is_snake_case(&self) -> bool; - - fn to_screaming_snake_case(&self) -> String; - fn is_screaming_snake_case(&self) -> bool; - - fn to_kebab_case(&self) -> String; - fn is_kebab_case(&self) -> bool; - - fn to_train_case(&self) -> String; - fn is_train_case(&self) -> bool; - - fn to_sentence_case(&self) -> String; - fn is_sentence_case(&self) -> bool; - - fn to_title_case(&self) -> String; - fn is_title_case(&self) -> bool; - - fn ordinalize(&self) -> String; - fn deordinalize(&self) -> String; - - fn to_foreign_key(&self) -> String; - fn is_foreign_key(&self) -> bool; - - #[cfg(feature = "heavyweight")] - fn demodulize(&self) -> String; - #[cfg(feature = "heavyweight")] - fn deconstantize(&self) -> String; - - #[cfg(feature = "heavyweight")] - fn to_class_case(&self) -> String; - #[cfg(feature = "heavyweight")] - fn is_class_case(&self) -> bool; - - #[cfg(feature = "heavyweight")] - fn to_table_case(&self) -> String; - #[cfg(feature = "heavyweight")] - fn is_table_case(&self) -> bool; - #[cfg(feature = "heavyweight")] - fn to_plural(&self) -> String; - #[cfg(feature = "heavyweight")] - fn to_singular(&self) -> String; -} - - -#[allow(missing_docs)] -pub trait InflectorNumbers { - fn ordinalize(&self) -> String; -} - - -macro_rules! define_implementations { - ( $slf:ident; $($imp_trait:ident => $typ:ident), *) => { - $( - #[inline] - fn $imp_trait(&$slf) -> $typ { - $imp_trait($slf) - } - )* - } -} - -macro_rules! define_number_implementations { - ( $slf:ident; $($imp_trait:ident => $typ:ident), *) => { - $( - #[inline] - fn $imp_trait(&$slf) -> $typ { - $imp_trait(&$slf.to_string()) - } - )* - } -} - -macro_rules! define_gated_implementations { - ( $slf:ident; $($imp_trait:ident => $typ:ident), *) => { - $( - #[inline] - #[cfg(feature = "heavyweight")] - fn $imp_trait(&$slf) -> $typ { - $imp_trait($slf) - } - )* - } -} - -macro_rules! implement_string_for { - ( $trt:ident; $($typ:ident), *) => { - $( - impl $trt for $typ { - define_implementations![self; - to_camel_case => String, - is_camel_case => bool, - to_pascal_case => String, - is_pascal_case => bool, - to_screaming_snake_case => String, - is_screaming_snake_case => bool, - to_snake_case => String, - is_snake_case => bool, - to_kebab_case => String, - is_kebab_case => bool, - to_train_case => String, - is_train_case => bool, - to_sentence_case => String, - is_sentence_case => bool, - to_title_case => String, - is_title_case => bool, - to_foreign_key => String, - is_foreign_key => bool, - ordinalize => String, - deordinalize => String - ]; - define_gated_implementations![self; - to_class_case => String, - is_class_case => bool, - to_table_case => String, - is_table_case => bool, - to_plural => String, - to_singular => String, - demodulize => String, - deconstantize => String - ]; - } - )* - } -} - -macro_rules! implement_number_for { - ( $trt:ident; $($typ:ident), *) => { - $( - impl $trt for $typ { - define_number_implementations![self; - ordinalize => String - ]; - } - )* - } -} - -implement_string_for![ - Inflector; - String, str -]; - -implement_number_for![ - InflectorNumbers; - i8, i16, i32, i64, u8, u16, u32, u64, isize, usize, f32, f64 -]; - -#[cfg(all(feature = "unstable", test))] -mod benchmarks { - extern crate test; - use self::test::Bencher; - use ::Inflector; - - macro_rules! benchmarks { - ( $($test_name:ident => $imp_trait:ident => $to_cast:expr), *) => { - $( - #[bench] - fn $test_name(b: &mut Bencher) { - b.iter(|| { - $to_cast.$imp_trait() - }); - } - )* - } - } - - benchmarks![ - benchmark_str_to_camel => to_camel_case => "foo_bar", - benchmark_str_is_camel => is_camel_case => "fooBar", - benchmark_str_to_screaming_snake => to_screaming_snake_case => "fooBar", - benchmark_str_is_screaming_snake => is_screaming_snake_case => "FOO_BAR", - benchmark_str_to_snake => to_snake_case => "fooBar", - benchmark_str_is_snake => is_snake_case => "foo_bar", - benchmark_str_to_kebab => to_kebab_case => "fooBar", - benchmark_str_is_kebab => is_kebab_case => "foo-bar", - benchmark_str_to_train => to_train_case => "fooBar", - benchmark_str_is_train => is_train_case => "Foo-Bar", - benchmark_str_to_sentence => to_sentence_case => "fooBar", - benchmark_str_is_sentence => is_sentence_case => "Foo bar", - benchmark_str_to_title => to_title_case => "fooBar", - benchmark_str_is_title => is_title_case => "Foo Bar", - benchmark_str_ordinalize => ordinalize => "1", - benchmark_str_deordinalize => deordinalize => "1st", - benchmark_str_to_foreign_key => to_foreign_key => "Foo::Bar", - benchmark_str_is_foreign_key => is_foreign_key => "bar_id", - benchmark_string_to_camel => to_camel_case => "foo_bar".to_string(), - benchmark_string_is_camel => is_camel_case => "fooBar".to_string(), - benchmark_string_to_screaming_snake => to_screaming_snake_case => "fooBar".to_string(), - benchmark_string_is_screaming_snake => is_screaming_snake_case => "FOO_BAR".to_string(), - benchmark_string_to_snake => to_snake_case => "fooBar".to_string(), - benchmark_string_is_snake => is_snake_case => "foo_bar".to_string(), - benchmark_string_to_kebab => to_kebab_case => "fooBar".to_string(), - benchmark_string_is_kebab => is_kebab_case => "foo-bar".to_string(), - benchmark_string_to_train => to_train_case => "fooBar".to_string(), - benchmark_string_is_train => is_train_case => "Foo-Bar".to_string(), - benchmark_string_to_sentence => to_sentence_case => "fooBar".to_string(), - benchmark_string_is_sentence => is_sentence_case => "Foo bar".to_string(), - benchmark_string_to_title => to_title_case => "fooBar".to_string(), - benchmark_string_is_title => is_title_case => "Foo Bar".to_string(), - benchmark_string_ordinalize => ordinalize => "1".to_string(), - benchmark_string_deordinalize => deordinalize => "1st".to_string(), - benchmark_string_to_foreign_key => to_foreign_key => "Foo::Bar".to_string(), - benchmark_string_is_foreign_key => is_foreign_key => "bar_id".to_string() - ]; - - #[cfg(feature = "heavyweight")] - benchmarks![ - benchmark_str_to_class => to_class_case => "foo", - benchmark_str_is_class => is_class_case => "Foo", - benchmark_str_to_table => to_table_case => "fooBar", - benchmark_str_is_table => is_table_case => "foo_bars", - benchmark_str_pluralize => to_plural => "crate", - benchmark_str_singular => to_singular => "crates", - benchmark_string_to_class => to_class_case => "foo".to_string(), - benchmark_string_is_class => is_class_case => "Foo".to_string(), - benchmark_string_to_table => to_table_case => "fooBar".to_string(), - benchmark_string_is_table => is_table_case => "foo_bars".to_string(), - benchmark_string_pluralize => to_plural => "crate".to_string(), - benchmark_string_singular => to_singular => "crates".to_string(), - benchmark_string_demodulize => demodulize => "Foo::Bar".to_string(), - benchmark_string_deconstantize => deconstantize => "Foo::Bar".to_string(), - benchmark_str_demodulize => demodulize => "Foo::Bar", - benchmark_str_deconstantize => deconstantize => "Foo::Bar" - ]; -} diff --git a/third_party/rust/Inflector/src/numbers/deordinalize/mod.rs b/third_party/rust/Inflector/src/numbers/deordinalize/mod.rs deleted file mode 100644 index f64cce1143f1..000000000000 --- a/third_party/rust/Inflector/src/numbers/deordinalize/mod.rs +++ /dev/null @@ -1,117 +0,0 @@ -/// Deorginalizes a `&str` -/// -/// ``` -/// use inflector::numbers::deordinalize::deordinalize; -/// let mock_string: &str = "0.1"; -/// let expected_string: String = "0.1".to_owned(); -/// let asserted_string: String = deordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::deordinalize::deordinalize; -/// let mock_string: &str = "-1st"; -/// let expected_string: String = "-1".to_owned(); -/// let asserted_string: String = deordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::deordinalize::deordinalize; -/// let mock_string: &str = "0th"; -/// let expected_string: String = "0".to_owned(); -/// let asserted_string: String = deordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::deordinalize::deordinalize; -/// let mock_string: &str = "1st"; -/// let expected_string: String = "1".to_owned(); -/// let asserted_string: String = deordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::deordinalize::deordinalize; -/// let mock_string: &str = "2nd"; -/// let expected_string: String = "2".to_owned(); -/// let asserted_string: String = deordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::deordinalize::deordinalize; -/// let mock_string: &str = "3rd"; -/// let expected_string: String = "3".to_owned(); -/// let asserted_string: String = deordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::deordinalize::deordinalize; -/// let mock_string: &str = "9th"; -/// let expected_string: String = "9".to_owned(); -/// let asserted_string: String = deordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::deordinalize::deordinalize; -/// let mock_string: &str = "12th"; -/// let expected_string: String = "12".to_owned(); -/// let asserted_string: String = deordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::deordinalize::deordinalize; -/// let mock_string: &str = "12000th"; -/// let expected_string: String = "12000".to_owned(); -/// let asserted_string: String = deordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::deordinalize::deordinalize; -/// let mock_string: &str = "12001th"; -/// let expected_string: String = "12001".to_owned(); -/// let asserted_string: String = deordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::deordinalize::deordinalize; -/// let mock_string: &str = "12002nd"; -/// let expected_string: String = "12002".to_owned(); -/// let asserted_string: String = deordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::deordinalize::deordinalize; -/// let mock_string: &str = "12003rd"; -/// let expected_string: String = "12003".to_owned(); -/// let asserted_string: String = deordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::deordinalize::deordinalize; -/// let mock_string: &str = "12004th"; -/// let expected_string: String = "12004".to_owned(); -/// let asserted_string: String = deordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -pub fn deordinalize(non_ordinalized_string: &str) -> String { - if non_ordinalized_string.contains('.') { - non_ordinalized_string.to_owned() - } else { - non_ordinalized_string.trim_end_matches("st") - .trim_end_matches("nd") - .trim_end_matches("rd") - .trim_end_matches("th") - .to_owned() - } -} diff --git a/third_party/rust/Inflector/src/numbers/mod.rs b/third_party/rust/Inflector/src/numbers/mod.rs deleted file mode 100644 index f28704f52e8f..000000000000 --- a/third_party/rust/Inflector/src/numbers/mod.rs +++ /dev/null @@ -1,9 +0,0 @@ -#![deny(warnings)] -/// Provides ordinalization of a string. -/// -/// Example string "1" becomes "1st" -pub mod ordinalize; -/// Provides deordinalization of a string. -/// -/// Example string "1st" becomes "1" -pub mod deordinalize; diff --git a/third_party/rust/Inflector/src/numbers/ordinalize/mod.rs b/third_party/rust/Inflector/src/numbers/ordinalize/mod.rs deleted file mode 100644 index 82b0d2d83449..000000000000 --- a/third_party/rust/Inflector/src/numbers/ordinalize/mod.rs +++ /dev/null @@ -1,147 +0,0 @@ -/// Orginalizes a `&str` -/// -/// ``` -/// use inflector::numbers::ordinalize::ordinalize; -/// let mock_string: &str = "a"; -/// let expected_string: String = "a".to_owned(); -/// let asserted_string: String = ordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::ordinalize::ordinalize; -/// let mock_string: &str = "0.1"; -/// let expected_string: String = "0.1".to_owned(); -/// let asserted_string: String = ordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::ordinalize::ordinalize; -/// let mock_string: &str = "-1"; -/// let expected_string: String = "-1st".to_owned(); -/// let asserted_string: String = ordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::ordinalize::ordinalize; -/// let mock_string: &str = "0"; -/// let expected_string: String = "0th".to_owned(); -/// let asserted_string: String = ordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::ordinalize::ordinalize; -/// let mock_string: &str = "1"; -/// let expected_string: String = "1st".to_owned(); -/// let asserted_string: String = ordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::ordinalize::ordinalize; -/// let mock_string: &str = "2"; -/// let expected_string: String = "2nd".to_owned(); -/// let asserted_string: String = ordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::ordinalize::ordinalize; -/// let mock_string: &str = "3"; -/// let expected_string: String = "3rd".to_owned(); -/// let asserted_string: String = ordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::ordinalize::ordinalize; -/// let mock_string: &str = "9"; -/// let expected_string: String = "9th".to_owned(); -/// let asserted_string: String = ordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::ordinalize::ordinalize; -/// let mock_string: &str = "12"; -/// let expected_string: String = "12th".to_owned(); -/// let asserted_string: String = ordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::ordinalize::ordinalize; -/// let mock_string: &str = "12000"; -/// let expected_string: String = "12000th".to_owned(); -/// let asserted_string: String = ordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::ordinalize::ordinalize; -/// let mock_string: &str = "12001"; -/// let expected_string: String = "12001st".to_owned(); -/// let asserted_string: String = ordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::ordinalize::ordinalize; -/// let mock_string: &str = "12002"; -/// let expected_string: String = "12002nd".to_owned(); -/// let asserted_string: String = ordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::ordinalize::ordinalize; -/// let mock_string: &str = "12003"; -/// let expected_string: String = "12003rd".to_owned(); -/// let asserted_string: String = ordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::numbers::ordinalize::ordinalize; -/// let mock_string: &str = "12004"; -/// let expected_string: String = "12004th".to_owned(); -/// let asserted_string: String = ordinalize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -pub fn ordinalize(non_ordinalized_string: &str) -> String { - let chars: Vec = non_ordinalized_string.clone().chars().collect(); - let last_number: char = chars[chars.len() - 1]; - if is_ordinalizable(last_number) { - return non_ordinalized_string.to_owned(); - } - if chars.len() > 1 { - if second_last_number_is_one(chars) { - return format!("{}{}", non_ordinalized_string, "th"); - } else if string_contains_decimal(non_ordinalized_string.to_owned()) { - return non_ordinalized_string.to_owned(); - } - } - match last_number { - '1' => format!("{}{}", non_ordinalized_string, "st"), - '2' => format!("{}{}", non_ordinalized_string, "nd"), - '3' => format!("{}{}", non_ordinalized_string, "rd"), - _ => format!("{}{}", non_ordinalized_string, "th"), - } -} - -fn is_ordinalizable(last_number: char) -> bool { - !last_number.is_numeric() -} - -fn second_last_number_is_one(chars: Vec) -> bool { - let second_last_number: char = chars[chars.len() - 2]; - second_last_number == '1' -} - -fn string_contains_decimal(non_ordinalized_string: String) -> bool { - non_ordinalized_string.contains('.') -} diff --git a/third_party/rust/Inflector/src/string/constants/mod.rs b/third_party/rust/Inflector/src/string/constants/mod.rs deleted file mode 100644 index 0ba4e429f944..000000000000 --- a/third_party/rust/Inflector/src/string/constants/mod.rs +++ /dev/null @@ -1,225 +0,0 @@ -pub const UNACCONTABLE_WORDS: [&'static str; 202] = ["accommodation", - "adulthood", - "advertising", - "advice", - "aggression", - "aid", - "air", - "aircraft", - "alcohol", - "anger", - "applause", - "arithmetic", - "assistance", - "athletics", - - "bacon", - "baggage", - "beef", - "biology", - "blood", - "botany", - "bread", - "butter", - - "carbon", - "cardboard", - "cash", - "chalk", - "chaos", - "chess", - "crossroads", - "countryside", - - "dancing", - "deer", - "dignity", - "dirt", - "dust", - - "economics", - "education", - "electricity", - "engineering", - "enjoyment", - "envy", - "equipment", - "ethics", - "evidence", - "evolution", - - "fame", - "fiction", - "flour", - "flu", - "food", - "fuel", - "fun", - "furniture", - - "gallows", - "garbage", - "garlic", - "genetics", - "gold", - "golf", - "gossip", - "grammar", - "gratitude", - "grief", - "guilt", - "gymnastics", - - "happiness", - "hardware", - "harm", - "hate", - "hatred", - "health", - "heat", - "help", - "homework", - "honesty", - "honey", - "hospitality", - "housework", - "humour", - "hunger", - "hydrogen", - - "ice", - "importance", - "inflation", - "information", - "innocence", - "iron", - "irony", - - "jam", - "jewelry", - "judo", - - "karate", - "knowledge", - - "lack", - "laughter", - "lava", - "leather", - "leisure", - "lightning", - "linguine", - "linguini", - "linguistics", - "literature", - "litter", - "livestock", - "logic", - "loneliness", - "luck", - "luggage", - - "macaroni", - "machinery", - "magic", - "management", - "mankind", - "marble", - "mathematics", - "mayonnaise", - "measles", - "methane", - "milk", - "money", - "mud", - "music", - "mumps", - - "nature", - "news", - "nitrogen", - "nonsense", - "nurture", - "nutrition", - - "obedience", - "obesity", - "oxygen", - - "pasta", - "patience", - "physics", - "poetry", - "pollution", - "poverty", - "pride", - "psychology", - "publicity", - "punctuation", - - "quartz", - - "racism", - "relaxation", - "reliability", - "research", - "respect", - "revenge", - "rice", - "rubbish", - "rum", - - "safety", - "scenery", - "seafood", - "seaside", - "series", - "shame", - "sheep", - "shopping", - "sleep", - "smoke", - "smoking", - "snow", - "soap", - "software", - "soil", - "spaghetti", - "species", - "steam", - "stuff", - "stupidity", - "sunshine", - "symmetry", - - "tennis", - "thirst", - "thunder", - "timber", - "traffic", - "transportation", - "trust", - - "underwear", - "unemployment", - "unity", - - "validity", - "veal", - "vegetation", - "vegetarianism", - "vengeance", - "violence", - "vitality", - - "warmth", - "wealth", - "weather", - "welfare", - "wheat", - "wildlife", - "wisdom", - "yoga", - - "zinc", - "zoology"]; diff --git a/third_party/rust/Inflector/src/string/deconstantize/mod.rs b/third_party/rust/Inflector/src/string/deconstantize/mod.rs deleted file mode 100644 index 5b106e565537..000000000000 --- a/third_party/rust/Inflector/src/string/deconstantize/mod.rs +++ /dev/null @@ -1,50 +0,0 @@ -#[cfg(feature = "heavyweight")] -use cases::classcase::to_class_case; - -#[cfg(feature = "heavyweight")] -/// Deconstantizes a `&str` -/// -/// ``` -/// use inflector::string::deconstantize::deconstantize; -/// let mock_string: &str = "Bar"; -/// let expected_string: String = "".to_owned(); -/// let asserted_string: String = deconstantize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::string::deconstantize::deconstantize; -/// let mock_string: &str = "::Bar"; -/// let expected_string: String = "".to_owned(); -/// let asserted_string: String = deconstantize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::string::deconstantize::deconstantize; -/// let mock_string: &str = "Foo::Bar"; -/// let expected_string: String = "Foo".to_owned(); -/// let asserted_string: String = deconstantize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::string::deconstantize::deconstantize; -/// let mock_string: &str = "Test::Foo::Bar"; -/// let expected_string: String = "Foo".to_owned(); -/// let asserted_string: String = deconstantize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -pub fn deconstantize(non_deconstantized_string: &str) -> String { - if non_deconstantized_string.contains("::") { - let split_string: Vec<&str> = non_deconstantized_string.split("::").collect(); - if split_string.len() > 1 { - to_class_case(split_string[split_string.len() - 2]) - } else { - "".to_owned() - } - } else { - "".to_owned() - } -} diff --git a/third_party/rust/Inflector/src/string/demodulize/mod.rs b/third_party/rust/Inflector/src/string/demodulize/mod.rs deleted file mode 100644 index 5d4bd77168b7..000000000000 --- a/third_party/rust/Inflector/src/string/demodulize/mod.rs +++ /dev/null @@ -1,46 +0,0 @@ -#[cfg(feature = "heavyweight")] -use cases::classcase::to_class_case; - -#[cfg(feature = "heavyweight")] -/// Demodulize a `&str` -/// -/// ``` -/// use inflector::string::demodulize::demodulize; -/// let mock_string: &str = "Bar"; -/// let expected_string: String = "Bar".to_owned(); -/// let asserted_string: String = demodulize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::string::demodulize::demodulize; -/// let mock_string: &str = "::Bar"; -/// let expected_string: String = "Bar".to_owned(); -/// let asserted_string: String = demodulize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::string::demodulize::demodulize; -/// let mock_string: &str = "Foo::Bar"; -/// let expected_string: String = "Bar".to_owned(); -/// let asserted_string: String = demodulize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::string::demodulize::demodulize; -/// let mock_string: &str = "Test::Foo::Bar"; -/// let expected_string: String = "Bar".to_owned(); -/// let asserted_string: String = demodulize(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -pub fn demodulize(non_demodulize_string: &str) -> String { - if non_demodulize_string.contains("::") { - let split_string: Vec<&str> = non_demodulize_string.split("::").collect(); - to_class_case(split_string[split_string.len() - 1]) - } else { - non_demodulize_string.to_owned() - } -} diff --git a/third_party/rust/Inflector/src/string/mod.rs b/third_party/rust/Inflector/src/string/mod.rs deleted file mode 100644 index 72702881d311..000000000000 --- a/third_party/rust/Inflector/src/string/mod.rs +++ /dev/null @@ -1,23 +0,0 @@ -#![deny(warnings)] -/// Provides demodulize a string. -/// -/// Example string `Foo::Bar` becomes `Bar` -#[cfg(feature = "heavyweight")] -pub mod demodulize; -/// Provides deconstantizea string. -/// -/// Example string `Foo::Bar` becomes `Foo` -#[cfg(feature = "heavyweight")] -pub mod deconstantize; -/// Provides conversion to plural strings. -/// -/// Example string `FooBar` -> `FooBars` -#[cfg(feature = "heavyweight")] -pub mod pluralize; -/// Provides conversion to singular strings. -/// -/// Example string `FooBars` -> `FooBar` -#[cfg(feature = "heavyweight")] -pub mod singularize; - -mod constants; diff --git a/third_party/rust/Inflector/src/string/pluralize/mod.rs b/third_party/rust/Inflector/src/string/pluralize/mod.rs deleted file mode 100644 index 1caeea52e584..000000000000 --- a/third_party/rust/Inflector/src/string/pluralize/mod.rs +++ /dev/null @@ -1,194 +0,0 @@ -#![deny(warnings)] -use regex::Regex; -use string::constants::UNACCONTABLE_WORDS; - -macro_rules! add_rule{ - ($r:ident, $rule:expr => $replace:expr) => { - $r.push((Regex::new($rule).unwrap(), $replace)); - } -} - -macro_rules! rules{ - ($r:ident; $($rule:expr => $replace:expr), *) => { - $( - add_rule!{$r, $rule => $replace} - )* - } -} - - -lazy_static!{ - static ref RULES: Vec<(Regex, &'static str)> = { - let mut r = Vec::with_capacity(24); - rules![r; - r"(\w*)s$" => "s", - r"(\w*([^aeiou]ese))$" => "", - r"(\w*(ax|test))is$" => "es", - r"(\w*(alias|[^aou]us|tlas|gas|ris))$" => "es", - r"(\w*(e[mn]u))s?$" => "s", - r"(\w*([^l]ias|[aeiou]las|[emjzr]as|[iu]am))$" => "", - r"(\w*(alumn|syllab|octop|vir|radi|nucle|fung|cact|stimul|termin|bacill|foc|uter|loc|strat))(?:us|i)$" => "i", - r"(\w*(alumn|alg|vertebr))(?:a|ae)$" => "ae", - r"(\w*(seraph|cherub))(?:im)?$" => "im", - r"(\w*(her|at|gr))o$" => "oes", - r"(\w*(agend|addend|millenni|dat|extrem|bacteri|desiderat|strat|candelabr|errat|ov|symposi|curricul|automat|quor))(?:a|um)$" => "a", - r"(\w*(apheli|hyperbat|periheli|asyndet|noumen|phenomen|criteri|organ|prolegomen|hedr|automat))(?:a|on)$" => "a", - r"(\w*)sis$" => "ses", - r"(\w*(kni|wi|li))fe$" => "ves", - r"(\w*(ar|l|ea|eo|oa|hoo))f$" => "ves", - r"(\w*([^aeiouy]|qu))y$" => "ies", - r"(\w*([^ch][ieo][ln]))ey$" => "ies", - r"(\w*(x|ch|ss|sh|zz)es)$" => "", - r"(\w*(x|ch|ss|sh|zz))$" => "es", - r"(\w*(matr|cod|mur|sil|vert|ind|append))(?:ix|ex)$" => "ices", - r"(\w*(m|l)(?:ice|ouse))$" => "ice", - r"(\w*(pe)(?:rson|ople))$" => "ople", - r"(\w*(child))(?:ren)?$" => "ren", - r"(\w*eaux)$" => "" - ]; - r - }; -} - -macro_rules! special_cases{ - ($s:ident, $($singular: expr => $plural:expr), *) => { - match &$s[..] { - $( - $singular => { - return $plural.to_owned(); - }, - )* - _ => () - } - } -} - - -/// Converts a `&str` to pluralized `String` -/// -/// ``` -/// use inflector::string::pluralize::to_plural; -/// let mock_string: &str = "foo_bar"; -/// let expected_string: String = "foo_bars".to_owned(); -/// let asserted_string: String = to_plural(mock_string); -/// assert_eq!(asserted_string, expected_string); -/// -/// ``` -/// ``` -/// use inflector::string::pluralize::to_plural; -/// let mock_string: &str = "ox"; -/// let expected_string: String = "oxen".to_owned(); -/// let asserted_string: String = to_plural(mock_string); -/// assert_eq!(asserted_string, expected_string); -/// -/// ``` -/// ``` -/// use inflector::string::pluralize::to_plural; -/// let mock_string: &str = "crate"; -/// let expected_string: String = "crates".to_owned(); -/// let asserted_string: String = to_plural(mock_string); -/// assert_eq!(asserted_string, expected_string); -/// -/// ``` -/// ``` -/// use inflector::string::pluralize::to_plural; -/// let mock_string: &str = "boxes"; -/// let expected_string: String = "boxes".to_owned(); -/// let asserted_string: String = to_plural(mock_string); -/// assert_eq!(asserted_string, expected_string); -/// -/// ``` -/// ``` -/// use inflector::string::pluralize::to_plural; -/// let mock_string: &str = "vengeance"; -/// let expected_string: String = "vengeance".to_owned(); -/// let asserted_string: String = to_plural(mock_string); -/// assert_eq!(asserted_string, expected_string); -/// -/// ``` -/// ``` -/// use inflector::string::pluralize::to_plural; -/// let mock_string: &str = "yoga"; -/// let expected_string: String = "yoga".to_owned(); -/// let asserted_string: String = to_plural(mock_string); -/// assert_eq!(asserted_string, expected_string); -/// -/// ``` -/// ``` -/// use inflector::string::pluralize::to_plural; -/// let mock_string: &str = "geometry"; -/// let expected_string: String = "geometries".to_owned(); -/// let asserted_string: String = to_plural(mock_string); -/// assert_eq!(asserted_string, expected_string); -/// -/// ``` -/// -pub fn to_plural(non_plural_string: &str) -> String { - if UNACCONTABLE_WORDS.contains(&non_plural_string.as_ref()) { - non_plural_string.to_owned() - } else { - special_cases![non_plural_string, - "ox" => "oxen", - "man" => "men", - "woman" => "women", - "die" => "dice", - "yes" => "yeses", - "foot" => "feet", - "eave" => "eaves", - "goose" => "geese", - "tooth" => "teeth", - "quiz" => "quizzes" - ]; - for &(ref rule, replace) in RULES.iter().rev() { - if let Some(c) = rule.captures(&non_plural_string) { - if let Some(c) = c.get(1) { - return format!("{}{}", c.as_str(), replace); - } - } - } - - format!("{}s", non_plural_string) - } -} - - -#[cfg(test)] -mod tests { - - macro_rules! as_item { - ($i:item) => { $i }; - } - - macro_rules! make_tests{ - ($($singular:ident => $plural:ident); *) =>{ - $( - as_item! { - #[test] - fn $singular(){ - assert_eq!( - stringify!($plural), - super::to_plural(stringify!($singular)) - ); - } - } - )* - } - } - - #[test] - fn boxes() { - assert_eq!("boxes", super::to_plural("box")); - } - - make_tests!{ - geometry => geometries; - ox => oxen; - woman => women; - test => tests; - axis => axes; - knife => knives; - agendum => agenda; - elf => elves; - zoology => zoology - } -} diff --git a/third_party/rust/Inflector/src/string/singularize/mod.rs b/third_party/rust/Inflector/src/string/singularize/mod.rs deleted file mode 100644 index 60e0b51ca7e5..000000000000 --- a/third_party/rust/Inflector/src/string/singularize/mod.rs +++ /dev/null @@ -1,189 +0,0 @@ -use regex::Regex; -use string::constants::UNACCONTABLE_WORDS; - -macro_rules! special_cases{ - ($s:ident, $($singular: expr => $plural:expr), *) => { - match &$s[..] { - $( - $singular => { - return $plural.to_owned(); - }, - )* - _ => () - } - } -} - - -/// Converts a `&str` to singularized `String` -/// -/// ``` -/// use inflector::string::singularize::to_singular; -/// let mock_string: &str = "foo_bars"; -/// let expected_string: String = "foo_bar".to_owned(); -/// let asserted_string: String = to_singular(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::string::singularize::to_singular; -/// let mock_string: &str = "oxen"; -/// let expected_string: String = "ox".to_owned(); -/// let asserted_string: String = to_singular(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::string::singularize::to_singular; -/// let mock_string: &str = "crates"; -/// let expected_string: String = "crate".to_owned(); -/// let asserted_string: String = to_singular(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::string::singularize::to_singular; -/// let mock_string: &str = "oxen"; -/// let expected_string: String = "ox".to_owned(); -/// let asserted_string: String = to_singular(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::string::singularize::to_singular; -/// let mock_string: &str = "boxes"; -/// let expected_string: String = "box".to_owned(); -/// let asserted_string: String = to_singular(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::string::singularize::to_singular; -/// let mock_string: &str = "vengeance"; -/// let expected_string: String = "vengeance".to_owned(); -/// let asserted_string: String = to_singular(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::string::singularize::to_singular; -/// let mock_string: &str = "yoga"; -/// let expected_string: String = "yoga".to_owned(); -/// let asserted_string: String = to_singular(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// -pub fn to_singular(non_singular_string: &str) -> String { - if UNACCONTABLE_WORDS.contains(&non_singular_string.as_ref()) { - non_singular_string.to_owned() - } else { - special_cases![non_singular_string, - "oxen" => "ox", - "boxes" => "box", - "men" => "man", - "women" => "woman", - "dice" => "die", - "yeses" => "yes", - "feet" => "foot", - "eaves" => "eave", - "geese" => "goose", - "teeth" => "tooth", - "quizzes" => "quiz" - ]; - for &(ref rule, replace) in RULES.iter().rev() { - if let Some(captures) = rule.captures(&non_singular_string) { - if let Some(c) = captures.get(1) { - let mut buf = String::new(); - captures.expand(&format!("{}{}", c.as_str(), replace), &mut buf); - return buf; - } - } - } - - format!("{}", non_singular_string) - } -} - -macro_rules! add_rule{ - ($r:ident, $rule:expr => $replace:expr) => { - $r.push((Regex::new($rule).unwrap(), $replace)); - } -} - -macro_rules! rules{ - ($r:ident; $($rule:expr => $replace:expr), *) => { - $( - add_rule!{$r, $rule => $replace} - )* - } -} - - -lazy_static!{ - static ref RULES: Vec<(Regex, &'static str)> = { - let mut r = Vec::with_capacity(27); - rules![r; - r"(\w*)s$" => "", - r"(\w*)(ss)$" => "$2", - r"(n)ews$" => "ews", - r"(\w*)(o)es$" => "", - r"(\w*)([ti])a$" => "um", - r"((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)(sis|ses)$" => "sis", - r"(^analy)(sis|ses)$" => "sis", - r"(\w*)([^f])ves$" => "fe", - r"(\w*)(hive)s$" => "", - r"(\w*)(tive)s$" => "", - r"(\w*)([lr])ves$" => "f", - r"(\w*([^aeiouy]|qu))ies$" => "y", - r"(s)eries$" => "eries", - r"(m)ovies$" => "ovie", - r"(\w*)(x|ch|ss|sh)es$" => "$2", - r"(m|l)ice$" => "ouse", - r"(bus)(es)?$" => "", - r"(shoe)s$" => "", - r"(cris|test)(is|es)$" => "is", - r"^(a)x[ie]s$" => "xis", - r"(octop|vir)(us|i)$" => "us", - r"(alias|status)(es)?$" => "", - r"^(ox)en" => "", - r"(vert|ind)ices$" => "ex", - r"(matr)ices$" => "ix", - r"(quiz)zes$" => "", - r"(database)s$" => "" - ]; - r - }; -} - -#[test] -fn singularize_ies_suffix() { - assert_eq!("reply", to_singular("replies")); - assert_eq!("lady", to_singular("ladies")); - assert_eq!("soliloquy", to_singular("soliloquies")); -} - -#[test] -fn singularize_ss_suffix() { - assert_eq!("glass", to_singular("glass")); - assert_eq!("access", to_singular("access")); - assert_eq!("glass", to_singular("glasses")); - assert_eq!("witch", to_singular("witches")); - assert_eq!("dish", to_singular("dishes")); -} - -#[test] -fn singularize_string_if_a_regex_will_match() { - let expected_string: String = "ox".to_owned(); - let asserted_string: String = to_singular("oxen"); - assert!(expected_string == asserted_string); - -} - -#[test] -fn singularize_string_returns_none_option_if_no_match() { - let expected_string: String = "bacon".to_owned(); - let asserted_string: String = to_singular("bacon"); - - assert!(expected_string == asserted_string); -} diff --git a/third_party/rust/Inflector/src/suffix/foreignkey/mod.rs b/third_party/rust/Inflector/src/suffix/foreignkey/mod.rs deleted file mode 100644 index e46696d4e789..000000000000 --- a/third_party/rust/Inflector/src/suffix/foreignkey/mod.rs +++ /dev/null @@ -1,139 +0,0 @@ -use cases::snakecase::to_snake_case; - -/// Converts a `&str` to a `foreign_key` -/// -/// ``` -/// use inflector::suffix::foreignkey::to_foreign_key; -/// let mock_string: &str = "foo_bar"; -/// let expected_string: String = "foo_bar_id".to_owned(); -/// let asserted_string: String = to_foreign_key(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::suffix::foreignkey::to_foreign_key; -/// let mock_string: &str = "Foo bar"; -/// let expected_string: String = "foo_bar_id".to_owned(); -/// let asserted_string: String = to_foreign_key(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::suffix::foreignkey::to_foreign_key; -/// let mock_string: &str = "Foo Bar"; -/// let expected_string: String = "foo_bar_id".to_owned(); -/// let asserted_string: String = to_foreign_key(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::suffix::foreignkey::to_foreign_key; -/// let mock_string: &str = "Foo::Bar"; -/// let expected_string: String = "bar_id".to_owned(); -/// let asserted_string: String = to_foreign_key(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::suffix::foreignkey::to_foreign_key; -/// let mock_string: &str = "Test::Foo::Bar"; -/// let expected_string: String = "bar_id".to_owned(); -/// let asserted_string: String = to_foreign_key(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::suffix::foreignkey::to_foreign_key; -/// let mock_string: &str = "FooBar"; -/// let expected_string: String = "foo_bar_id".to_owned(); -/// let asserted_string: String = to_foreign_key(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::suffix::foreignkey::to_foreign_key; -/// let mock_string: &str = "fooBar"; -/// let expected_string: String = "foo_bar_id".to_owned(); -/// let asserted_string: String = to_foreign_key(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -/// ``` -/// use inflector::suffix::foreignkey::to_foreign_key; -/// let mock_string: &str = "fooBar3"; -/// let expected_string: String = "foo_bar_3_id".to_owned(); -/// let asserted_string: String = to_foreign_key(mock_string); -/// assert!(asserted_string == expected_string); -/// -/// ``` -pub fn to_foreign_key(non_foreign_key_string: &str) -> String { - if non_foreign_key_string.contains("::") { - let split_string: Vec<&str> = non_foreign_key_string.split("::").collect(); - safe_convert(split_string[split_string.len() - 1]) - } else { - safe_convert(non_foreign_key_string) - } -} -fn safe_convert(safe_string: &str) -> String { - let snake_cased: String = to_snake_case(safe_string); - if snake_cased.ends_with("_id") { - snake_cased - } else { - format!("{}{}", snake_cased, "_id") - } -} - -/// Determines if a `&str` is a `foreign_key` -/// -/// ``` -/// use inflector::suffix::foreignkey::is_foreign_key; -/// let mock_string: &str = "Foo bar string that is really really long"; -/// let asserted_bool: bool = is_foreign_key(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::suffix::foreignkey::is_foreign_key; -/// let mock_string: &str = "foo-bar-string-that-is-really-really-long"; -/// let asserted_bool: bool = is_foreign_key(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::suffix::foreignkey::is_foreign_key; -/// let mock_string: &str = "FooBarIsAReallyReallyLongString"; -/// let asserted_bool: bool = is_foreign_key(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::suffix::foreignkey::is_foreign_key; -/// let mock_string: &str = "Foo Bar Is A Really Really Long String"; -/// let asserted_bool: bool = is_foreign_key(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::suffix::foreignkey::is_foreign_key; -/// let mock_string: &str = "fooBarIsAReallyReallyLongString"; -/// let asserted_bool: bool = is_foreign_key(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::suffix::foreignkey::is_foreign_key; -/// let mock_string: &str = "foo_bar_string_that_is_really_really_long"; -/// let asserted_bool: bool = is_foreign_key(mock_string); -/// assert!(asserted_bool == false); -/// -/// ``` -/// ``` -/// use inflector::suffix::foreignkey::is_foreign_key; -/// let mock_string: &str = "foo_bar_string_that_is_really_really_long_id"; -/// let asserted_bool: bool = is_foreign_key(mock_string); -/// assert!(asserted_bool == true); -/// -/// ``` -pub fn is_foreign_key(test_string: &str) -> bool { - to_foreign_key(test_string.clone()) == test_string -} diff --git a/third_party/rust/Inflector/src/suffix/mod.rs b/third_party/rust/Inflector/src/suffix/mod.rs deleted file mode 100644 index 2083cd5881b5..000000000000 --- a/third_party/rust/Inflector/src/suffix/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -#![deny(warnings)] -/// Provides foreign key conversion for String. -/// -/// Example string `foo` becomes `foo_id` -pub mod foreignkey; diff --git a/third_party/rust/Inflector/tests/lib.rs b/third_party/rust/Inflector/tests/lib.rs deleted file mode 100644 index 62d77f4b324b..000000000000 --- a/third_party/rust/Inflector/tests/lib.rs +++ /dev/null @@ -1,162 +0,0 @@ -#![deny(warnings)] -extern crate inflector; - -use inflector::Inflector; -use inflector::InflectorNumbers; - -macro_rules! str_tests { - ( $($test_name:ident => $imp_trait:ident => $to_cast:expr => $casted:expr), *) => { - $( - #[test] - fn $test_name() { - assert_eq!($to_cast.$imp_trait(), $casted) - } - )* - } -} - -macro_rules! string_tests { - ( $($test_name:ident => $imp_trait:ident => $to_cast:expr => $casted:expr), *) => { - $( - #[test] - fn $test_name() { - assert_eq!($to_cast.to_string().$imp_trait(), $casted) - } - )* - } -} - -macro_rules! number_tests { - ( $($test_name:ident => $imp_trait:ident => $typ:ident => $to_cast:expr => $casted:expr), *) => { - $( - #[test] - fn $test_name() { - let to_cast: $typ = $to_cast; - assert_eq!(to_cast.$imp_trait(), $casted) - } - )* - } -} - -macro_rules! gated_str_tests { - ( $($test_name:ident => $imp_trait:ident => $to_cast:expr => $casted:expr), *) => { - $( - #[test] - #[cfg(feature = "heavyweight")] - fn $test_name() { - assert_eq!($to_cast.$imp_trait(), $casted) - } - )* - } -} - -macro_rules! gated_string_tests { - ( $($test_name:ident => $imp_trait:ident => $to_cast:expr => $casted:expr), *) => { - $( - #[test] - #[cfg(feature = "heavyweight")] - fn $test_name() { - assert_eq!($to_cast.to_string().$imp_trait(), $casted) - } - )* - } -} - -str_tests![ - str_to_camel => to_camel_case => "foo_bar" => "fooBar".to_string(), - str_is_camel => is_camel_case => "fooBar" => true, - str_is_not_camel => is_camel_case => "foo_bar" => false, - str_to_screaming_snake => to_screaming_snake_case => "fooBar" => "FOO_BAR".to_string(), - str_is_screaming_snake => is_screaming_snake_case => "FOO_BAR" => true, - str_is_not_screaming_snake => is_screaming_snake_case => "foo_bar" => false, - str_to_snake => to_snake_case => "fooBar" => "foo_bar".to_string(), - str_is_snake => is_snake_case => "foo_bar" => true, - str_is_not_snake => is_snake_case => "fooBar" => false, - str_to_kebab => to_kebab_case => "fooBar" => "foo-bar".to_string(), - str_is_kebab => is_kebab_case => "foo-bar" => true, - str_is_not_kebab => is_kebab_case => "fooBar" => false, - str_to_train => to_train_case => "fooBar" => "Foo-Bar".to_string(), - str_is_train => is_train_case => "Foo-Bar" => true, - str_is_not_train => is_train_case => "FOO-Bar" => false, - str_to_sentence => to_sentence_case => "fooBar" => "Foo bar".to_string(), - str_is_sentence => is_sentence_case => "Foo bar" => true, - str_is_not_sentence => is_sentence_case => "foo_bar" => false, - str_to_title => to_title_case => "fooBar" => "Foo Bar".to_string(), - str_is_title => is_title_case => "Foo Bar" => true, - str_is_not_title => is_title_case => "Foo_Bar" => false, - str_ordinalize => ordinalize => "1" => "1st".to_string(), - str_deordinalize => deordinalize => "1st" => "1".to_string(), - str_to_foreign_key => to_foreign_key => "Foo::Bar" => "bar_id".to_string(), - str_is_foreign_key => is_foreign_key => "bar_id" => true, - str_is_not_foreign_key => is_foreign_key => "bar" => false -]; - -gated_str_tests![ - str_to_class_case => to_class_case => "foo" => "Foo".to_string(), - str_is_class_case => is_class_case => "Foo" => true, - str_is_not_class_case => is_class_case => "foo" => false, - str_to_table => to_table_case => "fooBar" => "foo_bars".to_string(), - str_is_table => is_table_case => "foo_bars" => true, - str_is_not_table => is_table_case => "fooBars" => false, - str_pluralize => to_plural => "crate" => "crates".to_string(), - str_singular => to_singular => "crates" => "crate".to_string(), - str_demodulize => demodulize => "Foo::Bar" => "Bar".to_string(), - str_deconstantize => deconstantize => "Foo::Bar" => "Foo".to_string() -]; - -string_tests![ - string_to_camel => to_camel_case => "foo_bar".to_string() => "fooBar".to_string(), - string_is_camel => is_camel_case => "fooBar".to_string() => true, - string_is_not_camel => is_camel_case => "foo_bar".to_string() => false, - string_to_screaming_snake => to_screaming_snake_case => "fooBar".to_string() => "FOO_BAR".to_string(), - string_is_screaming_snake => is_screaming_snake_case => "FOO_BAR".to_string() => true, - string_is_not_screaming_snake => is_screaming_snake_case => "foo_bar".to_string() => false, - string_to_snake => to_snake_case => "fooBar".to_string() => "foo_bar".to_string(), - string_is_snake => is_snake_case => "foo_bar".to_string() => true, - string_is_not_snake => is_snake_case => "fooBar".to_string() => false, - string_to_kebab => to_kebab_case => "fooBar".to_string() => "foo-bar".to_string(), - string_is_kebab => is_kebab_case => "foo-bar".to_string() => true, - string_is_not_kebab => is_kebab_case => "fooBar".to_string() => false, - string_to_train => to_train_case => "fooBar".to_string() => "Foo-Bar".to_string(), - string_is_train => is_train_case => "Foo-Bar".to_string() => true, - string_is_not_train => is_train_case => "foo-Bar".to_string() => false, - string_to_sentence => to_sentence_case => "fooBar".to_string() => "Foo bar".to_string(), - string_is_sentence => is_sentence_case => "Foo bar".to_string() => true, - string_is_not_sentence => is_sentence_case => "fooBar".to_string() => false, - string_to_title => to_title_case => "fooBar".to_string() => "Foo Bar".to_string(), - string_is_title => is_title_case => "Foo Bar".to_string() => true, - string_is_not_title => is_title_case => "fooBar".to_string() => false, - string_ordinalize => ordinalize => "1".to_string() => "1st".to_string(), - string_deordinalize => deordinalize => "1st".to_string() => "1".to_string(), - string_to_foreign_key => to_foreign_key => "Foo::Bar".to_string() => "bar_id".to_string(), - string_is_foreign_key => is_foreign_key => "bar_id".to_string() => true, - string_is_not_foreign_key => is_foreign_key => "bar".to_string() => false -]; - -gated_string_tests![ - string_to_class_case => to_class_case => "foo".to_string() => "Foo".to_string(), - string_is_class_case => is_class_case => "Foo".to_string() => true, - string_is_not_class_case => is_class_case => "ooBar".to_string() => false, - string_to_table => to_table_case => "fooBar".to_string() => "foo_bars".to_string(), - string_is_table => is_table_case => "foo_bars".to_string() => true, - string_is_not_table => is_table_case => "fooBar".to_string() => false, - string_pluralize => to_plural => "crate".to_string() => "crates".to_string(), - string_singular => to_singular => "crates".to_string() => "crate".to_string(), - string_demodulize => demodulize => "Foo::Bar".to_string() => "Bar".to_string(), - string_deconstantize => deconstantize => "Foo::Bar".to_string() => "Foo".to_string() -]; - -number_tests![ - i8_ordinalize => ordinalize => i8 => 1 => "1st".to_string(), - i16_ordinalize => ordinalize => i16 => 1 => "1st".to_string(), - i32_ordinalize => ordinalize => i32 => 1 => "1st".to_string(), - i64_ordinalize => ordinalize => i64 => 1 => "1st".to_string(), - u8_ordinalize => ordinalize => u8 => 1 => "1st".to_string(), - u16_ordinalize => ordinalize => u16 => 1 => "1st".to_string(), - u32_ordinalize => ordinalize => u32 => 1 => "1st".to_string(), - u64_ordinalize => ordinalize => u64 => 1 => "1st".to_string(), - isize_ordinalize => ordinalize => isize => 1 => "1st".to_string(), - usize_ordinalize => ordinalize => usize => 1 => "1st".to_string(), - f32_ordinalize => ordinalize => f32 => 1.0 => "1st".to_string(), - f64_ordinalize => ordinalize => f64 => 1.0 => "1st".to_string() -]; diff --git a/third_party/rust/ansi_term/.cargo-checksum.json b/third_party/rust/ansi_term/.cargo-checksum.json deleted file mode 100644 index c1b9d1b6e276..000000000000 --- a/third_party/rust/ansi_term/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"Cargo.toml":"48df4570f3bbfba5b3c19731a54abf70ac8608e4dab6f4dae6a694b18d6ad102","LICENCE":"a24742368cf773bbb8b6f0fcbe86ca4b802c2b7c081bc8bebf14ac38618e7c63","README.md":"779b02ebacd6f4d08e01ef289bd7976a4467054f40355593817fd6df7e8c9dd4","examples/colours.rs":"e4870671adb9574607e37a0e4145643f9047c881c310113de114ec20d76aaf4b","src/ansi.rs":"b8f5de966e7ec2fba7a4d5a373d0aceafe19ea6e20a3f4daaf448e119c989ae7","src/debug.rs":"0ab28b65c39538825707d8b7e81c6f91c78310856c936bba0ee609e06d138543","src/difference.rs":"da68156310cbaf57a3619160d0fb966f496f970c32a2e57601127cc8f54a2fbf","src/display.rs":"a43f19b7cf4d95e90e4f3954399405d8350523d423f0beed9f01399e17527b17","src/lib.rs":"b6df00ab61ca0d82c9f7b3798d516384dd2617fe73e8981f37125ecccc970dd7","src/style.rs":"7c5c2524428f0dfbe3b8d5876ddb81c47d8635704ee31ef63ddeb2429a67f457","src/windows.rs":"3b52469eed89fdc258139e4fd978f0e30c72168863966247df781da8715f0841","src/write.rs":"247c518f8b0c103c970bbe7bc70caba3ee961ab0d37095e2da5c69db98d2fc24"},"package":"ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"} \ No newline at end of file diff --git a/third_party/rust/ansi_term/Cargo.toml b/third_party/rust/ansi_term/Cargo.toml deleted file mode 100644 index 56a7f2d36fa0..000000000000 --- a/third_party/rust/ansi_term/Cargo.toml +++ /dev/null @@ -1,27 +0,0 @@ -# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO -# -# When uploading crates to the registry Cargo will automatically -# "normalize" Cargo.toml files for maximal compatibility -# with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g. crates.io) dependencies -# -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) - -[package] -name = "ansi_term" -version = "0.11.0" -authors = ["ogham@bsago.me", "Ryan Scheel (Havvy) ", "Josh Triplett "] -description = "Library for ANSI terminal colours and styles (bold, underline)" -homepage = "https://github.com/ogham/rust-ansi-term" -documentation = "https://docs.rs/ansi_term" -readme = "README.md" -license = "MIT" - -[lib] -name = "ansi_term" -[target."cfg(target_os=\"windows\")".dependencies.winapi] -version = "0.3.4" -features = ["errhandlingapi", "consoleapi", "processenv"] diff --git a/third_party/rust/ansi_term/LICENCE b/third_party/rust/ansi_term/LICENCE deleted file mode 100644 index 3f39e72bd6be..000000000000 --- a/third_party/rust/ansi_term/LICENCE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Benjamin Sago - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/third_party/rust/ansi_term/README.md b/third_party/rust/ansi_term/README.md deleted file mode 100644 index 1cb56a19a20b..000000000000 --- a/third_party/rust/ansi_term/README.md +++ /dev/null @@ -1,174 +0,0 @@ -# rust-ansi-term [![ansi-term on crates.io](http://meritbadge.herokuapp.com/ansi-term)](https://crates.io/crates/ansi_term) [![Build status](https://travis-ci.org/ogham/rust-ansi-term.svg?branch=master)](https://travis-ci.org/ogham/rust-ansi-term) [![Coverage status](https://coveralls.io/repos/ogham/rust-ansi-term/badge.svg?branch=master&service=github)](https://coveralls.io/github/ogham/rust-ansi-term?branch=master) - -This is a library for controlling colours and formatting, such as red bold text or blue underlined text, on ANSI terminals. - -### [View the Rustdoc](https://docs.rs/ansi_term/0.9.0/ansi_term/) - - -# Installation - -This crate works with [Cargo](http://crates.io). Add the following to your `Cargo.toml` dependencies section: - -```toml -[dependencies] -ansi_term = "0.9" -``` - - -## Basic usage - -There are two main data structures in this crate that you need to be concerned with: `ANSIString` and `Style`. -A `Style` holds stylistic information: colours, whether the text should be bold, or blinking, or whatever. -There are also `Colour` variants that represent simple foreground colour styles. -An `ANSIString` is a string paired with a `Style`. - -(Yes, it’s British English, but you won’t have to write “colour” very often. `Style` is used the majority of the time.) - -To format a string, call the `paint` method on a `Style` or a `Colour`, passing in the string you want to format as the argument. -For example, here’s how to get some red text: - -```rust -use ansi_term::Colour::Red; -println!("This is in red: {}", Red.paint("a red string")); -``` - -It’s important to note that the `paint` method does *not* actually return a string with the ANSI control characters surrounding it. -Instead, it returns an `ANSIString` value that has a `Display` implementation that, when formatted, returns the characters. -This allows strings to be printed with a minimum of `String` allocations being performed behind the scenes. - -If you *do* want to get at the escape codes, then you can convert the `ANSIString` to a string as you would any other `Display` value: - -```rust -use ansi_term::Colour::Red; -use std::string::ToString; -let red_string = Red.paint("a red string").to_string(); -``` - -**Note for Windows 10 users:** On Windows 10, the application must enable ANSI support first: - -```rust -let enabled = ansi_term::enable_ansi_support(); -``` - -## Bold, underline, background, and other styles - -For anything more complex than plain foreground colour changes, you need to construct `Style` objects themselves, rather than beginning with a `Colour`. -You can do this by chaining methods based on a new `Style`, created with `Style::new()`. -Each method creates a new style that has that specific property set. -For example: - -```rust -use ansi_term::Style; -println!("How about some {} and {}?", - Style::new().bold().paint("bold"), - Style::new().underline().paint("underline")); -``` - -For brevity, these methods have also been implemented for `Colour` values, so you can give your styles a foreground colour without having to begin with an empty `Style` value: - -```rust -use ansi_term::Colour::{Blue, Yellow}; -println!("Demonstrating {} and {}!", - Blue.bold().paint("blue bold"), - Yellow.underline().paint("yellow underline")); -println!("Yellow on blue: {}", Yellow.on(Blue).paint("wow!")); -``` - -The complete list of styles you can use are: -`bold`, `dimmed`, `italic`, `underline`, `blink`, `reverse`, `hidden`, and `on` for background colours. - -In some cases, you may find it easier to change the foreground on an existing `Style` rather than starting from the appropriate `Colour`. -You can do this using the `fg` method: - -```rust - use ansi_term::Style; - use ansi_term::Colour::{Blue, Cyan, Yellow}; - println!("Yellow on blue: {}", Style::new().on(Blue).fg(Yellow).paint("yow!")); - println!("Also yellow on blue: {}", Cyan.on(Blue).fg(Yellow).paint("zow!")); -``` - -Finally, you can turn a `Colour` into a `Style` with the `normal` method. -This will produce the exact same `ANSIString` as if you just used the `paint` method on the `Colour` directly, but it’s useful in certain cases: for example, you may have a method that returns `Styles`, and need to represent both the “red bold” and “red, but not bold” styles with values of the same type. The `Style` struct also has a `Default` implementation if you want to have a style with *nothing* set. - -```rust -use ansi_term::Style; -use ansi_term::Colour::Red; -Red.normal().paint("yet another red string"); -Style::default().paint("a completely regular string"); -``` - - -## Extended colours - -You can access the extended range of 256 colours by using the `Fixed` colour variant, which takes an argument of the colour number to use. -This can be included wherever you would use a `Colour`: - -```rust -use ansi_term::Colour::Fixed; -Fixed(134).paint("A sort of light purple"); -Fixed(221).on(Fixed(124)).paint("Mustard in the ketchup"); -``` - -The first sixteen of these values are the same as the normal and bold standard colour variants. -There’s nothing stopping you from using these as `Fixed` colours instead, but there’s nothing to be gained by doing so either. - -You can also access full 24-bit color by using the `RGB` colour variant, which takes separate `u8` arguments for red, green, and blue: - -```rust - use ansi_term::Colour::RGB; - RGB(70, 130, 180).paint("Steel blue"); -``` - -## Combining successive coloured strings - -The benefit of writing ANSI escape codes to the terminal is that they *stack*: you do not need to end every coloured string with a reset code if the text that follows it is of a similar style. -For example, if you want to have some blue text followed by some blue bold text, it’s possible to send the ANSI code for blue, followed by the ANSI code for bold, and finishing with a reset code without having to have an extra one between the two strings. - -This crate can optimise the ANSI codes that get printed in situations like this, making life easier for your terminal renderer. -The `ANSIStrings` struct takes a slice of several `ANSIString` values, and will iterate over each of them, printing only the codes for the styles that need to be updated as part of its formatting routine. - -The following code snippet uses this to enclose a binary number displayed in red bold text inside some red, but not bold, brackets: - -```rust -use ansi_term::Colour::Red; -use ansi_term::{ANSIString, ANSIStrings}; -let some_value = format!("{:b}", 42); -let strings: &[ANSIString<'static>] = &[ - Red.paint("["), - Red.bold().paint(some_value), - Red.paint("]"), -]; -println!("Value: {}", ANSIStrings(strings)); -``` - -There are several things to note here. -Firstly, the `paint` method can take *either* an owned `String` or a borrowed `&str`. -Internally, an `ANSIString` holds a copy-on-write (`Cow`) string value to deal with both owned and borrowed strings at the same time. -This is used here to display a `String`, the result of the `format!` call, using the same mechanism as some statically-available `&str` slices. -Secondly, that the `ANSIStrings` value works in the same way as its singular counterpart, with a `Display` implementation that only performs the formatting when required. - -## Byte strings - -This library also supports formatting `[u8]` byte strings; this supports -applications working with text in an unknown encoding. `Style` and -`Color` support painting `[u8]` values, resulting in an `ANSIByteString`. -This type does not implement `Display`, as it may not contain UTF-8, but -it does provide a method `write_to` to write the result to any -`io::Write`: - -```rust -use ansi_term::Colour::Green; -Green.paint("user data".as_bytes()).write_to(&mut std::io::stdout()).unwrap(); -``` - -Similarly, the type `ANSIByteStrings` supports writing a list of -`ANSIByteString` values with minimal escape sequences: - -```rust -use ansi_term::Colour::Green; -use ansi_term::ANSIByteStrings; -ANSIByteStrings(&[ - Green.paint("user data 1\n".as_bytes()), - Green.bold().paint("user data 2\n".as_bytes()), -]).write_to(&mut std::io::stdout()).unwrap(); -``` diff --git a/third_party/rust/ansi_term/examples/colours.rs b/third_party/rust/ansi_term/examples/colours.rs deleted file mode 100644 index 1870310631ff..000000000000 --- a/third_party/rust/ansi_term/examples/colours.rs +++ /dev/null @@ -1,13 +0,0 @@ -extern crate ansi_term; -use ansi_term::Colour::*; - -fn main() { - println!("{}", Black.paint("Black")); - println!("{}", Red.paint("Red")); - println!("{}", Green.paint("Green")); - println!("{}", Yellow.paint("Yellow")); - println!("{}", Blue.paint("Blue")); - println!("{}", Purple.paint("Purple")); - println!("{}", Cyan.paint("Cyan")); - println!("{}", White.paint("White")); -} diff --git a/third_party/rust/ansi_term/src/ansi.rs b/third_party/rust/ansi_term/src/ansi.rs deleted file mode 100644 index 009043ff7599..000000000000 --- a/third_party/rust/ansi_term/src/ansi.rs +++ /dev/null @@ -1,258 +0,0 @@ -use style::{Colour, Style}; - -use std::fmt; - -use write::AnyWrite; - - -// ---- generating ANSI codes ---- - -impl Style { - - /// Write any ANSI codes that go *before* a piece of text. These should be - /// the codes to set the terminal to a different colour or font style. - fn write_prefix(&self, f: &mut W) -> Result<(), W::Error> { - - // If there are actually no styles here, then don’t write *any* codes - // as the prefix. An empty ANSI code may not affect the terminal - // output at all, but a user may just want a code-free string. - if self.is_plain() { - return Ok(()); - } - - // Write the codes’ prefix, then write numbers, separated by - // semicolons, for each text style we want to apply. - write!(f, "\x1B[")?; - let mut written_anything = false; - - { - let mut write_char = |c| { - if written_anything { write!(f, ";")?; } - written_anything = true; - write!(f, "{}", c)?; - Ok(()) - }; - - if self.is_bold { write_char('1')? } - if self.is_dimmed { write_char('2')? } - if self.is_italic { write_char('3')? } - if self.is_underline { write_char('4')? } - if self.is_blink { write_char('5')? } - if self.is_reverse { write_char('7')? } - if self.is_hidden { write_char('8')? } - if self.is_strikethrough { write_char('9')? } - } - - // The foreground and background colours, if specified, need to be - // handled specially because the number codes are more complicated. - // (see `write_background_code` and `write_foreground_code`) - if let Some(bg) = self.background { - if written_anything { write!(f, ";")?; } - written_anything = true; - bg.write_background_code(f)?; - } - - if let Some(fg) = self.foreground { - if written_anything { write!(f, ";")?; } - fg.write_foreground_code(f)?; - } - - // All the codes end with an `m`, because reasons. - write!(f, "m")?; - - Ok(()) - } - - /// Write any ANSI codes that go *after* a piece of text. These should be - /// the codes to *reset* the terminal back to its normal colour and style. - fn write_suffix(&self, f: &mut W) -> Result<(), W::Error> { - if self.is_plain() { - Ok(()) - } - else { - write!(f, "{}", RESET) - } - } -} - - -/// The code to send to reset all styles and return to `Style::default()`. -pub static RESET: &str = "\x1B[0m"; - - - -impl Colour { - fn write_foreground_code(&self, f: &mut W) -> Result<(), W::Error> { - match *self { - Colour::Black => write!(f, "30"), - Colour::Red => write!(f, "31"), - Colour::Green => write!(f, "32"), - Colour::Yellow => write!(f, "33"), - Colour::Blue => write!(f, "34"), - Colour::Purple => write!(f, "35"), - Colour::Cyan => write!(f, "36"), - Colour::White => write!(f, "37"), - Colour::Fixed(num) => write!(f, "38;5;{}", &num), - Colour::RGB(r,g,b) => write!(f, "38;2;{};{};{}", &r, &g, &b), - } - } - - fn write_background_code(&self, f: &mut W) -> Result<(), W::Error> { - match *self { - Colour::Black => write!(f, "40"), - Colour::Red => write!(f, "41"), - Colour::Green => write!(f, "42"), - Colour::Yellow => write!(f, "43"), - Colour::Blue => write!(f, "44"), - Colour::Purple => write!(f, "45"), - Colour::Cyan => write!(f, "46"), - Colour::White => write!(f, "47"), - Colour::Fixed(num) => write!(f, "48;5;{}", &num), - Colour::RGB(r,g,b) => write!(f, "48;2;{};{};{}", &r, &g, &b), - } - } -} - - -/// Like `ANSIString`, but only displays the style prefix. -#[derive(Clone, Copy, Debug)] -pub struct Prefix(Style); - -/// Like `ANSIString`, but only displays the difference between two -/// styles. -#[derive(Clone, Copy, Debug)] -pub struct Infix(Style, Style); - -/// Like `ANSIString`, but only displays the style suffix. -#[derive(Clone, Copy, Debug)] -pub struct Suffix(Style); - - -impl Style { - - /// The prefix for this style. - pub fn prefix(self) -> Prefix { - Prefix(self) - } - - /// The infix between this style and another. - pub fn infix(self, other: Style) -> Infix { - Infix(self, other) - } - - /// The suffix for this style. - pub fn suffix(self) -> Suffix { - Suffix(self) - } -} - - -impl Colour { - - /// The prefix for this colour. - pub fn prefix(self) -> Prefix { - Prefix(self.normal()) - } - - /// The infix between this colour and another. - pub fn infix(self, other: Colour) -> Infix { - Infix(self.normal(), other.normal()) - } - - /// The suffix for this colour. - pub fn suffix(self) -> Suffix { - Suffix(self.normal()) - } -} - - -impl fmt::Display for Prefix { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let f: &mut fmt::Write = f; - self.0.write_prefix(f) - } -} - - -impl fmt::Display for Infix { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - use difference::Difference; - - match Difference::between(&self.0, &self.1) { - Difference::ExtraStyles(style) => { - let f: &mut fmt::Write = f; - style.write_prefix(f) - }, - Difference::Reset => { - let f: &mut fmt::Write = f; - write!(f, "{}{}", RESET, self.0.prefix()) - }, - Difference::NoDifference => { - Ok(()) // nothing to write - }, - } - } -} - - -impl fmt::Display for Suffix { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let f: &mut fmt::Write = f; - self.0.write_suffix(f) - } -} - - - -#[cfg(test)] -mod test { - use style::Style; - use style::Colour::*; - - macro_rules! test { - ($name: ident: $style: expr; $input: expr => $result: expr) => { - #[test] - fn $name() { - assert_eq!($style.paint($input).to_string(), $result.to_string()); - - let mut v = Vec::new(); - $style.paint($input.as_bytes()).write_to(&mut v).unwrap(); - assert_eq!(v.as_slice(), $result.as_bytes()); - } - }; - } - - test!(plain: Style::default(); "text/plain" => "text/plain"); - test!(red: Red; "hi" => "\x1B[31mhi\x1B[0m"); - test!(black: Black.normal(); "hi" => "\x1B[30mhi\x1B[0m"); - test!(yellow_bold: Yellow.bold(); "hi" => "\x1B[1;33mhi\x1B[0m"); - test!(yellow_bold_2: Yellow.normal().bold(); "hi" => "\x1B[1;33mhi\x1B[0m"); - test!(blue_underline: Blue.underline(); "hi" => "\x1B[4;34mhi\x1B[0m"); - test!(green_bold_ul: Green.bold().underline(); "hi" => "\x1B[1;4;32mhi\x1B[0m"); - test!(green_bold_ul_2: Green.underline().bold(); "hi" => "\x1B[1;4;32mhi\x1B[0m"); - test!(purple_on_white: Purple.on(White); "hi" => "\x1B[47;35mhi\x1B[0m"); - test!(purple_on_white_2: Purple.normal().on(White); "hi" => "\x1B[47;35mhi\x1B[0m"); - test!(yellow_on_blue: Style::new().on(Blue).fg(Yellow); "hi" => "\x1B[44;33mhi\x1B[0m"); - test!(yellow_on_blue_2: Cyan.on(Blue).fg(Yellow); "hi" => "\x1B[44;33mhi\x1B[0m"); - test!(cyan_bold_on_white: Cyan.bold().on(White); "hi" => "\x1B[1;47;36mhi\x1B[0m"); - test!(cyan_ul_on_white: Cyan.underline().on(White); "hi" => "\x1B[4;47;36mhi\x1B[0m"); - test!(cyan_bold_ul_on_white: Cyan.bold().underline().on(White); "hi" => "\x1B[1;4;47;36mhi\x1B[0m"); - test!(cyan_ul_bold_on_white: Cyan.underline().bold().on(White); "hi" => "\x1B[1;4;47;36mhi\x1B[0m"); - test!(fixed: Fixed(100); "hi" => "\x1B[38;5;100mhi\x1B[0m"); - test!(fixed_on_purple: Fixed(100).on(Purple); "hi" => "\x1B[45;38;5;100mhi\x1B[0m"); - test!(fixed_on_fixed: Fixed(100).on(Fixed(200)); "hi" => "\x1B[48;5;200;38;5;100mhi\x1B[0m"); - test!(rgb: RGB(70,130,180); "hi" => "\x1B[38;2;70;130;180mhi\x1B[0m"); - test!(rgb_on_blue: RGB(70,130,180).on(Blue); "hi" => "\x1B[44;38;2;70;130;180mhi\x1B[0m"); - test!(blue_on_rgb: Blue.on(RGB(70,130,180)); "hi" => "\x1B[48;2;70;130;180;34mhi\x1B[0m"); - test!(rgb_on_rgb: RGB(70,130,180).on(RGB(5,10,15)); "hi" => "\x1B[48;2;5;10;15;38;2;70;130;180mhi\x1B[0m"); - test!(bold: Style::new().bold(); "hi" => "\x1B[1mhi\x1B[0m"); - test!(underline: Style::new().underline(); "hi" => "\x1B[4mhi\x1B[0m"); - test!(bunderline: Style::new().bold().underline(); "hi" => "\x1B[1;4mhi\x1B[0m"); - test!(dimmed: Style::new().dimmed(); "hi" => "\x1B[2mhi\x1B[0m"); - test!(italic: Style::new().italic(); "hi" => "\x1B[3mhi\x1B[0m"); - test!(blink: Style::new().blink(); "hi" => "\x1B[5mhi\x1B[0m"); - test!(reverse: Style::new().reverse(); "hi" => "\x1B[7mhi\x1B[0m"); - test!(hidden: Style::new().hidden(); "hi" => "\x1B[8mhi\x1B[0m"); - test!(stricken: Style::new().strikethrough(); "hi" => "\x1B[9mhi\x1B[0m"); - -} diff --git a/third_party/rust/ansi_term/src/debug.rs b/third_party/rust/ansi_term/src/debug.rs deleted file mode 100644 index da30c625cd08..000000000000 --- a/third_party/rust/ansi_term/src/debug.rs +++ /dev/null @@ -1,122 +0,0 @@ -use std::fmt; - -use style::Style; - - -/// Styles have a special `Debug` implementation that only shows the fields that -/// are set. Fields that haven’t been touched aren’t included in the output. -/// -/// This behaviour gets bypassed when using the alternate formatting mode -/// `format!("{:#?}")`. -/// -/// use ansi_term::Colour::{Red, Blue}; -/// assert_eq!("Style { fg(Red), on(Blue), bold, italic }", -/// format!("{:?}", Red.on(Blue).bold().italic())); -impl fmt::Debug for Style { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - if fmt.alternate() { - fmt.debug_struct("Style") - .field("foreground", &self.foreground) - .field("background", &self.background) - .field("blink", &self.is_blink) - .field("bold", &self.is_bold) - .field("dimmed", &self.is_dimmed) - .field("hidden", &self.is_hidden) - .field("italic", &self.is_italic) - .field("reverse", &self.is_reverse) - .field("strikethrough", &self.is_strikethrough) - .field("underline", &self.is_underline) - .finish() - } - else if self.is_plain() { - fmt.write_str("Style {}") - } - else { - fmt.write_str("Style { ")?; - - let mut written_anything = false; - - if let Some(fg) = self.foreground { - if written_anything { fmt.write_str(", ")? } - written_anything = true; - write!(fmt, "fg({:?})", fg)? - } - - if let Some(bg) = self.background { - if written_anything { fmt.write_str(", ")? } - written_anything = true; - write!(fmt, "on({:?})", bg)? - } - - { - let mut write_flag = |name| { - if written_anything { fmt.write_str(", ")? } - written_anything = true; - fmt.write_str(name) - }; - - if self.is_blink { write_flag("blink")? } - if self.is_bold { write_flag("bold")? } - if self.is_dimmed { write_flag("dimmed")? } - if self.is_hidden { write_flag("hidden")? } - if self.is_italic { write_flag("italic")? } - if self.is_reverse { write_flag("reverse")? } - if self.is_strikethrough { write_flag("strikethrough")? } - if self.is_underline { write_flag("underline")? } - } - - write!(fmt, " }}") - } - } -} - - -#[cfg(test)] -mod test { - use style::Colour::*; - use style::Style; - - fn style() -> Style { - Style::new() - } - - macro_rules! test { - ($name: ident: $obj: expr => $result: expr) => { - #[test] - fn $name() { - assert_eq!($result, format!("{:?}", $obj)); - } - }; - } - - test!(empty: style() => "Style {}"); - test!(bold: style().bold() => "Style { bold }"); - test!(italic: style().italic() => "Style { italic }"); - test!(both: style().bold().italic() => "Style { bold, italic }"); - - test!(red: Red.normal() => "Style { fg(Red) }"); - test!(redblue: Red.normal().on(RGB(3, 2, 4)) => "Style { fg(Red), on(RGB(3, 2, 4)) }"); - - test!(everything: - Red.on(Blue).blink().bold().dimmed().hidden().italic().reverse().strikethrough().underline() => - "Style { fg(Red), on(Blue), blink, bold, dimmed, hidden, italic, reverse, strikethrough, underline }"); - - #[test] - fn long_and_detailed() { - let debug = r##"Style { - foreground: Some( - Blue - ), - background: None, - blink: false, - bold: true, - dimmed: false, - hidden: false, - italic: false, - reverse: false, - strikethrough: false, - underline: false -}"##; - assert_eq!(debug, format!("{:#?}", Blue.bold())); - } -} diff --git a/third_party/rust/ansi_term/src/difference.rs b/third_party/rust/ansi_term/src/difference.rs deleted file mode 100644 index 571574634fda..000000000000 --- a/third_party/rust/ansi_term/src/difference.rs +++ /dev/null @@ -1,179 +0,0 @@ -use super::Style; - - -/// When printing out one coloured string followed by another, use one of -/// these rules to figure out which *extra* control codes need to be sent. -#[derive(PartialEq, Clone, Copy, Debug)] -pub enum Difference { - - /// Print out the control codes specified by this style to end up looking - /// like the second string's styles. - ExtraStyles(Style), - - /// Converting between these two is impossible, so just send a reset - /// command and then the second string's styles. - Reset, - - /// The before style is exactly the same as the after style, so no further - /// control codes need to be printed. - NoDifference, -} - - -impl Difference { - - /// Compute the 'style difference' required to turn an existing style into - /// the given, second style. - /// - /// For example, to turn green text into green bold text, it's redundant - /// to write a reset command then a second green+bold command, instead of - /// just writing one bold command. This method should see that both styles - /// use the foreground colour green, and reduce it to a single command. - /// - /// This method returns an enum value because it's not actually always - /// possible to turn one style into another: for example, text could be - /// made bold and underlined, but you can't remove the bold property - /// without also removing the underline property. So when this has to - /// happen, this function returns None, meaning that the entire set of - /// styles should be reset and begun again. - pub fn between(first: &Style, next: &Style) -> Difference { - use self::Difference::*; - - // XXX(Havvy): This algorithm is kind of hard to replicate without - // having the Plain/Foreground enum variants, so I'm just leaving - // it commented out for now, and defaulting to Reset. - - if first == next { - return NoDifference; - } - - // Cannot un-bold, so must Reset. - if first.is_bold && !next.is_bold { - return Reset; - } - - if first.is_dimmed && !next.is_dimmed { - return Reset; - } - - if first.is_italic && !next.is_italic { - return Reset; - } - - // Cannot un-underline, so must Reset. - if first.is_underline && !next.is_underline { - return Reset; - } - - if first.is_blink && !next.is_blink { - return Reset; - } - - if first.is_reverse && !next.is_reverse { - return Reset; - } - - if first.is_hidden && !next.is_hidden { - return Reset; - } - - if first.is_strikethrough && !next.is_strikethrough { - return Reset; - } - - // Cannot go from foreground to no foreground, so must Reset. - if first.foreground.is_some() && next.foreground.is_none() { - return Reset; - } - - // Cannot go from background to no background, so must Reset. - if first.background.is_some() && next.background.is_none() { - return Reset; - } - - let mut extra_styles = Style::default(); - - if first.is_bold != next.is_bold { - extra_styles.is_bold = true; - } - - if first.is_dimmed != next.is_dimmed { - extra_styles.is_dimmed = true; - } - - if first.is_italic != next.is_italic { - extra_styles.is_italic = true; - } - - if first.is_underline != next.is_underline { - extra_styles.is_underline = true; - } - - if first.is_blink != next.is_blink { - extra_styles.is_blink = true; - } - - if first.is_reverse != next.is_reverse { - extra_styles.is_reverse = true; - } - - if first.is_hidden != next.is_hidden { - extra_styles.is_hidden = true; - } - - if first.is_strikethrough != next.is_strikethrough { - extra_styles.is_strikethrough = true; - } - - if first.foreground != next.foreground { - extra_styles.foreground = next.foreground; - } - - if first.background != next.background { - extra_styles.background = next.background; - } - - ExtraStyles(extra_styles) - } -} - - -#[cfg(test)] -mod test { - use super::*; - use super::Difference::*; - use style::Colour::*; - use style::Style; - - fn style() -> Style { - Style::new() - } - - macro_rules! test { - ($name: ident: $first: expr; $next: expr => $result: expr) => { - #[test] - fn $name() { - assert_eq!($result, Difference::between(&$first, &$next)); - } - }; - } - - test!(nothing: Green.normal(); Green.normal() => NoDifference); - test!(uppercase: Green.normal(); Green.bold() => ExtraStyles(style().bold())); - test!(lowercase: Green.bold(); Green.normal() => Reset); - test!(nothing2: Green.bold(); Green.bold() => NoDifference); - - test!(colour_change: Red.normal(); Blue.normal() => ExtraStyles(Blue.normal())); - - test!(addition_of_blink: style(); style().blink() => ExtraStyles(style().blink())); - test!(addition_of_dimmed: style(); style().dimmed() => ExtraStyles(style().dimmed())); - test!(addition_of_hidden: style(); style().hidden() => ExtraStyles(style().hidden())); - test!(addition_of_reverse: style(); style().reverse() => ExtraStyles(style().reverse())); - test!(addition_of_strikethrough: style(); style().strikethrough() => ExtraStyles(style().strikethrough())); - - test!(removal_of_strikethrough: style().strikethrough(); style() => Reset); - test!(removal_of_reverse: style().reverse(); style() => Reset); - test!(removal_of_hidden: style().hidden(); style() => Reset); - test!(removal_of_dimmed: style().dimmed(); style() => Reset); - test!(removal_of_blink: style().blink(); style() => Reset); -} diff --git a/third_party/rust/ansi_term/src/display.rs b/third_party/rust/ansi_term/src/display.rs deleted file mode 100644 index 8314ab85fad2..000000000000 --- a/third_party/rust/ansi_term/src/display.rs +++ /dev/null @@ -1,279 +0,0 @@ -use std::borrow::Cow; -use std::fmt; -use std::io; -use std::ops::Deref; - -use ansi::RESET; -use difference::Difference; -use style::{Style, Colour}; -use write::AnyWrite; - - -/// An `ANSIGenericString` includes a generic string type and a `Style` to -/// display that string. `ANSIString` and `ANSIByteString` are aliases for -/// this type on `str` and `[u8]`, respectively. -#[derive(PartialEq, Debug)] -pub struct ANSIGenericString<'a, S: 'a + ToOwned + ?Sized> -where ::Owned: fmt::Debug { - style: Style, - string: Cow<'a, S>, -} - - -/// Cloning an `ANSIGenericString` will clone its underlying string. -/// -/// ### Examples -/// -/// ``` -/// use ansi_term::ANSIString; -/// -/// let plain_string = ANSIString::from("a plain string"); -/// let clone_string = plain_string.clone(); -/// assert_eq!(clone_string, plain_string); -/// ``` -impl<'a, S: 'a + ToOwned + ?Sized> Clone for ANSIGenericString<'a, S> -where ::Owned: fmt::Debug { - fn clone(&self) -> ANSIGenericString<'a, S> { - ANSIGenericString { - style: self.style, - string: self.string.clone(), - } - } -} - -// You might think that the hand-written Clone impl above is the same as the -// one that gets generated with #[derive]. But it’s not *quite* the same! -// -// `str` is not Clone, and the derived Clone implementation puts a Clone -// constraint on the S type parameter (generated using --pretty=expanded): -// -// ↓_________________↓ -// impl <'a, S: ::std::clone::Clone + 'a + ToOwned + ?Sized> ::std::clone::Clone -// for ANSIGenericString<'a, S> where -// ::Owned: fmt::Debug { ... } -// -// This resulted in compile errors when you tried to derive Clone on a type -// that used it: -// -// #[derive(PartialEq, Debug, Clone, Default)] -// pub struct TextCellContents(Vec>); -// ^^^^^^^^^^^^^^^^^^^^^^^^^ -// error[E0277]: the trait `std::clone::Clone` is not implemented for `str` -// -// The hand-written impl above can ignore that constraint and still compile. - - - -/// An ANSI String is a string coupled with the `Style` to display it -/// in a terminal. -/// -/// Although not technically a string itself, it can be turned into -/// one with the `to_string` method. -/// -/// ### Examples -/// -/// ```no_run -/// use ansi_term::ANSIString; -/// use ansi_term::Colour::Red; -/// -/// let red_string = Red.paint("a red string"); -/// println!("{}", red_string); -/// ``` -/// -/// ``` -/// use ansi_term::ANSIString; -/// -/// let plain_string = ANSIString::from("a plain string"); -/// assert_eq!(&*plain_string, "a plain string"); -/// ``` -pub type ANSIString<'a> = ANSIGenericString<'a, str>; - -/// An `ANSIByteString` represents a formatted series of bytes. Use -/// `ANSIByteString` when styling text with an unknown encoding. -pub type ANSIByteString<'a> = ANSIGenericString<'a, [u8]>; - -impl<'a, I, S: 'a + ToOwned + ?Sized> From for ANSIGenericString<'a, S> -where I: Into>, - ::Owned: fmt::Debug { - fn from(input: I) -> ANSIGenericString<'a, S> { - ANSIGenericString { - string: input.into(), - style: Style::default(), - } - } -} - -impl<'a, S: 'a + ToOwned + ?Sized> Deref for ANSIGenericString<'a, S> -where ::Owned: fmt::Debug { - type Target = S; - - fn deref(&self) -> &S { - self.string.deref() - } -} - - -/// A set of `ANSIGenericString`s collected together, in order to be -/// written with a minimum of control characters. -pub struct ANSIGenericStrings<'a, S: 'a + ToOwned + ?Sized> - (pub &'a [ANSIGenericString<'a, S>]) - where ::Owned: fmt::Debug; - -/// A set of `ANSIString`s collected together, in order to be written with a -/// minimum of control characters. -pub type ANSIStrings<'a> = ANSIGenericStrings<'a, str>; - -/// A function to construct an `ANSIStrings` instance. -#[allow(non_snake_case)] -pub fn ANSIStrings<'a>(arg: &'a [ANSIString<'a>]) -> ANSIStrings<'a> { - ANSIGenericStrings(arg) -} - -/// A set of `ANSIByteString`s collected together, in order to be -/// written with a minimum of control characters. -pub type ANSIByteStrings<'a> = ANSIGenericStrings<'a, [u8]>; - -/// A function to construct an `ANSIByteStrings` instance. -#[allow(non_snake_case)] -pub fn ANSIByteStrings<'a>(arg: &'a [ANSIByteString<'a>]) -> ANSIByteStrings<'a> { - ANSIGenericStrings(arg) -} - - -// ---- paint functions ---- - -impl Style { - - /// Paints the given text with this colour, returning an ANSI string. - pub fn paint<'a, I, S: 'a + ToOwned + ?Sized>(self, input: I) -> ANSIGenericString<'a, S> - where I: Into>, - ::Owned: fmt::Debug { - ANSIGenericString { - string: input.into(), - style: self, - } - } -} - - -impl Colour { - - /// Paints the given text with this colour, returning an ANSI string. - /// This is a short-cut so you don’t have to use `Blue.normal()` just - /// to get blue text. - /// - /// ``` - /// use ansi_term::Colour::Blue; - /// println!("{}", Blue.paint("da ba dee")); - /// ``` - pub fn paint<'a, I, S: 'a + ToOwned + ?Sized>(self, input: I) -> ANSIGenericString<'a, S> - where I: Into>, - ::Owned: fmt::Debug { - ANSIGenericString { - string: input.into(), - style: self.normal(), - } - } -} - - -// ---- writers for individual ANSI strings ---- - -impl<'a> fmt::Display for ANSIString<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let w: &mut fmt::Write = f; - self.write_to_any(w) - } -} - -impl<'a> ANSIByteString<'a> { - /// Write an `ANSIByteString` to an `io::Write`. This writes the escape - /// sequences for the associated `Style` around the bytes. - pub fn write_to(&self, w: &mut W) -> io::Result<()> { - let w: &mut io::Write = w; - self.write_to_any(w) - } -} - -impl<'a, S: 'a + ToOwned + ?Sized> ANSIGenericString<'a, S> -where ::Owned: fmt::Debug, &'a S: AsRef<[u8]> { - fn write_to_any + ?Sized>(&self, w: &mut W) -> Result<(), W::Error> { - write!(w, "{}", self.style.prefix())?; - w.write_str(self.string.as_ref())?; - write!(w, "{}", self.style.suffix()) - } -} - - -// ---- writers for combined ANSI strings ---- - -impl<'a> fmt::Display for ANSIStrings<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - let f: &mut fmt::Write = f; - self.write_to_any(f) - } -} - -impl<'a> ANSIByteStrings<'a> { - /// Write `ANSIByteStrings` to an `io::Write`. This writes the minimal - /// escape sequences for the associated `Style`s around each set of - /// bytes. - pub fn write_to(&self, w: &mut W) -> io::Result<()> { - let w: &mut io::Write = w; - self.write_to_any(w) - } -} - -impl<'a, S: 'a + ToOwned + ?Sized> ANSIGenericStrings<'a, S> -where ::Owned: fmt::Debug, &'a S: AsRef<[u8]> { - fn write_to_any + ?Sized>(&self, w: &mut W) -> Result<(), W::Error> { - use self::Difference::*; - - let first = match self.0.first() { - None => return Ok(()), - Some(f) => f, - }; - - write!(w, "{}", first.style.prefix())?; - w.write_str(first.string.as_ref())?; - - for window in self.0.windows(2) { - match Difference::between(&window[0].style, &window[1].style) { - ExtraStyles(style) => write!(w, "{}", style.prefix())?, - Reset => write!(w, "{}{}", RESET, window[1].style.prefix())?, - NoDifference => {/* Do nothing! */}, - } - - w.write_str(&window[1].string)?; - } - - // Write the final reset string after all of the ANSIStrings have been - // written, *except* if the last one has no styles, because it would - // have already been written by this point. - if let Some(last) = self.0.last() { - if !last.style.is_plain() { - write!(w, "{}", RESET)?; - } - } - - Ok(()) - } -} - - -// ---- tests ---- - -#[cfg(test)] -mod tests { - pub use super::super::ANSIStrings; - pub use style::Style; - pub use style::Colour::*; - - #[test] - fn no_control_codes_for_plain() { - let one = Style::default().paint("one"); - let two = Style::default().paint("two"); - let output = format!("{}", ANSIStrings( &[ one, two ] )); - assert_eq!(&*output, "onetwo"); - } -} diff --git a/third_party/rust/ansi_term/src/lib.rs b/third_party/rust/ansi_term/src/lib.rs deleted file mode 100644 index f2a676a1c5e8..000000000000 --- a/third_party/rust/ansi_term/src/lib.rs +++ /dev/null @@ -1,205 +0,0 @@ -//! This is a library for controlling colours and formatting, such as -//! red bold text or blue underlined text, on ANSI terminals. -//! -//! -//! ## Basic usage -//! -//! There are two main data structures in this crate that you need to be -//! concerned with: `ANSIString` and `Style`. A `Style` holds stylistic -//! information: colours, whether the text should be bold, or blinking, or -//! whatever. There are also `Colour` variants that represent simple foreground -//! colour styles. An `ANSIString` is a string paired with a `Style`. -//! -//! (Yes, it’s British English, but you won’t have to write “colour” very often. -//! `Style` is used the majority of the time.) -//! -//! To format a string, call the `paint` method on a `Style` or a `Colour`, -//! passing in the string you want to format as the argument. For example, -//! here’s how to get some red text: -//! -//! use ansi_term::Colour::Red; -//! println!("This is in red: {}", Red.paint("a red string")); -//! -//! It’s important to note that the `paint` method does *not* actually return a -//! string with the ANSI control characters surrounding it. Instead, it returns -//! an `ANSIString` value that has a `Display` implementation that, when -//! formatted, returns the characters. This allows strings to be printed with a -//! minimum of `String` allocations being performed behind the scenes. -//! -//! If you *do* want to get at the escape codes, then you can convert the -//! `ANSIString` to a string as you would any other `Display` value: -//! -//! use ansi_term::Colour::Red; -//! use std::string::ToString; -//! let red_string = Red.paint("a red string").to_string(); -//! -//! -//! ## Bold, underline, background, and other styles -//! -//! For anything more complex than plain foreground colour changes, you need to -//! construct `Style` objects themselves, rather than beginning with a `Colour`. -//! You can do this by chaining methods based on a new `Style`, created with -//! `Style::new()`. Each method creates a new style that has that specific -//! property set. For example: -//! -//! use ansi_term::Style; -//! println!("How about some {} and {}?", -//! Style::new().bold().paint("bold"), -//! Style::new().underline().paint("underline")); -//! -//! For brevity, these methods have also been implemented for `Colour` values, -//! so you can give your styles a foreground colour without having to begin with -//! an empty `Style` value: -//! -//! use ansi_term::Colour::{Blue, Yellow}; -//! println!("Demonstrating {} and {}!", -//! Blue.bold().paint("blue bold"), -//! Yellow.underline().paint("yellow underline")); -//! println!("Yellow on blue: {}", Yellow.on(Blue).paint("wow!")); -//! -//! The complete list of styles you can use are: `bold`, `dimmed`, `italic`, -//! `underline`, `blink`, `reverse`, `hidden`, `strikethrough`, and `on` for -//! background colours. -//! -//! In some cases, you may find it easier to change the foreground on an -//! existing `Style` rather than starting from the appropriate `Colour`. -//! You can do this using the `fg` method: -//! -//! use ansi_term::Style; -//! use ansi_term::Colour::{Blue, Cyan, Yellow}; -//! println!("Yellow on blue: {}", Style::new().on(Blue).fg(Yellow).paint("yow!")); -//! println!("Also yellow on blue: {}", Cyan.on(Blue).fg(Yellow).paint("zow!")); -//! -//! Finally, you can turn a `Colour` into a `Style` with the `normal` method. -//! This will produce the exact same `ANSIString` as if you just used the -//! `paint` method on the `Colour` directly, but it’s useful in certain cases: -//! for example, you may have a method that returns `Styles`, and need to -//! represent both the “red bold” and “red, but not bold” styles with values of -//! the same type. The `Style` struct also has a `Default` implementation if you -//! want to have a style with *nothing* set. -//! -//! use ansi_term::Style; -//! use ansi_term::Colour::Red; -//! Red.normal().paint("yet another red string"); -//! Style::default().paint("a completely regular string"); -//! -//! -//! ## Extended colours -//! -//! You can access the extended range of 256 colours by using the `Fixed` colour -//! variant, which takes an argument of the colour number to use. This can be -//! included wherever you would use a `Colour`: -//! -//! use ansi_term::Colour::Fixed; -//! Fixed(134).paint("A sort of light purple"); -//! Fixed(221).on(Fixed(124)).paint("Mustard in the ketchup"); -//! -//! The first sixteen of these values are the same as the normal and bold -//! standard colour variants. There’s nothing stopping you from using these as -//! `Fixed` colours instead, but there’s nothing to be gained by doing so -//! either. -//! -//! You can also access full 24-bit color by using the `RGB` colour variant, -//! which takes separate `u8` arguments for red, green, and blue: -//! -//! use ansi_term::Colour::RGB; -//! RGB(70, 130, 180).paint("Steel blue"); -//! -//! ## Combining successive coloured strings -//! -//! The benefit of writing ANSI escape codes to the terminal is that they -//! *stack*: you do not need to end every coloured string with a reset code if -//! the text that follows it is of a similar style. For example, if you want to -//! have some blue text followed by some blue bold text, it’s possible to send -//! the ANSI code for blue, followed by the ANSI code for bold, and finishing -//! with a reset code without having to have an extra one between the two -//! strings. -//! -//! This crate can optimise the ANSI codes that get printed in situations like -//! this, making life easier for your terminal renderer. The `ANSIStrings` -//! struct takes a slice of several `ANSIString` values, and will iterate over -//! each of them, printing only the codes for the styles that need to be updated -//! as part of its formatting routine. -//! -//! The following code snippet uses this to enclose a binary number displayed in -//! red bold text inside some red, but not bold, brackets: -//! -//! use ansi_term::Colour::Red; -//! use ansi_term::{ANSIString, ANSIStrings}; -//! let some_value = format!("{:b}", 42); -//! let strings: &[ANSIString<'static>] = &[ -//! Red.paint("["), -//! Red.bold().paint(some_value), -//! Red.paint("]"), -//! ]; -//! println!("Value: {}", ANSIStrings(strings)); -//! -//! There are several things to note here. Firstly, the `paint` method can take -//! *either* an owned `String` or a borrowed `&str`. Internally, an `ANSIString` -//! holds a copy-on-write (`Cow`) string value to deal with both owned and -//! borrowed strings at the same time. This is used here to display a `String`, -//! the result of the `format!` call, using the same mechanism as some -//! statically-available `&str` slices. Secondly, that the `ANSIStrings` value -//! works in the same way as its singular counterpart, with a `Display` -//! implementation that only performs the formatting when required. -//! -//! ## Byte strings -//! -//! This library also supports formatting `[u8]` byte strings; this supports -//! applications working with text in an unknown encoding. `Style` and -//! `Color` support painting `[u8]` values, resulting in an `ANSIByteString`. -//! This type does not implement `Display`, as it may not contain UTF-8, but -//! it does provide a method `write_to` to write the result to any -//! `io::Write`: -//! -//! use ansi_term::Colour::Green; -//! Green.paint("user data".as_bytes()).write_to(&mut std::io::stdout()).unwrap(); -//! -//! Similarly, the type `ANSIByteStrings` supports writing a list of -//! `ANSIByteString` values with minimal escape sequences: -//! -//! use ansi_term::Colour::Green; -//! use ansi_term::ANSIByteStrings; -//! ANSIByteStrings(&[ -//! Green.paint("user data 1\n".as_bytes()), -//! Green.bold().paint("user data 2\n".as_bytes()), -//! ]).write_to(&mut std::io::stdout()).unwrap(); - - -#![crate_name = "ansi_term"] -#![crate_type = "rlib"] -#![crate_type = "dylib"] - -#![warn(missing_copy_implementations)] -#![warn(missing_docs)] -#![warn(trivial_casts, trivial_numeric_casts)] -#![warn(unused_extern_crates, unused_qualifications)] - -#[cfg(target_os="windows")] -extern crate winapi; - -mod ansi; -pub use ansi::{Prefix, Infix, Suffix}; - -mod style; -pub use style::{Colour, Style}; - -/// Color is a type alias for Colour for those who can't be bothered. -pub use Colour as Color; - -// I'm not beyond calling Colour Colour, rather than Color, but I did -// purposefully name this crate 'ansi-term' so people wouldn't get -// confused when they tried to install it. -// -// Only *after* they'd installed it. - -mod difference; -mod display; -pub use display::*; - -mod write; - -mod windows; -pub use windows::*; - -mod debug; diff --git a/third_party/rust/ansi_term/src/style.rs b/third_party/rust/ansi_term/src/style.rs deleted file mode 100644 index b9fb52326a1b..000000000000 --- a/third_party/rust/ansi_term/src/style.rs +++ /dev/null @@ -1,259 +0,0 @@ -/// A style is a collection of properties that can format a string -/// using ANSI escape codes. -#[derive(PartialEq, Clone, Copy)] -pub struct Style { - - /// The style's foreground colour, if it has one. - pub foreground: Option, - - /// The style's background colour, if it has one. - pub background: Option, - - /// Whether this style is bold. - pub is_bold: bool, - - /// Whether this style is dimmed. - pub is_dimmed: bool, - - /// Whether this style is italic. - pub is_italic: bool, - - /// Whether this style is underlined. - pub is_underline: bool, - - /// Whether this style is blinking. - pub is_blink: bool, - - /// Whether this style has reverse colours. - pub is_reverse: bool, - - /// Whether this style is hidden. - pub is_hidden: bool, - - /// Whether this style is struckthrough. - pub is_strikethrough: bool -} - -impl Style { - /// Creates a new Style with no differences. - pub fn new() -> Style { - Style::default() - } - - /// Returns a `Style` with the bold property set. - pub fn bold(&self) -> Style { - Style { is_bold: true, .. *self } - } - - /// Returns a `Style` with the dimmed property set. - pub fn dimmed(&self) -> Style { - Style { is_dimmed: true, .. *self } - } - - /// Returns a `Style` with the italic property set. - pub fn italic(&self) -> Style { - Style { is_italic: true, .. *self } - } - - /// Returns a `Style` with the underline property set. - pub fn underline(&self) -> Style { - Style { is_underline: true, .. *self } - } - - /// Returns a `Style` with the blink property set. - pub fn blink(&self) -> Style { - Style { is_blink: true, .. *self } - } - - /// Returns a `Style` with the reverse property set. - pub fn reverse(&self) -> Style { - Style { is_reverse: true, .. *self } - } - - /// Returns a `Style` with the hidden property set. - pub fn hidden(&self) -> Style { - Style { is_hidden: true, .. *self } - } - - /// Returns a `Style` with the hidden property set. - pub fn strikethrough(&self) -> Style { - Style { is_strikethrough: true, .. *self } - } - - /// Returns a `Style` with the foreground colour property set. - pub fn fg(&self, foreground: Colour) -> Style { - Style { foreground: Some(foreground), .. *self } - } - - /// Returns a `Style` with the background colour property set. - pub fn on(&self, background: Colour) -> Style { - Style { background: Some(background), .. *self } - } - - /// Return true if this `Style` has no actual styles, and can be written - /// without any control characters. - pub fn is_plain(self) -> bool { - self == Style::default() - } -} - -impl Default for Style { - - /// Returns a style with *no* properties set. Formatting text using this - /// style returns the exact same text. - /// - /// ``` - /// use ansi_term::Style; - /// assert_eq!(None, Style::default().foreground); - /// assert_eq!(None, Style::default().background); - /// assert_eq!(false, Style::default().is_bold); - /// assert_eq!("txt", Style::default().paint("txt").to_string()); - /// ``` - fn default() -> Style { - Style { - foreground: None, - background: None, - is_bold: false, - is_dimmed: false, - is_italic: false, - is_underline: false, - is_blink: false, - is_reverse: false, - is_hidden: false, - is_strikethrough: false, - } - } -} - - -// ---- colours ---- - -/// A colour is one specific type of ANSI escape code, and can refer -/// to either the foreground or background colour. -/// -/// These use the standard numeric sequences. -/// See -#[derive(PartialEq, Clone, Copy, Debug)] -pub enum Colour { - - /// Colour #0 (foreground code `30`, background code `40`). - /// - /// This is not necessarily the background colour, and using it as one may - /// render the text hard to read on terminals with dark backgrounds. - Black, - - /// Colour #1 (foreground code `31`, background code `41`). - Red, - - /// Colour #2 (foreground code `32`, background code `42`). - Green, - - /// Colour #3 (foreground code `33`, background code `43`). - Yellow, - - /// Colour #4 (foreground code `34`, background code `44`). - Blue, - - /// Colour #5 (foreground code `35`, background code `45`). - Purple, - - /// Colour #6 (foreground code `36`, background code `46`). - Cyan, - - /// Colour #7 (foreground code `37`, background code `47`). - /// - /// As above, this is not necessarily the foreground colour, and may be - /// hard to read on terminals with light backgrounds. - White, - - /// A colour number from 0 to 255, for use in 256-colour terminal - /// environments. - /// - /// - Colours 0 to 7 are the `Black` to `White` variants respectively. - /// These colours can usually be changed in the terminal emulator. - /// - Colours 8 to 15 are brighter versions of the eight colours above. - /// These can also usually be changed in the terminal emulator, or it - /// could be configured to use the original colours and show the text in - /// bold instead. It varies depending on the program. - /// - Colours 16 to 231 contain several palettes of bright colours, - /// arranged in six squares measuring six by six each. - /// - Colours 232 to 255 are shades of grey from black to white. - /// - /// It might make more sense to look at a [colour chart][cc]. - /// - /// [cc]: https://upload.wikimedia.org/wikipedia/en/1/15/Xterm_256color_chart.svg - Fixed(u8), - - /// A 24-bit RGB color, as specified by ISO-8613-3. - RGB(u8, u8, u8), -} - - -impl Colour { - /// Return a `Style` with the foreground colour set to this colour. - pub fn normal(self) -> Style { - Style { foreground: Some(self), .. Style::default() } - } - - /// Returns a `Style` with the bold property set. - pub fn bold(self) -> Style { - Style { foreground: Some(self), is_bold: true, .. Style::default() } - } - - /// Returns a `Style` with the dimmed property set. - pub fn dimmed(self) -> Style { - Style { foreground: Some(self), is_dimmed: true, .. Style::default() } - } - - /// Returns a `Style` with the italic property set. - pub fn italic(self) -> Style { - Style { foreground: Some(self), is_italic: true, .. Style::default() } - } - - /// Returns a `Style` with the underline property set. - pub fn underline(self) -> Style { - Style { foreground: Some(self), is_underline: true, .. Style::default() } - } - - /// Returns a `Style` with the blink property set. - pub fn blink(self) -> Style { - Style { foreground: Some(self), is_blink: true, .. Style::default() } - } - - /// Returns a `Style` with the reverse property set. - pub fn reverse(self) -> Style { - Style { foreground: Some(self), is_reverse: true, .. Style::default() } - } - - /// Returns a `Style` with the hidden property set. - pub fn hidden(self) -> Style { - Style { foreground: Some(self), is_hidden: true, .. Style::default() } - } - - /// Returns a `Style` with the strikethrough property set. - pub fn strikethrough(self) -> Style { - Style { foreground: Some(self), is_strikethrough: true, .. Style::default() } - } - - /// Returns a `Style` with the background colour property set. - pub fn on(self, background: Colour) -> Style { - Style { foreground: Some(self), background: Some(background), .. Style::default() } - } -} - -impl From for Style { - - /// You can turn a `Colour` into a `Style` with the foreground colour set - /// with the `From` trait. - /// - /// ``` - /// use ansi_term::{Style, Colour}; - /// let green_foreground = Style::default().fg(Colour::Green); - /// assert_eq!(green_foreground, Colour::Green.normal()); - /// assert_eq!(green_foreground, Colour::Green.into()); - /// assert_eq!(green_foreground, Style::from(Colour::Green)); - /// ``` - fn from(colour: Colour) -> Style { - colour.normal() - } -} diff --git a/third_party/rust/ansi_term/src/windows.rs b/third_party/rust/ansi_term/src/windows.rs deleted file mode 100644 index ff6fa683d8ba..000000000000 --- a/third_party/rust/ansi_term/src/windows.rs +++ /dev/null @@ -1,40 +0,0 @@ -/// Enables ANSI code support on Windows 10. -/// -/// This uses Windows API calls to alter the properties of the console that -/// the program is running in. -/// -/// https://msdn.microsoft.com/en-us/library/windows/desktop/mt638032(v=vs.85).aspx -/// -/// Returns a `Result` with the Windows error code if unsuccessful. -#[cfg(windows)] -pub fn enable_ansi_support() -> Result<(), u32> { - use winapi::um::processenv::GetStdHandle; - use winapi::um::errhandlingapi::GetLastError; - use winapi::um::consoleapi::{GetConsoleMode, SetConsoleMode}; - - const STD_OUT_HANDLE: u32 = -11i32 as u32; - const ENABLE_VIRTUAL_TERMINAL_PROCESSING: u32 = 0x0004; - - unsafe { - // https://docs.microsoft.com/en-us/windows/console/getstdhandle - let std_out_handle = GetStdHandle(STD_OUT_HANDLE); - let error_code = GetLastError(); - if error_code != 0 { return Err(error_code); } - - // https://docs.microsoft.com/en-us/windows/console/getconsolemode - let mut console_mode: u32 = 0; - GetConsoleMode(std_out_handle, &mut console_mode); - let error_code = GetLastError(); - if error_code != 0 { return Err(error_code); } - - // VT processing not already enabled? - if console_mode & ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0 { - // https://docs.microsoft.com/en-us/windows/console/setconsolemode - SetConsoleMode(std_out_handle, console_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING); - let error_code = GetLastError(); - if error_code != 0 { return Err(error_code); } - } - } - - return Ok(()); -} diff --git a/third_party/rust/ansi_term/src/write.rs b/third_party/rust/ansi_term/src/write.rs deleted file mode 100644 index bb146ac1567a..000000000000 --- a/third_party/rust/ansi_term/src/write.rs +++ /dev/null @@ -1,40 +0,0 @@ -use std::fmt; -use std::io; - - -pub trait AnyWrite { - type wstr: ?Sized; - type Error; - - fn write_fmt(&mut self, fmt: fmt::Arguments) -> Result<(), Self::Error>; - - fn write_str(&mut self, s: &Self::wstr) -> Result<(), Self::Error>; -} - - -impl<'a> AnyWrite for fmt::Write + 'a { - type wstr = str; - type Error = fmt::Error; - - fn write_fmt(&mut self, fmt: fmt::Arguments) -> Result<(), Self::Error> { - fmt::Write::write_fmt(self, fmt) - } - - fn write_str(&mut self, s: &Self::wstr) -> Result<(), Self::Error> { - fmt::Write::write_str(self, s) - } -} - - -impl<'a> AnyWrite for io::Write + 'a { - type wstr = [u8]; - type Error = io::Error; - - fn write_fmt(&mut self, fmt: fmt::Arguments) -> Result<(), Self::Error> { - io::Write::write_fmt(self, fmt) - } - - fn write_str(&mut self, s: &Self::wstr) -> Result<(), Self::Error> { - io::Write::write_all(self, s) - } -} diff --git a/third_party/rust/binjs_meta/.cargo-checksum.json b/third_party/rust/binjs_meta/.cargo-checksum.json deleted file mode 100644 index bcf84681a5c7..000000000000 --- a/third_party/rust/binjs_meta/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"Cargo.lock":"c4f860261c1fd22b88a416ddc2546fde7ac6b8d0ee584979b2cc930709840edd","Cargo.toml":"9fd70e5e3152c11487347f14f4f2703486e3de3a1c9f0249f6196ca3b0308511","README.md":"17e5ed3a3bd9b898e73c3056711daabe1238fe9682d24d255f8263fae4eb783d","examples/generate_spidermonkey.rs":"913a34e84f45bd8bbe305629ca5abb2818370333a769074a757ce1bb4bb54778","src/export.rs":"12d94158d1285ac880e3c105f086ad1c22c3c55432fdc3123f8f2ab4ccc71152","src/import.rs":"2f587c0737310e3b50280e0b62069de2bfa585d0812e2f0eb469cdada8502291","src/lib.rs":"546b6b13669d659d35a130dd29cfe3eac547a41d210adb194db1b214194295d7","src/spec.rs":"9adb6ff0168e3ec29735a5a9198756076385b6f6063883e47190846f46fa7247","src/util.rs":"9b19ace8cfc0e47e6090ba9223123eba0214d05c1969414272b6785b25de36d2"},"package":"d535cc5246fd9035268770420afd76c05f87e68b83ebed0ac94e8258e88fc353"} \ No newline at end of file diff --git a/third_party/rust/binjs_meta/Cargo.lock b/third_party/rust/binjs_meta/Cargo.lock deleted file mode 100644 index 5bd270096842..000000000000 --- a/third_party/rust/binjs_meta/Cargo.lock +++ /dev/null @@ -1,315 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "Inflector" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "aho-corasick" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "ansi_term" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "atty" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", - "termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "binjs_meta" -version = "0.5.4" -dependencies = [ - "Inflector 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)", - "clap 2.30.0 (registry+https://github.com/rust-lang/crates.io-index)", - "env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", - "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "weedle 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", - "yaml-rust 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "bitflags" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "cfg-if" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "clap" -version = "2.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", - "atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", - "textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", - "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", - "vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "either" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "env_logger" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", - "humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", - "termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "humantime" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "itertools" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "lazy_static" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "libc" -version = "0.2.36" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "linked-hash-map" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "log" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "memchr" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "nom" -version = "5.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "redox_syscall" -version = "0.1.37" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "redox_termios" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "regex" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)", - "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", - "regex-syntax 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)", - "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "regex-syntax" -version = "0.6.16" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "strsim" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "termcolor" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "termion" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", - "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "textwrap" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "thread_local" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "unicode-width" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "utf8-ranges" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "vec_map" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "version_check" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "weedle" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "nom 5.1.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "winapi-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "yaml-rust" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -dependencies = [ - "linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", -] - -[metadata] -"checksum Inflector 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)" = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" -"checksum aho-corasick 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "d6531d44de723825aa81398a6415283229725a00fa30713812ab9323faa82fc4" -"checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455" -"checksum atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8352656fd42c30a0c3c89d26dea01e3b77c0ab2af18230835c15e2e13cd51859" -"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf" -"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de" -"checksum clap 2.30.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1c07b9257a00f3fc93b7f3c417fc15607ec7a56823bc2c37ec744e266387de5b" -"checksum either 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "740178ddf48b1a9e878e6d6509a1442a2d42fd2928aae8e7a6f8a36fb01981b3" -"checksum env_logger 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "aafcde04e90a5226a6443b7aabdb016ba2f8307c847d524724bd9b346dd1a2d3" -"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" -"checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484" -"checksum lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c8f31047daa365f19be14b47c29df4f7c3b581832407daabe6ae77397619237d" -"checksum libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "1e5d97d6708edaa407429faa671b942dc0f2727222fb6b6539bf1db936e4b121" -"checksum linked-hash-map 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "70fb39025bc7cdd76305867c4eccf2f2dcf6e9a57f5b21a93e1c2d86cd03ec9e" -"checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2" -"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d" -"checksum nom 5.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b471253da97532da4b61552249c521e01e736071f71c1a4f7ebbfbf0a06aad6" -"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" -"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd" -"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" -"checksum regex 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3d8c9f33201f46669484bacc312b00e7541bed6aaf296dffe2bb4e0ac6b8ce2a" -"checksum regex-syntax 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "1132f845907680735a84409c3bebc64d1364a5683ffbce899550cd09d5eaefc1" -"checksum strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb4f380125926a99e52bc279241539c018323fab05ad6368b56f93d9369ff550" -"checksum termcolor 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" -"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096" -"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693" -"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" -"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f" -"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122" -"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c" -"checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" -"checksum weedle 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8a7d4f9feb723a800d8f7b74edc9fa44ff35cb0b2ec64886714362f423427f37" -"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3" -"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -"checksum winapi-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80" -"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -"checksum yaml-rust 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "57ab38ee1a4a266ed033496cf9af1828d8d6e6c1cfa5f643a2809effcae4d628" diff --git a/third_party/rust/binjs_meta/Cargo.toml b/third_party/rust/binjs_meta/Cargo.toml deleted file mode 100644 index 2d0f3464af67..000000000000 --- a/third_party/rust/binjs_meta/Cargo.toml +++ /dev/null @@ -1,46 +0,0 @@ -# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO -# -# When uploading crates to the registry Cargo will automatically -# "normalize" Cargo.toml files for maximal compatibility -# with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies -# -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) - -[package] -name = "binjs_meta" -version = "0.5.4" -authors = ["David Teller "] -description = "Part of binjs-ref. Tools for manipulating grammars. You probably do not want to use this crate directly unless you're writing an encoder, decoder or parser generator for binjs." -homepage = "https://binast.github.io/ecmascript-binary-ast/" -readme = "README.md" -keywords = ["javascript", "js", "binjs", "ast"] -categories = ["compression", "parsing", "web-programming"] -license = "MIT" -repository = "https://github.com/binast/binjs-ref" -[dependencies.Inflector] -version = "^0.11.4" -default-features = false - -[dependencies.itertools] -version = "^0.8" - -[dependencies.log] -version = "^0.4" - -[dependencies.weedle] -version = "0.11" -[dev-dependencies.clap] -version = "^2.0" - -[dev-dependencies.env_logger] -version = "^0.6" - -[dev-dependencies.yaml-rust] -version = "^0.4" -[badges.travis-ci] -branch = "master" -repository = "https://github.com/binast/binjs-ref" diff --git a/third_party/rust/binjs_meta/README.md b/third_party/rust/binjs_meta/README.md deleted file mode 100644 index 2358031280cd..000000000000 --- a/third_party/rust/binjs_meta/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# About - -This crate contains the tools used to manipulate the abstract syntax of JavaScript, -i.e. generate parsers, encoders, etc from a specification of ASTs of the language. - -Actual tools to manipulate ASTs for a specific version of JavaScript are -in dependent crates. diff --git a/third_party/rust/binjs_meta/examples/generate_spidermonkey.rs b/third_party/rust/binjs_meta/examples/generate_spidermonkey.rs deleted file mode 100644 index faddba9dac8d..000000000000 --- a/third_party/rust/binjs_meta/examples/generate_spidermonkey.rs +++ /dev/null @@ -1,1668 +0,0 @@ -// !!!! WARNING !!!! -// This is a snapshot of the code generator for SpiderMonkey, for demonstrating -// how to use binjs_meta crate in order to generate a parser. -// -// The latest version of this code is available as -// js/src/frontend/binsource/src/main.rs in the following repository: -// https://hg.mozilla.org/mozilla-central/ - -extern crate binjs_meta; -extern crate clap; -extern crate env_logger; -extern crate itertools; -#[macro_use] -extern crate log; -extern crate yaml_rust; - -use binjs_meta::export::{ToWebidl, TypeDeanonymizer, TypeName}; -use binjs_meta::import::Importer; -use binjs_meta::spec::*; -use binjs_meta::util::{Reindentable, ToCases, ToStr}; - -use std::collections::{HashMap, HashSet}; -use std::fs; - -use clap::{App, Arg}; - -use itertools::Itertools; - -/// Rules for generating the code for parsing a single field -/// of a node. -/// -/// Extracted from the yaml file. -#[derive(Clone, Default)] -struct FieldRules { - /// Declaring the variable to hold the contents of that field. - declare: Option, - - /// Replace the declaration and assignation. - replace: Option, - - /// Things to add before the field, typically for checking invariants. - before_field: Option, - - /// Things to add after the field, typically for checking invariants. - after_field: Option, - - /// Things to add before the field, as part of a block, typically for - /// putting guard values on the stack. - block_before_field: Option, - - /// Things to add before the field, as part of a block, typically for - /// cleanup. - block_after_field: Option, -} - -/// Rules for generating the code for parsing a full node -/// of a node. -/// -/// Extracted from the yaml file. -#[derive(Clone, Default)] -struct NodeRules { - /// This node inherits from another node. - inherits: Option, - - /// Override the result type for the method. - type_ok: Option, - - /// Stuff to add at start. - init: Option, - - /// How to append to a list. Used only for lists. - append: Option, - - /// Custom per-field treatment. Used only for interfaces. - by_field: HashMap, - - /// How to build the result, eventually. - build_result: Option, -} - -/// Rules for generating entire files. -/// -/// Extracted from the yaml file. -#[derive(Default)] -struct GlobalRules { - /// Header to add at the start of the .cpp file. - cpp_header: Option, - - /// Header to add at the end of the .cpp file. - cpp_footer: Option, - - /// Header to add at the start of the .hpp file - /// defining the class data/methods. - hpp_class_header: Option, - - /// Header to add at the start of the .hpp file. - /// defining the tokens. - hpp_tokens_header: Option, - - /// Footer to add at the start of the .hpp file. - /// defining the tokens. - hpp_tokens_footer: Option, - - /// Documentation for the `BinKind` class enum. - hpp_tokens_kind_doc: Option, - - /// Documentation for the `BinField` class enum. - hpp_tokens_field_doc: Option, - - /// Documentation for the `BinVariant` class enum. - hpp_tokens_variants_doc: Option, - - /// Per-node rules. - per_node: HashMap, -} -impl GlobalRules { - fn new(syntax: &Spec, yaml: &yaml_rust::yaml::Yaml) -> Self { - let rules = yaml.as_hash().expect("Rules are not a dictionary"); - - let mut cpp_header = None; - let mut cpp_footer = None; - let mut hpp_class_header = None; - let mut hpp_tokens_header = None; - let mut hpp_tokens_footer = None; - let mut hpp_tokens_kind_doc = None; - let mut hpp_tokens_field_doc = None; - let mut hpp_tokens_variants_doc = None; - let mut per_node = HashMap::new(); - - for (node_key, node_entries) in rules.iter() { - let node_key = node_key - .as_str() - .expect("Could not convert node_key to string"); - - match node_key { - "cpp" => { - update_rule(&mut cpp_header, &node_entries["header"]) - .unwrap_or_else(|_| panic!("Rule cpp.header must be a string")); - update_rule(&mut cpp_footer, &node_entries["footer"]) - .unwrap_or_else(|_| panic!("Rule cpp.footer must be a string")); - continue; - } - "hpp" => { - update_rule(&mut hpp_class_header, &node_entries["class"]["header"]) - .unwrap_or_else(|_| panic!("Rule hpp.class.header must be a string")); - update_rule(&mut hpp_tokens_header, &node_entries["tokens"]["header"]) - .unwrap_or_else(|_| panic!("Rule hpp.tokens.header must be a string")); - update_rule(&mut hpp_tokens_footer, &node_entries["tokens"]["footer"]) - .unwrap_or_else(|_| panic!("Rule hpp.tokens.footer must be a string")); - update_rule( - &mut hpp_tokens_kind_doc, - &node_entries["tokens"]["kind"]["doc"], - ) - .unwrap_or_else(|_| panic!("Rule hpp.tokens.kind.doc must be a string")); - update_rule( - &mut hpp_tokens_field_doc, - &node_entries["tokens"]["field"]["doc"], - ) - .unwrap_or_else(|_| panic!("Rule hpp.tokens.field.doc must be a string")); - update_rule( - &mut hpp_tokens_variants_doc, - &node_entries["tokens"]["variants"]["doc"], - ) - .unwrap_or_else(|_| panic!("Rule hpp.tokens.variants.doc must be a string")); - continue; - } - _ => {} - } - - let node_name = syntax - .get_node_name(&node_key) - .unwrap_or_else(|| panic!("Unknown node name {}", node_key)); - - let hash = node_entries - .as_hash() - .unwrap_or_else(|| panic!("Node {} isn't a dictionary")); - - let mut node_rule = NodeRules::default(); - for (node_item_key, node_item_entry) in hash { - let as_string = node_item_key - .as_str() - .unwrap_or_else(|| panic!("Keys for rule {} must be strings", node_key)); - match as_string { - "inherits" => { - let name = node_item_entry.as_str().unwrap_or_else(|| { - panic!("Rule {}.{} must be a string", node_key, as_string) - }); - let inherits = syntax - .get_node_name(name) - .unwrap_or_else(|| panic!("Unknown node name {}", node_key)); - node_rule.inherits = Some(inherits).cloned(); - } - "init" => { - update_rule(&mut node_rule.init, node_item_entry).unwrap_or_else(|()| { - panic!("Rule {}.{} must be a string", node_key, as_string) - }); - } - "build" => { - update_rule(&mut node_rule.build_result, node_item_entry).unwrap_or_else( - |()| panic!("Rule {}.{} must be a string", node_key, as_string), - ); - } - "append" => { - update_rule(&mut node_rule.append, node_item_entry).unwrap_or_else(|()| { - panic!("Rule {}.{} must be a string", node_key, as_string) - }); - } - "type-ok" => { - update_rule(&mut node_rule.type_ok, node_item_entry).unwrap_or_else(|()| { - panic!("Rule {}.{} must be a string", node_key, as_string) - }); - } - "fields" => { - let fields = node_item_entry.as_hash().unwrap_or_else(|| { - panic!( - "Rule {}.fields must be a hash, got {:?}", - node_key, node_entries["fields"] - ) - }); - for (field_key, field_entry) in fields { - let field_key = field_key - .as_str() - .unwrap_or_else(|| { - panic!( - "In rule {}, field entries must be field names", - node_key - ) - }) - .to_string(); - let field_name = - syntax.get_field_name(&field_key).unwrap_or_else(|| { - panic!("In rule {}, can't find field {}", node_key, field_key) - }); - - let mut field_rule = FieldRules::default(); - for (field_config_key, field_config_entry) in - field_entry.as_hash().unwrap_or_else(|| { - panic!("Rule {}.fields.{} must be a hash", node_key, field_key) - }) - { - let field_config_key = field_config_key - .as_str() - .expect("Expected a string as a key"); - match field_config_key { - "block" => { - update_rule( - &mut field_rule.declare, - &field_config_entry["declare"], - ) - .unwrap_or_else( - |()| { - panic!( - "Rule {}.fields.{}.{}.{} must be a string", - node_key, - field_key, - field_config_key, - "declare" - ) - }, - ); - - update_rule( - &mut field_rule.replace, - &field_config_entry["replace"], - ) - .unwrap_or_else( - |()| { - panic!( - "Rule {}.fields.{}.{}.{} must be a string", - node_key, - field_key, - field_config_key, - "replace" - ) - }, - ); - - update_rule( - &mut field_rule.block_before_field, - &field_config_entry["before"], - ) - .unwrap_or_else( - |()| { - panic!( - "Rule {}.fields.{}.{}.{} must be a string", - node_key, field_key, field_config_key, "before" - ) - }, - ); - - update_rule( - &mut field_rule.block_after_field, - &field_config_entry["after"], - ) - .unwrap_or_else( - |()| { - panic!( - "Rule {}.fields.{}.{}.{} must be a string", - node_key, field_key, field_config_key, "after" - ) - }, - ); - } - "before" => { - update_rule( - &mut field_rule.before_field, - &field_config_entry, - ) - .unwrap_or_else( - |()| { - panic!( - "Rule {}.fields.{}.{} must be a string", - node_key, field_key, field_config_key - ) - }, - ); - } - "after" => { - update_rule( - &mut field_rule.after_field, - &field_config_entry, - ) - .unwrap_or_else( - |()| { - panic!( - "Rule {}.fields.{}.{} must be a string", - node_key, field_key, field_config_key - ) - }, - ); - } - _ => panic!( - "Unexpected {}.fields.{}.{}", - node_key, field_key, field_config_key - ), - } - } - node_rule.by_field.insert(field_name.clone(), field_rule); - } - } - _ => panic!("Unexpected node_item_key {}.{}", node_key, as_string), - } - } - - per_node.insert(node_name.clone(), node_rule); - } - - Self { - cpp_header, - cpp_footer, - hpp_class_header, - hpp_tokens_header, - hpp_tokens_footer, - hpp_tokens_kind_doc, - hpp_tokens_field_doc, - hpp_tokens_variants_doc, - per_node, - } - } - fn get(&self, name: &NodeName) -> NodeRules { - let mut rules = self.per_node.get(name).cloned().unwrap_or_default(); - if let Some(ref parent) = rules.inherits { - let NodeRules { - inherits: _, - type_ok, - init, - append, - by_field, - build_result, - } = self.get(parent); - if rules.type_ok.is_none() { - rules.type_ok = type_ok; - } - if rules.init.is_none() { - rules.init = init; - } - if rules.append.is_none() { - rules.append = append; - } - if rules.build_result.is_none() { - rules.build_result = build_result; - } - for (key, value) in by_field { - rules.by_field.entry(key).or_insert(value); - } - } - rules - } -} - -/// The inforamtion used to generate a list parser. -struct ListParserData { - /// Name of the node. - name: NodeName, - - /// If `true`, supports empty lists. - supports_empty: bool, - - /// Name of the elements in the list. - elements: NodeName, -} - -/// The inforamtion used to generate a parser for an optional data structure. -struct OptionParserData { - /// Name of the node. - name: NodeName, - - /// Name of the element that may be contained. - elements: NodeName, -} - -/// The actual exporter. -struct CPPExporter { - /// The syntax to export. - syntax: Spec, - - /// Rules, as specified in yaml. - rules: GlobalRules, - - /// All parsers of lists. - list_parsers_to_generate: Vec, - - /// All parsers of options. - option_parsers_to_generate: Vec, - - /// A mapping from symbol (e.g. `+`, `-`, `instanceof`, ...) to the - /// name of the symbol as part of `enum class BinVariant` - /// (e.g. `UnaryOperatorDelete`). - variants_by_symbol: HashMap, -} - -impl CPPExporter { - fn new(syntax: Spec, rules: GlobalRules) -> Self { - let mut list_parsers_to_generate = vec![]; - let mut option_parsers_to_generate = vec![]; - for (parser_node_name, typedef) in syntax.typedefs_by_name() { - if typedef.is_optional() { - let content_name = TypeName::type_spec(typedef.spec()); - let content_node_name = syntax - .get_node_name(&content_name) - .unwrap_or_else(|| { - panic!( - "While generating an option parser, could not find node name {}", - content_name - ) - }) - .clone(); - debug!(target: "generate_spidermonkey", "CPPExporter::new adding optional typedef {:?} => {:?} => {:?}", - parser_node_name, - content_name, - content_node_name); - option_parsers_to_generate.push(OptionParserData { - name: parser_node_name.clone(), - elements: content_node_name, - }); - } else if let TypeSpec::Array { - ref contents, - ref supports_empty, - } = *typedef.spec() - { - let content_name = TypeName::type_(&**contents); - let content_node_name = syntax - .get_node_name(&content_name) - .unwrap_or_else(|| { - panic!( - "While generating an array parser, could not find node name {}", - content_name - ) - }) - .clone(); - list_parsers_to_generate.push(ListParserData { - name: parser_node_name.clone(), - supports_empty: *supports_empty, - elements: content_node_name, - }); - } - } - list_parsers_to_generate.sort_by(|a, b| str::cmp(a.name.to_str(), b.name.to_str())); - option_parsers_to_generate.sort_by(|a, b| str::cmp(a.name.to_str(), b.name.to_str())); - - // Prepare variant_by_symbol, which will let us lookup the BinVariant name of - // a symbol. Since some symbols can appear in several enums (e.g. "+" - // is both a unary and a binary operator), we need to collect all the - // string enums that contain each symbol and come up with a unique name - // (note that there is no guarantee of unicity – if collisions show up, - // we may need to tweak the name generation algorithm). - let mut enum_by_string: HashMap> = HashMap::new(); - for (name, enum_) in syntax.string_enums_by_name().iter() { - for string in enum_.strings().iter() { - let vec = enum_by_string - .entry(string.clone()) - .or_insert_with(|| vec![]); - vec.push(name.clone()); - } - } - let variants_by_symbol = enum_by_string - .drain() - .map(|(string, names)| { - let expanded = format!( - "{names}{symbol}", - names = names - .iter() - .map(NodeName::to_str) - .sorted() - .into_iter() - .format("Or"), - symbol = string.to_cpp_enum_case() - ); - (string, expanded) - }) - .collect(); - - CPPExporter { - syntax, - rules, - list_parsers_to_generate, - option_parsers_to_generate, - variants_by_symbol, - } - } - - // ----- Generating the header - - /// Get the type representing a success for parsing this node. - fn get_type_ok(&self, name: &NodeName, default: &str) -> String { - let rules_for_this_interface = self.rules.get(name); - // If the override is provided, use it. - if let Some(ref type_ok) = rules_for_this_interface.type_ok { - return type_ok.to_string(); - } - default.to_string() - } - - fn get_method_signature( - &self, - name: &NodeName, - default_type_ok: &str, - prefix: &str, - args: &str, - ) -> String { - let type_ok = self.get_type_ok(name, default_type_ok); - let kind = name.to_class_cases(); - format!( - " JS::Result<{type_ok}> parse{prefix}{kind}({args});\n", - prefix = prefix, - type_ok = type_ok, - kind = kind, - args = args, - ) - } - - fn get_method_definition_start( - &self, - name: &NodeName, - default_type_ok: &str, - prefix: &str, - args: &str, - ) -> String { - let type_ok = self.get_type_ok(name, default_type_ok); - let kind = name.to_class_cases(); - format!("template JS::Result<{type_ok}>\nBinASTParser::parse{prefix}{kind}({args})", - prefix = prefix, - type_ok = type_ok, - kind = kind, - args = args, - ) - } - - /// Declaring enums for kinds and fields. - fn export_declare_kinds_and_fields_enums(&self, buffer: &mut String) { - buffer.push_str(&self.rules.hpp_tokens_header.reindent("")); - - buffer.push_str("\n\n"); - if self.rules.hpp_tokens_kind_doc.is_some() { - buffer.push_str(&self.rules.hpp_tokens_kind_doc.reindent("")); - } - - let node_names = self.syntax.node_names().keys().sorted(); - buffer.push_str(&format!( - "\n#define FOR_EACH_BIN_KIND(F) \\\n{nodes}\n", - nodes = node_names - .map(|name| format!( - " F({enum_name}, \"{spec_name}\")", - enum_name = name.to_cpp_enum_case(), - spec_name = name - )) - .format(" \\\n") - )); - buffer.push_str( - " -enum class BinKind { -#define EMIT_ENUM(name, _) name, - FOR_EACH_BIN_KIND(EMIT_ENUM) -#undef EMIT_ENUM -}; -", - ); - - buffer.push_str(&format!("\n// The number of distinct values of BinKind.\nconst size_t BINKIND_LIMIT = {};\n\n\n", self.syntax.node_names().len())); - buffer.push_str("\n\n"); - if self.rules.hpp_tokens_field_doc.is_some() { - buffer.push_str(&self.rules.hpp_tokens_field_doc.reindent("")); - } - - let field_names = self.syntax.field_names().keys().sorted(); - buffer.push_str(&format!( - "\n#define FOR_EACH_BIN_FIELD(F) \\\n{nodes}\n", - nodes = field_names - .map(|name| format!( - " F({enum_name}, \"{spec_name}\")", - spec_name = name, - enum_name = name.to_cpp_enum_case() - )) - .format(" \\\n") - )); - buffer.push_str( - " -enum class BinField { -#define EMIT_ENUM(name, _) name, - FOR_EACH_BIN_FIELD(EMIT_ENUM) -#undef EMIT_ENUM -}; -", - ); - buffer.push_str(&format!("\n// The number of distinct values of BinField.\nconst size_t BINFIELD_LIMIT = {};\n\n\n", self.syntax.field_names().len())); - - if self.rules.hpp_tokens_variants_doc.is_some() { - buffer.push_str(&self.rules.hpp_tokens_variants_doc.reindent("")); - } - let enum_variants = self.variants_by_symbol.iter().sorted_by( - |&(ref symbol_1, ref name_1), &(ref symbol_2, ref name_2)| { - Ord::cmp(name_1, name_2).then_with(|| Ord::cmp(symbol_1, symbol_2)) - }, - ); - - buffer.push_str(&format!( - "\n#define FOR_EACH_BIN_VARIANT(F) \\\n{nodes}\n", - nodes = enum_variants - .map(|(symbol, name)| format!( - " F({variant_name}, \"{spec_name}\")", - spec_name = symbol, - variant_name = name - )) - .format(" \\\n") - )); - - buffer.push_str( - " -enum class BinVariant { -#define EMIT_ENUM(name, _) name, - FOR_EACH_BIN_VARIANT(EMIT_ENUM) -#undef EMIT_ENUM -}; -", - ); - buffer.push_str(&format!("\n// The number of distinct values of BinVariant.\nconst size_t BINVARIANT_LIMIT = {};\n\n\n", - self.variants_by_symbol.len())); - - buffer.push_str(&self.rules.hpp_tokens_footer.reindent("")); - buffer.push_str("\n"); - } - - /// Declare string enums - fn export_declare_string_enums_classes(&self, buffer: &mut String) { - buffer.push_str("\n\n// ----- Declaring string enums (by lexicographical order)\n"); - let string_enums_by_name = self - .syntax - .string_enums_by_name() - .iter() - .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str())); - for (name, enum_) in string_enums_by_name { - let rendered_cases = enum_ - .strings() - .iter() - .map(|str| { - format!( - "{case:<20} /* \"{original}\" */", - case = str.to_cpp_enum_case(), - original = str - ) - }) - .format(",\n "); - let rendered = format!( - "enum class {name} {{\n {cases}\n}};\n\n", - cases = rendered_cases, - name = name.to_class_cases() - ); - buffer.push_str(&rendered); - } - } - - fn export_declare_sums_of_interface_methods(&self, buffer: &mut String) { - let sums_of_interfaces = self - .syntax - .resolved_sums_of_interfaces_by_name() - .iter() - .sorted_by(|a, b| a.0.cmp(&b.0)) - .collect::>(); - buffer.push_str("\n\n// ----- Sums of interfaces (by lexicographical order)\n"); - buffer.push_str("// Implementations are autogenerated\n"); - buffer.push_str("// `ParseNode*` may never be nullptr\n"); - for &(ref name, _) in &sums_of_interfaces { - let rendered = self.get_method_signature(name, "ParseNode*", "", ""); - buffer.push_str(&rendered.reindent("")); - } - for (name, _) in sums_of_interfaces { - let rendered = self.get_method_signature( - name, - "ParseNode*", - "Sum", - "const size_t start, const BinKind kind, const BinFields& fields", - ); - buffer.push_str(&rendered.reindent("")); - } - } - - fn export_declare_single_interface_methods(&self, buffer: &mut String) { - buffer.push_str("\n\n// ----- Interfaces (by lexicographical order)\n"); - buffer.push_str("// Implementations are autogenerated\n"); - buffer.push_str("// `ParseNode*` may never be nullptr\n"); - let interfaces_by_name = self - .syntax - .interfaces_by_name() - .iter() - .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str())); - - let mut outer_parsers = Vec::with_capacity(interfaces_by_name.len()); - let mut inner_parsers = Vec::with_capacity(interfaces_by_name.len()); - - for (name, _) in interfaces_by_name { - let outer = self.get_method_signature(name, "ParseNode*", "", ""); - let inner = self.get_method_signature( - name, - "ParseNode*", - "Interface", - "const size_t start, const BinKind kind, const BinFields& fields", - ); - outer_parsers.push(outer.reindent("")); - inner_parsers.push(inner.reindent("")); - } - - for parser in outer_parsers.drain(..) { - buffer.push_str(&parser); - buffer.push_str("\n"); - } - - for parser in inner_parsers.drain(..) { - buffer.push_str(&parser); - buffer.push_str("\n"); - } - } - - fn export_declare_string_enums_methods(&self, buffer: &mut String) { - buffer.push_str("\n\n// ----- String enums (by lexicographical order)\n"); - buffer.push_str("// Implementations are autogenerated\n"); - let string_enums_by_name = self - .syntax - .string_enums_by_name() - .iter() - .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str())); - for (kind, _) in string_enums_by_name { - let type_ok = format!( - "typename BinASTParser::{kind}", - kind = kind.to_class_cases() - ); - let rendered = self.get_method_signature(kind, &type_ok, "", ""); - buffer.push_str(&rendered.reindent("")); - buffer.push_str("\n"); - } - } - - fn export_declare_list_methods(&self, buffer: &mut String) { - buffer.push_str("\n\n// ----- Lists (by lexicographical order)\n"); - buffer.push_str("// Implementations are autogenerated\n"); - for parser in &self.list_parsers_to_generate { - let rendered = self.get_method_signature(&parser.name, "ParseNode*", "", ""); - buffer.push_str(&rendered.reindent("")); - buffer.push_str("\n"); - } - } - - fn export_declare_option_methods(&self, buffer: &mut String) { - buffer.push_str("\n\n// ----- Default values (by lexicographical order)\n"); - buffer.push_str("// Implementations are autogenerated\n"); - for parser in &self.option_parsers_to_generate { - let rendered = self.get_method_signature(&parser.name, "ParseNode*", "", ""); - buffer.push_str(&rendered.reindent("")); - buffer.push_str("\n"); - } - } - - fn generate_autogenerated_warning(&self) -> String { - let warning = format!( - "// This file was autogenerated by binjs_generate_spidermonkey, -// please DO NOT EDIT BY HAND. -" - ); - warning - } - - /// Generate C++ headers for SpiderMonkey - fn to_spidermonkey_token_hpp(&self) -> String { - let mut buffer = String::new(); - - buffer.push_str(&self.generate_autogenerated_warning()); - - self.export_declare_kinds_and_fields_enums(&mut buffer); - - buffer.push_str("\n"); - buffer - } - fn to_spidermonkey_class_hpp(&self) -> String { - let mut buffer = String::new(); - - buffer.push_str(&self.generate_autogenerated_warning()); - - buffer.push_str(&self.rules.hpp_class_header.reindent("")); - buffer.push_str("\n"); - - self.export_declare_string_enums_classes(&mut buffer); - self.export_declare_sums_of_interface_methods(&mut buffer); - self.export_declare_single_interface_methods(&mut buffer); - self.export_declare_string_enums_methods(&mut buffer); - self.export_declare_list_methods(&mut buffer); - self.export_declare_option_methods(&mut buffer); - - buffer.push_str("\n"); - buffer - } -} - -impl CPPExporter { - /// Generate implementation of a single typesum. - fn generate_implement_sum( - &self, - buffer: &mut String, - name: &NodeName, - nodes: &HashSet, - ) { - // Generate comments (FIXME: We should use the actual webidl, not the resolved sum) - let nodes = nodes.iter().sorted().collect::>(); - let kind = name.to_class_cases(); - let rendered_bnf = format!( - "/*\n{name} ::= {nodes}\n*/", - nodes = nodes.iter().format("\n "), - name = name.to_str() - ); - - // Generate outer method - buffer.push_str(&format!( - "{bnf} -{first_line} -{{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - const auto start = tokenizer_->offset(); - - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - - BINJS_MOZ_TRY_DECL(result, parseSum{kind}(start, kind, fields)); - - MOZ_TRY(guard.done()); - return result; -}}\n", - bnf = rendered_bnf, - kind = kind, - first_line = self.get_method_definition_start(name, "ParseNode*", "", "") - )); - - // Generate inner method - let mut buffer_cases = String::new(); - for node in nodes { - buffer_cases.push_str(&format!( - " - case BinKind::{variant_name}: - MOZ_TRY_VAR(result, parseInterface{class_name}(start, kind, fields)); - break;", - class_name = node.to_class_cases(), - variant_name = node.to_cpp_enum_case() - )); - } - buffer.push_str(&format!( - "\n{first_line} -{{ - {type_ok} result; - switch(kind) {{{cases} - default: - return raiseInvalidKind(\"{kind}\", kind); - }} - return result; -}} - -", - kind = kind, - cases = buffer_cases, - first_line = self.get_method_definition_start( - name, - "ParseNode*", - "Sum", - "const size_t start, const BinKind kind, const BinFields& fields" - ), - type_ok = self.get_type_ok(name, "ParseNode*") - )); - } - - /// Generate the implementation of a single list parser - fn generate_implement_list(&self, buffer: &mut String, parser: &ListParserData) { - let rules_for_this_list = self.rules.get(&parser.name); - - // Warn if some rules are unused. - for &(condition, name) in &[ - (rules_for_this_list.build_result.is_some(), "build:"), - (rules_for_this_list.type_ok.is_some(), "type-ok:"), - (rules_for_this_list.by_field.len() > 0, "fields:"), - ] { - if condition { - warn!( - "In {}, rule `{}` was specified but is ignored.", - parser.name, name - ); - } - } - - let kind = parser.name.to_class_cases(); - let first_line = self.get_method_definition_start(&parser.name, "ParseNode*", "", ""); - - let init = match rules_for_this_list.init { - Some(str) => str.reindent(" "), - None => { - // We cannot generate the method if we don't know how to initialize the list. - let rendered = format!( - " -{first_line} -{{ - return raiseError(\"FIXME: Not implemented yet ({kind})\"); -}}\n", - first_line = first_line, - kind = kind, - ); - buffer.push_str(&rendered); - return; - } - }; - let append = match rules_for_this_list.append { - Some(str) => format!("{}", str.reindent(" ")), - None => " result->appendWithoutOrderAssumption(item);".to_string(), - }; - - let rendered = format!( - "\n{first_line} -{{ - uint32_t length; - AutoList guard(*tokenizer_); - - const auto start = tokenizer_->offset(); - MOZ_TRY(tokenizer_->enterList(length, guard));{empty_check} -{init} - - for (uint32_t i = 0; i < length; ++i) {{ - BINJS_MOZ_TRY_DECL(item, parse{inner}()); -{append} - }} - - MOZ_TRY(guard.done()); - return result; -}}\n", - first_line = first_line, - empty_check = if parser.supports_empty { - "".to_string() - } else { - format!( - "\n if (length == 0)\n return raiseEmpty(\"{kind}\");\n", - kind = kind - ) - }, - inner = parser.elements.to_class_cases(), - init = init, - append = append - ); - buffer.push_str(&rendered); - } - - fn generate_implement_option(&self, buffer: &mut String, parser: &OptionParserData) { - debug!(target: "generate_spidermonkey", "Implementing optional value {} backed by {}", - parser.name.to_str(), parser.elements.to_str()); - - let rules_for_this_node = self.rules.get(&parser.name); - - // Warn if some rules are unused. - for &(condition, name) in &[ - (rules_for_this_node.build_result.is_some(), "build:"), - (rules_for_this_node.append.is_some(), "append:"), - (rules_for_this_node.by_field.len() > 0, "fields:"), - ] { - if condition { - warn!( - "In {}, rule `{}` was specified but is ignored.", - parser.name, name - ); - } - } - - let type_ok = self.get_type_ok(&parser.name, "ParseNode*"); - let default_value = if type_ok == "Ok" { "Ok()" } else { "nullptr" }.to_string(); - - // At this stage, thanks to deanonymization, `contents` - // is something like `OptionalFooBar`. - let named_implementation = if let Some(NamedType::Typedef(ref typedef)) = - self.syntax.get_type_by_name(&parser.name) - { - assert!(typedef.is_optional()); - if let TypeSpec::NamedType(ref named) = *typedef.spec() { - self.syntax.get_type_by_name(named).unwrap_or_else(|| { - panic!( - "Internal error: Could not find type {}, which should have been generated.", - named.to_str() - ) - }) - } else { - panic!( - "Internal error: In {}, type {:?} should have been a named type", - parser.name.to_str(), - typedef - ); - } - } else { - panic!( - "Internal error: In {}, there should be a type with that name", - parser.name.to_str() - ); - }; - match named_implementation { - NamedType::Interface(_) => { - buffer.push_str(&format!( - "{first_line} -{{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - {type_ok} result; - if (kind == BinKind::{null}) {{ - result = {default_value}; - }} else {{ - const auto start = tokenizer_->offset(); - MOZ_TRY_VAR(result, parseInterface{contents}(start, kind, fields)); - }} - MOZ_TRY(guard.done()); - - return result; -}} - -", - first_line = - self.get_method_definition_start(&parser.name, "ParseNode*", "", ""), - null = self.syntax.get_null_name().to_cpp_enum_case(), - contents = parser.elements.to_class_cases(), - type_ok = type_ok, - default_value = default_value, - )); - } - NamedType::Typedef(ref type_) => match type_.spec() { - &TypeSpec::TypeSum(_) => { - buffer.push_str(&format!( - "{first_line} -{{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - {type_ok} result; - if (kind == BinKind::{null}) {{ - result = {default_value}; - }} else {{ - const auto start = tokenizer_->offset(); - MOZ_TRY_VAR(result, parseSum{contents}(start, kind, fields)); - }} - MOZ_TRY(guard.done()); - - return result; -}} - -", - first_line = - self.get_method_definition_start(&parser.name, "ParseNode*", "", ""), - contents = parser.elements.to_class_cases(), - type_ok = type_ok, - default_value = default_value, - null = self.syntax.get_null_name().to_cpp_enum_case(), - )); - } - &TypeSpec::String => { - let build_result = rules_for_this_node.init.reindent(" "); - let first_line = - self.get_method_definition_start(&parser.name, "ParseNode*", "", ""); - if build_result.len() == 0 { - buffer.push_str(&format!( - "{first_line} -{{ - return raiseError(\"FIXME: Not implemented yet ({kind})\"); -}} - -", - first_line = first_line, - kind = parser.name.to_str() - )); - } else { - buffer.push_str(&format!( - "{first_line} -{{ - BINJS_MOZ_TRY_DECL(result, tokenizer_->readMaybeAtom()); - -{build} - - return result; -}} - -", - first_line = first_line, - build = build_result, - )); - } - } - _else => unimplemented!("{:?}", _else), - }, - NamedType::StringEnum(_) => unimplemented!(), - } - } - - fn generate_implement_interface( - &self, - buffer: &mut String, - name: &NodeName, - interface: &Interface, - ) { - let rules_for_this_interface = self.rules.get(name); - - for &(condition, rule_name) in &[(rules_for_this_interface.append.is_some(), "build:")] { - if condition { - warn!( - "In {}, rule `{}` was specified but is ignored.", - name, rule_name - ); - } - } - - // Generate comments - let comment = format!("\n/*\n{}*/\n", ToWebidl::interface(interface, "", " ")); - buffer.push_str(&comment); - - // Generate public method - let kind = name.to_class_cases(); - buffer.push_str(&format!( - "{first_line} -{{ - BinKind kind; - BinFields fields(cx_); - AutoTaggedTuple guard(*tokenizer_); - - MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard)); - const auto start = tokenizer_->offset(); - - BINJS_MOZ_TRY_DECL(result, parseInterface{kind}(start, kind, fields)); - MOZ_TRY(guard.done()); - - return result; -}} - -", - first_line = self.get_method_definition_start(name, "ParseNode*", "", ""), - kind = kind - )); - - // Generate aux method - let number_of_fields = interface.contents().fields().len(); - let first_line = self.get_method_definition_start( - name, - "ParseNode*", - "Interface", - "const size_t start, const BinKind kind, const BinFields& fields", - ); - - let fields_type_list = format!( - "{{ {} }}", - interface - .contents() - .fields() - .iter() - .map(|field| format!("BinField::{}", field.name().to_cpp_enum_case())) - .format(", ") - ); - - let mut fields_implem = String::new(); - for field in interface.contents().fields() { - let rules_for_this_field = rules_for_this_interface - .by_field - .get(field.name()) - .cloned() - .unwrap_or_default(); - let needs_block = rules_for_this_field.block_before_field.is_some() - || rules_for_this_field.block_after_field.is_some(); - - let var_name = field.name().to_cpp_field_case(); - let (decl_var, parse_var) = match field.type_().get_primitive(&self.syntax) { - Some(IsNullable { - is_nullable: false, - content: Primitive::Number, - }) => { - if needs_block { - ( - Some(format!("double {var_name};", var_name = var_name)), - Some(format!( - "MOZ_TRY_VAR({var_name}, tokenizer_->readDouble());", - var_name = var_name - )), - ) - } else { - ( - None, - Some(format!( - "BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readDouble());", - var_name = var_name - )), - ) - } - } - Some(IsNullable { - is_nullable: false, - content: Primitive::Boolean, - }) => { - if needs_block { - ( - Some(format!("bool {var_name};", var_name = var_name)), - Some(format!( - "MOZ_TRY_VAR({var_name}, tokenizer_->readBool());", - var_name = var_name - )), - ) - } else { - ( - None, - Some(format!( - "BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readBool());", - var_name = var_name - )), - ) - } - } - Some(IsNullable { - is_nullable: false, - content: Primitive::Offset, - }) => { - if needs_block { - ( - Some(format!("uint32_t {var_name};", var_name = var_name)), - Some(format!( - "MOZ_TRY_VAR({var_name}, tokenizer_->readOffset());", - var_name = var_name - )), - ) - } else { - ( - None, - Some(format!( - "BINJS_MOZ_TRY_DECL({var_name}, tokenizer_->readOffset());", - var_name = var_name - )), - ) - } - } - Some(IsNullable { - content: Primitive::Void, - .. - }) => { - warn!("Internal error: We shouldn't have any `void` types at this stage."); - ( - Some(format!("// Skipping void field {}", field.name().to_str())), - None, - ) - } - Some(IsNullable { - is_nullable: false, - content: Primitive::String, - }) => ( - Some(format!("RootedAtom {var_name}(cx_);", var_name = var_name)), - Some(format!( - "MOZ_TRY_VAR({var_name}, tokenizer_->readAtom());", - var_name = var_name - )), - ), - Some(IsNullable { - content: Primitive::Interface(ref interface), - .. - }) if &self.get_type_ok(interface.name(), "?") == "Ok" => { - // Special case: `Ok` means that we shouldn't bind the return value. - let typename = TypeName::type_(field.type_()); - ( - None, - Some(format!("MOZ_TRY(parse{typename}());", typename = typename)), - ) - } - _else => { - let typename = TypeName::type_(field.type_()); - if needs_block { - ( - Some(format!( - "{typename} {var_name};", - var_name = var_name, - typename = typename - )), - Some(format!( - "MOZ_TRY_VAR({var_name}, parse{typename}());", - var_name = var_name, - typename = typename - )), - ) - } else { - ( - None, - Some(format!( - "BINJS_MOZ_TRY_DECL({var_name}, parse{typename}());", - var_name = var_name, - typename = typename - )), - ) - } - } - }; - - let rendered = { - if rules_for_this_field.replace.is_some() { - for &(condition, rule_name) in &[ - (rules_for_this_field.before_field.is_some(), "before:"), - (rules_for_this_field.after_field.is_some(), "after:"), - (rules_for_this_field.declare.is_some(), "declare:"), - ] { - if condition { - warn!("In {}, rule `{}` was specified but is ignored because `replace:` is also specified.", name, rule_name); - } - } - rules_for_this_field.replace.reindent(" ").newline() - } else { - let before_field = rules_for_this_field.before_field.reindent(" "); - let after_field = rules_for_this_field.after_field.reindent(" "); - let decl_var = if rules_for_this_field.declare.is_some() { - rules_for_this_field.declare.reindent(" ") - } else { - decl_var.reindent(" ") - }; - if needs_block { - let parse_var = parse_var.reindent(" "); - format!( - "{before_field} -{decl_var} - {{ -{block_before_field} -{parse_var} -{block_after_field} - }} -{after_field}", - before_field = before_field.reindent(" "), - decl_var = decl_var.reindent(" "), - parse_var = parse_var.reindent(" "), - after_field = after_field.reindent(" "), - block_before_field = - rules_for_this_field.block_before_field.reindent(" "), - block_after_field = - rules_for_this_field.block_after_field.reindent(" ") - ) - } else { - // We have a before_field and an after_field. This will create newlines - // for them. - format!( - " -{before_field} -{decl_var} -{parse_var} -{after_field} -", - before_field = before_field.reindent(" "), - decl_var = decl_var.reindent(" "), - parse_var = parse_var.reindent(" "), - after_field = after_field.reindent(" ") - ) - } - } - }; - fields_implem.push_str(&rendered); - } - - let init = rules_for_this_interface.init.reindent(" "); - let build_result = rules_for_this_interface.build_result.reindent(" "); - - if build_result == "" { - buffer.push_str(&format!( - "{first_line} -{{ - return raiseError(\"FIXME: Not implemented yet ({})\"); -}} - -", - kind = kind.to_str(), - first_line = first_line, - )); - } else { - let check_fields = if number_of_fields == 0 { - format!("MOZ_TRY(tokenizer_->checkFields0(kind, fields));") - } else { - format!( - "MOZ_TRY(tokenizer_->checkFields(kind, fields, {fields_type_list}));", - fields_type_list = fields_type_list - ) - }; - buffer.push_str(&format!( - "{first_line} -{{ - MOZ_ASSERT(kind == BinKind::{kind}); - CheckRecursionLimit(cx_); - - {check_fields} -{pre}{fields_implem} -{post} - return result; -}} - -", - check_fields = check_fields, - fields_implem = fields_implem, - pre = init, - post = build_result, - kind = name.to_cpp_enum_case(), - first_line = first_line, - )); - } - } - - /// Generate C++ code for SpiderMonkey - fn to_spidermonkey_cpp(&self) -> String { - let mut buffer = String::new(); - - buffer.push_str(&self.generate_autogenerated_warning()); - - // 0. Header - buffer.push_str(&self.rules.cpp_header.reindent("")); - buffer.push_str("\n"); - - // 1. Typesums - buffer.push_str( - "\n\n// ----- Sums of interfaces (autogenerated, by lexicographical order)\n", - ); - buffer.push_str("// Sums of sums are flattened.\n"); - - let sums_of_interfaces = self - .syntax - .resolved_sums_of_interfaces_by_name() - .iter() - .sorted_by(|a, b| a.0.cmp(&b.0)); - - for (name, nodes) in sums_of_interfaces { - self.generate_implement_sum(&mut buffer, name, nodes); - } - - // 2. Single interfaces - buffer.push_str("\n\n// ----- Interfaces (autogenerated, by lexicographical order)\n"); - buffer.push_str("// When fields have a non-trivial type, implementation is deanonymized and delegated to another parser.\n"); - let interfaces_by_name = self - .syntax - .interfaces_by_name() - .iter() - .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str())); - - for (name, interface) in interfaces_by_name { - self.generate_implement_interface(&mut buffer, name, interface); - } - - // 3. String Enums - buffer.push_str("\n\n// ----- String enums (autogenerated, by lexicographical order)\n"); - { - let string_enums_by_name = self - .syntax - .string_enums_by_name() - .iter() - .sorted_by(|a, b| str::cmp(a.0.to_str(), b.0.to_str())); - for (kind, enum_) in string_enums_by_name { - let convert = format!( - " switch (variant) {{ -{cases} - default: - return raiseInvalidVariant(\"{kind}\", variant); - }}", - kind = kind, - cases = enum_ - .strings() - .iter() - .map(|symbol| format!( - " case BinVariant::{binvariant_variant}: - return {kind}::{specialized_variant};", - kind = kind, - specialized_variant = symbol.to_cpp_enum_case(), - binvariant_variant = self.variants_by_symbol.get(symbol).unwrap() - )) - .format("\n") - ); - - let rendered_doc = format!( - "/*\nenum {kind} {{\n{cases}\n}};\n*/\n", - kind = kind, - cases = enum_ - .strings() - .iter() - .map(|s| format!(" \"{}\"", s)) - .format(",\n") - ); - buffer.push_str(&format!( - "{rendered_doc}{first_line} -{{ - BINJS_MOZ_TRY_DECL(variant, tokenizer_->readVariant()); - -{convert} -}} - -", - rendered_doc = rendered_doc, - convert = convert, - first_line = self.get_method_definition_start( - kind, - &format!("typename BinASTParser::{kind}", kind = kind), - "", - "" - ) - )); - } - } - - // 4. Lists - buffer.push_str("\n\n// ----- Lists (autogenerated, by lexicographical order)\n"); - for parser in &self.list_parsers_to_generate { - self.generate_implement_list(&mut buffer, parser); - } - - // 5. Optional values - buffer.push_str("\n\n // ----- Default values (by lexicographical order)\n"); - for parser in &self.option_parsers_to_generate { - self.generate_implement_option(&mut buffer, parser); - } - - buffer.push_str("\n"); - buffer.push_str(&self.rules.cpp_footer.reindent("")); - buffer.push_str("\n"); - - buffer - } -} - -fn update_rule(rule: &mut Option, entry: &yaml_rust::Yaml) -> Result, ()> { - if entry.is_badvalue() { - return Ok(None); - } else if let Some(as_str) = entry.as_str() { - *rule = Some(as_str.to_string()); - Ok(Some(())) - } else { - Err(()) - } -} - -fn main() { - env_logger::init(); - - let matches = App::new("BinAST C++ parser generator") - .author("David Teller, ") - .about("Converts an webidl syntax definition and a yaml set of rules into the C++ source code of a parser.") - .args(&[ - Arg::with_name("INPUT.webidl") - .required(true) - .help("Input webidl file to use. Must be a webidl source file."), - Arg::with_name("INPUT.yaml") - .required(true) - .help("Input rules file to use. Must be a yaml source file."), - Arg::with_name("OUT_HEADER_CLASS_FILE") - .long("out-class") - .required(true) - .takes_value(true) - .help("Output header file (.h, designed to be included from within the class file)"), - Arg::with_name("OUT_TOKEN_FILE") - .long("out-token") - .required(true) - .takes_value(true) - .help("Output token file (.h)"), - Arg::with_name("OUT_IMPL_FILE") - .long("out-impl") - .required(true) - .takes_value(true) - .help("Output implementation file (.cpp)"), - ]) - .get_matches(); - - let source_path = matches - .value_of("INPUT.webidl") - .expect("Expected INPUT.webidl"); - - let source = fs::read_to_string(source_path).expect("Could not read source"); - - println!("...importing webidl"); - let mut builder = - Importer::import(vec![source.as_str()].into_iter()).expect("Could not parse source"); - let fake_root = builder.node_name("@@ROOT@@"); // Unused - let null = builder.node_name(""); // Used - builder.add_interface(&null).unwrap(); - let syntax = builder.into_spec(SpecOptions { - root: &fake_root, - null: &null, - }); - - let deanonymizer = TypeDeanonymizer::new(&syntax); - let syntax_options = SpecOptions { - root: &fake_root, - null: &null, - }; - let new_syntax = deanonymizer.into_spec(syntax_options); - - let rules_source_path = matches.value_of("INPUT.yaml").unwrap(); - println!("...generating rules"); - let data = fs::read_to_string(rules_source_path).expect("Could not read rules"); - - let yaml = yaml_rust::YamlLoader::load_from_str(&data).expect("Could not parse rules"); - assert_eq!(yaml.len(), 1); - - let global_rules = GlobalRules::new(&new_syntax, &yaml[0]); - let exporter = CPPExporter::new(new_syntax, global_rules); - - let write_to = |description, arg, data: &str| { - let dest_path = matches.value_of(arg).unwrap(); - println!( - "...exporting {description}: {path}", - description = description, - path = dest_path - ); - fs::write(&dest_path, data).unwrap_or_else(|e| { - panic!( - "Could not write {description} at {path}: {error}", - description = description, - path = dest_path, - error = e - ) - }); - }; - - write_to( - "C++ class header code", - "OUT_HEADER_CLASS_FILE", - &exporter.to_spidermonkey_class_hpp(), - ); - write_to( - "C++ token header code", - "OUT_TOKEN_FILE", - &exporter.to_spidermonkey_token_hpp(), - ); - write_to( - "C++ token implementation code", - "OUT_IMPL_FILE", - &exporter.to_spidermonkey_cpp(), - ); - - println!("...done"); -} diff --git a/third_party/rust/binjs_meta/src/export.rs b/third_party/rust/binjs_meta/src/export.rs deleted file mode 100644 index b5fdfa79bc9c..000000000000 --- a/third_party/rust/binjs_meta/src/export.rs +++ /dev/null @@ -1,531 +0,0 @@ -use spec::*; -use util::*; - -use std::collections::{HashMap, HashSet}; - -use itertools::Itertools; - -/// A tool designed to replace all anonymous types in a specification -/// of the language by explicitly named types. -/// -/// Consider the following mini-specifications for JSON: -/// -/// ```idl -/// interface Value { -/// attribute (Object or String or Number or Array or Boolean)? value; -/// } -/// interface Object { -/// attribute FrozenArray properties; -/// } -/// interface Property { -/// attribute DOMString name; -/// attribute Value value; -/// } -/// interface Array { -/// attribute FrozenArray items; -/// } -/// // ... Skipping definitions of String, Number, Boolean -/// ``` -/// -/// The deanonymizer will rewrite them as follows: -/// -/// ```idl -/// interface Value { // Deanonymized optional sum -/// attribute OptionalObjectOrStringOrNumberOrArrayOrBoolean value; -/// } -/// interface Object { // Deanonymized list -/// attribute ListOfProperty properties; -/// } -/// interface Property { // No change -/// attribute DOMString name; -/// attribute Value value; -/// } -/// interface Array { // Deanonymized list of options -/// attribute ListOfOptionalValue items; -/// } -/// // ... Skipping definitions of String, Number, Boolean -/// -/// typedef ObjectOrStringOrNumberOrArrayOrBoolean? OptionalObjectOrStringOrNumberOrArrayOrBoolean; -/// typedef (Object -/// or String -/// or Number -/// or Array -/// or Boolean) -/// ObjectOrStringOrNumberOrArrayOrBoolean; -/// typedef FrozenArray ListOfProperty; -/// typedef FrozenArray ListOfOptionalValue; -/// typedef Value? Optionalvalue; -/// ``` -/// -/// This deanonymization lets us cleanly define intermediate data structures and/or parsers -/// implementing the webidl specification. -pub struct TypeDeanonymizer { - builder: SpecBuilder, - - /// When we encounter `typedef (A or B) C` - /// and `typedef (C or D) E`, we deanonymize into - /// `typedef (A or B or D) E`. - /// - /// This maintains the relationship that `E` (value) - /// contains `C` (key). - supersums_of: HashMap>, -} -impl TypeDeanonymizer { - /// Create an empty TypeDeanonymizer. - pub fn new(spec: &Spec) -> Self { - let mut result = TypeDeanonymizer { - builder: SpecBuilder::new(), - supersums_of: HashMap::new(), - }; - let mut skip_name_map: HashMap<&FieldName, FieldName> = HashMap::new(); - - // Copy field names - for (_, name) in spec.field_names() { - result.builder.import_field_name(name) - } - - for (_, interface) in spec.interfaces_by_name() { - for field in interface.contents().fields() { - if field.is_lazy() { - let skip_name = result - .builder - .field_name(format!("{}_skip", field.name().to_str()).to_str()); - skip_name_map.insert(field.name(), skip_name); - } - } - } - - // Copy and deanonymize interfaces. - for (name, interface) in spec.interfaces_by_name() { - result.builder.import_node_name(name); - // Collect interfaces to copy them into the `builder` - // and walk through their fields to deanonymize types. - - let mut fields = vec![]; - - // Copy other fields. - for field in interface.contents().fields() { - result.import_type(spec, field.type_(), None); - fields.push(field.clone()); - } - - // Copy the declaration. - let mut declaration = result.builder.add_interface(name).unwrap(); - for field in fields.drain(..) { - // Create *_skip field just before the lazy field. - // See also tagged_tuple in write.rs. - if field.is_lazy() { - declaration.with_field( - skip_name_map.get(field.name()).unwrap(), - Type::offset().required(), - ); - } - declaration.with_field_laziness( - field.name(), - field.type_().clone(), - field.laziness(), - ); - } - - if let Some(ref field_name) = interface.scoped_dictionary() { - declaration.with_scoped_dictionary(field_name); - } - } - // Copy and deanonymize typedefs - for (name, definition) in spec.typedefs_by_name() { - result.builder.import_node_name(name); - if result.builder.get_typedef(name).is_some() { - // Already imported by following links. - continue; - } - result.import_type(spec, &definition, Some(name.clone())); - } - // Copy and deanonymize string enums - for (name, definition) in spec.string_enums_by_name() { - result.builder.import_node_name(name); - let mut strings: Vec<_> = definition.strings().iter().collect(); - let mut declaration = result.builder.add_string_enum(name).unwrap(); - for string in strings.drain(..) { - declaration.with_string(&string); - } - } - debug!(target: "export_utils", "Names: {:?}", result.builder.names().keys().format(", ")); - - result - } - - pub fn supersums(&self) -> &HashMap> { - &self.supersums_of - } - - /// Convert into a new specification. - pub fn into_spec(self, options: SpecOptions) -> Spec { - self.builder.into_spec(options) - } - - /// If `name` is the name of a (deanonymized) type, return the corresponding type. - pub fn get_node_name(&self, name: &str) -> Option { - self.builder.get_node_name(name) - } - - /// Returns `(sum, name)` where `sum` is `Some(names)` iff this type can be resolved to a sum of interfaces. - fn import_type( - &mut self, - spec: &Spec, - type_: &Type, - public_name: Option, - ) -> (Option>, NodeName) { - debug!(target: "export_utils", "import_type {:?} => {:?}", public_name, type_); - if type_.is_optional() { - let (_, spec_name) = self.import_typespec(spec, &type_.spec, None); - let my_name = match public_name { - None => self.builder.node_name(&format!("Optional{}", spec_name)), - Some(ref name) => name.clone(), - }; - let deanonymized = Type::named(&spec_name).optional().unwrap(); // Named types can always be made optional. - if let Some(ref mut typedef) = self.builder.add_typedef(&my_name) { - debug!(target: "export_utils", "import_type introduced {:?}", my_name); - typedef.with_type(deanonymized.clone()); - } else { - debug!(target: "export_utils", "import_type: Attempting to redefine typedef {name}", name = my_name.to_str()); - } - (None, my_name) - } else { - self.import_typespec(spec, &type_.spec, public_name) - } - } - fn import_typespec( - &mut self, - spec: &Spec, - type_spec: &TypeSpec, - public_name: Option, - ) -> (Option>, NodeName) { - debug!(target: "export_utils", "import_typespec {:?} => {:?}", public_name, type_spec); - match *type_spec { - TypeSpec::Boolean - | TypeSpec::Number - | TypeSpec::UnsignedLong - | TypeSpec::PropertyKey - | TypeSpec::IdentifierName - | TypeSpec::String - | TypeSpec::Offset - | TypeSpec::Void => { - if let Some(ref my_name) = public_name { - if let Some(ref mut typedef) = self.builder.add_typedef(&my_name) { - debug!(target: "export_utils", "import_typespec: Defining {name} (primitive)", name = my_name.to_str()); - typedef.with_type(type_spec.clone().required()); - } else { - debug!(target: "export_utils", "import_typespec: Attempting to redefine typedef {name}", name = my_name.to_str()); - } - } - // This is a workaround for typedefs in the webidl that are not truly typedefs. - // See https://github.com/Yoric/ecmascript-binary-ast/pull/1 - let name = match *type_spec { - TypeSpec::PropertyKey => self.builder.node_name("PropertyKey"), - TypeSpec::IdentifierName => self.builder.node_name("IdentifierName"), - _ => self.builder.node_name(&format!("@@{:?}", type_spec)), - }; - (None, name) - } - TypeSpec::NamedType(ref link) => { - let resolved = spec.get_type_by_name(link) - .unwrap_or_else(|| panic!("While deanonymizing, could not find the definition of {} in the original spec.", link.to_str())); - let (sum, rewrite, primitive) = match resolved { - NamedType::StringEnum(_) => { - // - Can't use in a sum - // - No rewriting happened. - (None, None, None) - } - NamedType::Typedef(ref type_) => { - // - Might use in a sum. - // - Might be rewritten. - let (sum, name) = self.import_type(spec, type_, Some(link.clone())); - (sum, Some(name), type_.get_primitive(spec)) - } - NamedType::Interface(_) => { - // - May use in a sum. - // - If a rewriting takes place, it didn't change the names. - let sum = [link.clone()].iter().cloned().collect(); - (Some(sum), None, None) - } - }; - debug!(target: "export_utils", "import_typespec dealing with named type {}, public name {:?} => {:?}", - link, public_name, rewrite); - if let Some(ref my_name) = public_name { - // If we have a public name, alias it to `content` - if let Some(content) = rewrite { - let deanonymized = match primitive { - None - | Some(IsNullable { - is_nullable: true, .. - }) - | Some(IsNullable { - content: Primitive::Interface(_), - .. - }) => Type::named(&content).required(), - Some(IsNullable { - content: Primitive::String, - .. - }) => Type::string().required(), - Some(IsNullable { - content: Primitive::IdentifierName, - .. - }) => Type::identifier_name().required(), - Some(IsNullable { - content: Primitive::PropertyKey, - .. - }) => Type::property_key().required(), - Some(IsNullable { - content: Primitive::Number, - .. - }) => Type::number().required(), - Some(IsNullable { - content: Primitive::UnsignedLong, - .. - }) => Type::unsigned_long().required(), - Some(IsNullable { - content: Primitive::Boolean, - .. - }) => Type::bool().required(), - Some(IsNullable { - content: Primitive::Offset, - .. - }) => Type::offset().required(), - Some(IsNullable { - content: Primitive::Void, - .. - }) => Type::void().required(), - }; - debug!(target: "export_utils", "import_typespec aliasing {:?} => {:?}", - my_name, deanonymized); - if let Some(ref mut typedef) = self.builder.add_typedef(&my_name) { - debug!(target: "export_utils", "import_typespec: Defining {name} (name to content)", name = my_name.to_str()); - typedef.with_type(deanonymized.clone()); - } else { - debug!(target: "export_utils", "import_typespec: Attempting to redefine typedef {name}", name = my_name.to_str()); - } - } - // Also, don't forget to copy the typedef and alias `link` - let deanonymized = Type::named(link).required(); - if let Some(ref mut typedef) = self.builder.add_typedef(&my_name) { - debug!(target: "export_utils", "import_typespec: Defining {name} (name to link)", name = my_name.to_str()); - typedef.with_type(deanonymized.clone()); - } else { - debug!(target: "export_utils", "import_typespec: Attempting to redefine typedef {name}", name = my_name.to_str()); - } - } - (sum, link.clone()) - } - TypeSpec::Array { - ref contents, - ref supports_empty, - } => { - let (_, contents_name) = self.import_type(spec, contents, None); - let my_name = match public_name { - None => self.builder.node_name(&format!( - "{non_empty}ListOf{content}", - non_empty = if *supports_empty { "" } else { "NonEmpty" }, - content = contents_name.to_str() - )), - Some(ref name) => name.clone(), - }; - let deanonymized = if *supports_empty { - Type::named(&contents_name).array() - } else { - Type::named(&contents_name).non_empty_array() - }; - if let Some(ref mut typedef) = self.builder.add_typedef(&my_name) { - debug!(target: "export_utils", "import_typespec: Defining {name} (name to list)", - name = my_name.to_str()); - typedef.with_type(deanonymized.clone()); - } else { - debug!(target: "export_utils", "import_typespec: Attempting to redefine typedef {name}", name = my_name.to_str()); - } - (None, my_name) - } - TypeSpec::TypeSum(ref sum) => { - let mut full_sum = HashSet::new(); - let mut names = vec![]; - let mut subsums = vec![]; - for sub_type in sum.types() { - let (sub_sum, name) = self.import_typespec(spec, sub_type, None); - let mut sub_sum = sub_sum.unwrap_or_else( - || panic!("While treating {:?}, attempting to create a sum containing {}, which isn't an interface or a sum of interfaces", type_spec, name) - ); - if sub_sum.len() > 1 { - // The subtype is itself a sum. - subsums.push(name.clone()) - } - names.push(name); - for item in sub_sum.drain() { - full_sum.insert(item); - } - } - let my_name = match public_name { - None => self.builder.node_name(&format!( - "{}", - names.into_iter().sorted().into_iter().format("Or") - )), - Some(ref name) => name.clone(), - }; - for subsum_name in subsums { - // So, `my_name` is a superset of `subsum_name`. - let supersum_entry = self - .supersums_of - .entry(subsum_name.clone()) - .or_insert_with(|| HashSet::new()); - supersum_entry.insert(my_name.clone()); - } - let sum: Vec<_> = full_sum.iter().map(Type::named).collect(); - let deanonymized = Type::sum(&sum).required(); - if let Some(ref mut typedef) = self.builder.add_typedef(&my_name) { - debug!(target: "export_utils", "import_typespec: Defining {name} (name to sum)", name = my_name.to_str()); - typedef.with_type(deanonymized.clone()); - } else { - debug!(target: "export_utils", "import_type: Attempting to redefine typedef {name}", name = my_name.to_str()); - } - (Some(full_sum), my_name) - } - } - } -} - -/// Utility to give a name to a type or type spec. -pub struct TypeName; -impl TypeName { - pub fn type_(type_: &Type) -> String { - let spec_name = Self::type_spec(type_.spec()); - if type_.is_optional() { - format!("Optional{}", spec_name) - } else { - spec_name - } - } - - pub fn type_spec(spec: &TypeSpec) -> String { - match *spec { - TypeSpec::Array { - ref contents, - supports_empty: false, - } => format!("NonEmptyListOf{}", Self::type_(contents)), - TypeSpec::Array { - ref contents, - supports_empty: true, - } => format!("ListOf{}", Self::type_(contents)), - TypeSpec::NamedType(ref name) => name.to_string().clone(), - TypeSpec::Offset => "_Offset".to_string(), - TypeSpec::Boolean => "_Bool".to_string(), - TypeSpec::Number => "_Number".to_string(), - TypeSpec::UnsignedLong => "_UnsignedLong".to_string(), - TypeSpec::String => "_String".to_string(), - TypeSpec::Void => "_Void".to_string(), - TypeSpec::IdentifierName => "IdentifierName".to_string(), - TypeSpec::PropertyKey => "PropertyKey".to_string(), - TypeSpec::TypeSum(ref sum) => format!( - "{}", - sum.types() - .iter() - .map(Self::type_spec) - .sorted() - .into_iter() - .format("Or") - ), - } - } -} - -/// Export a type specification as webidl. -/// -/// Designed for generating documentation. -pub struct ToWebidl; -impl ToWebidl { - /// Export a TypeSpec. - pub fn spec(spec: &TypeSpec, prefix: &str, indent: &str) -> Option { - let result = match *spec { - TypeSpec::Offset => { - return None; - } - TypeSpec::Array { - ref contents, - ref supports_empty, - } => match Self::type_(&*contents, prefix, indent) { - None => { - return None; - } - Some(description) => format!( - "{emptiness}FrozenArray<{}>", - description, - emptiness = if *supports_empty { "" } else { "[NonEmpty] " } - ), - }, - TypeSpec::Boolean => "bool".to_string(), - TypeSpec::String => "string".to_string(), - TypeSpec::PropertyKey => "[PropertyKey] string".to_string(), - TypeSpec::IdentifierName => "[IdentifierName] string".to_string(), - TypeSpec::Number => "number".to_string(), - TypeSpec::UnsignedLong => "unsigned long".to_string(), - TypeSpec::NamedType(ref name) => name.to_str().to_string(), - TypeSpec::TypeSum(ref sum) => format!( - "({})", - sum.types() - .iter() - .filter_map(|x| Self::spec(x, "", indent)) - .format(" or ") - ), - TypeSpec::Void => "void".to_string(), - }; - Some(result) - } - - /// Export a Type - pub fn type_(type_: &Type, prefix: &str, indent: &str) -> Option { - let pretty_type = Self::spec(type_.spec(), prefix, indent); - match pretty_type { - None => None, - Some(pretty_type) => Some(format!( - "{}{}", - pretty_type, - if type_.is_optional() { "?" } else { "" } - )), - } - } - - /// Export an Interface - pub fn interface(interface: &Interface, prefix: &str, indent: &str) -> String { - let mut result = format!( - "{prefix} interface {name} : Node {{\n", - prefix = prefix, - name = interface.name().to_str() - ); - { - let prefix = format!("{prefix}{indent}", prefix = prefix, indent = indent); - for field in interface.contents().fields() { - match Self::type_(field.type_(), &prefix, indent) { - None => - /* generated field, ignore */ - {} - Some(description) => { - if let Some(ref doc) = field.doc() { - result.push_str(&format!( - "{prefix}// {doc}\n", - prefix = prefix, - doc = doc - )); - } - result.push_str(&format!( - "{prefix}{description} {name};\n", - prefix = prefix, - name = field.name().to_str(), - description = description - )); - if field.doc().is_some() { - result.push_str("\n"); - } - } - } - } - } - result.push_str(&format!("{prefix} }}\n", prefix = prefix)); - result - } -} diff --git a/third_party/rust/binjs_meta/src/import.rs b/third_party/rust/binjs_meta/src/import.rs deleted file mode 100644 index 329b1391776c..000000000000 --- a/third_party/rust/binjs_meta/src/import.rs +++ /dev/null @@ -1,358 +0,0 @@ -use spec::{self, Laziness, SpecBuilder, TypeSpec, TypeSum}; -use weedle::common::Identifier; -use weedle::types::*; -use weedle::*; - -fn nullable(src: &MayBeNull, dst: TypeSpec) -> spec::Type { - if src.q_mark.is_some() { - dst.optional() - .unwrap_or_else(|| panic!("This type could not be made optional {:?}", src.type_)) - } else { - dst.required() - } -} - -pub struct Importer { - builder: SpecBuilder, - /// The interfaces we have traversed so far. - path: Vec, -} - -impl Importer { - /// Import a WebIDL spec into a SpecBuilder. - /// - /// A WebIDL spec may consist in several files. Files are parsed in the order - /// of `sources`. An extension file (e.g. `es6-extended.webidl`) MUST appear - /// after the files it extends. - /// - /// ``` - /// extern crate binjs_meta; - /// use binjs_meta::spec::SpecOptions; - /// - /// let mut builder = binjs_meta::import::Importer::import(vec![" - /// interface FooContents { - /// attribute boolean value; - /// }; - /// interface LazyFoo { - /// [Lazy] attribute FooContents contents; - /// }; - /// interface EagerFoo { - /// attribute FooContents contents; - /// }; - /// "].into_iter()).expect("Could not parse"); - /// - /// let fake_root = builder.node_name("@@ROOT@@"); // Unused - /// let null = builder.node_name(""); // Used - /// let spec = builder.into_spec(SpecOptions { - /// root: &fake_root, - /// null: &null, - /// }); - /// - /// let name_eager = spec.get_node_name("EagerFoo") - /// .expect("Missing name EagerFoo"); - /// let name_lazy = spec.get_node_name("LazyFoo") - /// .expect("Missing name LazyFoo"); - /// let name_contents = spec.get_field_name("contents") - /// .expect("Missing name contents"); - /// - /// { - /// let interface_eager = spec.get_interface_by_name(&name_eager) - /// .expect("Missing interface EagerFoo"); - /// let contents_field = - /// interface_eager.get_field_by_name(&name_contents) - /// .expect("Missing field contents"); - /// assert_eq!(contents_field.is_lazy(), false); - /// } - /// - /// { - /// let interface_lazy = spec.get_interface_by_name(&name_lazy) - /// .expect("Missing interface LazyFoo"); - /// let contents_field = - /// interface_lazy.get_field_by_name(&name_contents) - /// .expect("Missing field contents"); - /// assert_eq!(contents_field.is_lazy(), true); - /// } - /// ``` - pub fn import<'a>( - sources: impl IntoIterator, - ) -> Result> { - let mut importer = Importer { - path: Vec::with_capacity(256), - builder: SpecBuilder::new(), - }; - for source in sources { - let ast = weedle::parse(source)?; - importer.import_all_definitions(&ast); - } - Ok(importer.builder) - } - - fn import_all_definitions(&mut self, ast: &Definitions) { - for definition in ast { - self.import_definition(&definition) - } - } - - fn import_definition(&mut self, def: &Definition) { - match *def { - Definition::Enum(ref enum_) => self.import_enum(enum_), - Definition::Typedef(ref typedef) => self.import_typedef(typedef), - Definition::Interface(ref interface) => self.import_interface(interface), - _ => panic!("Not implemented: importing {:?}", def), - } - } - - fn import_enum(&mut self, enum_: &EnumDefinition) { - let name = self.builder.node_name(enum_.identifier.0); - let mut node = self - .builder - .add_string_enum(&name) - .expect("Name already present"); - for variant in &enum_.values.body.list { - node.with_string(&variant.0); - } - } - - fn import_typedef(&mut self, typedef: &TypedefDefinition) { - let name = self.builder.node_name(typedef.identifier.0); - // The following are, unfortunately, not true typedefs. - // Ignore their definition. - let type_ = match typedef.identifier.0 { - "Identifier" => TypeSpec::IdentifierName.required(), - "IdentifierName" => TypeSpec::IdentifierName.required(), - "PropertyKey" => TypeSpec::PropertyKey.required(), - _ => self.convert_type(&typedef.type_.type_), - }; - debug!(target: "meta::import", "Importing typedef {type_:?} {name:?}", - type_ = type_, - name = name); - let mut node = self.builder.add_typedef(&name).unwrap_or_else(|| { - panic!( - "Error: Name {} is defined more than once in the spec.", - name - ) - }); - assert!(!type_.is_optional()); - node.with_spec(type_.spec); - } - - fn import_interface(&mut self, interface: &InterfaceDefinition) { - // Handle special, hardcoded, interfaces. - match interface.identifier.0 { - "Node" => { - // We're not interested in the root interface. - return; - } - "IdentifierName" => unimplemented!(), - _ => {} - } - if let Some(ref parent) = interface.inheritance { - assert_eq!(parent.identifier.0, "Node"); - } - - self.path.push(interface.identifier.0.to_owned()); - - // Now handle regular stuff. - let mut fields = Vec::new(); - for member in &interface.members.body { - if let interface::InterfaceMember::Attribute(interface::AttributeInterfaceMember { - modifier: None, - attributes, - identifier, - type_, - .. - }) = member - { - let name = self.builder.field_name(identifier.0); - let type_ = self.convert_type(&type_.type_); - - let is_lazy = attributes - .iter() - .flat_map(|attribute| &attribute.body.list) - .find(|attribute| match attribute { - attribute::ExtendedAttribute::NoArgs( - attribute::ExtendedAttributeNoArgs(Identifier("Lazy")), - ) => true, - _ => false, - }) - .is_some(); - - fields.push(( - name, - type_, - if is_lazy { - Laziness::Lazy - } else { - Laziness::Eager - }, - )); - } else { - panic!("Expected an attribute, got {:?}", member); - } - } - let name = self.builder.node_name(interface.identifier.0); - - // Set to `Some("Foo")` if this interface has attribute - // `[ExtendsTypeSum=Foo]`. - let mut extends_type_sum = None; - let mut scoped_dictionary = None; - { - let mut node = self - .builder - .add_interface(&name) - .expect("Name already present"); - for (field_name, field_type, laziness) in fields.drain(..) { - node.with_field_laziness(&field_name, field_type, laziness); - } - - for attribute in interface - .attributes - .iter() - .flat_map(|attribute| &attribute.body.list) - { - use weedle::attribute::ExtendedAttribute::*; - use weedle::attribute::*; - match *attribute { - NoArgs(ExtendedAttributeNoArgs(Identifier("Skippable"))) => { - panic!("Encountered deprecated attribute [Skippable]"); - } - NoArgs(ExtendedAttributeNoArgs(Identifier("Scope"))) => { - node.with_scope(true); - } - Ident(ExtendedAttributeIdent { - lhs_identifier: Identifier("ExtendsTypeSum"), - assign: _, - rhs: IdentifierOrString::Identifier(ref rhs), - }) => { - assert!(extends_type_sum.is_none()); - extends_type_sum = Some(rhs.0); - } - Ident(ExtendedAttributeIdent { - lhs_identifier: Identifier("ScopedDictionary"), - assign: _, - rhs: IdentifierOrString::Identifier(ref rhs), - }) => { - assert!(scoped_dictionary.is_none()); - scoped_dictionary = Some(rhs.0); - } - _ => panic!("Unknown attribute {:?}", attribute), - } - } - - // If the node contains an attribute `[ScopedDictionary=field]`, - // mark the node as inserting a scoped dictionary with this field. - if let Some(ref field_name) = scoped_dictionary { - node.with_scoped_dictionary_str(field_name); - } - } - - // If the node contains an attribute `[ExtendsTypeSum=Foobar]`, - // extend `typedef (... or ... or ...) Foobar` into - // `typedef (... or ... or ... or CurrentNode) Foobar`. - if let Some(ref extended) = extends_type_sum { - let node_name = self - .builder - .get_node_name(extended) - .unwrap_or_else(|| panic!("Could not find node name {}", extended)); - let mut typedef = self - .builder - .get_typedef_mut(&node_name) - .unwrap_or_else(|| panic!("Could not find typedef {}", extended)); - let typespec = typedef.spec_mut(); - let typesum = if let TypeSpec::TypeSum(ref mut typesum) = *typespec { - typesum - } else { - panic!( - "Attempting to extend a node that is not a type sum {}", - extended - ); - }; - typesum.with_type_case(TypeSpec::NamedType(name)); - } - - self.path.pop(); - } - - fn convert_single_type(&mut self, t: &NonAnyType) -> spec::Type { - match t { - NonAnyType::Boolean(ref b) => nullable(b, TypeSpec::Boolean), - NonAnyType::Identifier(ref id) => nullable(id, { - let name = self.builder.node_name(id.type_.0); - // Sadly, some identifiers are not truly `typedef`s. - match name.to_str() { - "IdentifierName" if self.is_at_interface("StaticMemberAssignmentTarget") => { - TypeSpec::PropertyKey - } - "IdentifierName" if self.is_at_interface("StaticMemberExpression") => { - TypeSpec::PropertyKey - } - "IdentifierName" if self.is_at_interface("ImportSpecifier") => { - TypeSpec::PropertyKey - } - "IdentifierName" if self.is_at_interface("ExportSpecifier") => { - TypeSpec::PropertyKey - } - "IdentifierName" if self.is_at_interface("ExportLocalSpecifier") => { - TypeSpec::PropertyKey - } - "IdentifierName" => TypeSpec::IdentifierName, - "Identifier" => TypeSpec::IdentifierName, - _ => TypeSpec::NamedType(name.clone()), - } - }), - NonAnyType::DOMString(ref s) => nullable( - s, - if self.is_at_interface("LiteralPropertyName") { - TypeSpec::PropertyKey - } else { - TypeSpec::String - }, - ), - NonAnyType::FrozenArrayType(ref t) => nullable( - t, - TypeSpec::Array { - contents: Box::new(self.convert_type(&t.type_.generics.body)), - supports_empty: true, - }, - ), - NonAnyType::FloatingPoint(ref t) => nullable(t, TypeSpec::Number), - NonAnyType::Integer(ref t) => nullable(t, TypeSpec::UnsignedLong), - _ => { - panic!("I don't know how to import {:?} yet", t); - } - } - } - - fn convert_union_type(&mut self, types: &MayBeNull) -> spec::Type { - let converted_types: Vec<_> = types - .type_ - .body - .list - .iter() - .map(|t| match t { - UnionMemberType::Single(AttributedNonAnyType { type_: t, .. }) => { - self.convert_single_type(t) - } - UnionMemberType::Union(t) => self.convert_union_type(t), - }) - .map(|t| t.spec) - .collect(); - - nullable(types, TypeSpec::TypeSum(TypeSum::new(converted_types))) - } - - fn convert_type(&mut self, t: &Type) -> spec::Type { - match t { - Type::Single(SingleType::NonAny(t)) => self.convert_single_type(t), - Type::Union(types) => self.convert_union_type(types), - _ => panic!("I don't know how to import {:?} yet", t), - } - } - - fn is_at_interface(&self, name: &str) -> bool { - if self.path.len() == 0 { - return false; - } - self.path[0].as_str() == name - } -} diff --git a/third_party/rust/binjs_meta/src/lib.rs b/third_party/rust/binjs_meta/src/lib.rs deleted file mode 100644 index 1c96ebbc19d6..000000000000 --- a/third_party/rust/binjs_meta/src/lib.rs +++ /dev/null @@ -1,21 +0,0 @@ -//! This crate offers tools designed to aid with the implementation -//! of the JavaScript syntax and BinAST encoders/decoders/manipulators. - -extern crate inflector; -extern crate itertools; - -#[macro_use] -extern crate log; -extern crate weedle; - -/// Generic tools for generating implementations of the Syntax. -pub mod export; - -/// Import a specification of the Syntax. -pub mod import; - -/// Manipulating the specifications of the language. -pub mod spec; - -/// Misc. utilities. -pub mod util; diff --git a/third_party/rust/binjs_meta/src/spec.rs b/third_party/rust/binjs_meta/src/spec.rs deleted file mode 100644 index 7f410a0a4ccc..000000000000 --- a/third_party/rust/binjs_meta/src/spec.rs +++ /dev/null @@ -1,1209 +0,0 @@ -//! Definition of a spec for a version (or subset) of JavaScript. - -pub use util::ToStr; - -use itertools::Itertools; - -use std; -use std::cell::*; -use std::collections::{HashMap, HashSet}; -use std::fmt::{Debug, Display}; -use std::hash::*; -use std::rc::*; - -/// Whether an attribute is eager or lazy. -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum Laziness { - /// An eager attribute is designed to be parsed immediately. - Eager, - /// A lazy attribute is designed for deferred parsing. - Lazy, -} - -/// The name of an interface or enum. -#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -pub struct NodeName(Rc); -impl NodeName { - pub fn to_string(&self) -> &String { - self.0.as_ref() - } - pub fn to_str(&self) -> &str { - self.0.as_ref() - } - pub fn to_rc_string(&self) -> &Rc { - &self.0 - } -} -impl Debug for NodeName { - fn fmt(&self, formatter: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { - Debug::fmt(self.to_str(), formatter) - } -} -impl Display for NodeName { - fn fmt(&self, formatter: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { - Display::fmt(self.to_str(), formatter) - } -} -impl ToStr for NodeName { - fn to_str(&self) -> &str { - &self.0 - } -} - -/// The name of a field in an interface. -#[derive(Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] -pub struct FieldName(Rc); -impl FieldName { - pub fn to_string(&self) -> &String { - self.0.as_ref() - } - pub fn to_rc_string(&self) -> &Rc { - &self.0 - } -} -impl Debug for FieldName { - fn fmt(&self, formatter: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { - Debug::fmt(self.to_str(), formatter) - } -} -impl ToStr for FieldName { - fn to_str(&self) -> &str { - self.0.as_ref() - } -} - -/// An enumeration of strings. -/// -/// A valid value is any of these strings. -#[derive(Debug)] -pub struct StringEnum { - name: NodeName, - // Invariant: values are distinct // FIXME: Not checked yet. - values: Vec, -} - -/// An enumeration of interfaces. -#[derive(Clone, Debug, PartialEq, Eq)] // FIXME: Get rid of Eq -pub struct TypeSum { - types: Vec, - /// Once we have called `into_spec`, this is guaranteed to resolve - /// to at least one Interface. - interfaces: HashSet, -} -impl TypeSum { - pub fn new(types: Vec) -> Self { - TypeSum { - types, - interfaces: HashSet::new(), - } - } - pub fn types(&self) -> &[TypeSpec] { - &self.types - } - pub fn types_mut(&mut self) -> &mut [TypeSpec] { - &mut self.types - } - pub fn interfaces(&self) -> &HashSet { - &self.interfaces - } - pub fn get_interface(&self, spec: &Spec, name: &NodeName) -> Option> { - debug!(target: "spec", "get_interface, looking for {:?} in sum {:?}", name, self); - for item in &self.types { - let result = item.get_interface(spec, name); - if result.is_some() { - return result; - } - } - None - } - - /// Add a new type case to this sum. - pub fn with_type_case(&mut self, spec: TypeSpec) -> &mut Self { - debug_assert_eq!(self.interfaces.len(), 0); - self.types.push(spec); - self - } -} - -/// Representation of a field in an interface. -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct Field { - /// The name of the field. - name: FieldName, - - /// The type of the field. - type_: Type, - - /// Documentation for the field. Ignored for the time being. - documentation: Option, - - laziness: Laziness, -} -impl Hash for Field { - fn hash(&self, state: &mut H) - where - H: Hasher, - { - self.name.hash(state) - } -} -impl Field { - pub fn new(name: FieldName, type_: Type) -> Self { - Field { - name, - type_, - documentation: None, - laziness: Laziness::Eager, - } - } - pub fn name(&self) -> &FieldName { - &self.name - } - pub fn type_(&self) -> &Type { - &self.type_ - } - pub fn is_lazy(&self) -> bool { - self.laziness == Laziness::Lazy - } - pub fn laziness(&self) -> Laziness { - self.laziness.clone() - } - pub fn with_laziness(mut self, laziness: Laziness) -> Self { - self.laziness = laziness; - self - } - pub fn doc(&self) -> Option<&str> { - match self.documentation { - None => None, - Some(ref s) => Some(&*s), - } - } - pub fn with_doc(mut self, doc: Option) -> Self { - self.documentation = doc; - self - } -} - -/// The contents of a type, typically that of a field. -/// -/// Note that we generally use `Type`, to represent -/// the fact that some fields accept `null` while -/// others do not. -#[derive(Clone, Debug, PartialEq, Eq)] -pub enum TypeSpec { - /// An array of values of the same type. - Array { - /// The type of values in the array. - contents: Box, - - /// If `true`, the array may be empty. - supports_empty: bool, - }, - - NamedType(NodeName), - - TypeSum(TypeSum), - - /// A boolean. - Boolean, - - /// A string. - String, - - /// A number, as per JavaScript specifications. - Number, - - UnsignedLong, - - /// A number of bytes in the binary file. - /// - /// This spec is used only internally, as a hidden - /// field injected by deanonymization, to represent - /// lazy fields. - Offset, - - /// Nothing. - /// - /// For the moment, this spec is used only internally. - Void, - - /// A string used to represent something bound in a scope (i.e. a variable, but not a property). - /// At this level, we make no distinction between `Identifier` and `IdentifierName`. - /// - /// Actually maps to a subset of `IdentifierName` in webidl. - IdentifierName, - - /// A key for a property. For the time being, we make no distinction between variants such - /// as `LiteralPropertyName` and `IdentifierName`-as-property-keys. - PropertyKey, -} - -#[derive(Clone, Debug)] -pub enum NamedType { - Interface(Rc), - Typedef(Rc), // FIXME: Check that there are no cycles. - StringEnum(Rc), -} - -impl NamedType { - pub fn as_interface(&self, spec: &Spec) -> Option> { - match *self { - NamedType::Interface(ref result) => Some(result.clone()), - NamedType::Typedef(ref type_) => { - if let TypeSpec::NamedType(ref named) = *type_.spec() { - let named = spec.get_type_by_name(named).expect("Type not found"); - named.as_interface(spec) - } else { - None - } - } - NamedType::StringEnum(_) => None, - } - } -} - -impl TypeSpec { - pub fn array(self) -> Type { - TypeSpec::Array { - contents: Box::new(Type { - spec: self, - or_null: false, - }), - supports_empty: true, - } - .required() - } - - pub fn non_empty_array(self) -> Type { - TypeSpec::Array { - contents: Box::new(Type { - spec: self, - or_null: false, - }), - supports_empty: false, - } - .required() - } - - pub fn optional(self) -> Option { - if let TypeSpec::Offset = self { - None - } else { - Some(Type { - spec: self, - or_null: true, - }) - } - } - - pub fn required(self) -> Type { - Type { - spec: self, - or_null: false, - } - } - - fn typespecs<'a>(&'a self) -> Vec<&'a TypeSpec> { - let mut result = Vec::new(); - let mut stack = vec![self]; - while let Some(current) = stack.pop() { - result.push(current); - match *current { - TypeSpec::Array { ref contents, .. } => { - stack.push(contents.spec()); - } - TypeSpec::TypeSum(ref sum) => { - for item in sum.types() { - stack.push(item) - } - } - _ => {} - } - } - result - } - - pub fn typenames<'a>(&'a self) -> HashSet<&'a NodeName> { - let mut result = HashSet::new(); - for spec in self.typespecs() { - if let TypeSpec::NamedType(ref name) = *spec { - result.insert(name); - } - } - result - } - - pub fn get_primitive(&self, spec: &Spec) -> Option> { - match *self { - TypeSpec::Boolean => Some(IsNullable::non_nullable(Primitive::Boolean)), - TypeSpec::Void => Some(IsNullable::non_nullable(Primitive::Void)), - TypeSpec::Number => Some(IsNullable::non_nullable(Primitive::Number)), - TypeSpec::UnsignedLong => Some(IsNullable::non_nullable(Primitive::UnsignedLong)), - TypeSpec::String => Some(IsNullable::non_nullable(Primitive::String)), - TypeSpec::Offset => Some(IsNullable::non_nullable(Primitive::Offset)), - TypeSpec::IdentifierName => Some(IsNullable::non_nullable(Primitive::IdentifierName)), - TypeSpec::PropertyKey => Some(IsNullable::non_nullable(Primitive::PropertyKey)), - TypeSpec::NamedType(ref name) => match spec.get_type_by_name(name).unwrap() { - NamedType::Interface(ref interface) => Some(IsNullable::non_nullable( - Primitive::Interface(interface.clone()), - )), - NamedType::Typedef(ref type_) => type_.get_primitive(spec), - NamedType::StringEnum(_) => None, - }, - _ => None, - } - } -} - -#[derive(Debug)] -pub struct IsNullable { - pub is_nullable: bool, - pub content: T, -} -impl IsNullable { - fn non_nullable(value: T) -> Self { - IsNullable { - is_nullable: false, - content: value, - } - } -} - -#[derive(Debug)] -pub enum Primitive { - String, - Boolean, - Void, - Number, - UnsignedLong, - Offset, - Interface(Rc), - IdentifierName, - PropertyKey, -} - -#[derive(Clone, Debug, PartialEq)] -pub struct Type { - pub spec: TypeSpec, - or_null: bool, -} -impl Eq for Type {} - -impl Type { - pub fn or_null(&mut self) -> &mut Self { - self.or_null = true; - self - } - - pub fn with_spec(&mut self, spec: TypeSpec) -> &mut Self { - self.spec = spec; - self - } - - pub fn with_type(&mut self, type_: Type) -> &mut Self { - self.spec = type_.spec; - self.or_null = type_.or_null; - self - } - - pub fn spec(&self) -> &TypeSpec { - &self.spec - } - pub fn spec_mut(&mut self) -> &mut TypeSpec { - &mut self.spec - } - pub fn is_optional(&self) -> bool { - self.or_null - } - - /// Shorthand constructors. - pub fn named(name: &NodeName) -> TypeSpec { - TypeSpec::NamedType(name.clone()) - } - pub fn sum(types: &[TypeSpec]) -> TypeSpec { - let specs = types.iter().cloned().collect(); - TypeSpec::TypeSum(TypeSum::new(specs)) - } - pub fn string() -> TypeSpec { - TypeSpec::String - } - pub fn number() -> TypeSpec { - TypeSpec::Number - } - pub fn unsigned_long() -> TypeSpec { - TypeSpec::UnsignedLong - } - pub fn bool() -> TypeSpec { - TypeSpec::Boolean - } - pub fn void() -> TypeSpec { - TypeSpec::Void - } - pub fn identifier_name() -> TypeSpec { - TypeSpec::IdentifierName - } - pub fn property_key() -> TypeSpec { - TypeSpec::PropertyKey - } - - /// An `offset` type, holding a number of bytes in the binary file. - pub fn offset() -> TypeSpec { - TypeSpec::Offset - } - - pub fn array(self) -> TypeSpec { - TypeSpec::Array { - contents: Box::new(self), - supports_empty: true, - } - } - - pub fn non_empty_array(self) -> TypeSpec { - TypeSpec::Array { - contents: Box::new(self), - supports_empty: false, - } - } - - pub fn get_primitive(&self, spec: &Spec) -> Option> { - if let Some(mut primitive) = self.spec.get_primitive(spec) { - primitive.is_nullable = primitive.is_nullable || self.or_null; - Some(primitive) - } else { - None - } - } -} - -/// Representation of an object, i.e. a set of fields. -/// -/// Field order is *not* specified, but is expected to remain stable during encoding -/// operations and during decoding operations. Note in particular that the order may -/// change between encoding and decoding. -#[derive(Clone, Debug)] -pub struct Obj { - fields: Vec, -} -impl PartialEq for Obj { - fn eq(&self, other: &Self) -> bool { - // Normalize order before comparing. - let me: HashSet<_> = self.fields.iter().collect(); - let other: HashSet<_> = other.fields.iter().collect(); - me == other - } -} -impl Eq for Obj {} - -impl Obj { - /// Create a new empty structure - pub fn new() -> Self { - Obj { fields: Vec::new() } - } - /// A list of the fields in the structure. - pub fn fields<'a>(&'a self) -> &'a [Field] { - &self.fields - } - /// Fetch a specific field in the structure - pub fn field<'a>(&'a self, name: &FieldName) -> Option<&'a Field> { - self.fields.iter().find(|field| &field.name == name) - } - - pub fn with_full_field(&mut self, field: Field) -> &mut Self { - if self.field(field.name()).is_some() { - warn!("Field: attempting to overwrite {:?}", field.name()); - return self; - } - self.fields.push(field); - self - } - - fn with_field_aux( - self, - name: &FieldName, - type_: Type, - laziness: Laziness, - doc: Option<&str>, - ) -> Self { - if self.field(name).is_some() { - warn!("Field: attempting to overwrite {:?}", name); - return self; - } - let mut fields = self.fields; - fields.push( - Field::new(name.clone(), type_) - .with_doc(doc.map(str::to_string)) - .with_laziness(laziness), - ); - Obj { fields } - } - - /// Extend a structure with a field. - pub fn with_field(self, name: &FieldName, type_: Type) -> Self { - self.with_field_aux(name, type_, Laziness::Eager, None) - } - - pub fn with_field_doc(self, name: &FieldName, type_: Type, doc: &str) -> Self { - self.with_field_aux(name, type_, Laziness::Eager, Some(doc)) - } - - pub fn with_field_lazy(self, name: &FieldName, type_: Type) -> Self { - self.with_field_aux(name, type_, Laziness::Lazy, None) - } -} - -impl StringEnum { - pub fn name(&self) -> &NodeName { - &self.name - } - - pub fn strings(&self) -> &[String] { - &self.values - } - - /// Add a string to the enum. Idempotent. - pub fn with_string(&mut self, string: &str) -> &mut Self { - let string = string.to_string(); - if self.values.iter().find(|x| **x == string).is_none() { - self.values.push(string.to_string()) - } - self - } - /// Add several enums to the list. Idempotent. - pub fn with_strings(&mut self, strings: &[&str]) -> &mut Self { - for string in strings { - self.with_string(string); - } - self - } -} - -#[derive(Clone, Debug)] -pub struct InterfaceDeclaration { - /// The name of the interface, e.g. `Node`. - name: NodeName, - - /// The contents of this interface, excluding the contents of parent interfaces. - contents: Obj, - - is_scope: bool, - - /// If Some(name), this interface introduces a scoped dictionary, i.e. a new - /// dictionary that is designed to be used when encoding/decoding its child - /// nodes. - scoped_dictionary: Option, -} - -impl InterfaceDeclaration { - /// A list of the fields in the interface. - pub fn fields<'a>(&'a self) -> &'a [Field] { - self.contents.fields() - } - /// Fetch a specific field in the structure - pub fn field<'a>(&'a self, name: &FieldName) -> Option<&'a Field> { - self.contents.field(name) - } - - pub fn with_full_field(&mut self, contents: Field) -> &mut Self { - let _ = self.contents.with_full_field(contents); - self - } - pub fn with_field(&mut self, name: &FieldName, type_: Type) -> &mut Self { - self.with_field_aux(name, type_, None, Laziness::Eager) - } - pub fn with_field_lazy(&mut self, name: &FieldName, type_: Type) -> &mut Self { - self.with_field_aux(name, type_, None, Laziness::Eager) - } - pub fn with_field_laziness( - &mut self, - name: &FieldName, - type_: Type, - laziness: Laziness, - ) -> &mut Self { - self.with_field_aux(name, type_, None, laziness) - } - pub fn with_field_doc(&mut self, name: &FieldName, type_: Type, doc: &str) -> &mut Self { - self.with_field_aux(name, type_, Some(doc), Laziness::Eager) - } - fn with_field_aux( - &mut self, - name: &FieldName, - type_: Type, - doc: Option<&str>, - laziness: Laziness, - ) -> &mut Self { - let mut contents = Obj::new(); - std::mem::swap(&mut self.contents, &mut contents); - self.contents = contents.with_field_aux(name, type_, laziness, doc); - self - } - pub fn with_scope(&mut self, value: bool) -> &mut Self { - self.is_scope = value; - self - } - pub fn with_scoped_dictionary(&mut self, field_name: &FieldName) -> &mut Self { - self.with_scoped_dictionary_str(field_name.to_str()) - } - pub fn with_scoped_dictionary_str(&mut self, field_name: &str) -> &mut Self { - let field_name = { - self.fields() - .into_iter() - .map(|field| field.name()) - .find(|candidate| candidate.to_str() == field_name) - .expect("Attempting to set a scoped dictionary with a non-existent field name") - .clone() - }; - self.scoped_dictionary = Some(field_name); - self - } -} - -/// A data structure used to progressively construct the `Spec`. -pub struct SpecBuilder { - /// All the interfaces entered so far. - interfaces_by_name: HashMap>, - - /// All the enums entered so far. - string_enums_by_name: HashMap>, - - typedefs_by_name: HashMap>, - - names: HashMap>, -} - -impl SpecBuilder { - pub fn new() -> Self { - SpecBuilder { - interfaces_by_name: HashMap::new(), - string_enums_by_name: HashMap::new(), - typedefs_by_name: HashMap::new(), - names: HashMap::new(), - } - } - - pub fn names(&self) -> &HashMap> { - &self.names - } - - /// Return an `NodeName` for a name. Equality comparison - /// on `NodeName` can be performed by checking physical - /// equality. - pub fn node_name(&mut self, name: &str) -> NodeName { - if let Some(result) = self.names.get(name) { - return NodeName(result.clone()); - } - let shared = Rc::new(name.to_string()); - let result = NodeName(shared.clone()); - self.names.insert(name.to_string(), shared); - result - } - pub fn get_node_name(&self, name: &str) -> Option { - self.names.get(name).map(|hit| NodeName(hit.clone())) - } - pub fn import_node_name(&mut self, node_name: &NodeName) { - self.names - .insert(node_name.to_string().clone(), node_name.0.clone()); - } - - pub fn field_name(&mut self, name: &str) -> FieldName { - if let Some(result) = self.names.get(name) { - return FieldName(result.clone()); - } - let shared = Rc::new(name.to_string()); - let result = FieldName(shared.clone()); - self.names.insert(name.to_string(), shared); - result - } - pub fn import_field_name(&mut self, field_name: &FieldName) { - self.names - .insert(field_name.to_string().clone(), field_name.0.clone()); - } - - pub fn add_interface(&mut self, name: &NodeName) -> Option> { - if self.interfaces_by_name.get(name).is_some() { - return None; - } - let result = RefCell::new(InterfaceDeclaration { - name: name.clone(), - contents: Obj::new(), - is_scope: false, - scoped_dictionary: None, - }); - self.interfaces_by_name.insert(name.clone(), result); - self.interfaces_by_name.get(name).map(RefCell::borrow_mut) - } - pub fn get_interface(&mut self, name: &NodeName) -> Option> { - self.interfaces_by_name.get(name).map(RefCell::borrow_mut) - } - - /// Add a named enumeration. - pub fn add_string_enum(&mut self, name: &NodeName) -> Option> { - if self.string_enums_by_name.get(name).is_some() { - return None; - } - let e = RefCell::new(StringEnum { - name: name.clone(), - values: vec![], - }); - self.string_enums_by_name.insert(name.clone(), e); - self.string_enums_by_name.get(name).map(RefCell::borrow_mut) - } - - pub fn add_typedef(&mut self, name: &NodeName) -> Option> { - if self.typedefs_by_name.get(name).is_some() { - return None; - } - let e = RefCell::new(TypeSpec::Void.required()); - self.typedefs_by_name.insert(name.clone(), e); - self.typedefs_by_name.get(name).map(RefCell::borrow_mut) - } - - /// Access an already added typedef. - pub fn get_typedef(&self, name: &NodeName) -> Option> { - self.typedefs_by_name.get(name).map(RefCell::borrow) - } - - /// Access an already added typedef, mutably. - pub fn get_typedef_mut(&mut self, name: &NodeName) -> Option> { - self.typedefs_by_name.get(name).map(RefCell::borrow_mut) - } - - /// Generate the graph. - pub fn into_spec<'a>(self, options: SpecOptions<'a>) -> Spec { - // 1. Collect node names. - let mut interfaces_by_name = self.interfaces_by_name; - let interfaces_by_name: HashMap<_, _> = interfaces_by_name - .drain() - .map(|(k, v)| { - ( - k, - Rc::new(Interface { - declaration: RefCell::into_inner(v), - }), - ) - }) - .collect(); - let mut string_enums_by_name = self.string_enums_by_name; - let string_enums_by_name: HashMap<_, _> = string_enums_by_name - .drain() - .map(|(k, v)| (k, Rc::new(RefCell::into_inner(v)))) - .collect(); - let mut typedefs_by_name = self.typedefs_by_name; - let typedefs_by_name: HashMap<_, _> = typedefs_by_name - .drain() - .map(|(k, v)| (k, Rc::new(RefCell::into_inner(v)))) - .collect(); - - let node_names: HashMap<_, _> = interfaces_by_name - .keys() - .chain(string_enums_by_name.keys()) - .chain(typedefs_by_name.keys()) - .map(|name| (name.to_string().clone(), name.clone())) - .collect(); - debug!(target: "spec", "Established list of node names: {:?} ({})", - node_names.keys() - .sorted(), - node_names.len()); - - // 2. Collect all field names. - let mut fields = HashMap::new(); - for interface in interfaces_by_name.values() { - for field in &interface.declaration.contents.fields { - fields.insert(field.name.to_string().clone(), field.name.clone()); - } - } - - let mut resolved_type_sums_by_name: HashMap> = HashMap::new(); - { - // 3. Check that node names are used but not duplicated. - for name in node_names.values() { - let mut instances = 0; - if interfaces_by_name.contains_key(name) { - instances += 1; - } - if string_enums_by_name.contains_key(name) { - instances += 1; - } - if typedefs_by_name.contains_key(name) { - instances += 1; - } - assert!(instances > 0, "Type name {} is never used", name.to_str()); - assert_eq!(instances, 1, "Duplicate type name {}", name.to_str()); - } - - // 4. Check that all instances of `TypeSpec::NamedType` refer to an existing name. - let mut used_typenames = HashSet::new(); - for type_ in typedefs_by_name.values() { - for name in type_.spec().typenames() { - used_typenames.insert(name); - } - } - for interface in interfaces_by_name.values() { - for field in interface.declaration.contents.fields() { - for name in field.type_().spec().typenames() { - used_typenames.insert(name); - } - } - } - for name in &used_typenames { - // Built-in types - if name.to_str() == "IdentifierName" - || name.to_str() == "Identifier" - || name.to_str() == "PropertyKey" - { - continue; - } - if typedefs_by_name.contains_key(name) { - continue; - } - if interfaces_by_name.contains_key(name) { - continue; - } - if string_enums_by_name.contains_key(name) { - continue; - } - panic!("No definition for type {}", name.to_str()); - } - - #[derive(Clone, Debug)] - enum TypeClassification { - SumOfInterfaces(HashSet), - Array, - Primitive, - StringEnum, - Optional, - } - - // 5. Classify typedefs between - // - stuff that can only be put in a sum of interfaces (interfaces, sums of interfaces, typedefs thereof); - // - stuff that can never be put in a sum of interfaces (other stuff) - // - bad stuff that attempts to mix both - - // name => unbound if we haven't seen the name yet - // => `None` if we are currently classifying (used to detect cycles), - // => `Some(SumOfInterfaces(set))` if the name describes a sum of interfaces - // => `Some(BadForSumOfInterfaces)` if the name describes something that can't be summed with an interface - let mut classification: HashMap> = HashMap::new(); - fn classify_type( - typedefs_by_name: &HashMap>, - string_enums_by_name: &HashMap>, - interfaces_by_name: &HashMap>, - cache: &mut HashMap>, - type_: &TypeSpec, - name: &NodeName, - ) -> TypeClassification { - debug!(target: "spec", "classify_type for {:?}: walking {:?}", name, type_); - match *type_ { - TypeSpec::Array { ref contents, .. } => { - // Check that the contents are correct. - let _ = classify_type( - typedefs_by_name, - string_enums_by_name, - interfaces_by_name, - cache, - contents.spec(), - name, - ); - // Regardless, the result is bad for a sum of interfaces. - debug!(target: "spec", "classify_type => don't put me in an interface"); - TypeClassification::Array - } - TypeSpec::Boolean - | TypeSpec::Number - | TypeSpec::String - | TypeSpec::Void - | TypeSpec::Offset - | TypeSpec::UnsignedLong - | TypeSpec::IdentifierName - | TypeSpec::PropertyKey => { - debug!(target: "spec", "classify_type => don't put me in an interface"); - TypeClassification::Primitive - } - TypeSpec::NamedType(ref name) => { - if let Some(fetch) = cache.get(name) { - if let Some(ref result) = *fetch { - debug!(target: "spec", "classify_type {:?} => (cached) {:?}", name, result); - return result.clone(); - } else { - panic!("Cycle detected while examining {}", name.to_str()); - } - } - // Start lookup for this name. - cache.insert(name.clone(), None); - let result = if name.to_str() == "IdentifierName" - || name.to_str() == "Identifier" - || name.to_str() == "PropertyKey" - { - TypeClassification::Primitive - } else if interfaces_by_name.contains_key(name) { - let mut names = HashSet::new(); - names.insert(name.clone()); - TypeClassification::SumOfInterfaces(names) - } else if string_enums_by_name.contains_key(name) { - TypeClassification::StringEnum - } else { - let type_ = typedefs_by_name - .get(name) - .unwrap_or_else(|| panic!("Type {} not found", name)); // Completeness checked abover in this method. - classify_type( - typedefs_by_name, - string_enums_by_name, - interfaces_by_name, - cache, - type_.spec(), - name, - ) - }; - debug!(target: "spec", "classify_type {:?} => (inserting in cache) {:?}", name, result); - cache.insert(name.clone(), Some(result.clone())); - result - } - TypeSpec::TypeSum(ref sum) => { - let mut names = HashSet::new(); - for type_ in sum.types() { - match classify_type(typedefs_by_name, string_enums_by_name, interfaces_by_name, cache, type_, name) { - TypeClassification::SumOfInterfaces(sum) => { - names.extend(sum); - } - class => - panic!("In type {name}, there is a non-interface type {class:?} ({type_:?}) in a sum {sum:?}", - name = name.to_str(), - class = class, - sum = sum, - type_ = type_), - } - } - debug!(target: "spec", "classify_type => built sum {:?}", names); - TypeClassification::SumOfInterfaces(names) - } - } - } - for (name, type_) in &typedefs_by_name { - classification.insert(name.clone(), None); - let class = classify_type( - &typedefs_by_name, - &string_enums_by_name, - &interfaces_by_name, - &mut classification, - type_.spec(), - name, - ); - if !type_.is_optional() { - classification.insert(name.clone(), Some(class)); - } else { - // FIXME: That looks weird. - classification.insert(name.clone(), Some(TypeClassification::Optional)); - } - } - - // 6. Using this classification, check that the attributes of interfaces don't mix - // poorly items of both kinds. - for (name, interface) in &interfaces_by_name { - for field in interface.declaration.contents.fields() { - classify_type( - &typedefs_by_name, - &string_enums_by_name, - &interfaces_by_name, - &mut classification, - field.type_().spec(), - name, - ); - } - } - - // 7. Fill resolved_type_sums_by_name, for later use. - for (name, class) in classification.drain() { - if !typedefs_by_name.contains_key(&name) { - continue; - } - if let Some(TypeClassification::SumOfInterfaces(sum)) = class { - resolved_type_sums_by_name.insert(name, sum); - } - } - } - - let spec = Spec { - interfaces_by_name, - string_enums_by_name, - typedefs_by_name, - resolved_type_sums_by_name, - node_names, - fields, - root: options.root.clone(), - null: options.null.clone(), - }; - - spec - } -} - -/// Representation of an interface in a grammar declaration. -/// -/// Interfaces represent nodes in the AST. Each interface -/// has a name, a type, defines properties (also known as -/// `attribute` in webidl) which hold values. -#[derive(Debug)] -pub struct Interface { - declaration: InterfaceDeclaration, -} - -impl Interface { - /// Returns the full list of fields for this structure. - /// This method is in charge of: - /// - ensuring that the fields of parent structures are properly accounted for; - /// - disregarding ignored fields (i.e. `position`, `type`); - /// - disregarding fields with a single possible value. - pub fn contents(&self) -> &Obj { - &self.declaration.contents - } - - /// Returns the name of the interface. - pub fn name(&self) -> &NodeName { - &self.declaration.name - } - - /// Returns a type specification for this interface. - /// - /// The result is a `NamedType` with this interface's name. - pub fn spec(&self) -> TypeSpec { - TypeSpec::NamedType(self.name().clone()) - } - - pub fn type_(&self) -> Type { - self.spec().required() - } - - pub fn get_field_by_name(&self, name: &FieldName) -> Option<&Field> { - for field in self.contents().fields() { - if name == field.name() { - return Some(field); - } - } - None - } - - pub fn is_scope(&self) -> bool { - self.declaration.is_scope - } - - /// If this interface introduces a scoped dictionary change, - /// return Some(field_name) where field_name is - /// the field of this interface containing the name of - /// the dictionary to use in the sub-ast. - pub fn scoped_dictionary(&self) -> Option { - self.declaration.scoped_dictionary.clone() - } -} - -/// Immutable representation of the spec. -pub struct Spec { - interfaces_by_name: HashMap>, - string_enums_by_name: HashMap>, - typedefs_by_name: HashMap>, - - resolved_type_sums_by_name: HashMap>, - - node_names: HashMap, - fields: HashMap, - root: NodeName, - null: NodeName, -} - -impl Spec { - pub fn get_interface_by_name(&self, name: &NodeName) -> Option<&Interface> { - self.interfaces_by_name - .get(name) - .map(std::borrow::Borrow::borrow) - } - pub fn interfaces_by_name(&self) -> &HashMap> { - &self.interfaces_by_name - } - pub fn string_enums_by_name(&self) -> &HashMap> { - &self.string_enums_by_name - } - pub fn typedefs_by_name(&self) -> &HashMap> { - &self.typedefs_by_name - } - pub fn resolved_sums_of_interfaces_by_name(&self) -> &HashMap> { - &self.resolved_type_sums_by_name - } - - pub fn get_type_by_name(&self, name: &NodeName) -> Option { - if let Some(interface) = self.interfaces_by_name.get(name) { - return Some(NamedType::Interface(interface.clone())); - } - if let Some(strings_enum) = self.string_enums_by_name.get(name) { - return Some(NamedType::StringEnum(strings_enum.clone())); - } - if let Some(type_) = self.typedefs_by_name.get(name) { - return Some(NamedType::Typedef(type_.clone())); - } - None - } - pub fn get_field_name(&self, name: &str) -> Option<&FieldName> { - self.fields.get(name) - } - pub fn get_node_name(&self, name: &str) -> Option<&NodeName> { - self.node_names.get(name) - } - pub fn node_names(&self) -> &HashMap { - &self.node_names - } - pub fn field_names(&self) -> &HashMap { - &self.fields - } - pub fn get_root_name(&self) -> &NodeName { - &self.root - } - pub fn get_null_name(&self) -> &NodeName { - &self.null - } - - /// The starting point for parsing. - pub fn get_root(&self) -> NamedType { - self.get_type_by_name(&self.root).unwrap() - } -} - -/// Informations passed during the creation of a `Spec` object. -pub struct SpecOptions<'a> { - /// The name of the node used to start encoding. - pub root: &'a NodeName, - pub null: &'a NodeName, -} - -pub trait HasInterfaces { - fn get_interface(&self, spec: &Spec, name: &NodeName) -> Option>; -} - -impl HasInterfaces for NamedType { - fn get_interface(&self, spec: &Spec, name: &NodeName) -> Option> { - debug!(target: "spec", "get_interface, looking for {:?} in named type {:?}", name, self); - match *self { - NamedType::Interface(_) => None, - NamedType::StringEnum(_) => None, - NamedType::Typedef(ref type_) => type_.spec().get_interface(spec, name), - } - } -} - -impl HasInterfaces for TypeSpec { - fn get_interface(&self, spec: &Spec, name: &NodeName) -> Option> { - debug!(target: "spec", "get_interface, looking for {:?} in spec {:?}", name, self); - match *self { - TypeSpec::NamedType(ref my_name) => { - let follow = spec.get_type_by_name(my_name); - if let Some(follow) = follow { - if name == my_name { - follow.as_interface(spec) - } else { - follow.get_interface(spec, name) - } - } else { - None - } - } - TypeSpec::TypeSum(ref sum) => sum.get_interface(spec, name), - _ => None, - } - } -} diff --git a/third_party/rust/binjs_meta/src/util.rs b/third_party/rust/binjs_meta/src/util.rs deleted file mode 100644 index d5fb75de36a5..000000000000 --- a/third_party/rust/binjs_meta/src/util.rs +++ /dev/null @@ -1,535 +0,0 @@ -//! Miscellaneous utilities. - -pub trait ToStr { - /// Return the value as a `str`. - fn to_str(&self) -> &str; - fn newline(&self) -> String { - format!("{}\n", self.to_str()) - } - - /// Append newline if the string is not empty. - fn newline_if_not_empty(&self) -> String { - let s = self.to_str(); - if s.len() == 0 { - "".to_string() - } else { - format!("{}\n", s) - } - } -} - -impl<'a> ToStr for &'a str { - fn to_str(&self) -> &str { - *self - } -} - -impl ToStr for str { - fn to_str(&self) -> &str { - self - } -} - -impl ToStr for String { - fn to_str(&self) -> &str { - &self - } -} - -/// A string or string-like construction that can be -/// converted to upper case, lower case, class case, etc -pub trait ToCases: ToStr { - /// Return the value in class case, e.g. - /// - /// ``` - /// use binjs_meta::util::ToCases; - /// - /// assert_eq!(&"foo_bar".to_class_cases(), "FooBar"); - /// assert_eq!(&"fooBars".to_class_cases(), "FooBars"); - /// ``` - fn to_class_cases(&self) -> String { - self.to_str().to_class_cases() - } - - /// Return the value in a format suitable for use as a cpp `enum` - /// variants. - /// - /// ``` - /// use binjs_meta::util::ToCases; - /// - /// assert_eq!(&"foo_bar".to_cpp_enum_case(), "FooBar"); - /// assert_eq!(&"fooBars".to_cpp_enum_case(), "FooBars"); - /// assert_eq!(&"+=".to_cpp_enum_case(), "PlusAssign"); - /// ``` - fn to_cpp_enum_case(&self) -> String { - self.to_str().to_cpp_enum_case() - } - - /// Return the value in a format suitable for use as a C++ field name - /// or identifier. - /// - /// ``` - /// use binjs_meta::util::ToCases; - /// - /// assert_eq!(&"foo_bar".to_cpp_field_case(), "fooBar"); - /// assert_eq!(&"fooBars".to_cpp_field_case(), "fooBars"); - /// assert_eq!(&"class".to_cpp_field_case(), "class_"); - /// ``` - fn to_cpp_field_case(&self) -> String { - self.to_str().to_cpp_field_case() - } - - /// Return the value in a format suitable for use as a Rust field name - /// or identifier. - /// - /// ``` - /// use binjs_meta::util::ToCases; - /// - /// assert_eq!(&"foo_bar".to_rust_identifier_case(), "foo_bar"); - /// assert_eq!(&"fooBars".to_rust_identifier_case(), "foo_bars"); - /// assert_eq!(&"self".to_rust_identifier_case(), "self_"); - /// ``` - fn to_rust_identifier_case(&self) -> String { - self.to_str().to_rust_identifier_case() - } -} - -impl ToCases for T -where - T: ToStr, -{ - fn to_class_cases(&self) -> String { - match self.to_str() { - "" => "Null".to_string(), - other => { - let result = inflector::cases::pascalcase::to_pascal_case(other); - assert!( - result.to_str().len() != 0, - "Could not convert '{}' to class case", - other - ); - result - } - } - } - fn to_cpp_enum_case(&self) -> String { - match self.to_str() { - "+=" => "PlusAssign".to_string(), - "-=" => "MinusAssign".to_string(), - "*=" => "MulAssign".to_string(), - "/=" => "DivAssign".to_string(), - "%=" => "ModAssign".to_string(), - "**=" => "PowAssign".to_string(), - "<<=" => "LshAssign".to_string(), - ">>=" => "RshAssign".to_string(), - ">>>=" => "UrshAssign".to_string(), - "|=" => "BitOrAssign".to_string(), - "^=" => "BitXorAssign".to_string(), - "&=" => "BitAndAssign".to_string(), - "," => "Comma".to_string(), - "||" => "LogicalOr".to_string(), - "&&" => "LogicalAnd".to_string(), - "|" => "BitOr".to_string(), - "^" => "BitXor".to_string(), - "&" => "BitAnd".to_string(), - "==" => "Eq".to_string(), - "!=" => "Neq".to_string(), - "===" => "StrictEq".to_string(), - "!==" => "StrictNeq".to_string(), - "<" => "LessThan".to_string(), - "<=" => "LeqThan".to_string(), - ">" => "GreaterThan".to_string(), - ">=" => "GeqThan".to_string(), - "<<" => "Lsh".to_string(), - ">>" => "Rsh".to_string(), - ">>>" => "Ursh".to_string(), - "+" => "Plus".to_string(), - "-" => "Minus".to_string(), - "~" => "BitNot".to_string(), - "*" => "Mul".to_string(), - "/" => "Div".to_string(), - "%" => "Mod".to_string(), - "**" => "Pow".to_string(), - "!" => "Not".to_string(), - "++" => "Incr".to_string(), - "--" => "Decr".to_string(), - "" => "_Null".to_string(), - _ => { - let class_cased = self.to_class_cases(); - assert!( - &class_cased != "", - "FIXME: `to_class_cases` does not handle {} yet", - self.to_str() - ); - class_cased - } - } - } - fn to_cpp_field_case(&self) -> String { - let snake = inflector::cases::camelcase::to_camel_case(self.to_str()); - match &snake as &str { - "class" => "class_".to_string(), - "operator" => "operator_".to_string(), - "const" => "const_".to_string(), - "void" => "void_".to_string(), - "delete" => "delete_".to_string(), - "in" => "in_".to_string(), - // Names reserved by us - "result" => "result_".to_string(), - "kind" => "kind_".to_string(), - // Special cases - "" => unimplemented!( - "FIXME: `to_cpp_field_case` does not handle {} yet", - self.to_str() - ), - _ => snake, - } - } - fn to_rust_identifier_case(&self) -> String { - let snake = inflector::cases::snakecase::to_snake_case(self.to_str()); - match &snake as &str { - "self" => "self_".to_string(), - "super" => "super_".to_string(), - "type" => "type_".to_string(), - "" if self.to_str() == "" => "null".to_string(), - "" => unimplemented!( - "FIXME: `to_rust_identifier_case` does not handle {} yet", - self.to_str() - ), - _ => snake, - } - } -} - -/// A string or string-like construction that can be reindented. -pub trait Reindentable { - /// Remove leading whitespace, replace it with `prefix`. - /// - /// If `self` spans more than one line, the leading whitespace - /// is computed from the first line and extracted from all lines - /// and `prefix` is added to all lines. - /// - /// ``` - /// use binjs_meta::util::Reindentable; - /// - /// assert_eq!(&"abc".reindent(" "), " abc"); - /// assert_eq!(&" def".reindent(" "), " def"); - /// assert_eq!(&" ghi".reindent(" "), " ghi"); - /// assert_eq!(&" jkl\n mno".reindent(" "), " jkl\n mno"); - /// ``` - fn reindent(&self, prefix: &str) -> String; - - /// Remove leading whitespace, replace it with `prefix`, - /// ensure that the text fits within `width` columns. - /// - /// If `self` spans more than one line, the leading whitespace - /// is computed from the first line and extracted from all lines. - /// and `prefix` is added to all lines. - /// - /// If the result goes past `width` columns, `self` is split - /// into several lines to try and fit within `width` columns. - /// - /// ``` - /// use binjs_meta::util::Reindentable; - /// - /// assert_eq!(&"abc".fit("// ", 30), "// abc"); - /// assert_eq!(&" def".fit("// ", 30), "// def"); - /// assert_eq!(&" ghi".fit("// ", 30), "// ghi"); - /// assert_eq!(&" jkl\n mno".fit("// ", 30), "// jkl\n// mno"); - /// assert_eq!(&"abc def ghi".fit("// ", 8), "// abc\n// def\n// ghi"); - /// assert_eq!(&"abc def ghi".fit("// ", 5), "// abc\n// def\n// ghi"); - /// ``` - fn fit(&self, prefix: &str, width: usize) -> String; -} - -impl Reindentable for T -where - T: ToStr, -{ - fn reindent(&self, prefix: &str) -> String { - use itertools::Itertools; - - let str = self.to_str(); - - // Determine the number of whitespace chars on the first line. - // Trim that many whitespace chars on the following lines. - if let Some(first_line) = str.lines().next() { - let indent_len = first_line - .chars() - .take_while(|c| char::is_whitespace(*c)) - .count(); - format!( - "{}", - str.lines() - .map(|line| if line.len() > indent_len { - format!( - "{prefix}{text}", - prefix = prefix, - text = line[indent_len..].to_string() - ) - } else { - "".to_string() - }) - .format("\n") - ) - } else { - "".to_string() - } - } - - fn fit(&self, prefix: &str, columns: usize) -> String { - use itertools::Itertools; - - let str = self.to_str(); - // Determine the number of whitespace chars on the first line. - // Trim that many whitespace chars on the following lines. - if let Some(first_line) = str.lines().next() { - let indent_len = first_line - .chars() - .take_while(|c| char::is_whitespace(*c)) - .count(); - let mut lines = vec![]; - 'per_line: for line in str.lines() { - eprintln!("Inspecting line {}", line); - let text = &line[indent_len..]; - let mut gobbled = 0; - while text.len() > gobbled { - let rest = &text[gobbled..]; - eprintln!("Line still contains {} ({})", rest, gobbled); - if rest.len() + prefix.len() > columns { - // Try and find the largest prefix of `text` that fits within `columns`. - let mut iterator = rest - .chars() - .enumerate() - .filter(|&(_, c)| char::is_whitespace(c)); - let mut last_whitespace_before_break = None; - let mut first_whitespace_after_break = None; - while let Some((found_pos, _)) = iterator.next() { - if found_pos + prefix.len() <= columns { - last_whitespace_before_break = Some(found_pos); - } else { - first_whitespace_after_break = Some(found_pos); - break; - } - } - - match (last_whitespace_before_break, first_whitespace_after_break) { - (None, None) => { - eprintln!("Ok, string didn't contain any whitespace: '{}'", rest); - // Oh, `rest` does not contain any whitespace. Well, use everything. - lines.push(format!("{prefix}{rest}", prefix = prefix, rest = rest)); - continue 'per_line; - } - (Some(pos), _) | (None, Some(pos)) if pos != 0 => { - eprintln!("Best whitespace found at {}", pos); - // Use `rest[0..pos]`, trimmed right. - gobbled += pos + 1; - let line = format!( - "{prefix}{rest}", - prefix = prefix, - rest = rest[0..pos].trim_end() - ); - lines.push(line) - } - _else => panic!("{:?}", _else), - } - } else { - let line = format!("{prefix}{rest}", prefix = prefix, rest = rest); - lines.push(line); - continue 'per_line; - } - } - } - format!("{lines}", lines = lines.iter().format("\n")) - } else { - "".to_string() - } - } -} - -impl Reindentable for Option { - fn reindent(&self, prefix: &str) -> String { - match *self { - None => "".to_string(), - Some(ref string) => string.reindent(prefix), - } - } - fn fit(&self, prefix: &str, columns: usize) -> String { - match *self { - None => "".to_string(), - Some(ref string) => string.fit(prefix, columns), - } - } -} - -pub mod name_sorter { - use std; - use std::collections::HashMap; - - /// A type used to sort names by length, then prefixes, to speed - /// up lookups. - pub struct NameSorter { - per_length: HashMap>, - len: usize, - } - impl NameSorter { - pub fn new() -> Self { - NameSorter { - per_length: HashMap::new(), - len: 0, - } - } - - /// Return the number of items in the sorter. - pub fn len(&self) -> usize { - debug_assert!({ - // Let's check that the length is always the sum of sublengths. - let len = self - .per_length - .values() - .map(|v| match v { - &Node::Leaf(Some(_)) => 1, - &Node::Leaf(_) => panic!("Invariant error: empty leaf!"), - &Node::Internal { ref len, .. } => *len, - }) - .fold(0, |x, y| (x + y)); - len == self.len - }); - self.len - } - - /// Insert a value in a sorter. - /// - /// ``` - /// let mut sorter = binjs_meta::util::name_sorter::NameSorter::new(); - /// assert_eq!(sorter.len(), 0); - /// - /// assert!(sorter.insert("abcd", 0).is_none()); - /// assert_eq!(sorter.len(), 1); - /// assert_eq!(*sorter.get("abcd").unwrap(), 0); - /// assert!(sorter.get("dbca").is_none()); - /// assert!(sorter.get("").is_none()); - /// - /// assert!(sorter.insert("dcba", 1).is_none()); - /// assert_eq!(sorter.len(), 2); - /// assert_eq!(*sorter.get("abcd").unwrap(), 0); - /// assert_eq!(*sorter.get("dcba").unwrap(), 1); - /// assert!(sorter.get("").is_none()); - /// - /// assert_eq!(sorter.insert("abcd", 3).unwrap(), 0); - /// assert_eq!(sorter.len(), 2); - /// assert_eq!(*sorter.get("abcd").unwrap(), 3); - /// assert_eq!(*sorter.get("dcba").unwrap(), 1); - /// assert!(sorter.get("").is_none()); - /// - /// assert!(sorter.insert("", 4).is_none()); - /// assert_eq!(sorter.len(), 3); - /// assert_eq!(*sorter.get("abcd").unwrap(), 3); - /// assert_eq!(*sorter.get("dcba").unwrap(), 1); - /// assert_eq!(*sorter.get("").unwrap(), 4); - /// - /// assert_eq!(sorter.insert("", 5).unwrap(), 4); - /// assert_eq!(sorter.len(), 3); - /// assert_eq!(*sorter.get("abcd").unwrap(), 3); - /// assert_eq!(*sorter.get("dcba").unwrap(), 1); - /// assert_eq!(*sorter.get("").unwrap(), 5); - /// ``` - pub fn insert(&mut self, key: &str, value: T) -> Option { - if let Some(node) = self.per_length.get_mut(&key.len()) { - let result = node.insert(key, value); - if result.is_none() { - self.len += 1; - } - return result; - } - let node = Node::new(key, value); - self.per_length.insert(key.len(), node); - self.len += 1; - None - } - - pub fn iter(&self) -> impl Iterator)> { - self.per_length.iter().map(|(&len, node)| (len, node)) - } - - pub fn get(&self, key: &str) -> Option<&T> { - self.per_length - .get(&key.len()) - .and_then(|node| node.get(key)) - } - } - - pub enum Node { - Leaf(Option), - Internal { - /// The children of this node. - /// - /// Invariant: May only be empty during a call to `insert()`. - children: HashMap>, - - /// Number of leaves in this subtree. - len: usize, - }, - } - impl Node { - fn get(&self, key: &str) -> Option<&T> { - match (self, key.chars().next()) { - (&Node::Leaf(Some(ref result)), None) => Some(result), - (&Node::Internal { ref children, .. }, Some(c)) => { - debug_assert!(children.len() != 0); - children.get(&c).and_then(|node| node.get(&key[1..])) - } - _ => panic!("Invariant error: length"), - } - } - - fn insert(&mut self, key: &str, value: T) -> Option { - match (self, key.chars().next()) { - (&mut Node::Leaf(ref mut old), None) => { - // We have reached the end of `name`. - let mut data = Some(value); - std::mem::swap(&mut data, old); - data - } - ( - &mut Node::Internal { - ref mut children, - ref mut len, - }, - Some(c), - ) => { - let result = { - let entry = if key.len() == 1 { - children.entry(c).or_insert_with(|| Node::Leaf(None)) - } else { - children.entry(c).or_insert_with(|| Node::Internal { - children: HashMap::new(), - len: 0, - }) - }; - entry.insert(&key[1..], value) - }; - if result.is_none() { - *len += 1; - } - debug_assert!(*len > 0); - debug_assert!(children.len() != 0); - result - } - _ => panic!("Invariant error: length"), - } - } - fn new(key: &str, value: T) -> Self { - if key.len() == 0 { - Node::Leaf(Some(value)) - } else { - let mut node = Node::Internal { - children: HashMap::new(), - len: 0, - }; - assert!(node.insert(key, value).is_none()); - node - } - } - } -} diff --git a/third_party/rust/weedle/.cargo-checksum.json b/third_party/rust/weedle/.cargo-checksum.json deleted file mode 100644 index 3fadecee00dc..000000000000 --- a/third_party/rust/weedle/.cargo-checksum.json +++ /dev/null @@ -1 +0,0 @@ -{"files":{"Cargo.toml":"84dc605d368f68a3e25b2e240552ce6e2a8731e80f73cfd4cb0b931528b473a7","LICENSE.md":"47cdc00faacda4d0ac0dabfcef03ab6f4bef6a02f80cb3fd0482047f00f9a16d","README.md":"e4363ea12b63bb6d3e461396f6fd46fe4cbf9a8635258499f4d551dadfc06655","src/argument.rs":"be162d59a9f1ef7d9d51d0f3492946f0dd263202af8355eeaee14ce4181775fc","src/attribute.rs":"b3577059be9c1262d3360b4b4cf4cc6cb052251e5b9d64906fb40fc5e925da69","src/common.rs":"7ac264f83ff596914af32fb08947cc500a75df57e43d9b2fce93163e5a20a738","src/dictionary.rs":"be209d70b0db33acf753ca63998a63dd37a9d4b193583a1490782781360c2d01","src/interface.rs":"4e1f37079dec75633b26289b82bda0d3b4a1479a4aede74c01e20fe6c2d93496","src/lib.rs":"762c35dc6ef77b6b1c871bd0391d09203a479937e4688a029a17c8d8a5f9e8ba","src/literal.rs":"dd58d410e2329633e2b2151157b29671ad5f78c8be0bec5c81be083168311f94","src/macros.rs":"aa95fd957d5175fb2779faec5d40b717fb5efd581f0f13ef7ba3510f37092da3","src/mixin.rs":"d65ff3a49615dabdf3f7845723f01ae730a83c8ef5bdd9a945d35149a9ef2858","src/namespace.rs":"fe6b406c2ab8bd904d0dff8a12321c77f4082ab364559e578e53ab415c8541fa","src/term.rs":"48ac583ae73d115afbedca6e7e9f32b316b7a308ba37cb9153eeac9773561028","src/types.rs":"3f81a1d820f0b6777f46c74366359953bf79465c3eb1ace4b3a383c22f4e1d88","src/whitespace.rs":"069df2ae0f37d621a8ef84b08408c090ff1ead8164e52caa8ea7d57838f04cac","tests/defs/dom.webidl":"93a70734538233a6b9db7578375b5a3d8783bcdcfc9970cc61cddcd03c832d6c","tests/defs/html.webidl":"4b2be1a0435b1fc26e60083006e2ecf7158611c190f95e5c4c8290510de22777","tests/defs/interface-constructor.webidl":"8b31240c838607e460086cb55a57a111605199f88f4291a83f7125c8c3c4fd1a","tests/defs/mediacapture-streams.webidl":"82615b15129e87aac56a0ca74bd763c5416732020a2b567dc4582835e0846144","tests/webidl.rs":"097683a01f3c058be3341d7d8b0af18964686059485941cbee22e63b94406c1f"},"package":"8a7d4f9feb723a800d8f7b74edc9fa44ff35cb0b2ec64886714362f423427f37"} \ No newline at end of file diff --git a/third_party/rust/weedle/Cargo.toml b/third_party/rust/weedle/Cargo.toml deleted file mode 100644 index ea808e820a79..000000000000 --- a/third_party/rust/weedle/Cargo.toml +++ /dev/null @@ -1,27 +0,0 @@ -# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO -# -# When uploading crates to the registry Cargo will automatically -# "normalize" Cargo.toml files for maximal compatibility -# with all versions of Cargo and also rewrite `path` dependencies -# to registry (e.g., crates.io) dependencies -# -# If you believe there's an error in this file please file an -# issue against the rust-lang/cargo repository. If you're -# editing this file be aware that the upstream Cargo.toml -# will likely look very different (and much more reasonable) - -[package] -edition = "2018" -name = "weedle" -version = "0.11.0" -authors = ["Sharad Chand "] -description = "A WebIDL Parser" -homepage = "https://github.com/rustwasm/weedle" -documentation = "https://docs.rs/weedle" -readme = "./README.md" -license = "MIT" -repository = "https://github.com/rustwasm/weedle" -[dependencies.nom] -version = "5.0.0" -features = ["std"] -default-features = false diff --git a/third_party/rust/weedle/LICENSE.md b/third_party/rust/weedle/LICENSE.md deleted file mode 100644 index a364c103059a..000000000000 --- a/third_party/rust/weedle/LICENSE.md +++ /dev/null @@ -1,15 +0,0 @@ -Copyright 2018-Present Sharad Chand - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, -and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF -CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/third_party/rust/weedle/README.md b/third_party/rust/weedle/README.md deleted file mode 100644 index acd0182f2145..000000000000 --- a/third_party/rust/weedle/README.md +++ /dev/null @@ -1,49 +0,0 @@ -
- -

Weedle

- - A Web IDL parser - -

- Build Status - Crates.io version - Download - docs.rs docs -

- -

- API Docs - | - Chat -

- - Built with 🦀🕸 by The Rust and WebAssembly Working Group -
- -## About - -Parses valid WebIDL definitions & produces a data structure starting from -[`Definitions`](https://docs.rs/weedle/latest/weedle/type.Definitions.html). - -## Usage - -### `Cargo.toml` - -```toml -[dependencies] -weedle = "0.9.0" -``` - -### `src/main.rs` - -```rust -fn main() { - let parsed = weedle::parse(" - interface Window { - readonly attribute Storage sessionStorage; - }; - ").unwrap(); - - println!("{:?}", parsed); -} -``` diff --git a/third_party/rust/weedle/src/argument.rs b/third_party/rust/weedle/src/argument.rs deleted file mode 100644 index f2ac5a01337e..000000000000 --- a/third_party/rust/weedle/src/argument.rs +++ /dev/null @@ -1,76 +0,0 @@ -use crate::attribute::ExtendedAttributeList; -use crate::common::{Default, Identifier, Punctuated}; -use crate::types::{AttributedType, Type}; - -/// Parses a list of argument. Ex: `double v1, double v2, double v3, optional double alpha` -pub type ArgumentList<'a> = Punctuated, term!(,)>; - -ast_types! { - /// Parses an argument. Ex: `double v1|double... v1s` - enum Argument<'a> { - /// Parses `[attributes]? optional? attributedtype identifier ( = default )?` - /// - /// Note: `= default` is only allowed if `optional` is present - Single(struct SingleArgument<'a> { - attributes: Option>, - optional: Option, - type_: AttributedType<'a>, - identifier: Identifier<'a>, - default: Option> = map!( - cond!(optional.is_some(), weedle!(Option>)), - |default| default.unwrap_or(None) - ), - }), - /// Parses `[attributes]? type... identifier` - Variadic(struct VariadicArgument<'a> { - attributes: Option>, - type_: Type<'a>, - ellipsis: term!(...), - identifier: Identifier<'a>, - }), - } -} - -#[cfg(test)] -mod test { - use super::*; - use crate::literal::{DecLit, DefaultValue, IntegerLit}; - use crate::Parse; - - test!(should_parse_single_argument { "short a" => - ""; - SingleArgument; - attributes.is_none(); - optional.is_none(); - identifier.0 == "a"; - default.is_none(); - }); - - test!(should_parse_variadic_argument { "short... a" => - ""; - VariadicArgument; - attributes.is_none(); - identifier.0 == "a"; - }); - - test!(should_parse_optional_single_argument { "optional short a" => - ""; - SingleArgument; - attributes.is_none(); - optional.is_some(); - identifier.0 == "a"; - default.is_none(); - }); - - test!(should_parse_optional_single_argument_with_default { "optional short a = 5" => - ""; - SingleArgument; - attributes.is_none(); - optional.is_some(); - identifier.0 == "a"; - default == Some(Default { - assign: term!(=), - value: DefaultValue::Integer(IntegerLit::Dec(DecLit("5"))), - }); - }); -} diff --git a/third_party/rust/weedle/src/attribute.rs b/third_party/rust/weedle/src/attribute.rs deleted file mode 100644 index 0a7045002336..000000000000 --- a/third_party/rust/weedle/src/attribute.rs +++ /dev/null @@ -1,99 +0,0 @@ -use crate::argument::ArgumentList; -use crate::common::{Bracketed, Identifier, Parenthesized, Punctuated}; -use crate::literal::StringLit; - -/// Parses a list of attributes. Ex: `[ attribute1, attribute2 ]` -pub type ExtendedAttributeList<'a> = Bracketed, term!(,)>>; - -/// Matches comma separated identifier list -pub type IdentifierList<'a> = Punctuated, term!(,)>; - -ast_types! { - /// Parses on of the forms of attribute - enum ExtendedAttribute<'a> { - /// Parses an argument list. Ex: `Constructor((double x, double y))` - /// - /// (( )) means ( ) chars - ArgList(struct ExtendedAttributeArgList<'a> { - identifier: Identifier<'a>, - args: Parenthesized>, - }), - /// Parses a named argument list. Ex: `NamedConstructor=Image((DOMString src))` - /// - /// (( )) means ( ) chars - NamedArgList(struct ExtendedAttributeNamedArgList<'a> { - lhs_identifier: Identifier<'a>, - assign: term!(=), - rhs_identifier: Identifier<'a>, - args: Parenthesized>, - - }), - /// Parses an identifier list. Ex: `Exposed=((Window,Worker))` - /// - /// (( )) means ( ) chars - IdentList(struct ExtendedAttributeIdentList<'a> { - identifier: Identifier<'a>, - assign: term!(=), - list: Parenthesized>, - }), - /// Parses an attribute with an identifier. Ex: `PutForwards=name` - #[derive(Copy)] - Ident(struct ExtendedAttributeIdent<'a> { - lhs_identifier: Identifier<'a>, - assign: term!(=), - rhs: IdentifierOrString<'a>, - }), - /// Parses a plain attribute. Ex: `Replaceable` - #[derive(Copy)] - NoArgs(struct ExtendedAttributeNoArgs<'a>( - Identifier<'a>, - )), - } - - /// Parses `stringifier|static` - #[derive(Copy)] - enum IdentifierOrString<'a> { - Identifier(Identifier<'a>), - String(StringLit<'a>), - } -} - -#[cfg(test)] -mod test { - use super::*; - use crate::Parse; - - test!(should_parse_attribute_no_args { "Replaceable" => - ""; - ExtendedAttributeNoArgs => ExtendedAttributeNoArgs(Identifier("Replaceable")) - }); - - test!(should_parse_attribute_arg_list { "Constructor(double x, double y)" => - ""; - ExtendedAttributeArgList; - identifier.0 == "Constructor"; - args.body.list.len() == 2; - }); - - test!(should_parse_attribute_ident { "PutForwards=name" => - ""; - ExtendedAttributeIdent; - lhs_identifier.0 == "PutForwards"; - rhs == IdentifierOrString::Identifier(Identifier("name")); - }); - - test!(should_parse_ident_list { "Exposed=(Window,Worker)" => - ""; - ExtendedAttributeIdentList; - identifier.0 == "Exposed"; - list.body.list.len() == 2; - }); - - test!(should_parse_named_arg_list { "NamedConstructor=Image(DOMString src)" => - ""; - ExtendedAttributeNamedArgList; - lhs_identifier.0 == "NamedConstructor"; - rhs_identifier.0 == "Image"; - args.body.list.len() == 1; - }); -} diff --git a/third_party/rust/weedle/src/common.rs b/third_party/rust/weedle/src/common.rs deleted file mode 100644 index 81c6aa21a0a1..000000000000 --- a/third_party/rust/weedle/src/common.rs +++ /dev/null @@ -1,208 +0,0 @@ -use crate::literal::DefaultValue; -use crate::term; -use crate::Parse; - -impl<'a, T: Parse<'a>> Parse<'a> for Option { - parser!(opt!(weedle!(T))); -} - -impl<'a, T: Parse<'a>> Parse<'a> for Box { - parser!(do_parse!(inner: weedle!(T) >> (Box::new(inner)))); -} - -/// Parses `item1 item2 item3...` -impl<'a, T: Parse<'a>> Parse<'a> for Vec { - parser!(many0!(weedle!(T))); -} - -impl<'a, T: Parse<'a>, U: Parse<'a>> Parse<'a> for (T, U) { - parser!(do_parse!(t: weedle!(T) >> u: weedle!(U) >> ((t, u)))); -} - -impl<'a, T: Parse<'a>, U: Parse<'a>, V: Parse<'a>> Parse<'a> for (T, U, V) { - parser!(do_parse!( - t: weedle!(T) >> u: weedle!(U) >> v: weedle!(V) >> ((t, u, v)) - )); -} - -ast_types! { - /// Parses `( body )` - #[derive(Copy, Default)] - struct Parenthesized where [T: Parse<'a>] { - open_paren: term::OpenParen, - body: T, - close_paren: term::CloseParen, - } - - /// Parses `[ body ]` - #[derive(Copy, Default)] - struct Bracketed where [T: Parse<'a>] { - open_bracket: term::OpenBracket, - body: T, - close_bracket: term::CloseBracket, - } - - /// Parses `{ body }` - #[derive(Copy, Default)] - struct Braced where [T: Parse<'a>] { - open_brace: term::OpenBrace, - body: T, - close_brace: term::CloseBrace, - } - - /// Parses `< body >` - #[derive(Copy, Default)] - struct Generics where [T: Parse<'a>] { - open_angle: term::LessThan, - body: T, - close_angle: term::GreaterThan, - } - - /// Parses `(item1, item2, item3,...)?` - struct Punctuated where [T: Parse<'a>, S: Parse<'a> + ::std::default::Default] { - list: Vec = separated_list!(weedle!(S), weedle!(T)), - separator: S = marker, - } - - /// Parses `item1, item2, item3, ...` - struct PunctuatedNonEmpty where [T: Parse<'a>, S: Parse<'a> + ::std::default::Default] { - list: Vec = terminated!( - separated_nonempty_list!(weedle!(S), weedle!(T)), - opt!(weedle!(S)) - ), - separator: S = marker, - } - - /// Represents an identifier - /// - /// Follows `/_?[A-Za-z][0-9A-Z_a-z-]*/` - #[derive(Copy)] - struct Identifier<'a>( - // See https://heycam.github.io/webidl/#idl-names for why the leading - // underscore is trimmed - &'a str = ws!(do_parse!( - opt!(char!('_')) >> - id: recognize!(do_parse!( - take_while1!(|c: char| c.is_ascii_alphabetic()) >> - take_while!(|c: char| c.is_ascii_alphanumeric() || c == '_' || c == '-') >> - (()) - )) >> - (id) - )), - ) - - /// Parses rhs of an assignment expression. Ex: `= 45` - #[derive(Copy)] - struct Default<'a> { - assign: term!(=), - value: DefaultValue<'a>, - } -} - -#[cfg(test)] -mod test { - use super::*; - - test!(should_parse_optional_present { "one" => - ""; - Option; - is_some(); - }); - - test!(should_parse_optional_not_present { "" => - ""; - Option; - is_none(); - }); - - test!(should_parse_boxed { "one" => - ""; - Box; - }); - - test!(should_parse_vec { "one two three" => - ""; - Vec; - len() == 3; - }); - - test!(should_parse_parenthesized { "( one )" => - ""; - Parenthesized; - body.0 == "one"; - }); - - test!(should_parse_bracketed { "[ one ]" => - ""; - Bracketed; - body.0 == "one"; - }); - - test!(should_parse_braced { "{ one }" => - ""; - Braced; - body.0 == "one"; - }); - - test!(should_parse_generics { "" => - ""; - Generics; - body.0 == "one"; - }); - - test!(should_parse_generics_two { "" => - ""; - Generics<(Identifier, term!(,), Identifier)> => - Generics { - open_angle: term!(<), - body: (Identifier("one"), term!(,), Identifier("two")), - close_angle: term!(>), - } - }); - - test!(should_parse_comma_separated_values { "one, two, three" => - ""; - Punctuated; - list.len() == 3; - }); - - test!(err should_not_parse_comma_separated_values_empty { "" => - PunctuatedNonEmpty - }); - - test!(should_parse_identifier { "hello" => - ""; - Identifier; - 0 == "hello"; - }); - - test!(should_parse_numbered_identifier { "hello5" => - ""; - Identifier; - 0 == "hello5"; - }); - - test!(should_parse_underscored_identifier { "_hello_" => - ""; - Identifier; - 0 == "hello_"; - }); - - test!(should_parse_identifier_surrounding_with_spaces { " hello " => - ""; - Identifier; - 0 == "hello"; - }); - - test!(should_parse_identifier_preceeding_others { "hello note" => - "note"; - Identifier; - 0 == "hello"; - }); - - test!(should_parse_identifier_attached_to_symbol { "hello=" => - "="; - Identifier; - 0 == "hello"; - }); -} diff --git a/third_party/rust/weedle/src/dictionary.rs b/third_party/rust/weedle/src/dictionary.rs deleted file mode 100644 index 3c9b23cac556..000000000000 --- a/third_party/rust/weedle/src/dictionary.rs +++ /dev/null @@ -1,33 +0,0 @@ -use crate::attribute::ExtendedAttributeList; -use crate::common::{Default, Identifier}; -use crate::types::Type; - -/// Parses dictionary members -pub type DictionaryMembers<'a> = Vec>; - -ast_types! { - /// Parses dictionary member `[attributes]? required? type identifier ( = default )?;` - struct DictionaryMember<'a> { - attributes: Option>, - required: Option, - type_: Type<'a>, - identifier: Identifier<'a>, - default: Option>, - semi_colon: term!(;), - } -} - -#[cfg(test)] -mod test { - use super::*; - use crate::Parse; - - test!(should_parse_dictionary_member { "required long num = 5;" => - ""; - DictionaryMember; - attributes.is_none(); - required.is_some(); - identifier.0 == "num"; - default.is_some(); - }); -} diff --git a/third_party/rust/weedle/src/interface.rs b/third_party/rust/weedle/src/interface.rs deleted file mode 100644 index 27945669cbf5..000000000000 --- a/third_party/rust/weedle/src/interface.rs +++ /dev/null @@ -1,202 +0,0 @@ -use crate::argument::ArgumentList; -use crate::attribute::ExtendedAttributeList; -use crate::common::{Generics, Identifier, Parenthesized}; -use crate::literal::ConstValue; -use crate::types::{AttributedType, ConstType, ReturnType}; - -/// Parses interface members -pub type InterfaceMembers<'a> = Vec>; - -ast_types! { - /// Parses inheritance clause `: identifier` - #[derive(Copy)] - struct Inheritance<'a> { - colon: term!(:), - identifier: Identifier<'a>, - } - - /// Parses one of the interface member variants - enum InterfaceMember<'a> { - /// Parses a const interface member `[attributes]? const type identifier = value;` - Const(struct ConstMember<'a> { - attributes: Option>, - const_: term!(const), - const_type: ConstType<'a>, - identifier: Identifier<'a>, - assign: term!(=), - const_value: ConstValue<'a>, - semi_colon: term!(;), - }), - /// Parses `[attributes]? (stringifier|inherit|static)? readonly? attribute attributedtype identifier;` - Attribute(struct AttributeInterfaceMember<'a> { - attributes: Option>, - modifier: Option, - readonly: Option, - attribute: term!(attribute), - type_: AttributedType<'a>, - identifier: Identifier<'a>, - semi_colon: term!(;), - }), - /// Parses `[attributes]? constructor(( args ));` - /// - /// (( )) means ( ) chars - Constructor(struct ConstructorInterfaceMember<'a> { - attributes: Option>, - constructor: term!(constructor), - args: Parenthesized>, - semi_colon: term!(;), - }), - /// Parses `[attributes]? (stringifier|static)? special? returntype identifier? (( args ));` - /// - /// (( )) means ( ) chars - Operation(struct OperationInterfaceMember<'a> { - attributes: Option>, - modifier: Option, - special: Option, - return_type: ReturnType<'a>, - identifier: Option>, - args: Parenthesized>, - semi_colon: term!(;), - }), - /// Parses an iterable declaration `[attributes]? (iterable | iterable) ;` - Iterable(enum IterableInterfaceMember<'a> { - /// Parses an iterable declaration `[attributes]? iterable;` - Single(struct SingleTypedIterable<'a> { - attributes: Option>, - iterable: term!(iterable), - generics: Generics>, - semi_colon: term!(;), - }), - /// Parses an iterable declaration `[attributes]? iterable;` - Double(struct DoubleTypedIterable<'a> { - attributes: Option>, - iterable: term!(iterable), - generics: Generics<(AttributedType<'a>, term!(,), AttributedType<'a>)>, - semi_colon: term!(;), - }), - }), - /// Parses an maplike declaration `[attributes]? readonly? maplike;` - Maplike(struct MaplikeInterfaceMember<'a> { - attributes: Option>, - readonly: Option, - maplike: term!(maplike), - generics: Generics<(AttributedType<'a>, term!(,), AttributedType<'a>)>, - semi_colon: term!(;), - }), - Setlike(struct SetlikeInterfaceMember<'a> { - attributes: Option>, - readonly: Option, - setlike: term!(setlike), - generics: Generics>, - semi_colon: term!(;), - }), - /// Parses `stringifier;` - #[derive(Default)] - Stringifier(struct StringifierMember<'a> { - attributes: Option>, - stringifier: term!(stringifier), - semi_colon: term!(;), - }), - } - - /// Parses one of the special keyword `getter|setter|deleter` - #[derive(Copy)] - enum Special { - Getter(term!(getter)), - Setter(term!(setter)), - Deleter(term!(deleter)), - LegacyCaller(term!(legacycaller)), - } - - /// Parses `stringifier|inherit|static` - #[derive(Copy)] - enum StringifierOrInheritOrStatic { - Stringifier(term!(stringifier)), - Inherit(term!(inherit)), - Static(term!(static)), - } - - /// Parses `stringifier|static` - #[derive(Copy)] - enum StringifierOrStatic { - Stringifier(term!(stringifier)), - Static(term!(static)), - } -} - -#[cfg(test)] -mod test { - use super::*; - use crate::Parse; - - test!(should_parse_stringifier_member { "stringifier;" => - ""; - StringifierMember; - }); - - test!(should_parse_stringifier_or_static { "static" => - ""; - StringifierOrStatic; - }); - - test!(should_parse_stringifier_or_inherit_or_static { "inherit" => - ""; - StringifierOrInheritOrStatic; - }); - - test!(should_parse_setlike_interface_member { "readonly setlike;" => - ""; - SetlikeInterfaceMember; - attributes.is_none(); - readonly == Some(term!(readonly)); - }); - - test!(should_parse_maplike_interface_member { "readonly maplike;" => - ""; - MaplikeInterfaceMember; - attributes.is_none(); - readonly == Some(term!(readonly)); - }); - - test!(should_parse_attribute_interface_member { "readonly attribute unsigned long width;" => - ""; - AttributeInterfaceMember; - attributes.is_none(); - readonly == Some(term!(readonly)); - identifier.0 == "width"; - }); - - test!(should_parse_double_typed_iterable { "iterable;" => - ""; - DoubleTypedIterable; - attributes.is_none(); - }); - - test!(should_parse_single_typed_iterable { "iterable;" => - ""; - SingleTypedIterable; - attributes.is_none(); - }); - - test!(should_parse_constructor_interface_member { "constructor(long a);" => - ""; - ConstructorInterfaceMember; - attributes.is_none(); - }); - - test!(should_parse_operation_interface_member { "void readString(long a, long b);" => - ""; - OperationInterfaceMember; - attributes.is_none(); - modifier.is_none(); - special.is_none(); - identifier.is_some(); - }); - - test!(should_parse_const_member { "const long name = 5;" => - ""; - ConstMember; - attributes.is_none(); - identifier.0 == "name"; - }); -} diff --git a/third_party/rust/weedle/src/lib.rs b/third_party/rust/weedle/src/lib.rs deleted file mode 100644 index 1b7bef847341..000000000000 --- a/third_party/rust/weedle/src/lib.rs +++ /dev/null @@ -1,425 +0,0 @@ -//! Weedle - A WebIDL Parser -//! -//! Parses valid WebIDL definitions & produces a data structure starting from -//! [`Definitions`](struct.Definitions.html). -//! -//! ### Example -//! -//! ``` -//! extern crate weedle; -//! -//! let parsed = weedle::parse(" -//! interface Window { -//! readonly attribute Storage sessionStorage; -//! }; -//! ").unwrap(); -//! println!("{:?}", parsed); -//! ``` -//! -//! Note: -//! This parser follows the grammar given at [WebIDL](https://heycam.github.io/webidl). -//! -//! If any flaws found when parsing string with a valid grammar, create an issue. - -// need a higher recusion limit for macros -#![recursion_limit = "128"] - -#[macro_use( - alt, - cond, - do_parse, - map, - many0, - opt, - recognize, - separated_list, - separated_nonempty_list, - terminated -)] -extern crate nom; - -use self::argument::ArgumentList; -use self::attribute::ExtendedAttributeList; -use self::common::{Braced, Identifier, Parenthesized, PunctuatedNonEmpty}; -use self::dictionary::DictionaryMembers; -use self::interface::{Inheritance, InterfaceMembers}; -use self::literal::StringLit; -use self::mixin::MixinMembers; -use self::namespace::NamespaceMembers; -use self::types::{AttributedType, ReturnType}; -pub use nom::{error::ErrorKind, Err, IResult}; - -#[macro_use] -mod macros; -#[macro_use] -mod whitespace; -#[macro_use] -pub mod term; -pub mod argument; -pub mod attribute; -pub mod common; -pub mod dictionary; -pub mod interface; -pub mod literal; -pub mod mixin; -pub mod namespace; -pub mod types; - -/// A convenient parse function -/// -/// ### Example -/// -/// ``` -/// extern crate weedle; -/// -/// let parsed = weedle::parse(" -/// interface Window { -/// readonly attribute Storage sessionStorage; -/// }; -/// ").unwrap(); -/// -/// println!("{:?}", parsed); -/// ``` -pub fn parse(raw: &str) -> Result, Err<(&str, ErrorKind)>> { - let (remaining, parsed) = Definitions::parse(raw)?; - assert!( - remaining.is_empty(), - "There is redundant raw data after parsing" - ); - Ok(parsed) -} - -pub trait Parse<'a>: Sized { - fn parse(input: &'a str) -> IResult<&'a str, Self>; -} - -/// Parses WebIDL definitions. It is the root struct for a complete WebIDL definition. -/// -/// ### Example -/// ``` -/// use weedle::{Definitions, Parse}; -/// -/// let (_, parsed) = Definitions::parse(" -/// interface Window { -/// readonly attribute Storage sessionStorage; -/// }; -/// ").unwrap(); -/// -/// println!("{:?}", parsed); -/// ``` -/// -/// It is recommended to use [`parse`](fn.parse.html) instead. -pub type Definitions<'a> = Vec>; - -ast_types! { - /// Parses a definition - enum Definition<'a> { - /// Parses `[attributes]? callback identifier = type ( (arg1, arg2, ..., argN)? );` - Callback(struct CallbackDefinition<'a> { - attributes: Option>, - callback: term!(callback), - identifier: Identifier<'a>, - assign: term!(=), - return_type: ReturnType<'a>, - arguments: Parenthesized>, - semi_colon: term!(;), - }), - /// Parses `[attributes]? callback interface identifier ( : inheritance )? { members };` - CallbackInterface(struct CallbackInterfaceDefinition<'a> { - attributes: Option>, - callback: term!(callback), - interface: term!(interface), - identifier: Identifier<'a>, - inheritance: Option>, - members: Braced>, - semi_colon: term!(;), - }), - /// Parses `[attributes]? interface identifier ( : inheritance )? { members };` - Interface(struct InterfaceDefinition<'a> { - attributes: Option>, - interface: term!(interface), - identifier: Identifier<'a>, - inheritance: Option>, - members: Braced>, - semi_colon: term!(;), - }), - /// Parses `[attributes]? interface mixin identifier { members };` - InterfaceMixin(struct InterfaceMixinDefinition<'a> { - attributes: Option>, - interface: term!(interface), - mixin: term!(mixin), - identifier: Identifier<'a>, - members: Braced>, - semi_colon: term!(;), - }), - /// Parses `[attributes]? namespace identifier { members };` - Namespace(struct NamespaceDefinition<'a> { - attributes: Option>, - namespace: term!(namespace), - identifier: Identifier<'a>, - members: Braced>, - semi_colon: term!(;), - }), - /// Parses `[attributes]? dictionary identifier ( : inheritance )? { members };` - Dictionary(struct DictionaryDefinition<'a> { - attributes: Option>, - dictionary: term!(dictionary), - identifier: Identifier<'a>, - inheritance: Option>, - members: Braced>, - semi_colon: term!(;), - }), - /// Parses `[attributes]? partial interface identifier { members };` - PartialInterface(struct PartialInterfaceDefinition<'a> { - attributes: Option>, - partial: term!(partial), - interface: term!(interface), - identifier: Identifier<'a>, - members: Braced>, - semi_colon: term!(;), - }), - /// Parses `[attributes]? partial interface mixin identifier { members };` - PartialInterfaceMixin(struct PartialInterfaceMixinDefinition<'a> { - attributes: Option>, - partial: term!(partial), - interface: term!(interface), - mixin: term!(mixin), - identifier: Identifier<'a>, - members: Braced>, - semi_colon: term!(;), - }), - /// Parses `[attributes]? partial dictionary identifier { members };` - PartialDictionary(struct PartialDictionaryDefinition<'a> { - attributes: Option>, - partial: term!(partial), - dictionary: term!(dictionary), - identifier: Identifier<'a>, - members: Braced>, - semi_colon: term!(;), - }), - /// Parses `[attributes]? partial namespace identifier { members };` - PartialNamespace(struct PartialNamespaceDefinition<'a> { - attributes: Option>, - partial: term!(partial), - namespace: term!(namespace), - identifier: Identifier<'a>, - members: Braced>, - semi_colon: term!(;), - }), - /// Parses `[attributes]? enum identifier { values };` - Enum(struct EnumDefinition<'a> { - attributes: Option>, - enum_: term!(enum), - identifier: Identifier<'a>, - values: Braced>, - semi_colon: term!(;), - }), - /// Parses `[attributes]? typedef attributedtype identifier;` - Typedef(struct TypedefDefinition<'a> { - attributes: Option>, - typedef: term!(typedef), - type_: AttributedType<'a>, - identifier: Identifier<'a>, - semi_colon: term!(;), - }), - /// Parses `[attributes]? identifier includes identifier;` - IncludesStatement(struct IncludesStatementDefinition<'a> { - attributes: Option>, - lhs_identifier: Identifier<'a>, - includes: term!(includes), - rhs_identifier: Identifier<'a>, - semi_colon: term!(;), - }), - /// Parses `[attributes]? identifier implements identifier;` - Implements(struct ImplementsDefinition<'a> { - attributes: Option>, - lhs_identifier: Identifier<'a>, - includes: term!(implements), - rhs_identifier: Identifier<'a>, - semi_colon: term!(;), - }), - } -} - -/// Parses a non-empty enum value list -pub type EnumValueList<'a> = PunctuatedNonEmpty, term!(,)>; - -#[cfg(test)] -mod test { - use super::*; - - test!(should_parse_includes_statement { "first includes second;" => - ""; - IncludesStatementDefinition; - attributes.is_none(); - lhs_identifier.0 == "first"; - rhs_identifier.0 == "second"; - }); - - test!(should_parse_typedef { "typedef short Short;" => - ""; - TypedefDefinition; - attributes.is_none(); - identifier.0 == "Short"; - }); - - test!(should_parse_enum { r#"enum name { "first", "second" }; "# => - ""; - EnumDefinition; - attributes.is_none(); - identifier.0 == "name"; - values.body.list.len() == 2; - }); - - test!(should_parse_dictionary { "dictionary A { long c; long g; };" => - ""; - DictionaryDefinition; - attributes.is_none(); - identifier.0 == "A"; - inheritance.is_none(); - members.body.len() == 2; - }); - - test!(should_parse_dictionary_inherited { "dictionary C : B { long e; long f; };" => - ""; - DictionaryDefinition; - attributes.is_none(); - identifier.0 == "C"; - inheritance.is_some(); - members.body.len() == 2; - }); - - test!(should_parse_partial_namespace { " - partial namespace VectorUtils { - readonly attribute Vector unit; - double dotProduct(Vector x, Vector y); - Vector crossProduct(Vector x, Vector y); - }; - " => - ""; - PartialNamespaceDefinition; - attributes.is_none(); - identifier.0 == "VectorUtils"; - members.body.len() == 3; - }); - - test!(should_parse_partial_dictionary { "partial dictionary C { long e; long f; };" => - ""; - PartialDictionaryDefinition; - attributes.is_none(); - identifier.0 == "C"; - members.body.len() == 2; - }); - - test!(should_parse_partial_interface_mixin { " - partial interface mixin WindowSessionStorage { - readonly attribute Storage sessionStorage; - }; - " => - ""; - PartialInterfaceMixinDefinition; - attributes.is_none(); - identifier.0 == "WindowSessionStorage"; - members.body.len() == 1; - }); - - test!(should_parse_partial_interface { " - partial interface Window { - readonly attribute Storage sessionStorage; - }; - " => - ""; - PartialInterfaceDefinition; - attributes.is_none(); - identifier.0 == "Window"; - members.body.len() == 1; - }); - - test!(should_parse_namespace { " - namespace VectorUtils { - readonly attribute Vector unit; - double dotProduct(Vector x, Vector y); - Vector crossProduct(Vector x, Vector y); - }; - " => - ""; - NamespaceDefinition; - attributes.is_none(); - identifier.0 == "VectorUtils"; - members.body.len() == 3; - }); - - test!(should_parse_interface_mixin { " - interface mixin WindowSessionStorage { - readonly attribute Storage sessionStorage; - }; - " => - ""; - InterfaceMixinDefinition; - attributes.is_none(); - identifier.0 == "WindowSessionStorage"; - members.body.len() == 1; - }); - - test!(should_parse_interface { " - interface Window { - readonly attribute Storage sessionStorage; - }; - " => - ""; - InterfaceDefinition; - attributes.is_none(); - identifier.0 == "Window"; - members.body.len() == 1; - }); - - test!(should_parse_callback_interface {" - callback interface Options { - attribute DOMString? option1; - attribute DOMString? option2; - attribute long? option3; - }; - " => - ""; - CallbackInterfaceDefinition; - attributes.is_none(); - identifier.0 == "Options"; - members.body.len() == 3; - }); - - test!(should_parse_callback { "callback AsyncOperationCallback = void (DOMString status);" => - ""; - CallbackDefinition; - attributes.is_none(); - identifier.0 == "AsyncOperationCallback"; - arguments.body.list.len() == 1; - }); - - test!(should_parse_with_line_comments { " - // This is a comment - callback AsyncOperationCallback = void (DOMString status); - " => - ""; - CallbackDefinition; - }); - - test!(should_parse_with_block_comments { " - /* This is a comment */ - callback AsyncOperationCallback = void (DOMString status); - " => - ""; - CallbackDefinition; - }); - - test!(should_parse_with_multiple_comments { " - // This is a comment - // This is a comment - // This is a comment - - // This is a comment - callback AsyncOperationCallback = void (DOMString status); - " => - ""; - CallbackDefinition; - }); -} diff --git a/third_party/rust/weedle/src/literal.rs b/third_party/rust/weedle/src/literal.rs deleted file mode 100644 index 34d9bb1421c5..000000000000 --- a/third_party/rust/weedle/src/literal.rs +++ /dev/null @@ -1,281 +0,0 @@ -ast_types! { - /// Represents an integer value - #[derive(Copy)] - enum IntegerLit<'a> { - /// Parses `-?[1-9][0-9]*` - #[derive(Copy)] - Dec(struct DecLit<'a>( - &'a str = ws!(recognize!(do_parse!( - opt!(char!('-')) >> - one_of!("123456789") >> - take_while!(|c: char| c.is_ascii_digit()) >> - (()) - ))), - )), - /// Parses `-?0[Xx][0-9A-Fa-f]+)` - #[derive(Copy)] - Hex(struct HexLit<'a>( - &'a str = ws!(recognize!(do_parse!( - opt!(char!('-')) >> - char!('0') >> - alt!(char!('x') | char!('X')) >> - take_while!(|c: char| c.is_ascii_hexdigit()) >> - (()) - ))), - )), - /// Parses `-?0[0-7]*` - #[derive(Copy)] - Oct(struct OctLit<'a>( - &'a str = ws!(recognize!(do_parse!( - opt!(char!('-')) >> - char!('0') >> - take_while!(|c| '0' <= c && c <= '7') >> - (()) - ))), - )), - } - - /// Represents a string value - /// - /// Follow `/"[^"]*"/` - #[derive(Copy)] - struct StringLit<'a>( - &'a str = ws!(do_parse!( - char!('"') >> - s: take_while!(|c| c != '"') >> - char!('"') >> - (s) - )), - ) - - /// Represents a default literal value. Ex: `34|34.23|"value"|[ ]|true|false|null` - #[derive(Copy)] - enum DefaultValue<'a> { - Boolean(BooleanLit), - /// Represents `[ ]` - #[derive(Copy, Default)] - EmptyArray(struct EmptyArrayLit { - open_bracket: term!(OpenBracket), - close_bracket: term!(CloseBracket), - }), - /// Represents `{ }` - #[derive(Copy, Default)] - EmptyDictionary(struct EmptyDictionaryLit { - open_brace: term!(OpenBrace), - close_brace: term!(CloseBrace), - }), - Float(FloatLit<'a>), - Integer(IntegerLit<'a>), - Null(term!(null)), - String(StringLit<'a>), - } - - /// Represents `true`, `false`, `34.23`, `null`, `56`, ... - #[derive(Copy)] - enum ConstValue<'a> { - Boolean(BooleanLit), - Float(FloatLit<'a>), - Integer(IntegerLit<'a>), - Null(term!(null)), - } - - /// Represents either `true` or `false` - #[derive(Copy)] - struct BooleanLit( - bool = alt!( - weedle!(term!(true)) => {|_| true} | - weedle!(term!(false)) => {|_| false} - ), - ) - - /// Represents a floating point value, `NaN`, `Infinity`, '+Infinity` - #[derive(Copy)] - enum FloatLit<'a> { - /// Parses `/-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+)/` - #[derive(Copy)] - Value(struct FloatValueLit<'a>( - &'a str = ws!(recognize!(do_parse!( - opt!(char!('-')) >> - alt!( - do_parse!( - // (?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+) - alt!( - do_parse!( - take_while1!(|c: char| c.is_ascii_digit()) >> - char!('.') >> - take_while!(|c: char| c.is_ascii_digit()) >> - (()) - ) - | - do_parse!( - take_while!(|c: char| c.is_ascii_digit()) >> - char!('.') >> - take_while1!(|c: char| c.is_ascii_digit()) >> - (()) - ) - ) >> - // (?:[Ee][+-]?[0-9]+)? - opt!(do_parse!( - alt!(char!('e') | char!('E')) >> - opt!(alt!(char!('+') | char!('-'))) >> - take_while1!(|c: char| c.is_ascii_digit()) >> - (()) - )) >> - (()) - ) - | - // [0-9]+[Ee][+-]?[0-9]+ - do_parse!( - take_while1!(|c: char| c.is_ascii_digit()) >> - alt!(char!('e') | char!('E')) >> - opt!(alt!(char!('+') | char!('-'))) >> - take_while1!(|c: char| c.is_ascii_digit()) >> - (()) - ) - ) >> - (()) - ))), - )), - NegInfinity(term!(-Infinity)), - Infinity(term!(Infinity)), - NaN(term!(NaN)), - } -} - -#[cfg(test)] -mod test { - use super::*; - use crate::term::*; - use crate::Parse; - - test!(should_parse_integer { "45" => - ""; - IntegerLit => IntegerLit::Dec(DecLit("45")) - }); - - test!(should_parse_integer_surrounding_with_spaces { " 123123 " => - ""; - IntegerLit => IntegerLit::Dec(DecLit("123123")) - }); - - test!(should_parse_integer_preceeding_others { "3453 string" => - "string"; - IntegerLit => IntegerLit::Dec(DecLit("3453")) - }); - - test!(should_parse_neg_integer { "-435" => - ""; - IntegerLit => IntegerLit::Dec(DecLit("-435")) - }); - - test!(should_parse_hex_number { "0X08" => - ""; - IntegerLit => IntegerLit::Hex(HexLit("0X08")) - }); - - test!(should_parse_hex_large_number { "0xA" => - ""; - IntegerLit => IntegerLit::Hex(HexLit("0xA")) - }); - - test!(should_parse_zero { "0" => - ""; - IntegerLit => IntegerLit::Oct(OctLit("0")) - }); - - test!(should_parse_oct_number { "-07561" => - ""; - IntegerLit => IntegerLit::Oct(OctLit("-07561")) - }); - - test!(should_parse_float { "45.434" => - ""; - FloatLit => FloatLit::Value(FloatValueLit("45.434")) - }); - - test!(should_parse_float_surrounding_with_spaces { " 2345.2345 " => - ""; - FloatLit => FloatLit::Value(FloatValueLit("2345.2345")) - }); - - test!(should_parse_float_preceeding_others { "3453.32334 string" => - "string"; - FloatLit => FloatLit::Value(FloatValueLit("3453.32334")) - }); - - test!(should_parse_neg_float { "-435.3435" => - ""; - FloatLit => FloatLit::Value(FloatValueLit("-435.3435")) - }); - - test!(should_parse_float_exp { "5.3434e23" => - ""; - FloatLit => FloatLit::Value(FloatValueLit("5.3434e23")) - }); - - test!(should_parse_float_exp_with_decimal { "3e23" => - ""; - FloatLit => FloatLit::Value(FloatValueLit("3e23")) - }); - - test!(should_parse_neg_infinity { "-Infinity" => - ""; - FloatLit => FloatLit::NegInfinity(term!(-Infinity)) - }); - - test!(should_parse_infinity { "Infinity" => - ""; - FloatLit => FloatLit::Infinity(term!(Infinity)) - }); - - test!(should_parse_string { r#""this is a string""# => - ""; - StringLit => StringLit("this is a string") - }); - - test!(should_parse_string_surround_with_spaces { r#" "this is a string" "# => - ""; - StringLit => StringLit("this is a string") - }); - - test!(should_parse_string_followed_by_string { r#" "this is first" "this is second" "# => - r#""this is second" "#; - StringLit => StringLit("this is first") - }); - - test!(should_parse_string_with_spaces { r#" " this is a string " "# => - ""; - StringLit => StringLit(" this is a string ") - }); - - test!(should_parse_string_with_comment { r#" "// this is still a string" - "# => - ""; - StringLit => StringLit("// this is still a string") - }); - - test!(should_parse_string_with_multiline_comment { r#" "/*" "*/" "# => - r#""*/" "#; - StringLit => StringLit("/*") - }); - - test!(should_parse_null { "null" => - ""; - Null => Null - }); - - test!(should_parse_empty_array { "[]" => - ""; - EmptyArrayLit => Default::default() - }); - - test!(should_parse_bool_true { "true" => - ""; - BooleanLit => BooleanLit(true) - }); - - test!(should_parse_bool_false { "false" => - ""; - BooleanLit => BooleanLit(false) - }); -} diff --git a/third_party/rust/weedle/src/macros.rs b/third_party/rust/weedle/src/macros.rs deleted file mode 100644 index cb55a1bc238e..000000000000 --- a/third_party/rust/weedle/src/macros.rs +++ /dev/null @@ -1,614 +0,0 @@ -macro_rules! tag { - ($i:expr, $tag: expr) => { - nom::bytes::complete::tag($tag)($i) - }; -} - -macro_rules! take_while { - ($input:expr, $submac:ident!( $($args:tt)* )) => { - $crate::macros::take_while!($input, (|c| $submac!(c, $($args)*))) - }; - ($input:expr, $f:expr) => { - nom::bytes::complete::take_while($f)($input) - }; -} - -macro_rules! take_while1 { - ($input:expr, $submac:ident!( $($args:tt)* )) => { - $crate::macros::take_while1!($input, (|c| $submac!(c, $($args)*))) - }; - ($input:expr, $f:expr) => { - nom::bytes::complete::take_while1($f)($input) - }; -} - -macro_rules! take_until { - ($i:expr, $substr:expr) => { - nom::bytes::complete::take_until($substr)($i) - }; -} - -macro_rules! one_of { - ($i:expr, $inp: expr) => { - nom::character::complete::one_of($inp)($i) - }; -} - -macro_rules! char { - ($i:expr, $c: expr) => { - nom::character::complete::char($c)($i) - }; -} - -macro_rules! parser { - ($submac:ident!( $($args:tt)* )) => { - fn parse(input: &'a str) -> $crate::IResult<&'a str, Self> { - $submac!(input, $($args)*) - } - }; -} - -macro_rules! weedle { - ($i:expr, $t:ty) => { - <$t as $crate::Parse<'a>>::parse($i) - }; -} - -macro_rules! ast_types { - (@extract_type struct $name:ident<'a> $($rest:tt)*) => ($name<'a>); - (@extract_type struct $name:ident $($rest:tt)*) => ($name); - (@extract_type enum $name:ident<'a> $($rest:tt)*) => ($name<'a>); - (@extract_type enum $name:ident $($rest:tt)*) => ($name); - - () => (); - ( - $(#[$attr:meta])* - struct $name:ident<'a> { - $($fields:tt)* - } - $($rest:tt)* - ) => ( - __ast_struct! { - @launch_pad - $(#[$attr])* - $name - [ 'a ] - [ ] - { $($fields)* } - } - ast_types!($($rest)*); - ); - ( - $(#[$attr:meta])* - struct $name:ident<$($generics:ident),+> where [$($bounds:tt)+] { - $($fields:tt)* - } - $($rest:tt)* - ) => ( - __ast_struct! { - @launch_pad - $(#[$attr])* - $name - [$($generics)+] - [$($bounds)+] - { $($fields)* } - } - ast_types!($($rest)*); - ); - ( - $(#[$attr:meta])* - struct $name:ident { - $($fields:tt)* - } - $($rest:tt)* - ) => ( - __ast_struct! { - @launch_pad - $(#[$attr])* - $name - [ ] - [ ] - { $($fields)* } - } - ast_types!($($rest)*); - ); - - ( - $(#[$attr:meta])* - struct $name:ident<'a> ( - $($fields:tt)* - ) - $($rest:tt)* - ) => ( - __ast_tuple_struct! { - @launch_pad - $(#[$attr])* - $name - [ 'a ] - ( $($fields)* ) - } - ast_types!($($rest)*); - ); - ( - $(#[$attr:meta])* - struct $name:ident ( - $($fields:tt)* - ) - $($rest:tt)* - ) => ( - __ast_tuple_struct! { - @launch_pad - $(#[$attr])* - $name - [ ] - ( $($fields)* ) - } - ast_types!($($rest)*); - ); - - ( - $(#[$attr:meta])* - enum $name:ident<'a> { - $($variants:tt)* - } - $($rest:tt)* - ) => ( - __ast_enum! { - @launch_pad - $(#[$attr])* - $name - [ 'a ] - { $($variants)* } - } - ast_types!($($rest)*); - ); - ( - $(#[$attr:meta])* - enum $name:ident { - $($variants:tt)* - } - $($rest:tt)* - ) => ( - __ast_enum! { - @launch_pad - $(#[$attr])* - $name - [ ] - { $($variants)* } - } - ast_types!($($rest)*); - ); -} - -macro_rules! __ast_tuple_struct { - (@launch_pad - $(#[$attr:meta])* - $name:ident - [ $($maybe_a:tt)* ] - ( $inner:ty = $submac:ident!( $($args:tt)* ), ) - ) => ( - $(#[$attr])* - #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] - pub struct $name<$($maybe_a)*>(pub $inner); - - impl<'a> $crate::Parse<'a> for $name<$($maybe_a)*> { - fn parse(input: &'a str) -> $crate::IResult<&'a str, Self> { - use $crate::nom::lib::std::result::Result::*; - - match $submac!(input, $($args)*) { - Err(e) => Err(e), - Ok((i, inner)) => Ok((i, $name(inner))), - } - } - } - ); - (@launch_pad - $(#[$attr:meta])* - $name:ident - [ $($maybe_a:tt)* ] - ( $inner:ty, ) - ) => ( - __ast_tuple_struct! { - @launch_pad - $(#[$attr])* - $name - [ $($maybe_a)* ] - ( $inner = weedle!($inner), ) - } - ); -} - -macro_rules! __ast_struct { - (@build_struct_decl - { - $(#[$attr:meta])* - $name:ident - [ $($generics:tt)* ] - $($field:ident : $type:ty)* - } - { } - ) => { - $(#[$attr])* - #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] - pub struct $name<$($generics)*> { - $(pub $field : $type,)* - } - }; - (@build_struct_decl - { $($prev:tt)* } - { $field:ident : $type:ty, $($rest:tt)* } - ) => ( - __ast_struct! { - @build_struct_decl - { $($prev)* $field : $type } - { $($rest)* } - } - ); - (@build_struct_decl - { $($prev:tt)* } - { $field:ident : $type:ty = $submac:ident!( $($args:tt)* ), $($rest:tt)* } - ) => ( - __ast_struct! { - @build_struct_decl - { $($prev)* $field : $type } - { $($rest)* } - } - ); - (@build_struct_decl - { $($prev:tt)* } - { $field:ident : $type:ty = marker, $($rest:tt)* } - ) => ( - __ast_struct! { - @build_struct_decl - { $($prev)* $field : $type } - { $($rest)* } - } - ); - - (@build_parser - { $i:expr, $($field:ident)* } - { } - ) => ({ - use $crate::nom::lib::std::result::Result::Ok; - Ok(($i, Self { $($field,)* })) - }); - (@build_parser - { $i:expr, $($prev:tt)* } - { $field:ident : $type:ty = $submac:ident!( $($args:tt)* ), $($rest:tt)* } - ) => ({ - use $crate::nom::lib::std::result::Result::*; - - match $submac!($i, $($args)*) { - Err(e) => Err(e), - Ok((i, $field)) => { - __ast_struct! { - @build_parser - { i, $($prev)* $field } - { $($rest)* } - } - }, - } - }); - (@build_parser - { $($prev:tt)* } - { $field:ident : $type:ty = marker, $($rest:tt)* } - ) => ({ - let $field = ::std::default::Default::default(); - __ast_struct! { - @build_parser - { $($prev)* $field } - { $($rest)* } - } - }); - (@build_parser - { $($prev:tt)* } - { $field:ident : $type:ty, $($rest:tt)* } - ) => ( - __ast_struct! { - @build_parser - { $($prev)* } - { $field : $type = weedle!($type), $($rest)* } - } - ); - - ( - @launch_pad - $(#[$attr:meta])* - $name:ident - [ ] - [ ] - { $($fields:tt)* } - ) => { - __ast_struct! { - @build_struct_decl - { - $(#[$attr])* - $name - [ ] - } - { $($fields)* } - } - - impl<'a> $crate::Parse<'a> for $name { - fn parse(input: &'a str) -> $crate::IResult<&'a str, Self> { - __ast_struct! { - @build_parser - { input, } - { $($fields)* } - } - } - } - }; - ( - @launch_pad - $(#[$attr:meta])* - $name:ident - [ 'a ] - [ ] - { $($fields:tt)* } - ) => { - __ast_struct! { - @build_struct_decl - { - $(#[$attr])* - $name - [ 'a ] - } - { $($fields)* } - } - - impl<'a> $crate::Parse<'a> for $name<'a> { - fn parse(input: &'a str) -> $crate::IResult<&'a str, Self> { - __ast_struct! { - @build_parser - { input, } - { $($fields)* } - } - } - } - }; - ( - @launch_pad - $(#[$attr:meta])* - $name:ident - [$($generics:ident)+] - [$($bounds:tt)+] - { $($fields:tt)* } - ) => { - __ast_struct! { - @build_struct_decl - { - $(#[$attr])* - $name - [$($generics),+] - } - { $($fields)* } - } - - impl<'a, $($generics),+> $crate::Parse<'a> for $name<$($generics),+> where $($bounds)+ { - fn parse(input: &'a str) -> $crate::IResult<&'a str, Self> { - __ast_struct! { - @build_parser - { input, } - { $($fields)* } - } - } - } - }; -} - -macro_rules! __ast_enum { - (@build_enum_decl - { - $(#[$attr:meta])* - $name:ident - [ $($maybe_a:tt)* ] - $($variant:ident($member:ty))* - } - { } - ) => ( - $(#[$attr])* - #[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)] - pub enum $name<$($maybe_a)*> { - $($variant($member),)* - } - ); - (@build_enum_decl - { $($prev:tt)* } - { $variant:ident($member:ty), $($rest:tt)* } - ) => ( - __ast_enum! { - @build_enum_decl - { $($prev)* $variant($member) } - { $($rest)* } - } - ); - (@build_enum_decl - { $($prev:tt)* } - { $(#[$attr:meta])* $variant:ident( $($member:tt)* ), $($rest:tt)* } - ) => ( - __ast_enum! { - @build_enum_decl - { $($prev)* $variant(ast_types! { @extract_type $($member)* }) } - { $($rest)* } - } - ); - - (@build_sub_types { }) => (); - (@build_sub_types - { $variant:ident($member:ty), $($rest:tt)* } - ) => ( - __ast_enum! { - @build_sub_types - { $($rest)* } - } - ); - (@build_sub_types - { $(#[$attr:meta])* $variant:ident( $($member:tt)* ), $($rest:tt)* } - ) => ( - ast_types! { - $(#[$attr])* - $($member)* - } - __ast_enum! { - @build_sub_types - { $($rest)* } - } - ); - - - (@build_conversions $name:ident [ $($maybe_a:tt)* ] { }) => (); - (@build_conversions - $name:ident - [ $($maybe_a:tt)* ] - { $variant:ident($member:ty), $($rest:tt)* } - ) => ( - impl<$($maybe_a)*> From<$member> for $name<$($maybe_a)*> { - fn from(x: $member) -> Self { - $name::$variant(x) - } - } - __ast_enum! { - @build_conversions - $name - [ $($maybe_a)* ] - { $($rest)* } - } - ); - (@build_conversions - $name:ident - [ $($maybe_a:tt)* ] - { $(#[$attr:meta])* $variant:ident( $($member:tt)* ), $($rest:tt)* } - ) => ( - __ast_enum! { - @build_conversions - $name - [ $($maybe_a)* ] - { $variant(ast_types! { @extract_type $($member)* }), $($rest)* } - } - ); - - (@build_parse - { $name:ident [ $($maybe_a:tt)* ] $($member:ty)* } - { } - ) => ( - impl<'a> $crate::Parse<'a> for $name<$($maybe_a)*> { - parser!(alt!( - $(weedle!($member) => {From::from})|* - )); - } - ); - (@build_parse - { $($prev:tt)* } - { $variant:ident($member:ty), $($rest:tt)* } - ) => ( - __ast_enum! { - @build_parse - { $($prev)* $member } - { $($rest)* } - } - ); - (@build_parse - { $($prev:tt)* } - { $(#[$attr:meta])* $variant:ident( $($member:tt)* ), $($rest:tt)* } - ) => ( - __ast_enum! { - @build_parse - { $($prev)* ast_types! { @extract_type $($member)* } } - { $($rest)* } - } - ); - - (@launch_pad - $(#[$attr:meta])* - $name:ident - [ $($maybe_a:tt)* ] - { $($variants:tt)* } - ) => ( - __ast_enum! { - @build_enum_decl - { $(#[$attr])* $name [ $($maybe_a)* ] } - { $($variants)* } - } - - __ast_enum! { - @build_sub_types - { $($variants)* } - } - - __ast_enum! { - @build_conversions - $name - [ $($maybe_a)* ] - { $($variants)* } - } - - __ast_enum! { - @build_parse - { $name [ $($maybe_a)* ] } - { $($variants)* } - } - ); -} - -#[cfg(test)] -macro_rules! test { - (@arg $parsed:ident) => {}; - (@arg $parsed:ident $($lhs:tt).+ == $rhs:expr; $($rest:tt)*) => { - assert_eq!($parsed.$($lhs).+, $rhs); - test!(@arg $parsed $($rest)*); - }; - (@arg $parsed:ident $($lhs:tt).+(); $($rest:tt)*) => { - assert!($parsed.$($lhs).+()); - test!(@arg $parsed $($rest)*); - }; - (@arg $parsed:ident $($lhs:tt).+() == $rhs:expr; $($rest:tt)*) => { - assert_eq!($parsed.$($lhs).+(), $rhs); - test!(@arg $parsed $($rest)*); - }; - (err $name:ident { $raw:expr => $typ:ty }) => { - #[test] - fn $name() { - <$typ>::parse($raw).unwrap_err(); - } - }; - ($name:ident { $raw:expr => $rem:expr; $typ:ty => $val:expr }) => { - #[test] - fn $name() { - let (rem, parsed) = <$typ>::parse($raw).unwrap(); - assert_eq!(rem, $rem); - assert_eq!(parsed, $val); - } - }; - ($name:ident { $raw:expr => $rem:expr; $typ:ty; $($body:tt)* }) => { - #[test] - fn $name() { - let (_rem, _parsed) = <$typ>::parse($raw).unwrap(); - assert_eq!(_rem, $rem); - test!(@arg _parsed $($body)*); - } - }; -} - -#[cfg(test)] -macro_rules! test_variants { - ($struct_:ident { $( $variant:ident == $value:expr ),* $(,)* }) => { - #[allow(non_snake_case)] - mod $struct_ { - $( - mod $variant { - use $crate::types::*; - #[test] - fn should_parse() { - let (rem, parsed) = $struct_::parse($value).unwrap(); - assert_eq!(rem, ""); - match parsed { - $struct_::$variant(_) => {}, - _ => { panic!("Failed to parse"); } - } - } - } - )* - } - }; -} diff --git a/third_party/rust/weedle/src/mixin.rs b/third_party/rust/weedle/src/mixin.rs deleted file mode 100644 index dcb40d50c574..000000000000 --- a/third_party/rust/weedle/src/mixin.rs +++ /dev/null @@ -1,60 +0,0 @@ -use crate::argument::ArgumentList; -use crate::attribute::ExtendedAttributeList; -use crate::common::{Identifier, Parenthesized}; -use crate::interface::{ConstMember, StringifierMember}; -use crate::types::{AttributedType, ReturnType}; - -/// Parses the members declarations of a mixin -pub type MixinMembers<'a> = Vec>; - -ast_types! { - /// Parses one of the variants of a mixin member - enum MixinMember<'a> { - Const(ConstMember<'a>), - /// Parses `[attributes]? stringifier? returntype identifier? (( args ));` - /// - /// (( )) means ( ) chars - Operation(struct OperationMixinMember<'a> { - attributes: Option>, - stringifier: Option, - return_type: ReturnType<'a>, - identifier: Option>, - args: Parenthesized>, - semi_colon: term!(;), - }), - /// Parses `[attributes]? stringifier? readonly? attribute attributedtype identifier;` - Attribute(struct AttributeMixinMember<'a> { - attributes: Option>, - stringifier: Option, - readonly: Option, - attribute: term!(attribute), - type_: AttributedType<'a>, - identifier: Identifier<'a>, - semi_colon: term!(;), - }), - Stringifier(StringifierMember<'a>), - } -} - -#[cfg(test)] -mod test { - use super::*; - use crate::Parse; - - test!(should_parse_attribute_mixin_member { "stringifier readonly attribute short name;" => - ""; - AttributeMixinMember; - attributes.is_none(); - stringifier.is_some(); - readonly.is_some(); - identifier.0 == "name"; - }); - - test!(should_parse_operation_mixin_member { "short fnName(long a);" => - ""; - OperationMixinMember; - attributes.is_none(); - stringifier.is_none(); - identifier.is_some(); - }); -} diff --git a/third_party/rust/weedle/src/namespace.rs b/third_party/rust/weedle/src/namespace.rs deleted file mode 100644 index ed28573218dc..000000000000 --- a/third_party/rust/weedle/src/namespace.rs +++ /dev/null @@ -1,52 +0,0 @@ -use crate::argument::ArgumentList; -use crate::attribute::ExtendedAttributeList; -use crate::common::{Identifier, Parenthesized}; -use crate::types::{AttributedType, ReturnType}; - -/// Parses namespace members declaration -pub type NamespaceMembers<'a> = Vec>; - -ast_types! { - /// Parses namespace member declaration - enum NamespaceMember<'a> { - /// Parses `[attributes]? returntype identifier? (( args ));` - /// - /// (( )) means ( ) chars - Operation(struct OperationNamespaceMember<'a> { - attributes: Option>, - return_type: ReturnType<'a>, - identifier: Option>, - args: Parenthesized>, - semi_colon: term!(;), - }), - /// Parses `[attribute]? readonly attributetype type identifier;` - Attribute(struct AttributeNamespaceMember<'a> { - attributes: Option>, - readonly: term!(readonly), - attribute: term!(attribute), - type_: AttributedType<'a>, - identifier: Identifier<'a>, - semi_colon: term!(;), - }), - } -} - -#[cfg(test)] -mod test { - use super::*; - use crate::Parse; - - test!(should_parse_attribute_namespace_member { "readonly attribute short name;" => - ""; - AttributeNamespaceMember; - attributes.is_none(); - identifier.0 == "name"; - }); - - test!(should_parse_operation_namespace_member { "short (long a, long b);" => - ""; - OperationNamespaceMember; - attributes.is_none(); - identifier.is_none(); - }); -} diff --git a/third_party/rust/weedle/src/term.rs b/third_party/rust/weedle/src/term.rs deleted file mode 100644 index 008a538f0eca..000000000000 --- a/third_party/rust/weedle/src/term.rs +++ /dev/null @@ -1,690 +0,0 @@ -macro_rules! generate_terms { - ($( $(#[$attr:meta])* $typ:ident => $tok:expr ),*) => { - $( - $(#[$attr])* - #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] - pub struct $typ; - - impl<'a> $crate::Parse<'a> for $typ { - parser!(do_parse!( - ws!(tag!($tok)) >> - ($typ) - )); - } - )* - }; -} - -macro_rules! ident_tag ( - ($i:expr, $tok:expr) => ( - { - match tag!($i, $tok) { - Err(e) => Err(e), - Ok((i, o)) => { - use nom::{character::is_alphanumeric, Err as NomErr, error::ErrorKind}; - let mut res = Ok((i, o)); - if let Some(&c) = i.as_bytes().first() { - if is_alphanumeric(c) || c == b'_' || c == b'-' { - res = Err(NomErr::Error(($i, ErrorKind::Tag))); - } - } - res - }, - } - } - ) -); - -macro_rules! generate_terms_for_names { - ($( $(#[$attr:meta])* $typ:ident => $tok:expr,)*) => { - $( - $(#[$attr])* - #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] - pub struct $typ; - - impl<'a> $crate::Parse<'a> for $typ { - parser!(do_parse!( - ws!(ident_tag!($tok)) >> - ($typ) - )); - } - )* - }; -} - -generate_terms! { - /// Represents the terminal symbol `(` - OpenParen => "(", - - /// Represents the terminal symbol `)` - CloseParen => ")", - - /// Represents the terminal symbol `[` - OpenBracket => "[", - - /// Represents the terminal symbol `]` - CloseBracket => "]", - - /// Represents the terminal symbol `{` - OpenBrace => "{", - - /// Represents the terminal symbol `}` - CloseBrace => "}", - - /// Represents the terminal symbol `,` - Comma => ",", - - /// Represents the terminal symbol `-` - Minus => "-", - - /// Represents the terminal symbol `.` - Dot => ".", - - /// Represents the terminal symbol `...` - Ellipsis => "...", - - /// Represents the terminal symbol `:` - Colon => ":", - - /// Represents the terminal symbol `;` - SemiColon => ";", - - /// Represents the terminal symbol `<` - LessThan => "<", - - /// Represents the terminal symbol `=` - Assign => "=", - - /// Represents the terminal symbol `>` - GreaterThan => ">", - - /// Represents the terminal symbol `?` - QMark => "?" -} - -generate_terms_for_names! { - /// Represents the terminal symbol `or` - Or => "or", - - /// Represents the terminal symbol `optional` - Optional => "optional", - - /// Represents the terminal symbol `attribute` - Attribute => "attribute", - - /// Represents the terminal symbol `callback` - Callback => "callback", - - /// Represents the terminal symbol `const` - Const => "const", - - /// Represents the terminal symbol `deleter` - Deleter => "deleter", - - /// Represents the terminal symbol `dictionary` - Dictionary => "dictionary", - - /// Represents the terminal symbol `enum` - Enum => "enum", - - /// Represents the terminal symbol `getter` - Getter => "getter", - - /// Represents the terminal symbol `includes` - Includes => "includes", - - /// Represents the terminal symbol `inherit` - Inherit => "inherit", - - /// Represents the terminal symbol `interface` - Interface => "interface", - - /// Represents the terminal symbol `iterable` - Iterable => "iterable", - - /// Represents the terminal symbol `maplike` - Maplike => "maplike", - - /// Represents the terminal symbol `namespace` - Namespace => "namespace", - - /// Represents the terminal symbol `partial` - Partial => "partial", - - /// Represents the terminal symbol `required` - Required => "required", - - /// Represents the terminal symbol `setlike` - Setlike => "setlike", - - /// Represents the terminal symbol `setter` - Setter => "setter", - - /// Represents the terminal symbol `static` - Static => "static", - - /// Represents the terminal symbol `stringifier` - Stringifier => "stringifier", - - /// Represents the terminal symbol `typedef` - Typedef => "typedef", - - /// Represents the terminal symbol `unrestricted` - Unrestricted => "unrestricted", - - /// Represents the terminal symbol `symbol` - Symbol => "symbol", - - /// Represents the terminal symbol `Infinity` - NegInfinity => "-Infinity", - - /// Represents the terminal symbol `ByteString` - ByteString => "ByteString", - - /// Represents the terminal symbol `DOMString` - DOMString => "DOMString", - - /// Represents the terminal symbol `FrozenArray` - FrozenArray => "FrozenArray", - - /// Represents the terminal symbol `Infinity` - Infinity => "Infinity", - - /// Represents the terminal symbol `NaN` - NaN => "NaN", - - /// Represents the terminal symbol `USVString` - USVString => "USVString", - - /// Represents the terminal symbol `any` - Any => "any", - - /// Represents the terminal symbol `boolean` - Boolean => "boolean", - - /// Represents the terminal symbol `byte` - Byte => "byte", - - /// Represents the terminal symbol `double` - Double => "double", - - /// Represents the terminal symbol `false` - False => "false", - - /// Represents the terminal symbol `float` - Float => "float", - - /// Represents the terminal symbol `long` - Long => "long", - - /// Represents the terminal symbol `null` - Null => "null", - - /// Represents the terminal symbol `object` - Object => "object", - - /// Represents the terminal symbol `octet` - Octet => "octet", - - /// Represents the terminal symbol `sequence` - Sequence => "sequence", - - /// Represents the terminal symbol `short` - Short => "short", - - /// Represents the terminal symbol `true` - True => "true", - - /// Represents the terminal symbol `unsigned` - Unsigned => "unsigned", - - /// Represents the terminal symbol `void` - Void => "void", - - /// Represents the terminal symbol `record` - Record => "record", - - /// Represents the terminal symbol `ArrayBuffer` - ArrayBuffer => "ArrayBuffer", - - /// Represents the terminal symbol `DataView` - DataView => "DataView", - - /// Represents the terminal symbol `Int8Array` - Int8Array => "Int8Array", - - /// Represents the terminal symbol `Int16Array` - Int16Array => "Int16Array", - - /// Represents the terminal symbol `Int32Array` - Int32Array => "Int32Array", - - /// Represents the terminal symbol `Uint8Array` - Uint8Array => "Uint8Array", - - /// Represents the terminal symbol `Uint16Array` - Uint16Array => "Uint16Array", - - /// Represents the terminal symbol `Uint32Array` - Uint32Array => "Uint32Array", - - /// Represents the terminal symbol `Uint8ClampedArray` - Uint8ClampedArray => "Uint8ClampedArray", - - /// Represents the terminal symbol `Float32Array` - Float32Array => "Float32Array", - - /// Represents the terminal symbol `Float64Array` - Float64Array => "Float64Array", - - /// Represents the terminal symbol `ArrayBufferView` - ArrayBufferView => "ArrayBufferView", - - /// Represents the terminal symbol `BufferSource - BufferSource => "BufferSource", - - /// Represents the terminal symbol `Promise` - Promise => "Promise", - - /// Represents the terminal symbol `Error` - Error => "Error", - - /// Represents the terminal symbol `readonly` - ReadOnly => "readonly", - - /// Represents the terminal symbol `mixin` - Mixin => "mixin", - - /// Represents the terminal symbol `implements` - Implements => "implements", - - /// Represents the terminal symbol `legacycaller` - LegacyCaller => "legacycaller", - - /// Represents the terminal symbol `constructor` - Constructor => "constructor", -} - -#[macro_export] -macro_rules! term { - (OpenParen) => { - $crate::term::OpenParen - }; - (CloseParen) => { - $crate::term::CloseParen - }; - (OpenBracket) => { - $crate::term::OpenBracket - }; - (CloseBracket) => { - $crate::term::CloseBracket - }; - (OpenBrace) => { - $crate::term::OpenBrace - }; - (CloseBrace) => { - $crate::term::CloseBrace - }; - (,) => { - $crate::term::Comma - }; - (-) => { - $crate::term::Minus - }; - (.) => { - $crate::term::Dot - }; - (...) => { - $crate::term::Ellipsis - }; - (:) => { - $crate::term::Colon - }; - (;) => { - $crate::term::SemiColon - }; - (<) => { - $crate::term::LessThan - }; - (=) => { - $crate::term::Assign - }; - (>) => { - $crate::term::GreaterThan - }; - (?) => { - $crate::term::QMark - }; - (or) => { - $crate::term::Or - }; - (optional) => { - $crate::term::Optional - }; - (attribute) => { - $crate::term::Attribute - }; - (callback) => { - $crate::term::Callback - }; - (const) => { - $crate::term::Const - }; - (deleter) => { - $crate::term::Deleter - }; - (dictionary) => { - $crate::term::Dictionary - }; - (enum) => { - $crate::term::Enum - }; - (getter) => { - $crate::term::Getter - }; - (includes) => { - $crate::term::Includes - }; - (inherit) => { - $crate::term::Inherit - }; - (interface) => { - $crate::term::Interface - }; - (iterable) => { - $crate::term::Iterable - }; - (maplike) => { - $crate::term::Maplike - }; - (namespace) => { - $crate::term::Namespace - }; - (partial) => { - $crate::term::Partial - }; - (required) => { - $crate::term::Required - }; - (setlike) => { - $crate::term::Setlike - }; - (setter) => { - $crate::term::Setter - }; - (static) => { - $crate::term::Static - }; - (stringifier) => { - $crate::term::Stringifier - }; - (typedef) => { - $crate::term::Typedef - }; - (unrestricted) => { - $crate::term::Unrestricted - }; - (symbol) => { - $crate::term::Symbol - }; - (- Infinity) => { - $crate::term::NegInfinity - }; - (ByteString) => { - $crate::term::ByteString - }; - (DOMString) => { - $crate::term::DOMString - }; - (FrozenArray) => { - $crate::term::FrozenArray - }; - (Infinity) => { - $crate::term::Infinity - }; - (NaN) => { - $crate::term::NaN - }; - (USVString) => { - $crate::term::USVString - }; - (any) => { - $crate::term::Any - }; - (boolean) => { - $crate::term::Boolean - }; - (byte) => { - $crate::term::Byte - }; - (double) => { - $crate::term::Double - }; - (false) => { - $crate::term::False - }; - (float) => { - $crate::term::Float - }; - (long) => { - $crate::term::Long - }; - (null) => { - $crate::term::Null - }; - (object) => { - $crate::term::Object - }; - (octet) => { - $crate::term::Octet - }; - (sequence) => { - $crate::term::Sequence - }; - (short) => { - $crate::term::Short - }; - (true) => { - $crate::term::True - }; - (unsigned) => { - $crate::term::Unsigned - }; - (void) => { - $crate::term::Void - }; - (record) => { - $crate::term::Record - }; - (ArrayBuffer) => { - $crate::term::ArrayBuffer - }; - (DataView) => { - $crate::term::DataView - }; - (Int8Array) => { - $crate::term::Int8Array - }; - (Int16Array) => { - $crate::term::Int16Array - }; - (Int32Array) => { - $crate::term::Int32Array - }; - (Uint8Array) => { - $crate::term::Uint8Array - }; - (Uint16Array) => { - $crate::term::Uint16Array - }; - (Uint32Array) => { - $crate::term::Uint32Array - }; - (Uint8ClampedArray) => { - $crate::term::Uint8ClampedArray - }; - (Float32Array) => { - $crate::term::Float32Array - }; - (Float64Array) => { - $crate::term::Float64Array - }; - (ArrayBufferView) => { - $crate::term::ArrayBufferView - }; - (BufferSource) => { - $crate::term::BufferSource - }; - (Promise) => { - $crate::term::Promise - }; - (Error) => { - $crate::term::Error - }; - (readonly) => { - $crate::term::ReadOnly - }; - (mixin) => { - $crate::term::Mixin - }; - (implements) => { - $crate::term::Implements - }; - (legacycaller) => { - $crate::term::LegacyCaller - }; - (constructor) => { - $crate::term::Constructor - }; -} - -#[cfg(test)] -mod test { - macro_rules! generate_tests { - ($($m:ident, $typ:ident, $string:expr;)*) => { - $( - mod $m { - use super::super::$typ; - use crate::Parse; - - #[test] - fn should_parse() { - let (rem, parsed) = $typ::parse(concat!($string)).unwrap(); - assert_eq!(rem, ""); - assert_eq!(parsed, $typ); - } - - #[test] - fn should_parse_with_preceding_spaces() { - let (rem, parsed) = $typ::parse(concat!(" ", $string)).unwrap(); - assert_eq!(rem, ""); - assert_eq!(parsed, $typ); - } - - #[test] - fn should_parse_with_succeeding_spaces() { - let (rem, parsed) = $typ::parse(concat!($string, " ")).unwrap(); - assert_eq!(rem, ""); - assert_eq!(parsed, $typ); - } - - #[test] - fn should_parse_with_surrounding_spaces() { - let (rem, parsed) = $typ::parse(concat!(" ", $string, " ")).unwrap(); - assert_eq!(rem, ""); - assert_eq!(parsed, $typ); - } - - #[test] - fn should_parse_if_anything_next() { - let (rem, parsed) = $typ::parse(concat!($string, " anything")).unwrap(); - assert_eq!(rem, "anything"); - assert_eq!(parsed, $typ); - } - } - )* - }; - } - - generate_tests![ - openparen, OpenParen, "("; - closeparen, CloseParen, ")"; - openbracket, OpenBracket, "["; - closebracket, CloseBracket, "]"; - openbrace, OpenBrace, "{"; - closebrace, CloseBrace, "}"; - comma, Comma, ","; - minus, Minus, "-"; - dot, Dot, "."; - ellipsis, Ellipsis, "..."; - colon, Colon, ":"; - semicolon, SemiColon, ";"; - lessthan, LessThan, "<"; - assign, Assign, "="; - greaterthan, GreaterThan, ">"; - qmark, QMark, "?"; - or, Or, "or"; - optional, Optional, "optional"; - attribute, Attribute, "attribute"; - callback, Callback, "callback"; - const_, Const, "const"; - deleter, Deleter, "deleter"; - dictionary, Dictionary, "dictionary"; - enum_, Enum, "enum"; - getter, Getter, "getter"; - includes, Includes, "includes"; - inherit, Inherit, "inherit"; - interface, Interface, "interface"; - iterable, Iterable, "iterable"; - maplike, Maplike, "maplike"; - namespace, Namespace, "namespace"; - partial, Partial, "partial"; - required, Required, "required"; - setlike, Setlike, "setlike"; - setter, Setter, "setter"; - static_, Static, "static"; - stringifier, Stringifier, "stringifier"; - typedef, Typedef, "typedef"; - unrestricted, Unrestricted, "unrestricted"; - symbol, Symbol, "symbol"; - neginfinity, NegInfinity, "-Infinity"; - bytestring, ByteString, "ByteString"; - domstring, DOMString, "DOMString"; - frozenarray, FrozenArray, "FrozenArray"; - infinity, Infinity, "Infinity"; - nan, NaN, "NaN"; - usvstring, USVString, "USVString"; - any, Any, "any"; - boolean, Boolean, "boolean"; - byte, Byte, "byte"; - double, Double, "double"; - false_, False, "false"; - float, Float, "float"; - long, Long, "long"; - null, Null, "null"; - object, Object, "object"; - octet, Octet, "octet"; - sequence, Sequence, "sequence"; - short, Short, "short"; - true_, True, "true"; - unsigned, Unsigned, "unsigned"; - void, Void, "void"; - record, Record, "record"; - arraybuffer, ArrayBuffer, "ArrayBuffer"; - dataview, DataView, "DataView"; - int8array, Int8Array, "Int8Array"; - int16array, Int16Array, "Int16Array"; - int32array, Int32Array, "Int32Array"; - uint8array, Uint8Array, "Uint8Array"; - uint16array, Uint16Array, "Uint16Array"; - uint32array, Uint32Array, "Uint32Array"; - uint8clampedarray, Uint8ClampedArray, "Uint8ClampedArray"; - float32array, Float32Array, "Float32Array"; - float64array, Float64Array, "Float64Array"; - promise, Promise, "Promise"; - error, Error, "Error"; - implements, Implements, "implements"; - legacycaller, LegacyCaller, "legacycaller"; - constructor, Constructor, "constructor"; - ]; -} diff --git a/third_party/rust/weedle/src/types.rs b/third_party/rust/weedle/src/types.rs deleted file mode 100644 index 8ee7e176f9b3..000000000000 --- a/third_party/rust/weedle/src/types.rs +++ /dev/null @@ -1,380 +0,0 @@ -use crate::attribute::ExtendedAttributeList; -use crate::common::{Generics, Identifier, Parenthesized, Punctuated}; -use crate::term; -use crate::Parse; - -/// Parses a union of types -pub type UnionType<'a> = Parenthesized, term!(or)>>; - -ast_types! { - /// Parses either single type or a union type - enum Type<'a> { - /// Parses one of the single types - Single(enum SingleType<'a> { - Any(term!(any)), - NonAny(NonAnyType<'a>), - }), - Union(MayBeNull>), - } - - // Parses any single non-any type - enum NonAnyType<'a> { - Promise(PromiseType<'a>), - Integer(MayBeNull), - FloatingPoint(MayBeNull), - Boolean(MayBeNull), - Byte(MayBeNull), - Octet(MayBeNull), - ByteString(MayBeNull), - DOMString(MayBeNull), - USVString(MayBeNull), - Sequence(MayBeNull>), - Object(MayBeNull), - Symbol(MayBeNull), - Error(MayBeNull), - ArrayBuffer(MayBeNull), - DataView(MayBeNull), - Int8Array(MayBeNull), - Int16Array(MayBeNull), - Int32Array(MayBeNull), - Uint8Array(MayBeNull), - Uint16Array(MayBeNull), - Uint32Array(MayBeNull), - Uint8ClampedArray(MayBeNull), - Float32Array(MayBeNull), - Float64Array(MayBeNull), - ArrayBufferView(MayBeNull), - BufferSource(MayBeNull), - FrozenArrayType(MayBeNull>), - RecordType(MayBeNull>), - Identifier(MayBeNull>), - } - - /// Parses `sequence` - struct SequenceType<'a> { - sequence: term!(sequence), - generics: Generics>>, - } - - /// Parses `FrozenArray` - struct FrozenArrayType<'a> { - frozen_array: term!(FrozenArray), - generics: Generics>>, - } - - /// Parses a nullable type. Ex: `object | object??` - /// - /// `??` means an actual ? not an optional requirement - #[derive(Copy)] - struct MayBeNull where [T: Parse<'a>] { - type_: T, - q_mark: Option, - } - - /// Parses a `Promise` type - struct PromiseType<'a> { - promise: term!(Promise), - generics: Generics>>, - } - - /// Parses `unsigned? short|long|(long long)` - #[derive(Copy)] - enum IntegerType { - /// Parses `unsigned? long long` - #[derive(Copy)] - LongLong(struct LongLongType { - unsigned: Option, - long_long: (term!(long), term!(long)), - }), - /// Parses `unsigned? long` - #[derive(Copy)] - Long(struct LongType { - unsigned: Option, - long: term!(long), - }), - /// Parses `unsigned? short` - #[derive(Copy)] - Short(struct ShortType { - unsigned: Option, - short: term!(short), - }), - } - - /// Parses `unrestricted? float|double` - #[derive(Copy)] - enum FloatingPointType { - /// Parses `unrestricted? float` - #[derive(Copy)] - Float(struct FloatType { - unrestricted: Option, - float: term!(float), - }), - /// Parses `unrestricted? double` - #[derive(Copy)] - Double(struct DoubleType { - unrestricted: Option, - double: term!(double), - }), - } - - /// Parses `record` - struct RecordType<'a> { - record: term!(record), - generics: Generics<(StringType, term!(,), Box>)>, - } - - /// Parses one of the string types `ByteString|DOMString|USVString` - #[derive(Copy)] - enum StringType { - Byte(term!(ByteString)), - DOM(term!(DOMString)), - USV(term!(USVString)), - } - - /// Parses one of the member of a union type - enum UnionMemberType<'a> { - Single(AttributedNonAnyType<'a>), - Union(MayBeNull>), - } - - /// Parses a const type - enum ConstType<'a> { - Integer(MayBeNull), - FloatingPoint(MayBeNull), - Boolean(MayBeNull), - Byte(MayBeNull), - Octet(MayBeNull), - Identifier(MayBeNull>), - } - - /// Parses the return type which may be `void` or any given Type - enum ReturnType<'a> { - Void(term!(void)), - Type(Type<'a>), - } - - /// Parses `[attributes]? type` - struct AttributedType<'a> { - attributes: Option>, - type_: Type<'a>, - } - - /// Parses `[attributes]? type` where the type is a single non-any type - struct AttributedNonAnyType<'a> { - attributes: Option>, - type_: NonAnyType<'a>, - } -} - -#[cfg(test)] -mod test { - use super::*; - - test!(should_parse_may_be_null { "short" => - ""; - MayBeNull; - q_mark.is_none(); - }); - - test!(should_parse_nullable { "short?" => - ""; - MayBeNull; - q_mark.is_some(); - }); - - test_variants!( - ReturnType { - Void == "void", - Type == "any", - } - ); - - test_variants!( - ConstType { - Integer == "short", - FloatingPoint == "float", - Boolean == "boolean", - Byte == "byte", - Octet == "octet", - Identifier == "name", - } - ); - - test_variants!( - NonAnyType { - Promise == "Promise", - Integer == "long", - FloatingPoint == "float", - Boolean == "boolean", - Byte == "byte", - Octet == "octet", - ByteString == "ByteString", - DOMString == "DOMString", - USVString == "USVString", - Sequence == "sequence", - Object == "object", - Symbol == "symbol", - Error == "Error", - ArrayBuffer == "ArrayBuffer", - DataView == "DataView", - Int8Array == "Int8Array", - Int16Array == "Int16Array", - Int32Array == "Int32Array", - Uint8Array == "Uint8Array", - Uint16Array == "Uint16Array", - Uint32Array == "Uint32Array", - Uint8ClampedArray == "Uint8ClampedArray", - Float32Array == "Float32Array", - Float64Array == "Float64Array", - ArrayBufferView == "ArrayBufferView", - BufferSource == "BufferSource", - FrozenArrayType == "FrozenArray", - RecordType == "record", - Identifier == "mango" - } - ); - - test_variants!( - UnionMemberType { - Single == "byte", - Union == "([Clamp] unsigned long or byte)" - } - ); - - test_variants!( - StringType { - DOM == "DOMString", - USV == "USVString", - Byte == "ByteString" - } - ); - - test!(should_parse_record_type { "record" => - ""; - RecordType; - }); - - test!(should_parse_double_type { "double" => - ""; - DoubleType; - }); - - test!(should_parse_float_type { "float" => - ""; - FloatType; - }); - - test_variants!( - FloatingPointType { - Float == "float", - Double == "double" - } - ); - - test!(should_parse_long_long_type { "long long" => - ""; - LongLongType; - }); - - test!(should_parse_long_type { "long" => - ""; - LongType; - }); - - test!(should_parse_short_type { "short" => - ""; - ShortType; - }); - - test_variants!( - IntegerType { - Short == "short", - Long == "long", - LongLong == "long long" - } - ); - - test!(should_parse_promise_type { "Promise" => - ""; - PromiseType; - }); - - test!(should_parse_frozen_array_type { "FrozenArray" => - ""; - FrozenArrayType; - }); - - test!(should_parse_sequence_type { "sequence" => - ""; - SequenceType; - }); - - test_variants!( - SingleType { - Any == "any", - NonAny == "Promise", - } - ); - - test_variants!( - Type { - Single == "short", - Union == "(short or float)" - } - ); - - test!(should_parse_attributed_type { "[Named] short" => - ""; - AttributedType; - attributes.is_some(); - }); - - test!(should_parse_type_as_identifier { "DOMStringMap" => - // if type is not parsed as identifier, it is parsed as `DOMString` and 'Map' is left - ""; - crate::types::Type; - }); - - #[test] - fn should_parse_union_member_type_attributed_union() { - use crate::types::UnionMemberType; - let (rem, parsed) = UnionMemberType::parse("([Clamp] byte or [Named] byte)").unwrap(); - assert_eq!(rem, ""); - match parsed { - UnionMemberType::Union(MayBeNull { - type_: - Parenthesized { - body: Punctuated { list, .. }, - .. - }, - .. - }) => { - assert_eq!(list.len(), 2); - - match list[0] { - UnionMemberType::Single(AttributedNonAnyType { ref attributes, .. }) => { - assert!(attributes.is_some()); - } - - _ => { - panic!("Failed to parse list[0] attributes"); - } - }; - - match list[1] { - UnionMemberType::Single(AttributedNonAnyType { ref attributes, .. }) => { - assert!(attributes.is_some()); - } - - _ => { - panic!("Failed to parse list[1] attributes"); - } - }; - } - - _ => { - panic!("Failed to parse"); - } - } - } -} diff --git a/third_party/rust/weedle/src/whitespace.rs b/third_party/rust/weedle/src/whitespace.rs deleted file mode 100644 index e6bbf0a61fc7..000000000000 --- a/third_party/rust/weedle/src/whitespace.rs +++ /dev/null @@ -1,31 +0,0 @@ -use crate::IResult; - -pub(crate) fn sp(input: &str) -> IResult<&str, &str> { - recognize!( - input, - many0!(alt!( - // ignores line comments - do_parse!(tag!("//") >> take_until!("\n") >> char!('\n') >> (())) - | - // ignores whitespace - map!(take_while1!(|c| c == '\t' || c == '\n' || c == '\r' || c == ' '), |_| ()) - | - // ignores block comments - do_parse!(tag!("/*") >> take_until!("*/") >> tag!("*/") >> (())) - )) - ) -} - -/// ws! also ignores line & block comments -macro_rules! ws ( - ($i:expr, $($args:tt)*) => ({ - use $crate::whitespace::sp; - - do_parse!($i, - sp >> - s: $($args)* >> - sp >> - (s) - ) - }); -); diff --git a/third_party/rust/weedle/tests/defs/dom.webidl b/third_party/rust/weedle/tests/defs/dom.webidl deleted file mode 100644 index 22d436ff5a6a..000000000000 --- a/third_party/rust/weedle/tests/defs/dom.webidl +++ /dev/null @@ -1,549 +0,0 @@ -[Constructor(DOMString type, optional EventInit eventInitDict), - Exposed=(Window,Worker,AudioWorklet)] -interface Event { - readonly attribute DOMString type; - readonly attribute EventTarget? target; - readonly attribute EventTarget? srcElement; // historical - readonly attribute EventTarget? currentTarget; - sequence composedPath(); - - const unsigned short NONE = 0; - const unsigned short CAPTURING_PHASE = 1; - const unsigned short AT_TARGET = 2; - const unsigned short BUBBLING_PHASE = 3; - readonly attribute unsigned short eventPhase; - - void stopPropagation(); - attribute boolean cancelBubble; // historical alias of .stopPropagation - void stopImmediatePropagation(); - - readonly attribute boolean bubbles; - readonly attribute boolean cancelable; - attribute boolean returnValue; // historical - void preventDefault(); - readonly attribute boolean defaultPrevented; - readonly attribute boolean composed; - - [Unforgeable] readonly attribute boolean isTrusted; - readonly attribute DOMHighResTimeStamp timeStamp; - - void initEvent(DOMString type, optional boolean bubbles = false, optional boolean cancelable = false); // historical -}; - -dictionary EventInit { - boolean bubbles = false; - boolean cancelable = false; - boolean composed = false; -}; - -[Constructor(DOMString type, optional CustomEventInit eventInitDict), - Exposed=(Window,Worker)] -interface CustomEvent : Event { - readonly attribute any detail; - - void initCustomEvent(DOMString type, optional boolean bubbles = false, optional boolean cancelable = false, optional any detail = null); -}; - -dictionary CustomEventInit : EventInit { - any detail = null; -}; - -[Constructor, - Exposed=(Window,Worker,AudioWorklet)] -interface EventTarget { - void addEventListener(DOMString type, EventListener? callback, optional (AddEventListenerOptions or boolean) options); - void removeEventListener(DOMString type, EventListener? callback, optional (EventListenerOptions or boolean) options); - boolean dispatchEvent(Event event); -}; - -callback interface EventListener { - void handleEvent(Event event); -}; - -dictionary EventListenerOptions { - boolean capture = false; -}; - -dictionary AddEventListenerOptions : EventListenerOptions { - boolean passive = false; - boolean once = false; -}; - -[Constructor, - Exposed=(Window,Worker)] -interface AbortController { - [SameObject] readonly attribute AbortSignal signal; - - void abort(); -}; - -[Exposed=(Window,Worker)] -interface AbortSignal : EventTarget { - readonly attribute boolean aborted; - - attribute EventHandler onabort; -}; - -interface mixin NonElementParentNode { - Element? getElementById(DOMString elementId); -}; -Document includes NonElementParentNode; -DocumentFragment includes NonElementParentNode; - -interface mixin DocumentOrShadowRoot { -}; -Document includes DocumentOrShadowRoot; -ShadowRoot includes DocumentOrShadowRoot; - -interface mixin ParentNode { - [SameObject] readonly attribute HTMLCollection children; - readonly attribute Element? firstElementChild; - readonly attribute Element? lastElementChild; - readonly attribute unsigned long childElementCount; - - [CEReactions, Unscopable] void prepend((Node or DOMString)... nodes); - [CEReactions, Unscopable] void append((Node or DOMString)... nodes); - - Element? querySelector(DOMString selectors); - [NewObject] NodeList querySelectorAll(DOMString selectors); -}; -Document includes ParentNode; -DocumentFragment includes ParentNode; -Element includes ParentNode; - -interface mixin NonDocumentTypeChildNode { - readonly attribute Element? previousElementSibling; - readonly attribute Element? nextElementSibling; -}; -Element includes NonDocumentTypeChildNode; -CharacterData includes NonDocumentTypeChildNode; - -interface mixin ChildNode { - [CEReactions, Unscopable] void before((Node or DOMString)... nodes); - [CEReactions, Unscopable] void after((Node or DOMString)... nodes); - [CEReactions, Unscopable] void replaceWith((Node or DOMString)... nodes); - [CEReactions, Unscopable] void remove(); -}; -DocumentType includes ChildNode; -Element includes ChildNode; -CharacterData includes ChildNode; - -interface mixin Slotable { - readonly attribute HTMLSlotElement? assignedSlot; -}; -Element includes Slotable; -Text includes Slotable; - -[Exposed=Window] -interface NodeList { - getter Node? item(unsigned long index); - readonly attribute unsigned long length; - iterable; -}; - -[Exposed=Window, LegacyUnenumerableNamedProperties] -interface HTMLCollection { - readonly attribute unsigned long length; - getter Element? item(unsigned long index); - getter Element? namedItem(DOMString name); -}; - -[Constructor(MutationCallback callback), - Exposed=Window] -interface MutationObserver { - void observe(Node target, optional MutationObserverInit options); - void disconnect(); - sequence takeRecords(); -}; - -callback MutationCallback = void (sequence mutations, MutationObserver observer); - -dictionary MutationObserverInit { - boolean childList = false; - boolean attributes; - boolean characterData; - boolean subtree = false; - boolean attributeOldValue; - boolean characterDataOldValue; - sequence attributeFilter; -}; - -[Exposed=Window] -interface MutationRecord { - readonly attribute DOMString type; - [SameObject] readonly attribute Node target; - [SameObject] readonly attribute NodeList addedNodes; - [SameObject] readonly attribute NodeList removedNodes; - readonly attribute Node? previousSibling; - readonly attribute Node? nextSibling; - readonly attribute DOMString? attributeName; - readonly attribute DOMString? attributeNamespace; - readonly attribute DOMString? oldValue; -}; - -[Exposed=Window] -interface Node : EventTarget { - const unsigned short ELEMENT_NODE = 1; - const unsigned short ATTRIBUTE_NODE = 2; - const unsigned short TEXT_NODE = 3; - const unsigned short CDATA_SECTION_NODE = 4; - const unsigned short ENTITY_REFERENCE_NODE = 5; // historical - const unsigned short ENTITY_NODE = 6; // historical - const unsigned short PROCESSING_INSTRUCTION_NODE = 7; - const unsigned short COMMENT_NODE = 8; - const unsigned short DOCUMENT_NODE = 9; - const unsigned short DOCUMENT_TYPE_NODE = 10; - const unsigned short DOCUMENT_FRAGMENT_NODE = 11; - const unsigned short NOTATION_NODE = 12; // historical - readonly attribute unsigned short nodeType; - readonly attribute DOMString nodeName; - - readonly attribute USVString baseURI; - - readonly attribute boolean isConnected; - readonly attribute Document? ownerDocument; - Node getRootNode(optional GetRootNodeOptions options); - readonly attribute Node? parentNode; - readonly attribute Element? parentElement; - boolean hasChildNodes(); - [SameObject] readonly attribute NodeList childNodes; - readonly attribute Node? firstChild; - readonly attribute Node? lastChild; - readonly attribute Node? previousSibling; - readonly attribute Node? nextSibling; - - [CEReactions] attribute DOMString? nodeValue; - [CEReactions] attribute DOMString? textContent; - [CEReactions] void normalize(); - - [CEReactions, NewObject] Node cloneNode(optional boolean deep = false); - boolean isEqualNode(Node? otherNode); - boolean isSameNode(Node? otherNode); // historical alias of === - - const unsigned short DOCUMENT_POSITION_DISCONNECTED = 0x01; - const unsigned short DOCUMENT_POSITION_PRECEDING = 0x02; - const unsigned short DOCUMENT_POSITION_FOLLOWING = 0x04; - const unsigned short DOCUMENT_POSITION_CONTAINS = 0x08; - const unsigned short DOCUMENT_POSITION_CONTAINED_BY = 0x10; - const unsigned short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20; - unsigned short compareDocumentPosition(Node other); - boolean contains(Node? other); - - DOMString? lookupPrefix(DOMString? namespace); - DOMString? lookupNamespaceURI(DOMString? prefix); - boolean isDefaultNamespace(DOMString? namespace); - - [CEReactions] Node insertBefore(Node node, Node? child); - [CEReactions] Node appendChild(Node node); - [CEReactions] Node replaceChild(Node node, Node child); - [CEReactions] Node removeChild(Node child); -}; - -dictionary GetRootNodeOptions { - boolean composed = false; -}; - -[Constructor, - Exposed=Window] -interface Document : Node { - [SameObject] readonly attribute DOMImplementation implementation; - readonly attribute USVString URL; - readonly attribute USVString documentURI; - readonly attribute USVString origin; - readonly attribute DOMString compatMode; - readonly attribute DOMString characterSet; - readonly attribute DOMString charset; // historical alias of .characterSet - readonly attribute DOMString inputEncoding; // historical alias of .characterSet - readonly attribute DOMString contentType; - - readonly attribute DocumentType? doctype; - readonly attribute Element? documentElement; - HTMLCollection getElementsByTagName(DOMString qualifiedName); - HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName); - HTMLCollection getElementsByClassName(DOMString classNames); - - [CEReactions, NewObject] Element createElement(DOMString localName, optional (DOMString or ElementCreationOptions) options); - [CEReactions, NewObject] Element createElementNS(DOMString? namespace, DOMString qualifiedName, optional (DOMString or ElementCreationOptions) options); - [NewObject] DocumentFragment createDocumentFragment(); - [NewObject] Text createTextNode(DOMString data); - [NewObject] CDATASection createCDATASection(DOMString data); - [NewObject] Comment createComment(DOMString data); - [NewObject] ProcessingInstruction createProcessingInstruction(DOMString target, DOMString data); - - [CEReactions, NewObject] Node importNode(Node node, optional boolean deep = false); - [CEReactions] Node adoptNode(Node node); - - [NewObject] Attr createAttribute(DOMString localName); - [NewObject] Attr createAttributeNS(DOMString? namespace, DOMString qualifiedName); - - [NewObject] Event createEvent(DOMString interface); - - [NewObject] Range createRange(); - - // NodeFilter.SHOW_ALL = 0xFFFFFFFF - [NewObject] NodeIterator createNodeIterator(Node root, optional unsigned long whatToShow = 0xFFFFFFFF, optional NodeFilter? filter = null); - [NewObject] TreeWalker createTreeWalker(Node root, optional unsigned long whatToShow = 0xFFFFFFFF, optional NodeFilter? filter = null); -}; - -[Exposed=Window] -interface XMLDocument : Document {}; - -dictionary ElementCreationOptions { - DOMString is; -}; - -[Exposed=Window] -interface DOMImplementation { - [NewObject] DocumentType createDocumentType(DOMString qualifiedName, DOMString publicId, DOMString systemId); - [NewObject] XMLDocument createDocument(DOMString? namespace, [TreatNullAs=EmptyString] DOMString qualifiedName, optional DocumentType? doctype = null); - [NewObject] Document createHTMLDocument(optional DOMString title); - - boolean hasFeature(); // useless; always returns true -}; - -[Exposed=Window] -interface DocumentType : Node { - readonly attribute DOMString name; - readonly attribute DOMString publicId; - readonly attribute DOMString systemId; -}; - -[Constructor, - Exposed=Window] -interface DocumentFragment : Node { -}; - -[Exposed=Window] -interface ShadowRoot : DocumentFragment { - readonly attribute ShadowRootMode mode; - readonly attribute Element host; -}; - -enum ShadowRootMode { "open", "closed" }; - -[Exposed=Window] -interface Element : Node { - readonly attribute DOMString? namespaceURI; - readonly attribute DOMString? prefix; - readonly attribute DOMString localName; - readonly attribute DOMString tagName; - - [CEReactions] attribute DOMString id; - [CEReactions] attribute DOMString className; - [SameObject, PutForwards=value] readonly attribute DOMTokenList classList; - [CEReactions, Unscopable] attribute DOMString slot; - - boolean hasAttributes(); - [SameObject] readonly attribute NamedNodeMap attributes; - sequence getAttributeNames(); - DOMString? getAttribute(DOMString qualifiedName); - DOMString? getAttributeNS(DOMString? namespace, DOMString localName); - [CEReactions] void setAttribute(DOMString qualifiedName, DOMString value); - [CEReactions] void setAttributeNS(DOMString? namespace, DOMString qualifiedName, DOMString value); - [CEReactions] void removeAttribute(DOMString qualifiedName); - [CEReactions] void removeAttributeNS(DOMString? namespace, DOMString localName); - boolean hasAttribute(DOMString qualifiedName); - boolean hasAttributeNS(DOMString? namespace, DOMString localName); - - Attr? getAttributeNode(DOMString qualifiedName); - Attr? getAttributeNodeNS(DOMString? namespace, DOMString localName); - [CEReactions] Attr? setAttributeNode(Attr attr); - [CEReactions] Attr? setAttributeNodeNS(Attr attr); - [CEReactions] Attr removeAttributeNode(Attr attr); - - ShadowRoot attachShadow(ShadowRootInit init); - readonly attribute ShadowRoot? shadowRoot; - - Element? closest(DOMString selectors); - boolean matches(DOMString selectors); - boolean webkitMatchesSelector(DOMString selectors); // historical alias of .matches - - HTMLCollection getElementsByTagName(DOMString qualifiedName); - HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName); - HTMLCollection getElementsByClassName(DOMString classNames); - - [CEReactions] Element? insertAdjacentElement(DOMString where, Element element); // historical - void insertAdjacentText(DOMString where, DOMString data); // historical -}; - -dictionary ShadowRootInit { - required ShadowRootMode mode; -}; - -[Exposed=Window, - LegacyUnenumerableNamedProperties] -interface NamedNodeMap { - readonly attribute unsigned long length; - getter Attr? item(unsigned long index); - getter Attr? getNamedItem(DOMString qualifiedName); - Attr? getNamedItemNS(DOMString? namespace, DOMString localName); - [CEReactions] Attr? setNamedItem(Attr attr); - [CEReactions] Attr? setNamedItemNS(Attr attr); - [CEReactions] Attr removeNamedItem(DOMString qualifiedName); - [CEReactions] Attr removeNamedItemNS(DOMString? namespace, DOMString localName); -}; - -[Exposed=Window] -interface Attr : Node { - readonly attribute DOMString? namespaceURI; - readonly attribute DOMString? prefix; - readonly attribute DOMString localName; - readonly attribute DOMString name; - [CEReactions] attribute DOMString value; - - readonly attribute Element? ownerElement; - - readonly attribute boolean specified; // useless; always returns true -}; - -[Exposed=Window] -interface CharacterData : Node { - attribute [TreatNullAs=EmptyString] DOMString data; - readonly attribute unsigned long length; - DOMString substringData(unsigned long offset, unsigned long count); - void appendData(DOMString data); - void insertData(unsigned long offset, DOMString data); - void deleteData(unsigned long offset, unsigned long count); - void replaceData(unsigned long offset, unsigned long count, DOMString data); -}; - -[Constructor(optional DOMString data = ""), - Exposed=Window] -interface Text : CharacterData { - [NewObject] Text splitText(unsigned long offset); - readonly attribute DOMString wholeText; -}; - -[Exposed=Window] -interface CDATASection : Text { -}; - -[Exposed=Window] -interface ProcessingInstruction : CharacterData { - readonly attribute DOMString target; -}; - -[Constructor(optional DOMString data = ""), - Exposed=Window] -interface Comment : CharacterData { -}; - -[Exposed=Window] -interface AbstractRange { - readonly attribute Node startContainer; - readonly attribute unsigned long startOffset; - readonly attribute Node endContainer; - readonly attribute unsigned long endOffset; - readonly attribute boolean collapsed; -}; - -[Exposed=Window] -interface StaticRange : AbstractRange { -}; - -[Constructor, - Exposed=Window] -interface Range : AbstractRange { - readonly attribute Node commonAncestorContainer; - - void setStart(Node node, unsigned long offset); - void setEnd(Node node, unsigned long offset); - void setStartBefore(Node node); - void setStartAfter(Node node); - void setEndBefore(Node node); - void setEndAfter(Node node); - void collapse(optional boolean toStart = false); - void selectNode(Node node); - void selectNodeContents(Node node); - - const unsigned short START_TO_START = 0; - const unsigned short START_TO_END = 1; - const unsigned short END_TO_END = 2; - const unsigned short END_TO_START = 3; - short compareBoundaryPoints(unsigned short how, Range sourceRange); - - [CEReactions] void deleteContents(); - [CEReactions, NewObject] DocumentFragment extractContents(); - [CEReactions, NewObject] DocumentFragment cloneContents(); - [CEReactions] void insertNode(Node node); - [CEReactions] void surroundContents(Node newParent); - - [NewObject] Range cloneRange(); - void detach(); - - boolean isPointInRange(Node node, unsigned long offset); - short comparePoint(Node node, unsigned long offset); - - boolean intersectsNode(Node node); - - stringifier; -}; - -[Exposed=Window] -interface NodeIterator { - [SameObject] readonly attribute Node root; - readonly attribute Node referenceNode; - readonly attribute boolean pointerBeforeReferenceNode; - readonly attribute unsigned long whatToShow; - readonly attribute NodeFilter? filter; - - Node? nextNode(); - Node? previousNode(); - - void detach(); -}; - -[Exposed=Window] -interface TreeWalker { - [SameObject] readonly attribute Node root; - readonly attribute unsigned long whatToShow; - readonly attribute NodeFilter? filter; - attribute Node currentNode; - - Node? parentNode(); - Node? firstChild(); - Node? lastChild(); - Node? previousSibling(); - Node? nextSibling(); - Node? previousNode(); - Node? nextNode(); -}; - -[Exposed=Window] -callback interface NodeFilter { - // Constants for acceptNode() - const unsigned short FILTER_ACCEPT = 1; - const unsigned short FILTER_REJECT = 2; - const unsigned short FILTER_SKIP = 3; - - // Constants for whatToShow - const unsigned long SHOW_ALL = 0xFFFFFFFF; - const unsigned long SHOW_ELEMENT = 0x1; - const unsigned long SHOW_ATTRIBUTE = 0x2; - const unsigned long SHOW_TEXT = 0x4; - const unsigned long SHOW_CDATA_SECTION = 0x8; - const unsigned long SHOW_ENTITY_REFERENCE = 0x10; // historical - const unsigned long SHOW_ENTITY = 0x20; // historical - const unsigned long SHOW_PROCESSING_INSTRUCTION = 0x40; - const unsigned long SHOW_COMMENT = 0x80; - const unsigned long SHOW_DOCUMENT = 0x100; - const unsigned long SHOW_DOCUMENT_TYPE = 0x200; - const unsigned long SHOW_DOCUMENT_FRAGMENT = 0x400; - const unsigned long SHOW_NOTATION = 0x800; // historical - - unsigned short acceptNode(Node node); -}; - -[Exposed=Window] -interface DOMTokenList { - readonly attribute unsigned long length; - getter DOMString? item(unsigned long index); - boolean contains(DOMString token); - [CEReactions] void add(DOMString... tokens); - [CEReactions] void remove(DOMString... tokens); - [CEReactions] boolean toggle(DOMString token, optional boolean force); - [CEReactions] boolean replace(DOMString token, DOMString newToken); - boolean supports(DOMString token); - [CEReactions] stringifier attribute DOMString value; - iterable; -}; diff --git a/third_party/rust/weedle/tests/defs/html.webidl b/third_party/rust/weedle/tests/defs/html.webidl deleted file mode 100644 index 5a01c03fc74c..000000000000 --- a/third_party/rust/weedle/tests/defs/html.webidl +++ /dev/null @@ -1,2410 +0,0 @@ -[Exposed=Window, - LegacyUnenumerableNamedProperties] -interface HTMLAllCollection { - readonly attribute unsigned long length; - getter Element (unsigned long index); - getter (HTMLCollection or Element)? namedItem(DOMString name); - (HTMLCollection or Element)? item(optional DOMString nameOrIndex); - - // Note: HTMLAllCollection objects have a custom [[Call]] internal method and an [[IsHTMLDDA]] internal slot. -}; - -[Exposed=Window] -interface HTMLFormControlsCollection : HTMLCollection { - // inherits length and item() - getter (RadioNodeList or Element)? namedItem(DOMString name); // shadows inherited namedItem() -}; - -[Exposed=Window] -interface RadioNodeList : NodeList { - attribute DOMString value; -}; - -[Exposed=Window] -interface HTMLOptionsCollection : HTMLCollection { - // inherits item(), namedItem() - [CEReactions] attribute unsigned long length; // shadows inherited length - [CEReactions] setter void (unsigned long index, HTMLOptionElement? option); - [CEReactions] void add((HTMLOptionElement or HTMLOptGroupElement) element, optional (HTMLElement or long)? before = null); - [CEReactions] void remove(long index); - attribute long selectedIndex; -}; - -[Exposed=(Window,Worker)] -interface DOMStringList { - readonly attribute unsigned long length; - getter DOMString? item(unsigned long index); - boolean contains(DOMString string); -}; - -enum DocumentReadyState { "loading", "interactive", "complete" }; -typedef (HTMLScriptElement or SVGScriptElement) HTMLOrSVGScriptElement; - -[OverrideBuiltins] -partial interface Document { - // resource metadata management - [PutForwards=href, Unforgeable] readonly attribute Location? location; - attribute USVString domain; - readonly attribute USVString referrer; - attribute USVString cookie; - readonly attribute DOMString lastModified; - readonly attribute DocumentReadyState readyState; - - // DOM tree accessors - getter object (DOMString name); - [CEReactions] attribute DOMString title; - [CEReactions] attribute DOMString dir; - [CEReactions] attribute HTMLElement? body; - readonly attribute HTMLHeadElement? head; - [SameObject] readonly attribute HTMLCollection images; - [SameObject] readonly attribute HTMLCollection embeds; - [SameObject] readonly attribute HTMLCollection plugins; - [SameObject] readonly attribute HTMLCollection links; - [SameObject] readonly attribute HTMLCollection forms; - [SameObject] readonly attribute HTMLCollection scripts; - NodeList getElementsByName(DOMString elementName); - readonly attribute HTMLOrSVGScriptElement? currentScript; // classic scripts in a document tree only - - // dynamic markup insertion - [CEReactions] Document open(optional DOMString type, optional DOMString replace = ""); // type is ignored - WindowProxy open(USVString url, DOMString name, DOMString features); - [CEReactions] void close(); - [CEReactions] void write(DOMString... text); - [CEReactions] void writeln(DOMString... text); - - // user interaction - readonly attribute WindowProxy? defaultView; - readonly attribute Element? activeElement; - boolean hasFocus(); - [CEReactions] attribute DOMString designMode; - [CEReactions] boolean execCommand(DOMString commandId, optional boolean showUI = false, optional DOMString value = ""); - boolean queryCommandEnabled(DOMString commandId); - boolean queryCommandIndeterm(DOMString commandId); - boolean queryCommandState(DOMString commandId); - boolean queryCommandSupported(DOMString commandId); - DOMString queryCommandValue(DOMString commandId); - - // special event handler IDL attributes that only apply to Document objects - [LenientThis] attribute EventHandler onreadystatechange; -}; -Document includes GlobalEventHandlers; -Document includes DocumentAndElementEventHandlers; - -[Exposed=Window, - HTMLConstructor] -interface HTMLElement : Element { - // metadata attributes - [CEReactions] attribute DOMString title; - [CEReactions] attribute DOMString lang; - [CEReactions] attribute boolean translate; - [CEReactions] attribute DOMString dir; - - // user interaction - [CEReactions] attribute boolean hidden; - void click(); - [CEReactions] attribute DOMString accessKey; - readonly attribute DOMString accessKeyLabel; - [CEReactions] attribute boolean draggable; - [CEReactions] attribute boolean spellcheck; - [CEReactions] attribute DOMString autocapitalize; - - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString innerText; -}; - -HTMLElement includes GlobalEventHandlers; -HTMLElement includes DocumentAndElementEventHandlers; -HTMLElement includes ElementContentEditable; - -// Note: intentionally not [HTMLConstructor] -[Exposed=Window] -interface HTMLUnknownElement : HTMLElement { }; - -interface mixin HTMLOrSVGElement { - [SameObject] readonly attribute DOMStringMap dataset; - attribute DOMString nonce; - - [CEReactions] attribute long tabIndex; - void focus(optional FocusOptions options = {}); - void blur(); -}; -HTMLElement includes HTMLOrSVGElement; -SVGElement includes HTMLOrSVGElement; - -[Exposed=Window, - OverrideBuiltins] -interface DOMStringMap { - getter DOMString (DOMString name); - [CEReactions] setter void (DOMString name, DOMString value); - [CEReactions] deleter void (DOMString name); -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLHtmlElement : HTMLElement {}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLHeadElement : HTMLElement {}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLTitleElement : HTMLElement { - [CEReactions] attribute DOMString text; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLBaseElement : HTMLElement { - [CEReactions] attribute USVString href; - [CEReactions] attribute DOMString target; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLLinkElement : HTMLElement { - [CEReactions] attribute USVString href; - [CEReactions] attribute DOMString? crossOrigin; - [CEReactions] attribute DOMString rel; - [CEReactions] attribute DOMString as; // (default "") - [SameObject, PutForwards=value] readonly attribute DOMTokenList relList; - [CEReactions] attribute DOMString media; - [CEReactions] attribute DOMString integrity; - [CEReactions] attribute DOMString hreflang; - [CEReactions] attribute DOMString type; - [SameObject, PutForwards=value] readonly attribute DOMTokenList sizes; - [CEReactions] attribute DOMString referrerPolicy; -}; -HTMLLinkElement includes LinkStyle; - -[Exposed=Window, - HTMLConstructor] -interface HTMLMetaElement : HTMLElement { - [CEReactions] attribute DOMString name; - [CEReactions] attribute DOMString httpEquiv; - [CEReactions] attribute DOMString content; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLStyleElement : HTMLElement { - [CEReactions] attribute DOMString media; -}; -HTMLStyleElement includes LinkStyle; - -[Exposed=Window, - HTMLConstructor] -interface HTMLBodyElement : HTMLElement {}; - -HTMLBodyElement includes WindowEventHandlers; - -[Exposed=Window, - HTMLConstructor] -interface HTMLHeadingElement : HTMLElement {}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLParagraphElement : HTMLElement {}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLHRElement : HTMLElement {}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLPreElement : HTMLElement {}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLQuoteElement : HTMLElement { - [CEReactions] attribute USVString cite; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLOListElement : HTMLElement { - [CEReactions] attribute boolean reversed; - [CEReactions] attribute long start; - [CEReactions] attribute DOMString type; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLUListElement : HTMLElement {}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLMenuElement : HTMLElement { -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLLIElement : HTMLElement { - [CEReactions] attribute long value; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLDListElement : HTMLElement {}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLDivElement : HTMLElement {}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLAnchorElement : HTMLElement { - [CEReactions] attribute DOMString target; - [CEReactions] attribute DOMString download; - [CEReactions] attribute USVString ping; - [CEReactions] attribute DOMString rel; - [SameObject, PutForwards=value] readonly attribute DOMTokenList relList; - [CEReactions] attribute DOMString hreflang; - [CEReactions] attribute DOMString type; - - [CEReactions] attribute DOMString text; - - [CEReactions] attribute DOMString referrerPolicy; -}; -HTMLAnchorElement includes HTMLHyperlinkElementUtils; - -[Exposed=Window, - HTMLConstructor] -interface HTMLDataElement : HTMLElement { - [CEReactions] attribute DOMString value; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLTimeElement : HTMLElement { - [CEReactions] attribute DOMString dateTime; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLSpanElement : HTMLElement {}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLBRElement : HTMLElement {}; - -interface mixin HTMLHyperlinkElementUtils { - [CEReactions] stringifier attribute USVString href; - readonly attribute USVString origin; - [CEReactions] attribute USVString protocol; - [CEReactions] attribute USVString username; - [CEReactions] attribute USVString password; - [CEReactions] attribute USVString host; - [CEReactions] attribute USVString hostname; - [CEReactions] attribute USVString port; - [CEReactions] attribute USVString pathname; - [CEReactions] attribute USVString search; - [CEReactions] attribute USVString hash; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLModElement : HTMLElement { - [CEReactions] attribute USVString cite; - [CEReactions] attribute DOMString dateTime; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLPictureElement : HTMLElement {}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLSourceElement : HTMLElement { - [CEReactions] attribute USVString src; - [CEReactions] attribute DOMString type; - [CEReactions] attribute USVString srcset; - [CEReactions] attribute DOMString sizes; - [CEReactions] attribute DOMString media; -}; - -[Exposed=Window, - HTMLConstructor, - NamedConstructor=Image(optional unsigned long width, optional unsigned long height)] -interface HTMLImageElement : HTMLElement { - [CEReactions] attribute DOMString alt; - [CEReactions] attribute USVString src; - [CEReactions] attribute USVString srcset; - [CEReactions] attribute DOMString sizes; - [CEReactions] attribute DOMString? crossOrigin; - [CEReactions] attribute DOMString useMap; - [CEReactions] attribute boolean isMap; - [CEReactions] attribute unsigned long width; - [CEReactions] attribute unsigned long height; - readonly attribute unsigned long naturalWidth; - readonly attribute unsigned long naturalHeight; - readonly attribute boolean complete; - readonly attribute USVString currentSrc; - [CEReactions] attribute DOMString referrerPolicy; - [CEReactions] attribute DOMString decoding; - - Promise decode(); -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLIFrameElement : HTMLElement { - [CEReactions] attribute USVString src; - [CEReactions] attribute DOMString srcdoc; - [CEReactions] attribute DOMString name; - [SameObject, PutForwards=value] readonly attribute DOMTokenList sandbox; - [CEReactions] attribute boolean allowFullscreen; - [CEReactions] attribute boolean allowPaymentRequest; - [CEReactions] attribute boolean allowUserMedia; - [CEReactions] attribute DOMString width; - [CEReactions] attribute DOMString height; - [CEReactions] attribute DOMString referrerPolicy; - readonly attribute Document? contentDocument; - readonly attribute WindowProxy? contentWindow; - Document? getSVGDocument(); -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLEmbedElement : HTMLElement { - [CEReactions] attribute USVString src; - [CEReactions] attribute DOMString type; - [CEReactions] attribute DOMString width; - [CEReactions] attribute DOMString height; - Document? getSVGDocument(); -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLObjectElement : HTMLElement { - [CEReactions] attribute USVString data; - [CEReactions] attribute DOMString type; - [CEReactions] attribute boolean typeMustMatch; - [CEReactions] attribute DOMString name; - [CEReactions] attribute DOMString useMap; - readonly attribute HTMLFormElement? form; - [CEReactions] attribute DOMString width; - [CEReactions] attribute DOMString height; - readonly attribute Document? contentDocument; - readonly attribute WindowProxy? contentWindow; - Document? getSVGDocument(); - - readonly attribute boolean willValidate; - readonly attribute ValidityState validity; - readonly attribute DOMString validationMessage; - boolean checkValidity(); - boolean reportValidity(); - void setCustomValidity(DOMString error); -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLParamElement : HTMLElement { - [CEReactions] attribute DOMString name; - [CEReactions] attribute DOMString value; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLVideoElement : HTMLMediaElement { - [CEReactions] attribute unsigned long width; - [CEReactions] attribute unsigned long height; - readonly attribute unsigned long videoWidth; - readonly attribute unsigned long videoHeight; - [CEReactions] attribute USVString poster; - [CEReactions] attribute boolean playsInline; -}; - -[Exposed=Window, - HTMLConstructor, - NamedConstructor=Audio(optional DOMString src)] -interface HTMLAudioElement : HTMLMediaElement {}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLTrackElement : HTMLElement { - [CEReactions] attribute DOMString kind; - [CEReactions] attribute USVString src; - [CEReactions] attribute DOMString srclang; - [CEReactions] attribute DOMString label; - [CEReactions] attribute boolean default; - - const unsigned short NONE = 0; - const unsigned short LOADING = 1; - const unsigned short LOADED = 2; - const unsigned short ERROR = 3; - readonly attribute unsigned short readyState; - - readonly attribute TextTrack track; -}; - -enum CanPlayTypeResult { "" /* empty string */, "maybe", "probably" }; -typedef (MediaStream or MediaSource or Blob) MediaProvider; - -[Exposed=Window] -interface HTMLMediaElement : HTMLElement { - - // error state - readonly attribute MediaError? error; - - // network state - [CEReactions] attribute USVString src; - attribute MediaProvider? srcObject; - readonly attribute USVString currentSrc; - [CEReactions] attribute DOMString? crossOrigin; - const unsigned short NETWORK_EMPTY = 0; - const unsigned short NETWORK_IDLE = 1; - const unsigned short NETWORK_LOADING = 2; - const unsigned short NETWORK_NO_SOURCE = 3; - readonly attribute unsigned short networkState; - [CEReactions] attribute DOMString preload; - readonly attribute TimeRanges buffered; - void load(); - CanPlayTypeResult canPlayType(DOMString type); - - // ready state - const unsigned short HAVE_NOTHING = 0; - const unsigned short HAVE_METADATA = 1; - const unsigned short HAVE_CURRENT_DATA = 2; - const unsigned short HAVE_FUTURE_DATA = 3; - const unsigned short HAVE_ENOUGH_DATA = 4; - readonly attribute unsigned short readyState; - readonly attribute boolean seeking; - - // playback state - attribute double currentTime; - void fastSeek(double time); - readonly attribute unrestricted double duration; - object getStartDate(); - readonly attribute boolean paused; - attribute double defaultPlaybackRate; - attribute double playbackRate; - readonly attribute TimeRanges played; - readonly attribute TimeRanges seekable; - readonly attribute boolean ended; - [CEReactions] attribute boolean autoplay; - [CEReactions] attribute boolean loop; - Promise play(); - void pause(); - - // controls - [CEReactions] attribute boolean controls; - attribute double volume; - attribute boolean muted; - [CEReactions] attribute boolean defaultMuted; - - // tracks - [SameObject] readonly attribute AudioTrackList audioTracks; - [SameObject] readonly attribute VideoTrackList videoTracks; - [SameObject] readonly attribute TextTrackList textTracks; - TextTrack addTextTrack(TextTrackKind kind, optional DOMString label = "", optional DOMString language = ""); -}; - -[Exposed=Window] -interface MediaError { - const unsigned short MEDIA_ERR_ABORTED = 1; - const unsigned short MEDIA_ERR_NETWORK = 2; - const unsigned short MEDIA_ERR_DECODE = 3; - const unsigned short MEDIA_ERR_SRC_NOT_SUPPORTED = 4; - - readonly attribute unsigned short code; - readonly attribute DOMString message; -}; - -[Exposed=Window] -interface AudioTrackList : EventTarget { - readonly attribute unsigned long length; - getter AudioTrack (unsigned long index); - AudioTrack? getTrackById(DOMString id); - - attribute EventHandler onchange; - attribute EventHandler onaddtrack; - attribute EventHandler onremovetrack; -}; - -[Exposed=Window] -interface AudioTrack { - readonly attribute DOMString id; - readonly attribute DOMString kind; - readonly attribute DOMString label; - readonly attribute DOMString language; - attribute boolean enabled; -}; - -[Exposed=Window] -interface VideoTrackList : EventTarget { - readonly attribute unsigned long length; - getter VideoTrack (unsigned long index); - VideoTrack? getTrackById(DOMString id); - readonly attribute long selectedIndex; - - attribute EventHandler onchange; - attribute EventHandler onaddtrack; - attribute EventHandler onremovetrack; -}; - -[Exposed=Window] -interface VideoTrack { - readonly attribute DOMString id; - readonly attribute DOMString kind; - readonly attribute DOMString label; - readonly attribute DOMString language; - attribute boolean selected; -}; - -[Exposed=Window] -interface TextTrackList : EventTarget { - readonly attribute unsigned long length; - getter TextTrack (unsigned long index); - TextTrack? getTrackById(DOMString id); - - attribute EventHandler onchange; - attribute EventHandler onaddtrack; - attribute EventHandler onremovetrack; -}; - -enum TextTrackMode { "disabled", "hidden", "showing" }; -enum TextTrackKind { "subtitles", "captions", "descriptions", "chapters", "metadata" }; - -[Exposed=Window] -interface TextTrack : EventTarget { - readonly attribute TextTrackKind kind; - readonly attribute DOMString label; - readonly attribute DOMString language; - - readonly attribute DOMString id; - readonly attribute DOMString inBandMetadataTrackDispatchType; - - attribute TextTrackMode mode; - - readonly attribute TextTrackCueList? cues; - readonly attribute TextTrackCueList? activeCues; - - void addCue(TextTrackCue cue); - void removeCue(TextTrackCue cue); - - attribute EventHandler oncuechange; -}; - -[Exposed=Window] -interface TextTrackCueList { - readonly attribute unsigned long length; - getter TextTrackCue (unsigned long index); - TextTrackCue? getCueById(DOMString id); -}; - -[Exposed=Window] -interface TextTrackCue : EventTarget { - readonly attribute TextTrack? track; - - attribute DOMString id; - attribute double startTime; - attribute double endTime; - attribute boolean pauseOnExit; - - attribute EventHandler onenter; - attribute EventHandler onexit; -}; - -[Exposed=Window] -interface TimeRanges { - readonly attribute unsigned long length; - double start(unsigned long index); - double end(unsigned long index); -}; - -[Exposed=Window, - Constructor(DOMString type, optional TrackEventInit eventInitDict = {})] -interface TrackEvent : Event { - readonly attribute (VideoTrack or AudioTrack or TextTrack)? track; -}; - -dictionary TrackEventInit : EventInit { - (VideoTrack or AudioTrack or TextTrack)? track = null; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLMapElement : HTMLElement { - [CEReactions] attribute DOMString name; - [SameObject] readonly attribute HTMLCollection areas; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLAreaElement : HTMLElement { - [CEReactions] attribute DOMString alt; - [CEReactions] attribute DOMString coords; - [CEReactions] attribute DOMString shape; - [CEReactions] attribute DOMString target; - [CEReactions] attribute DOMString download; - [CEReactions] attribute USVString ping; - [CEReactions] attribute DOMString rel; - [SameObject, PutForwards=value] readonly attribute DOMTokenList relList; - [CEReactions] attribute DOMString referrerPolicy; -}; -HTMLAreaElement includes HTMLHyperlinkElementUtils; - -[Exposed=Window, - HTMLConstructor] -interface HTMLTableElement : HTMLElement { - [CEReactions] attribute HTMLTableCaptionElement? caption; - HTMLTableCaptionElement createCaption(); - [CEReactions] void deleteCaption(); - - [CEReactions] attribute HTMLTableSectionElement? tHead; - HTMLTableSectionElement createTHead(); - [CEReactions] void deleteTHead(); - - [CEReactions] attribute HTMLTableSectionElement? tFoot; - HTMLTableSectionElement createTFoot(); - [CEReactions] void deleteTFoot(); - - [SameObject] readonly attribute HTMLCollection tBodies; - HTMLTableSectionElement createTBody(); - - [SameObject] readonly attribute HTMLCollection rows; - HTMLTableRowElement insertRow(optional long index = -1); - [CEReactions] void deleteRow(long index); -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLTableCaptionElement : HTMLElement {}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLTableColElement : HTMLElement { - [CEReactions] attribute unsigned long span; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLTableSectionElement : HTMLElement { - [SameObject] readonly attribute HTMLCollection rows; - HTMLTableRowElement insertRow(optional long index = -1); - [CEReactions] void deleteRow(long index); -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLTableRowElement : HTMLElement { - readonly attribute long rowIndex; - readonly attribute long sectionRowIndex; - [SameObject] readonly attribute HTMLCollection cells; - HTMLTableCellElement insertCell(optional long index = -1); - [CEReactions] void deleteCell(long index); -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLTableCellElement : HTMLElement { - [CEReactions] attribute unsigned long colSpan; - [CEReactions] attribute unsigned long rowSpan; - [CEReactions] attribute DOMString headers; - readonly attribute long cellIndex; - - [CEReactions] attribute DOMString scope; // only conforming for th elements - [CEReactions] attribute DOMString abbr; // only conforming for th elements -}; - -[Exposed=Window, - OverrideBuiltins, - LegacyUnenumerableNamedProperties, - HTMLConstructor] -interface HTMLFormElement : HTMLElement { - [CEReactions] attribute DOMString acceptCharset; - [CEReactions] attribute USVString action; - [CEReactions] attribute DOMString autocomplete; - [CEReactions] attribute DOMString enctype; - [CEReactions] attribute DOMString encoding; - [CEReactions] attribute DOMString method; - [CEReactions] attribute DOMString name; - [CEReactions] attribute boolean noValidate; - [CEReactions] attribute DOMString target; - - [SameObject] readonly attribute HTMLFormControlsCollection elements; - readonly attribute unsigned long length; - getter Element (unsigned long index); - getter (RadioNodeList or Element) (DOMString name); - - void submit(); - [CEReactions] void reset(); - boolean checkValidity(); - boolean reportValidity(); -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLLabelElement : HTMLElement { - readonly attribute HTMLFormElement? form; - [CEReactions] attribute DOMString htmlFor; - readonly attribute HTMLElement? control; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLInputElement : HTMLElement { - [CEReactions] attribute DOMString accept; - [CEReactions] attribute DOMString alt; - [CEReactions] attribute DOMString autocomplete; - [CEReactions] attribute boolean autofocus; - [CEReactions] attribute boolean defaultChecked; - attribute boolean checked; - [CEReactions] attribute DOMString dirName; - [CEReactions] attribute boolean disabled; - readonly attribute HTMLFormElement? form; - attribute FileList? files; - [CEReactions] attribute USVString formAction; - [CEReactions] attribute DOMString formEnctype; - [CEReactions] attribute DOMString formMethod; - [CEReactions] attribute boolean formNoValidate; - [CEReactions] attribute DOMString formTarget; - [CEReactions] attribute unsigned long height; - attribute boolean indeterminate; - readonly attribute HTMLElement? list; - [CEReactions] attribute DOMString max; - [CEReactions] attribute long maxLength; - [CEReactions] attribute DOMString min; - [CEReactions] attribute long minLength; - [CEReactions] attribute boolean multiple; - [CEReactions] attribute DOMString name; - [CEReactions] attribute DOMString pattern; - [CEReactions] attribute DOMString placeholder; - [CEReactions] attribute boolean readOnly; - [CEReactions] attribute boolean required; - [CEReactions] attribute unsigned long size; - [CEReactions] attribute USVString src; - [CEReactions] attribute DOMString step; - [CEReactions] attribute DOMString type; - [CEReactions] attribute DOMString defaultValue; - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString value; - attribute object? valueAsDate; - attribute unrestricted double valueAsNumber; - [CEReactions] attribute unsigned long width; - - void stepUp(optional long n = 1); - void stepDown(optional long n = 1); - - readonly attribute boolean willValidate; - readonly attribute ValidityState validity; - readonly attribute DOMString validationMessage; - boolean checkValidity(); - boolean reportValidity(); - void setCustomValidity(DOMString error); - - readonly attribute NodeList? labels; - - void select(); - attribute unsigned long? selectionStart; - attribute unsigned long? selectionEnd; - attribute DOMString? selectionDirection; - void setRangeText(DOMString replacement); - void setRangeText(DOMString replacement, unsigned long start, unsigned long end, optional SelectionMode selectionMode = "preserve"); - void setSelectionRange(unsigned long start, unsigned long end, optional DOMString direction); -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLButtonElement : HTMLElement { - [CEReactions] attribute boolean autofocus; - [CEReactions] attribute boolean disabled; - readonly attribute HTMLFormElement? form; - [CEReactions] attribute USVString formAction; - [CEReactions] attribute DOMString formEnctype; - [CEReactions] attribute DOMString formMethod; - [CEReactions] attribute boolean formNoValidate; - [CEReactions] attribute DOMString formTarget; - [CEReactions] attribute DOMString name; - [CEReactions] attribute DOMString type; - [CEReactions] attribute DOMString value; - - readonly attribute boolean willValidate; - readonly attribute ValidityState validity; - readonly attribute DOMString validationMessage; - boolean checkValidity(); - boolean reportValidity(); - void setCustomValidity(DOMString error); - - readonly attribute NodeList labels; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLSelectElement : HTMLElement { - [CEReactions] attribute DOMString autocomplete; - [CEReactions] attribute boolean autofocus; - [CEReactions] attribute boolean disabled; - readonly attribute HTMLFormElement? form; - [CEReactions] attribute boolean multiple; - [CEReactions] attribute DOMString name; - [CEReactions] attribute boolean required; - [CEReactions] attribute unsigned long size; - - readonly attribute DOMString type; - - [SameObject] readonly attribute HTMLOptionsCollection options; - [CEReactions] attribute unsigned long length; - getter Element? item(unsigned long index); - HTMLOptionElement? namedItem(DOMString name); - [CEReactions] void add((HTMLOptionElement or HTMLOptGroupElement) element, optional (HTMLElement or long)? before = null); - [CEReactions] void remove(); // ChildNode overload - [CEReactions] void remove(long index); - [CEReactions] setter void (unsigned long index, HTMLOptionElement? option); - - [SameObject] readonly attribute HTMLCollection selectedOptions; - attribute long selectedIndex; - attribute DOMString value; - - readonly attribute boolean willValidate; - readonly attribute ValidityState validity; - readonly attribute DOMString validationMessage; - boolean checkValidity(); - boolean reportValidity(); - void setCustomValidity(DOMString error); - - readonly attribute NodeList labels; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLDataListElement : HTMLElement { - [SameObject] readonly attribute HTMLCollection options; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLOptGroupElement : HTMLElement { - [CEReactions] attribute boolean disabled; - [CEReactions] attribute DOMString label; -}; - -[Exposed=Window, - HTMLConstructor, - NamedConstructor=Option(optional DOMString text = "", optional DOMString value, optional boolean defaultSelected = false, optional boolean selected = false)] -interface HTMLOptionElement : HTMLElement { - [CEReactions] attribute boolean disabled; - readonly attribute HTMLFormElement? form; - [CEReactions] attribute DOMString label; - [CEReactions] attribute boolean defaultSelected; - attribute boolean selected; - [CEReactions] attribute DOMString value; - - [CEReactions] attribute DOMString text; - readonly attribute long index; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLTextAreaElement : HTMLElement { - [CEReactions] attribute DOMString autocomplete; - [CEReactions] attribute boolean autofocus; - [CEReactions] attribute unsigned long cols; - [CEReactions] attribute DOMString dirName; - [CEReactions] attribute boolean disabled; - readonly attribute HTMLFormElement? form; - [CEReactions] attribute long maxLength; - [CEReactions] attribute long minLength; - [CEReactions] attribute DOMString name; - [CEReactions] attribute DOMString placeholder; - [CEReactions] attribute boolean readOnly; - [CEReactions] attribute boolean required; - [CEReactions] attribute unsigned long rows; - [CEReactions] attribute DOMString wrap; - - readonly attribute DOMString type; - [CEReactions] attribute DOMString defaultValue; - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString value; - readonly attribute unsigned long textLength; - - readonly attribute boolean willValidate; - readonly attribute ValidityState validity; - readonly attribute DOMString validationMessage; - boolean checkValidity(); - boolean reportValidity(); - void setCustomValidity(DOMString error); - - readonly attribute NodeList labels; - - void select(); - attribute unsigned long selectionStart; - attribute unsigned long selectionEnd; - attribute DOMString selectionDirection; - void setRangeText(DOMString replacement); - void setRangeText(DOMString replacement, unsigned long start, unsigned long end, optional SelectionMode selectionMode = "preserve"); - void setSelectionRange(unsigned long start, unsigned long end, optional DOMString direction); -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLOutputElement : HTMLElement { - [SameObject, PutForwards=value] readonly attribute DOMTokenList htmlFor; - readonly attribute HTMLFormElement? form; - [CEReactions] attribute DOMString name; - - readonly attribute DOMString type; - [CEReactions] attribute DOMString defaultValue; - [CEReactions] attribute DOMString value; - - readonly attribute boolean willValidate; - readonly attribute ValidityState validity; - readonly attribute DOMString validationMessage; - boolean checkValidity(); - boolean reportValidity(); - void setCustomValidity(DOMString error); - - readonly attribute NodeList labels; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLProgressElement : HTMLElement { - [CEReactions] attribute double value; - [CEReactions] attribute double max; - readonly attribute double position; - readonly attribute NodeList labels; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLMeterElement : HTMLElement { - [CEReactions] attribute double value; - [CEReactions] attribute double min; - [CEReactions] attribute double max; - [CEReactions] attribute double low; - [CEReactions] attribute double high; - [CEReactions] attribute double optimum; - readonly attribute NodeList labels; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLFieldSetElement : HTMLElement { - [CEReactions] attribute boolean disabled; - readonly attribute HTMLFormElement? form; - [CEReactions] attribute DOMString name; - - readonly attribute DOMString type; - - [SameObject] readonly attribute HTMLCollection elements; - - readonly attribute boolean willValidate; - [SameObject] readonly attribute ValidityState validity; - readonly attribute DOMString validationMessage; - boolean checkValidity(); - boolean reportValidity(); - void setCustomValidity(DOMString error); -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLLegendElement : HTMLElement { - readonly attribute HTMLFormElement? form; -}; - -enum SelectionMode { - "select", - "start", - "end", - "preserve" // default -}; - -[Exposed=Window] -interface ValidityState { - readonly attribute boolean valueMissing; - readonly attribute boolean typeMismatch; - readonly attribute boolean patternMismatch; - readonly attribute boolean tooLong; - readonly attribute boolean tooShort; - readonly attribute boolean rangeUnderflow; - readonly attribute boolean rangeOverflow; - readonly attribute boolean stepMismatch; - readonly attribute boolean badInput; - readonly attribute boolean customError; - readonly attribute boolean valid; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLDetailsElement : HTMLElement { - [CEReactions] attribute boolean open; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLDialogElement : HTMLElement { - [CEReactions] attribute boolean open; - attribute DOMString returnValue; - [CEReactions] void show(); - [CEReactions] void showModal(); - [CEReactions] void close(optional DOMString returnValue); -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLScriptElement : HTMLElement { - [CEReactions] attribute USVString src; - [CEReactions] attribute DOMString type; - [CEReactions] attribute boolean noModule; - [CEReactions] attribute boolean async; - [CEReactions] attribute boolean defer; - [CEReactions] attribute DOMString? crossOrigin; - [CEReactions] attribute DOMString text; - [CEReactions] attribute DOMString integrity; - -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLTemplateElement : HTMLElement { - readonly attribute DocumentFragment content; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLSlotElement : HTMLElement { - [CEReactions] attribute DOMString name; - sequence assignedNodes(optional AssignedNodesOptions options = {}); - sequence assignedElements(optional AssignedNodesOptions options = {}); -}; - -dictionary AssignedNodesOptions { - boolean flatten = false; -}; - -typedef (CanvasRenderingContext2D or ImageBitmapRenderingContext or WebGLRenderingContext) RenderingContext; - -[Exposed=Window, - HTMLConstructor] -interface HTMLCanvasElement : HTMLElement { - [CEReactions] attribute unsigned long width; - [CEReactions] attribute unsigned long height; - - RenderingContext? getContext(DOMString contextId, optional any options = null); - - USVString toDataURL(optional DOMString type, optional any quality); - void toBlob(BlobCallback _callback, optional DOMString type, optional any quality); - OffscreenCanvas transferControlToOffscreen(); -}; - -callback BlobCallback = void (Blob? blob); - -typedef (HTMLImageElement or - SVGImageElement) HTMLOrSVGImageElement; - -typedef (HTMLOrSVGImageElement or - HTMLVideoElement or - HTMLCanvasElement or - ImageBitmap or - OffscreenCanvas) CanvasImageSource; - -enum CanvasFillRule { "nonzero", "evenodd" }; - -dictionary CanvasRenderingContext2DSettings { - boolean alpha = true; -}; - -enum ImageSmoothingQuality { "low", "medium", "high" }; - -[Exposed=Window] -interface CanvasRenderingContext2D { - // back-reference to the canvas - readonly attribute HTMLCanvasElement canvas; -}; -CanvasRenderingContext2D includes CanvasState; -CanvasRenderingContext2D includes CanvasTransform; -CanvasRenderingContext2D includes CanvasCompositing; -CanvasRenderingContext2D includes CanvasImageSmoothing; -CanvasRenderingContext2D includes CanvasFillStrokeStyles; -CanvasRenderingContext2D includes CanvasShadowStyles; -CanvasRenderingContext2D includes CanvasFilters; -CanvasRenderingContext2D includes CanvasRect; -CanvasRenderingContext2D includes CanvasDrawPath; -CanvasRenderingContext2D includes CanvasUserInterface; -CanvasRenderingContext2D includes CanvasText; -CanvasRenderingContext2D includes CanvasDrawImage; -CanvasRenderingContext2D includes CanvasImageData; -CanvasRenderingContext2D includes CanvasPathDrawingStyles; -CanvasRenderingContext2D includes CanvasTextDrawingStyles; -CanvasRenderingContext2D includes CanvasPath; - -interface mixin CanvasState { - // state - void save(); // push state on state stack - void restore(); // pop state stack and restore state -}; - -interface mixin CanvasTransform { - // transformations (default transform is the identity matrix) - void scale(unrestricted double x, unrestricted double y); - void rotate(unrestricted double angle); - void translate(unrestricted double x, unrestricted double y); - void transform(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f); - - [NewObject] DOMMatrix getTransform(); - void setTransform(unrestricted double a, unrestricted double b, unrestricted double c, unrestricted double d, unrestricted double e, unrestricted double f); - void setTransform(optional DOMMatrix2DInit transform = {}); - void resetTransform(); - -}; - -interface mixin CanvasCompositing { - // compositing - attribute unrestricted double globalAlpha; // (default 1.0) - attribute DOMString globalCompositeOperation; // (default source-over) -}; - -interface mixin CanvasImageSmoothing { - // image smoothing - attribute boolean imageSmoothingEnabled; // (default true) - attribute ImageSmoothingQuality imageSmoothingQuality; // (default low) - -}; - -interface mixin CanvasFillStrokeStyles { - // colors and styles (see also the CanvasPathDrawingStyles and CanvasTextDrawingStyles interfaces) - attribute (DOMString or CanvasGradient or CanvasPattern) strokeStyle; // (default black) - attribute (DOMString or CanvasGradient or CanvasPattern) fillStyle; // (default black) - CanvasGradient createLinearGradient(double x0, double y0, double x1, double y1); - CanvasGradient createRadialGradient(double x0, double y0, double r0, double x1, double y1, double r1); - CanvasPattern? createPattern(CanvasImageSource image, [TreatNullAs=EmptyString] DOMString repetition); - -}; - -interface mixin CanvasShadowStyles { - // shadows - attribute unrestricted double shadowOffsetX; // (default 0) - attribute unrestricted double shadowOffsetY; // (default 0) - attribute unrestricted double shadowBlur; // (default 0) - attribute DOMString shadowColor; // (default transparent black) -}; - -interface mixin CanvasFilters { - // filters - attribute DOMString filter; // (default "none") -}; - -interface mixin CanvasRect { - // rects - void clearRect(unrestricted double x, unrestricted double y, unrestricted double w, unrestricted double h); - void fillRect(unrestricted double x, unrestricted double y, unrestricted double w, unrestricted double h); - void strokeRect(unrestricted double x, unrestricted double y, unrestricted double w, unrestricted double h); -}; - -interface mixin CanvasDrawPath { - // path API (see also CanvasPath) - void beginPath(); - void fill(optional CanvasFillRule fillRule = "nonzero"); - void fill(Path2D path, optional CanvasFillRule fillRule = "nonzero"); - void stroke(); - void stroke(Path2D path); - void clip(optional CanvasFillRule fillRule = "nonzero"); - void clip(Path2D path, optional CanvasFillRule fillRule = "nonzero"); - void resetClip(); - boolean isPointInPath(unrestricted double x, unrestricted double y, optional CanvasFillRule fillRule = "nonzero"); - boolean isPointInPath(Path2D path, unrestricted double x, unrestricted double y, optional CanvasFillRule fillRule = "nonzero"); - boolean isPointInStroke(unrestricted double x, unrestricted double y); - boolean isPointInStroke(Path2D path, unrestricted double x, unrestricted double y); -}; - -interface mixin CanvasUserInterface { - void drawFocusIfNeeded(Element element); - void drawFocusIfNeeded(Path2D path, Element element); - void scrollPathIntoView(); - void scrollPathIntoView(Path2D path); -}; - -interface mixin CanvasText { - // text (see also the CanvasPathDrawingStyles and CanvasTextDrawingStyles interfaces) - void fillText(DOMString text, unrestricted double x, unrestricted double y, optional unrestricted double maxWidth); - void strokeText(DOMString text, unrestricted double x, unrestricted double y, optional unrestricted double maxWidth); - TextMetrics measureText(DOMString text); -}; - -interface mixin CanvasDrawImage { - // drawing images - void drawImage(CanvasImageSource image, unrestricted double dx, unrestricted double dy); - void drawImage(CanvasImageSource image, unrestricted double dx, unrestricted double dy, unrestricted double dw, unrestricted double dh); - void drawImage(CanvasImageSource image, unrestricted double sx, unrestricted double sy, unrestricted double sw, unrestricted double sh, unrestricted double dx, unrestricted double dy, unrestricted double dw, unrestricted double dh); -}; - -interface mixin CanvasImageData { - // pixel manipulation - ImageData createImageData(long sw, long sh); - ImageData createImageData(ImageData imagedata); - ImageData getImageData(long sx, long sy, long sw, long sh); - void putImageData(ImageData imagedata, long dx, long dy); - void putImageData(ImageData imagedata, long dx, long dy, long dirtyX, long dirtyY, long dirtyWidth, long dirtyHeight); -}; - -enum CanvasLineCap { "butt", "round", "square" }; -enum CanvasLineJoin { "round", "bevel", "miter" }; -enum CanvasTextAlign { "start", "end", "left", "right", "center" }; -enum CanvasTextBaseline { "top", "hanging", "middle", "alphabetic", "ideographic", "bottom" }; -enum CanvasDirection { "ltr", "rtl", "inherit" }; - -interface mixin CanvasPathDrawingStyles { - // line caps/joins - attribute unrestricted double lineWidth; // (default 1) - attribute CanvasLineCap lineCap; // (default "butt") - attribute CanvasLineJoin lineJoin; // (default "miter") - attribute unrestricted double miterLimit; // (default 10) - - // dashed lines - void setLineDash(sequence segments); // default empty - sequence getLineDash(); - attribute unrestricted double lineDashOffset; -}; - -interface mixin CanvasTextDrawingStyles { - // text - attribute DOMString font; // (default 10px sans-serif) - attribute CanvasTextAlign textAlign; // (default: "start") - attribute CanvasTextBaseline textBaseline; // (default: "alphabetic") - attribute CanvasDirection direction; // (default: "inherit") -}; - -interface mixin CanvasPath { - // shared path API methods - void closePath(); - void moveTo(unrestricted double x, unrestricted double y); - void lineTo(unrestricted double x, unrestricted double y); - void quadraticCurveTo(unrestricted double cpx, unrestricted double cpy, unrestricted double x, unrestricted double y); - void bezierCurveTo(unrestricted double cp1x, unrestricted double cp1y, unrestricted double cp2x, unrestricted double cp2y, unrestricted double x, unrestricted double y); - void arcTo(unrestricted double x1, unrestricted double y1, unrestricted double x2, unrestricted double y2, unrestricted double radius); - void rect(unrestricted double x, unrestricted double y, unrestricted double w, unrestricted double h); - void arc(unrestricted double x, unrestricted double y, unrestricted double radius, unrestricted double startAngle, unrestricted double endAngle, optional boolean anticlockwise = false); - void ellipse(unrestricted double x, unrestricted double y, unrestricted double radiusX, unrestricted double radiusY, unrestricted double rotation, unrestricted double startAngle, unrestricted double endAngle, optional boolean anticlockwise = false); -}; - -[Exposed=(Window,Worker)] -interface CanvasGradient { - // opaque object - void addColorStop(double offset, DOMString color); -}; - -[Exposed=(Window,Worker)] -interface CanvasPattern { - // opaque object - void setTransform(optional DOMMatrix2DInit transform = {}); -}; - -[Exposed=Window] -interface TextMetrics { - // x-direction - readonly attribute double width; // advance width - readonly attribute double actualBoundingBoxLeft; - readonly attribute double actualBoundingBoxRight; - - // y-direction - readonly attribute double fontBoundingBoxAscent; - readonly attribute double fontBoundingBoxDescent; - readonly attribute double actualBoundingBoxAscent; - readonly attribute double actualBoundingBoxDescent; - readonly attribute double emHeightAscent; - readonly attribute double emHeightDescent; - readonly attribute double hangingBaseline; - readonly attribute double alphabeticBaseline; - readonly attribute double ideographicBaseline; -}; - -[Constructor(unsigned long sw, unsigned long sh), - Constructor(Uint8ClampedArray data, unsigned long sw, optional unsigned long sh), - Exposed=(Window,Worker), - Serializable] -interface ImageData { - readonly attribute unsigned long width; - readonly attribute unsigned long height; - readonly attribute Uint8ClampedArray data; -}; - -[Constructor(optional (Path2D or DOMString) path), - Exposed=(Window,Worker)] -interface Path2D { - void addPath(Path2D path, optional DOMMatrix2DInit transform = {}); -}; -Path2D includes CanvasPath; - -[Exposed=Window] -interface ImageBitmapRenderingContext { - readonly attribute HTMLCanvasElement canvas; - void transferFromImageBitmap(ImageBitmap? bitmap); -}; - -dictionary ImageBitmapRenderingContextSettings { - boolean alpha = true; -}; - -typedef (OffscreenCanvasRenderingContext2D or - WebGLRenderingContext) OffscreenRenderingContext; - -dictionary ImageEncodeOptions { - DOMString type = "image/png"; - unrestricted double quality = 1.0; -}; - -enum OffscreenRenderingContextId { "2d", "webgl" }; - -[Constructor([EnforceRange] unsigned long long width, [EnforceRange] unsigned long long height), Exposed=(Window,Worker), Transferable] -interface OffscreenCanvas : EventTarget { - attribute unsigned long long width; - attribute unsigned long long height; - - OffscreenRenderingContext? getContext(OffscreenRenderingContextId contextId, optional any options = null); - ImageBitmap transferToImageBitmap(); - Promise convertToBlob(optional ImageEncodeOptions options = {}); -}; - -[Exposed=(Window,Worker)] -interface OffscreenCanvasRenderingContext2D { - void commit(); - readonly attribute OffscreenCanvas canvas; -}; - -OffscreenCanvasRenderingContext2D includes CanvasState; -OffscreenCanvasRenderingContext2D includes CanvasTransform; -OffscreenCanvasRenderingContext2D includes CanvasCompositing; -OffscreenCanvasRenderingContext2D includes CanvasImageSmoothing; -OffscreenCanvasRenderingContext2D includes CanvasFillStrokeStyles; -OffscreenCanvasRenderingContext2D includes CanvasShadowStyles; -OffscreenCanvasRenderingContext2D includes CanvasFilters; -OffscreenCanvasRenderingContext2D includes CanvasRect; -OffscreenCanvasRenderingContext2D includes CanvasDrawPath; -OffscreenCanvasRenderingContext2D includes CanvasDrawImage; -OffscreenCanvasRenderingContext2D includes CanvasImageData; -OffscreenCanvasRenderingContext2D includes CanvasPathDrawingStyles; -OffscreenCanvasRenderingContext2D includes CanvasPath; - -[Exposed=Window] -interface CustomElementRegistry { - [CEReactions] void define(DOMString name, Function constructor, optional ElementDefinitionOptions options = {}); - any get(DOMString name); - Promise whenDefined(DOMString name); - [CEReactions] void upgrade(Node root); -}; - -dictionary ElementDefinitionOptions { - DOMString extends; -}; - -dictionary FocusOptions { - boolean preventScroll = false; -}; - -interface mixin ElementContentEditable { - [CEReactions] attribute DOMString contentEditable; - readonly attribute boolean isContentEditable; - [CEReactions] attribute DOMString inputMode; -}; - -[Exposed=Window, - Constructor] -interface DataTransfer { - attribute DOMString dropEffect; - attribute DOMString effectAllowed; - - [SameObject] readonly attribute DataTransferItemList items; - - void setDragImage(Element image, long x, long y); - - /* old interface */ - readonly attribute FrozenArray types; - DOMString getData(DOMString format); - void setData(DOMString format, DOMString data); - void clearData(optional DOMString format); - [SameObject] readonly attribute FileList files; -}; - -[Exposed=Window] -interface DataTransferItemList { - readonly attribute unsigned long length; - getter DataTransferItem (unsigned long index); - DataTransferItem? add(DOMString data, DOMString type); - DataTransferItem? add(File data); - void remove(unsigned long index); - void clear(); -}; - -[Exposed=Window] -interface DataTransferItem { - readonly attribute DOMString kind; - readonly attribute DOMString type; - void getAsString(FunctionStringCallback? _callback); - File? getAsFile(); -}; - -callback FunctionStringCallback = void (DOMString data); - -[Exposed=Window, - Constructor(DOMString type, optional DragEventInit eventInitDict = {})] -interface DragEvent : MouseEvent { - readonly attribute DataTransfer? dataTransfer; -}; - -dictionary DragEventInit : MouseEventInit { - DataTransfer? dataTransfer = null; -}; - -[Global=Window, - Exposed=Window, - LegacyUnenumerableNamedProperties] -interface Window : EventTarget { - // the current browsing context - [Unforgeable] readonly attribute WindowProxy window; - [Replaceable] readonly attribute WindowProxy self; - [Unforgeable] readonly attribute Document document; - attribute DOMString name; - [PutForwards=href, Unforgeable] readonly attribute Location location; - readonly attribute History history; - readonly attribute CustomElementRegistry customElements; - [Replaceable] readonly attribute BarProp locationbar; - [Replaceable] readonly attribute BarProp menubar; - [Replaceable] readonly attribute BarProp personalbar; - [Replaceable] readonly attribute BarProp scrollbars; - [Replaceable] readonly attribute BarProp statusbar; - [Replaceable] readonly attribute BarProp toolbar; - attribute DOMString status; - void close(); - readonly attribute boolean closed; - void stop(); - void focus(); - void blur(); - - // other browsing contexts - [Replaceable] readonly attribute WindowProxy frames; - [Replaceable] readonly attribute unsigned long length; - [Unforgeable] readonly attribute WindowProxy? top; - attribute any opener; - [Replaceable] readonly attribute WindowProxy? parent; - readonly attribute Element? frameElement; - WindowProxy? open(optional USVString url = "about:blank", optional DOMString target = "_blank", optional [TreatNullAs=EmptyString] DOMString features = ""); - getter object (DOMString name); - // Since this is the global object, the IDL named getter adds a NamedPropertiesObject exotic - // object on the prototype chain. Indeed, this does not make the global object an exotic object. - // Indexed access is taken care of by the WindowProxy exotic object. - - // the user agent - readonly attribute Navigator navigator; - readonly attribute ApplicationCache applicationCache; - - // user prompts - void alert(); - void alert(DOMString message); - boolean confirm(optional DOMString message = ""); - DOMString? prompt(optional DOMString message = "", optional DOMString default = ""); - void print(); - - unsigned long requestAnimationFrame(FrameRequestCallback callback); - void cancelAnimationFrame(unsigned long handle); - - void postMessage(any message, USVString targetOrigin, optional sequence transfer = []); -}; -Window includes GlobalEventHandlers; -Window includes WindowEventHandlers; - -callback FrameRequestCallback = void (DOMHighResTimeStamp time); - -[Exposed=Window] -interface BarProp { - readonly attribute boolean visible; -}; - -enum ScrollRestoration { "auto", "manual" }; - -[Exposed=Window] -interface History { - readonly attribute unsigned long length; - attribute ScrollRestoration scrollRestoration; - readonly attribute any state; - void go(optional long delta = 0); - void back(); - void forward(); - void pushState(any data, DOMString title, optional USVString? url = null); - void replaceState(any data, DOMString title, optional USVString? url = null); -}; - -[Exposed=Window] -interface Location { // but see also additional creation steps and overridden internal methods - [Unforgeable] stringifier attribute USVString href; - [Unforgeable] readonly attribute USVString origin; - [Unforgeable] attribute USVString protocol; - [Unforgeable] attribute USVString host; - [Unforgeable] attribute USVString hostname; - [Unforgeable] attribute USVString port; - [Unforgeable] attribute USVString pathname; - [Unforgeable] attribute USVString search; - [Unforgeable] attribute USVString hash; - - [Unforgeable] void assign(USVString url); - [Unforgeable] void replace(USVString url); - [Unforgeable] void reload(); - - [Unforgeable, SameObject] readonly attribute DOMStringList ancestorOrigins; -}; - -[Exposed=Window, - Constructor(DOMString type, optional PopStateEventInit eventInitDict = {})] -interface PopStateEvent : Event { - readonly attribute any state; -}; - -dictionary PopStateEventInit : EventInit { - any state = null; -}; - -[Exposed=Window, - Constructor(DOMString type, optional HashChangeEventInit eventInitDict = {})] -interface HashChangeEvent : Event { - readonly attribute USVString oldURL; - readonly attribute USVString newURL; -}; - -dictionary HashChangeEventInit : EventInit { - USVString oldURL = ""; - USVString newURL = ""; -}; - -[Exposed=Window, - Constructor(DOMString type, optional PageTransitionEventInit eventInitDict = {})] -interface PageTransitionEvent : Event { - readonly attribute boolean persisted; -}; - -dictionary PageTransitionEventInit : EventInit { - boolean persisted = false; -}; - -[Exposed=Window] -interface BeforeUnloadEvent : Event { - attribute DOMString returnValue; -}; - -[Exposed=Window] -interface ApplicationCache : EventTarget { - - // update status - const unsigned short UNCACHED = 0; - const unsigned short IDLE = 1; - const unsigned short CHECKING = 2; - const unsigned short DOWNLOADING = 3; - const unsigned short UPDATEREADY = 4; - const unsigned short OBSOLETE = 5; - readonly attribute unsigned short status; - - // updates - void update(); - void abort(); - void swapCache(); - - // events - attribute EventHandler onchecking; - attribute EventHandler onerror; - attribute EventHandler onnoupdate; - attribute EventHandler ondownloading; - attribute EventHandler onprogress; - attribute EventHandler onupdateready; - attribute EventHandler oncached; - attribute EventHandler onobsolete; -}; - -interface mixin NavigatorOnLine { - readonly attribute boolean onLine; -}; - -[Constructor(DOMString type, optional ErrorEventInit eventInitDict = {}), Exposed=(Window,Worker)] -interface ErrorEvent : Event { - readonly attribute DOMString message; - readonly attribute USVString filename; - readonly attribute unsigned long lineno; - readonly attribute unsigned long colno; - readonly attribute any error; -}; - -dictionary ErrorEventInit : EventInit { - DOMString message = ""; - USVString filename = ""; - unsigned long lineno = 0; - unsigned long colno = 0; - any error = null; -}; - -[Constructor(DOMString type, PromiseRejectionEventInit eventInitDict), Exposed=(Window,Worker)] -interface PromiseRejectionEvent : Event { - readonly attribute Promise promise; - readonly attribute any reason; -}; - -dictionary PromiseRejectionEventInit : EventInit { - required Promise promise; - any reason; -}; - -[TreatNonObjectAsNull] -callback EventHandlerNonNull = any (Event event); -typedef EventHandlerNonNull? EventHandler; - -[TreatNonObjectAsNull] -callback OnErrorEventHandlerNonNull = any ((Event or DOMString) event, optional DOMString source, optional unsigned long lineno, optional unsigned long colno, optional any error); -typedef OnErrorEventHandlerNonNull? OnErrorEventHandler; - -[TreatNonObjectAsNull] -callback OnBeforeUnloadEventHandlerNonNull = DOMString? (Event event); -typedef OnBeforeUnloadEventHandlerNonNull? OnBeforeUnloadEventHandler; - -interface mixin GlobalEventHandlers { - attribute EventHandler onabort; - attribute EventHandler onauxclick; - attribute EventHandler onblur; - attribute EventHandler oncancel; - attribute EventHandler oncanplay; - attribute EventHandler oncanplaythrough; - attribute EventHandler onchange; - attribute EventHandler onclick; - attribute EventHandler onclose; - attribute EventHandler oncontextmenu; - attribute EventHandler oncuechange; - attribute EventHandler ondblclick; - attribute EventHandler ondrag; - attribute EventHandler ondragend; - attribute EventHandler ondragenter; - attribute EventHandler ondragexit; - attribute EventHandler ondragleave; - attribute EventHandler ondragover; - attribute EventHandler ondragstart; - attribute EventHandler ondrop; - attribute EventHandler ondurationchange; - attribute EventHandler onemptied; - attribute EventHandler onended; - attribute OnErrorEventHandler onerror; - attribute EventHandler onfocus; - attribute EventHandler oninput; - attribute EventHandler oninvalid; - attribute EventHandler onkeydown; - attribute EventHandler onkeypress; - attribute EventHandler onkeyup; - attribute EventHandler onload; - attribute EventHandler onloadeddata; - attribute EventHandler onloadedmetadata; - attribute EventHandler onloadend; - attribute EventHandler onloadstart; - attribute EventHandler onmousedown; - [LenientThis] attribute EventHandler onmouseenter; - [LenientThis] attribute EventHandler onmouseleave; - attribute EventHandler onmousemove; - attribute EventHandler onmouseout; - attribute EventHandler onmouseover; - attribute EventHandler onmouseup; - attribute EventHandler onwheel; - attribute EventHandler onpause; - attribute EventHandler onplay; - attribute EventHandler onplaying; - attribute EventHandler onprogress; - attribute EventHandler onratechange; - attribute EventHandler onreset; - attribute EventHandler onresize; - attribute EventHandler onscroll; - attribute EventHandler onsecuritypolicyviolation; - attribute EventHandler onseeked; - attribute EventHandler onseeking; - attribute EventHandler onselect; - attribute EventHandler onstalled; - attribute EventHandler onsubmit; - attribute EventHandler onsuspend; - attribute EventHandler ontimeupdate; - attribute EventHandler ontoggle; - attribute EventHandler onvolumechange; - attribute EventHandler onwaiting; -}; - -interface mixin WindowEventHandlers { - attribute EventHandler onafterprint; - attribute EventHandler onbeforeprint; - attribute OnBeforeUnloadEventHandler onbeforeunload; - attribute EventHandler onhashchange; - attribute EventHandler onlanguagechange; - attribute EventHandler onmessage; - attribute EventHandler onmessageerror; - attribute EventHandler onoffline; - attribute EventHandler ononline; - attribute EventHandler onpagehide; - attribute EventHandler onpageshow; - attribute EventHandler onpopstate; - attribute EventHandler onrejectionhandled; - attribute EventHandler onstorage; - attribute EventHandler onunhandledrejection; - attribute EventHandler onunload; -}; - -interface mixin DocumentAndElementEventHandlers { - attribute EventHandler oncopy; - attribute EventHandler oncut; - attribute EventHandler onpaste; -}; - -typedef (DOMString or Function) TimerHandler; - -interface mixin WindowOrWorkerGlobalScope { - [Replaceable] readonly attribute USVString origin; - - // base64 utility methods - DOMString btoa(DOMString data); - ByteString atob(DOMString data); - - // timers - long setTimeout(TimerHandler handler, optional long timeout = 0, any... arguments); - void clearTimeout(optional long handle = 0); - long setInterval(TimerHandler handler, optional long timeout = 0, any... arguments); - void clearInterval(optional long handle = 0); - - // ImageBitmap - Promise createImageBitmap(ImageBitmapSource image, optional ImageBitmapOptions options = {}); - Promise createImageBitmap(ImageBitmapSource image, long sx, long sy, long sw, long sh, optional ImageBitmapOptions options = {}); -}; -Window includes WindowOrWorkerGlobalScope; -WorkerGlobalScope includes WindowOrWorkerGlobalScope; - -[Exposed=Window] -interface Navigator { - // objects implementing this interface also implement the interfaces given below -}; -Navigator includes NavigatorID; -Navigator includes NavigatorLanguage; -Navigator includes NavigatorOnLine; -Navigator includes NavigatorContentUtils; -Navigator includes NavigatorCookies; -Navigator includes NavigatorPlugins; -Navigator includes NavigatorConcurrentHardware; - -interface mixin NavigatorID { - readonly attribute DOMString appCodeName; // constant "Mozilla" - readonly attribute DOMString appName; // constant "Netscape" - readonly attribute DOMString appVersion; - readonly attribute DOMString platform; - readonly attribute DOMString product; // constant "Gecko" - [Exposed=Window] readonly attribute DOMString productSub; - readonly attribute DOMString userAgent; - [Exposed=Window] readonly attribute DOMString vendor; - [Exposed=Window] readonly attribute DOMString vendorSub; // constant "" -}; - -partial interface NavigatorID { - [Exposed=Window] boolean taintEnabled(); // constant false - [Exposed=Window] readonly attribute DOMString oscpu; -}; - -interface mixin NavigatorLanguage { - readonly attribute DOMString language; - readonly attribute FrozenArray languages; -}; - -interface mixin NavigatorContentUtils { - void registerProtocolHandler(DOMString scheme, USVString url, DOMString title); - void unregisterProtocolHandler(DOMString scheme, USVString url); -}; - -interface mixin NavigatorCookies { - readonly attribute boolean cookieEnabled; -}; - -interface mixin NavigatorPlugins { - [SameObject] readonly attribute PluginArray plugins; - [SameObject] readonly attribute MimeTypeArray mimeTypes; - boolean javaEnabled(); -}; - -[Exposed=Window, - LegacyUnenumerableNamedProperties] -interface PluginArray { - void refresh(optional boolean reload = false); - readonly attribute unsigned long length; - getter Plugin? item(unsigned long index); - getter Plugin? namedItem(DOMString name); -}; - -[Exposed=Window, - LegacyUnenumerableNamedProperties] -interface MimeTypeArray { - readonly attribute unsigned long length; - getter MimeType? item(unsigned long index); - getter MimeType? namedItem(DOMString name); -}; - -[Exposed=Window, - LegacyUnenumerableNamedProperties] -interface Plugin { - readonly attribute DOMString name; - readonly attribute DOMString description; - readonly attribute DOMString filename; - readonly attribute unsigned long length; - getter MimeType? item(unsigned long index); - getter MimeType? namedItem(DOMString name); -}; - -[Exposed=Window] -interface MimeType { - readonly attribute DOMString type; - readonly attribute DOMString description; - readonly attribute DOMString suffixes; // comma-separated - readonly attribute Plugin enabledPlugin; -}; - -[Exposed=(Window,Worker), Serializable, Transferable] -interface ImageBitmap { - readonly attribute unsigned long width; - readonly attribute unsigned long height; - void close(); -}; - -typedef (CanvasImageSource or - Blob or - ImageData) ImageBitmapSource; - -enum ImageOrientation { "none", "flipY" }; -enum PremultiplyAlpha { "none", "premultiply", "default" }; -enum ColorSpaceConversion { "none", "default" }; -enum ResizeQuality { "pixelated", "low", "medium", "high" }; - -dictionary ImageBitmapOptions { - ImageOrientation imageOrientation = "none"; - PremultiplyAlpha premultiplyAlpha = "default"; - ColorSpaceConversion colorSpaceConversion = "default"; - [EnforceRange] unsigned long resizeWidth; - [EnforceRange] unsigned long resizeHeight; - ResizeQuality resizeQuality = "low"; -}; - -[Constructor(DOMString type, optional MessageEventInit eventInitDict = {}), Exposed=(Window,Worker,AudioWorklet)] -interface MessageEvent : Event { - readonly attribute any data; - readonly attribute USVString origin; - readonly attribute DOMString lastEventId; - readonly attribute MessageEventSource? source; - readonly attribute FrozenArray ports; - - void initMessageEvent(DOMString type, optional boolean bubbles = false, optional boolean cancelable = false, optional any data = null, optional USVString origin = "", optional DOMString lastEventId = "", optional MessageEventSource? source = null, optional sequence ports = []); -}; - -dictionary MessageEventInit : EventInit { - any data = null; - USVString origin = ""; - DOMString lastEventId = ""; - MessageEventSource? source = null; - sequence ports = []; -}; - -typedef (WindowProxy or MessagePort or ServiceWorker) MessageEventSource; - -[Constructor(USVString url, optional EventSourceInit eventSourceInitDict = {}), Exposed=(Window,Worker)] -interface EventSource : EventTarget { - readonly attribute USVString url; - readonly attribute boolean withCredentials; - - // ready state - const unsigned short CONNECTING = 0; - const unsigned short OPEN = 1; - const unsigned short CLOSED = 2; - readonly attribute unsigned short readyState; - - // networking - attribute EventHandler onopen; - attribute EventHandler onmessage; - attribute EventHandler onerror; - void close(); -}; - -dictionary EventSourceInit { - boolean withCredentials = false; -}; - -enum BinaryType { "blob", "arraybuffer" }; -[Constructor(USVString url, optional (DOMString or sequence) protocols = []), Exposed=(Window,Worker)] -interface WebSocket : EventTarget { - readonly attribute USVString url; - - // ready state - const unsigned short CONNECTING = 0; - const unsigned short OPEN = 1; - const unsigned short CLOSING = 2; - const unsigned short CLOSED = 3; - readonly attribute unsigned short readyState; - readonly attribute unsigned long long bufferedAmount; - - // networking - attribute EventHandler onopen; - attribute EventHandler onerror; - attribute EventHandler onclose; - readonly attribute DOMString extensions; - readonly attribute DOMString protocol; - void close(optional [Clamp] unsigned short code, optional USVString reason); - - // messaging - attribute EventHandler onmessage; - attribute BinaryType binaryType; - void send(USVString data); - void send(Blob data); - void send(ArrayBuffer data); - void send(ArrayBufferView data); -}; - -[Constructor(DOMString type, optional CloseEventInit eventInitDict = {}), Exposed=(Window,Worker)] -interface CloseEvent : Event { - readonly attribute boolean wasClean; - readonly attribute unsigned short code; - readonly attribute USVString reason; -}; - -dictionary CloseEventInit : EventInit { - boolean wasClean = false; - unsigned short code = 0; - USVString reason = ""; -}; - -[Constructor, Exposed=(Window,Worker)] -interface MessageChannel { - readonly attribute MessagePort port1; - readonly attribute MessagePort port2; -}; - -[Exposed=(Window,Worker,AudioWorklet), Transferable] -interface MessagePort : EventTarget { - void postMessage(any message, optional sequence transfer = []); - void start(); - void close(); - - // event handlers - attribute EventHandler onmessage; - attribute EventHandler onmessageerror; -}; - -[Constructor(DOMString name), Exposed=(Window,Worker)] -interface BroadcastChannel : EventTarget { - readonly attribute DOMString name; - void postMessage(any message); - void close(); - attribute EventHandler onmessage; - attribute EventHandler onmessageerror; -}; - -[Exposed=Worker] -interface WorkerGlobalScope : EventTarget { - readonly attribute WorkerGlobalScope self; - readonly attribute WorkerLocation location; - readonly attribute WorkerNavigator navigator; - void importScripts(USVString... urls); - - attribute OnErrorEventHandler onerror; - attribute EventHandler onlanguagechange; - attribute EventHandler onoffline; - attribute EventHandler ononline; - attribute EventHandler onrejectionhandled; - attribute EventHandler onunhandledrejection; -}; - -[Global=(Worker,DedicatedWorker),Exposed=DedicatedWorker] -interface DedicatedWorkerGlobalScope : WorkerGlobalScope { - [Replaceable] readonly attribute DOMString name; - - void postMessage(any message, optional sequence transfer = []); - - void close(); - - attribute EventHandler onmessage; - attribute EventHandler onmessageerror; -}; - -[Global=(Worker,SharedWorker),Exposed=SharedWorker] -interface SharedWorkerGlobalScope : WorkerGlobalScope { - [Replaceable] readonly attribute DOMString name; - - void close(); - - attribute EventHandler onconnect; -}; - -interface mixin AbstractWorker { - attribute EventHandler onerror; -}; - -[Constructor(USVString scriptURL, optional WorkerOptions options = {}), Exposed=(Window,Worker)] -interface Worker : EventTarget { - void terminate(); - - void postMessage(any message, optional sequence transfer = []); - attribute EventHandler onmessage; - attribute EventHandler onmessageerror; -}; - -dictionary WorkerOptions { - WorkerType type = "classic"; - RequestCredentials credentials = "omit"; // credentials is only used if type is "module" - DOMString name = ""; -}; - -enum WorkerType { "classic", "module" }; - -Worker includes AbstractWorker; - -[Constructor(USVString scriptURL, optional (DOMString or WorkerOptions) options = {}), - Exposed=(Window,Worker)] -interface SharedWorker : EventTarget { - readonly attribute MessagePort port; -}; -SharedWorker includes AbstractWorker; - -interface mixin NavigatorConcurrentHardware { - readonly attribute unsigned long long hardwareConcurrency; -}; - -[Exposed=Worker] -interface WorkerNavigator {}; -WorkerNavigator includes NavigatorID; -WorkerNavigator includes NavigatorLanguage; -WorkerNavigator includes NavigatorOnLine; -WorkerNavigator includes NavigatorConcurrentHardware; - -[Exposed=Worker] -interface WorkerLocation { - stringifier readonly attribute USVString href; - readonly attribute USVString origin; - readonly attribute USVString protocol; - readonly attribute USVString host; - readonly attribute USVString hostname; - readonly attribute USVString port; - readonly attribute USVString pathname; - readonly attribute USVString search; - readonly attribute USVString hash; -}; - -[Exposed=Window] -interface Storage { - readonly attribute unsigned long length; - DOMString? key(unsigned long index); - getter DOMString? getItem(DOMString key); - setter void setItem(DOMString key, DOMString value); - deleter void removeItem(DOMString key); - void clear(); -}; - -interface mixin WindowSessionStorage { - readonly attribute Storage sessionStorage; -}; -Window includes WindowSessionStorage; - -interface mixin WindowLocalStorage { - readonly attribute Storage localStorage; -}; -Window includes WindowLocalStorage; - -[Exposed=Window, - Constructor(DOMString type, optional StorageEventInit eventInitDict = {})] -interface StorageEvent : Event { - readonly attribute DOMString? key; - readonly attribute DOMString? oldValue; - readonly attribute DOMString? newValue; - readonly attribute USVString url; - readonly attribute Storage? storageArea; -}; - -dictionary StorageEventInit : EventInit { - DOMString? key = null; - DOMString? oldValue = null; - DOMString? newValue = null; - USVString url = ""; - Storage? storageArea = null; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLMarqueeElement : HTMLElement { - [CEReactions] attribute DOMString behavior; - [CEReactions] attribute DOMString bgColor; - [CEReactions] attribute DOMString direction; - [CEReactions] attribute DOMString height; - [CEReactions] attribute unsigned long hspace; - [CEReactions] attribute long loop; - [CEReactions] attribute unsigned long scrollAmount; - [CEReactions] attribute unsigned long scrollDelay; - [CEReactions] attribute boolean trueSpeed; - [CEReactions] attribute unsigned long vspace; - [CEReactions] attribute DOMString width; - - attribute EventHandler onbounce; - attribute EventHandler onfinish; - attribute EventHandler onstart; - - void start(); - void stop(); -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLFrameSetElement : HTMLElement { - [CEReactions] attribute DOMString cols; - [CEReactions] attribute DOMString rows; -}; -HTMLFrameSetElement includes WindowEventHandlers; - -[Exposed=Window, - HTMLConstructor] -interface HTMLFrameElement : HTMLElement { - [CEReactions] attribute DOMString name; - [CEReactions] attribute DOMString scrolling; - [CEReactions] attribute USVString src; - [CEReactions] attribute DOMString frameBorder; - [CEReactions] attribute USVString longDesc; - [CEReactions] attribute boolean noResize; - readonly attribute Document? contentDocument; - readonly attribute WindowProxy? contentWindow; - - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString marginHeight; - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString marginWidth; -}; - -partial interface HTMLAnchorElement { - [CEReactions] attribute DOMString coords; - [CEReactions] attribute DOMString charset; - [CEReactions] attribute DOMString name; - [CEReactions] attribute DOMString rev; - [CEReactions] attribute DOMString shape; -}; - -partial interface HTMLAreaElement { - [CEReactions] attribute boolean noHref; -}; - -partial interface HTMLBodyElement { - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString text; - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString link; - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString vLink; - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString aLink; - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString bgColor; - [CEReactions] attribute DOMString background; -}; - -partial interface HTMLBRElement { - [CEReactions] attribute DOMString clear; -}; - -partial interface HTMLTableCaptionElement { - [CEReactions] attribute DOMString align; -}; - -partial interface HTMLTableColElement { - [CEReactions] attribute DOMString align; - [CEReactions] attribute DOMString ch; - [CEReactions] attribute DOMString chOff; - [CEReactions] attribute DOMString vAlign; - [CEReactions] attribute DOMString width; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLDirectoryElement : HTMLElement { - [CEReactions] attribute boolean compact; -}; - -partial interface HTMLDivElement { - [CEReactions] attribute DOMString align; -}; - -partial interface HTMLDListElement { - [CEReactions] attribute boolean compact; -}; - -partial interface HTMLEmbedElement { - [CEReactions] attribute DOMString align; - [CEReactions] attribute DOMString name; -}; - -[Exposed=Window, - HTMLConstructor] -interface HTMLFontElement : HTMLElement { - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString color; - [CEReactions] attribute DOMString face; - [CEReactions] attribute DOMString size; -}; - -partial interface HTMLHeadingElement { - [CEReactions] attribute DOMString align; -}; - -partial interface HTMLHRElement { - [CEReactions] attribute DOMString align; - [CEReactions] attribute DOMString color; - [CEReactions] attribute boolean noShade; - [CEReactions] attribute DOMString size; - [CEReactions] attribute DOMString width; -}; - -partial interface HTMLHtmlElement { - [CEReactions] attribute DOMString version; -}; - -partial interface HTMLIFrameElement { - [CEReactions] attribute DOMString align; - [CEReactions] attribute DOMString scrolling; - [CEReactions] attribute DOMString frameBorder; - [CEReactions] attribute USVString longDesc; - - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString marginHeight; - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString marginWidth; -}; - -partial interface HTMLImageElement { - [CEReactions] attribute DOMString name; - [CEReactions] attribute USVString lowsrc; - [CEReactions] attribute DOMString align; - [CEReactions] attribute unsigned long hspace; - [CEReactions] attribute unsigned long vspace; - [CEReactions] attribute USVString longDesc; - - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString border; -}; - -partial interface HTMLInputElement { - [CEReactions] attribute DOMString align; - [CEReactions] attribute DOMString useMap; -}; - -partial interface HTMLLegendElement { - [CEReactions] attribute DOMString align; -}; - -partial interface HTMLLIElement { - [CEReactions] attribute DOMString type; -}; - -partial interface HTMLLinkElement { - [CEReactions] attribute DOMString charset; - [CEReactions] attribute DOMString rev; - [CEReactions] attribute DOMString target; -}; - -partial interface HTMLMenuElement { - [CEReactions] attribute boolean compact; -}; - -partial interface HTMLMetaElement { - [CEReactions] attribute DOMString scheme; -}; - -partial interface HTMLObjectElement { - [CEReactions] attribute DOMString align; - [CEReactions] attribute DOMString archive; - [CEReactions] attribute DOMString code; - [CEReactions] attribute boolean declare; - [CEReactions] attribute unsigned long hspace; - [CEReactions] attribute DOMString standby; - [CEReactions] attribute unsigned long vspace; - [CEReactions] attribute DOMString codeBase; - [CEReactions] attribute DOMString codeType; - - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString border; -}; - -partial interface HTMLOListElement { - [CEReactions] attribute boolean compact; -}; - -partial interface HTMLParagraphElement { - [CEReactions] attribute DOMString align; -}; - -partial interface HTMLParamElement { - [CEReactions] attribute DOMString type; - [CEReactions] attribute DOMString valueType; -}; - -partial interface HTMLPreElement { - [CEReactions] attribute long width; -}; - -partial interface HTMLStyleElement { - [CEReactions] attribute DOMString type; -}; - -partial interface HTMLScriptElement { - [CEReactions] attribute DOMString charset; - [CEReactions] attribute DOMString event; - [CEReactions] attribute DOMString htmlFor; -}; - -partial interface HTMLTableElement { - [CEReactions] attribute DOMString align; - [CEReactions] attribute DOMString border; - [CEReactions] attribute DOMString frame; - [CEReactions] attribute DOMString rules; - [CEReactions] attribute DOMString summary; - [CEReactions] attribute DOMString width; - - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString bgColor; - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString cellPadding; - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString cellSpacing; -}; - -partial interface HTMLTableSectionElement { - [CEReactions] attribute DOMString align; - [CEReactions] attribute DOMString ch; - [CEReactions] attribute DOMString chOff; - [CEReactions] attribute DOMString vAlign; -}; - -partial interface HTMLTableCellElement { - [CEReactions] attribute DOMString align; - [CEReactions] attribute DOMString axis; - [CEReactions] attribute DOMString height; - [CEReactions] attribute DOMString width; - - [CEReactions] attribute DOMString ch; - [CEReactions] attribute DOMString chOff; - [CEReactions] attribute boolean noWrap; - [CEReactions] attribute DOMString vAlign; - - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString bgColor; -}; - -partial interface HTMLTableRowElement { - [CEReactions] attribute DOMString align; - [CEReactions] attribute DOMString ch; - [CEReactions] attribute DOMString chOff; - [CEReactions] attribute DOMString vAlign; - - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString bgColor; -}; - -partial interface HTMLUListElement { - [CEReactions] attribute boolean compact; - [CEReactions] attribute DOMString type; -}; - -partial interface Document { - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString fgColor; - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString linkColor; - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString vlinkColor; - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString alinkColor; - [CEReactions] attribute [TreatNullAs=EmptyString] DOMString bgColor; - - [SameObject] readonly attribute HTMLCollection anchors; - [SameObject] readonly attribute HTMLCollection applets; - - void clear(); - void captureEvents(); - void releaseEvents(); - - [SameObject] readonly attribute HTMLAllCollection all; -}; - -partial interface Window { - void captureEvents(); - void releaseEvents(); - - [Replaceable, SameObject] readonly attribute External external; -}; - -[Exposed=Window, - NoInterfaceObject] -interface External { - void AddSearchProvider(); - void IsSearchProviderInstalled(); -}; - - diff --git a/third_party/rust/weedle/tests/defs/interface-constructor.webidl b/third_party/rust/weedle/tests/defs/interface-constructor.webidl deleted file mode 100644 index 93cb28a4af16..000000000000 --- a/third_party/rust/weedle/tests/defs/interface-constructor.webidl +++ /dev/null @@ -1,4 +0,0 @@ -interface InterfaceWithConstructor { - [Throws] - constructor(long a); -}; diff --git a/third_party/rust/weedle/tests/defs/mediacapture-streams.webidl b/third_party/rust/weedle/tests/defs/mediacapture-streams.webidl deleted file mode 100644 index 5780cfb34e83..000000000000 --- a/third_party/rust/weedle/tests/defs/mediacapture-streams.webidl +++ /dev/null @@ -1,246 +0,0 @@ -[Exposed=Window, - Constructor, - Constructor(MediaStream stream), - Constructor(sequence tracks)] -interface MediaStream : EventTarget { - readonly attribute DOMString id; - sequence getAudioTracks(); - sequence getVideoTracks(); - sequence getTracks(); - MediaStreamTrack? getTrackById(DOMString trackId); - void addTrack(MediaStreamTrack track); - void removeTrack(MediaStreamTrack track); - MediaStream clone(); - readonly attribute boolean active; - attribute EventHandler onaddtrack; - attribute EventHandler onremovetrack; -}; - -[Exposed=Window] -interface MediaStreamTrack : EventTarget { - readonly attribute DOMString kind; - readonly attribute DOMString id; - readonly attribute DOMString label; - attribute boolean enabled; - readonly attribute boolean muted; - attribute EventHandler onmute; - attribute EventHandler onunmute; - readonly attribute MediaStreamTrackState readyState; - attribute EventHandler onended; - MediaStreamTrack clone(); - void stop(); - MediaTrackCapabilities getCapabilities(); - MediaTrackConstraints getConstraints(); - MediaTrackSettings getSettings(); - Promise applyConstraints(optional MediaTrackConstraints constraints = {}); -}; - -enum MediaStreamTrackState { - "live", - "ended" -}; - -dictionary MediaTrackSupportedConstraints { - boolean width = true; - boolean height = true; - boolean aspectRatio = true; - boolean frameRate = true; - boolean facingMode = true; - boolean resizeMode = true; - boolean volume = true; - boolean sampleRate = true; - boolean sampleSize = true; - boolean echoCancellation = true; - boolean autoGainControl = true; - boolean noiseSuppression = true; - boolean latency = true; - boolean channelCount = true; - boolean deviceId = true; - boolean groupId = true; -}; - -dictionary MediaTrackCapabilities { - ULongRange width; - ULongRange height; - DoubleRange aspectRatio; - DoubleRange frameRate; - sequence facingMode; - sequence resizeMode; - DoubleRange volume; - ULongRange sampleRate; - ULongRange sampleSize; - sequence echoCancellation; - sequence autoGainControl; - sequence noiseSuppression; - DoubleRange latency; - ULongRange channelCount; - DOMString deviceId; - DOMString groupId; -}; - -dictionary MediaTrackConstraints : MediaTrackConstraintSet { - sequence advanced; -}; - -dictionary MediaTrackConstraintSet { - ConstrainULong width; - ConstrainULong height; - ConstrainDouble aspectRatio; - ConstrainDouble frameRate; - ConstrainDOMString facingMode; - ConstrainDOMString resizeMode; - ConstrainDouble volume; - ConstrainULong sampleRate; - ConstrainULong sampleSize; - ConstrainBoolean echoCancellation; - ConstrainBoolean autoGainControl; - ConstrainBoolean noiseSuppression; - ConstrainDouble latency; - ConstrainULong channelCount; - ConstrainDOMString deviceId; - ConstrainDOMString groupId; -}; - -dictionary MediaTrackSettings { - long width; - long height; - double aspectRatio; - double frameRate; - DOMString facingMode; - DOMString resizeMode; - double volume; - long sampleRate; - long sampleSize; - boolean echoCancellation; - boolean autoGainControl; - boolean noiseSuppression; - double latency; - long channelCount; - DOMString deviceId; - DOMString groupId; -}; - -enum VideoFacingModeEnum { - "user", - "environment", - "left", - "right" -}; - -enum VideoResizeModeEnum { - "none", - "crop-and-scale" -}; - -[Exposed=Window, - Constructor(DOMString type, MediaStreamTrackEventInit eventInitDict)] -interface MediaStreamTrackEvent : Event { - [SameObject] - readonly attribute MediaStreamTrack track; -}; - -dictionary MediaStreamTrackEventInit : EventInit { - required MediaStreamTrack track; -}; - -partial interface Navigator { - [SameObject, SecureContext] - readonly attribute MediaDevices mediaDevices; -}; - -[Exposed=Window, SecureContext] -interface MediaDevices : EventTarget { - attribute EventHandler ondevicechange; - Promise> enumerateDevices(); -}; - -[Exposed=Window, SecureContext] -interface MediaDeviceInfo { - readonly attribute DOMString deviceId; - readonly attribute MediaDeviceKind kind; - readonly attribute DOMString label; - readonly attribute DOMString groupId; - [Default] object toJSON(); -}; - -enum MediaDeviceKind { - "audioinput", - "audiooutput", - "videoinput" -}; - -[Exposed=Window] interface InputDeviceInfo : MediaDeviceInfo { - MediaTrackCapabilities getCapabilities(); -}; - -partial interface Navigator { - [SecureContext] - void getUserMedia(MediaStreamConstraints constraints, NavigatorUserMediaSuccessCallback successCallback, NavigatorUserMediaErrorCallback errorCallback); -}; - -partial interface MediaDevices { - MediaTrackSupportedConstraints getSupportedConstraints(); - Promise getUserMedia(optional MediaStreamConstraints constraints = {}); -}; - -dictionary MediaStreamConstraints { - (boolean or MediaTrackConstraints) video = false; - (boolean or MediaTrackConstraints) audio = false; -}; - -callback NavigatorUserMediaSuccessCallback = void (MediaStream stream); - -callback NavigatorUserMediaErrorCallback = void (MediaStreamError error); - -typedef object MediaStreamError; - -dictionary DoubleRange { - double max; - double min; -}; - -dictionary ConstrainDoubleRange : DoubleRange { - double exact; - double ideal; -}; - -dictionary ULongRange { - [Clamp] unsigned long max; - [Clamp] unsigned long min; -}; - -dictionary ConstrainULongRange : ULongRange { - [Clamp] unsigned long exact; - [Clamp] unsigned long ideal; -}; - -dictionary ConstrainBooleanParameters { - boolean exact; - boolean ideal; -}; - -dictionary ConstrainDOMStringParameters { - (DOMString or sequence) exact; - (DOMString or sequence) ideal; -}; - -typedef ([Clamp] unsigned long or ConstrainULongRange) ConstrainULong; - -typedef (double or ConstrainDoubleRange) ConstrainDouble; - -typedef (boolean or ConstrainBooleanParameters) ConstrainBoolean; - -typedef (DOMString or sequence or ConstrainDOMStringParameters) ConstrainDOMString; - -dictionary Capabilities { -}; - -dictionary Settings { -}; - -dictionary ConstraintSet { -}; - -dictionary Constraints : ConstraintSet { - sequence advanced; -}; diff --git a/third_party/rust/weedle/tests/webidl.rs b/third_party/rust/weedle/tests/webidl.rs deleted file mode 100644 index 7aaf815218dd..000000000000 --- a/third_party/rust/weedle/tests/webidl.rs +++ /dev/null @@ -1,99 +0,0 @@ -extern crate weedle; - -use std::fs; -use std::io::Read; - -use weedle::*; - -fn read_file(path: &str) -> String { - let mut file = fs::File::open(path).unwrap(); - let mut file_content = String::new(); - file.read_to_string(&mut file_content).unwrap(); - file_content -} - -#[test] -pub fn should_parse_dom_webidl() { - let content = read_file("./tests/defs/dom.webidl"); - let parsed = weedle::parse(&content).unwrap(); - - assert_eq!(parsed.len(), 62); -} - -#[test] -fn should_parse_html_webidl() { - let content = read_file("./tests/defs/html.webidl"); - let parsed = weedle::parse(&content).unwrap(); - - assert_eq!(parsed.len(), 325); -} - -#[test] -fn should_parse_mediacapture_streams_webidl() { - let content = read_file("./tests/defs/mediacapture-streams.webidl"); - let parsed = weedle::parse(&content).unwrap(); - - assert_eq!(parsed.len(), 37); -} - -#[test] -fn interface_constructor() { - let content = read_file("./tests/defs/interface-constructor.webidl"); - let mut parsed = weedle::parse(&content).unwrap(); - - assert_eq!(parsed.len(), 1); - - let definition = parsed.pop().unwrap(); - - match definition { - Definition::Interface(mut interface) => { - assert!(interface.attributes.is_none()); - assert_eq!(interface.interface, term!(interface)); - assert_eq!(interface.identifier.0, "InterfaceWithConstructor"); - assert_eq!(interface.inheritance, None); - - assert_eq!(interface.members.body.len(), 1); - - let body = interface.members.body.pop().unwrap(); - - match body { - interface::InterfaceMember::Constructor(constructor) => { - let mut attributes = constructor.attributes.unwrap().body.list; - assert_eq!(attributes.len(), 1); - let attribute = attributes.pop().unwrap(); - - match attribute { - attribute::ExtendedAttribute::NoArgs(attribute) => { - assert_eq!((attribute.0).0, "Throws"); - } - _ => unreachable!(), - } - - let mut args = constructor.args.body.list; - assert_eq!(args.len(), 1); - let arg = args.pop().unwrap(); - - match arg { - argument::Argument::Single(arg) => { - assert!(arg.attributes.is_none()); - assert!(arg.optional.is_none()); - assert!(arg.type_.attributes.is_none()); - - match arg.type_.type_ { - types::Type::Single(types::SingleType::NonAny( - types::NonAnyType::Integer(_), - )) => {} - _ => unreachable!(), - } - } - _ => unreachable!(), - }; - - assert_eq!(constructor.constructor, term::Constructor); - } - _ => unreachable!(), - } - } - _ => unreachable!(), - } -} diff --git a/tools/lint/clippy.yml b/tools/lint/clippy.yml index c0cee728dde6..cdd23376ee87 100644 --- a/tools/lint/clippy.yml +++ b/tools/lint/clippy.yml @@ -13,7 +13,6 @@ clippy: - gfx/wr/webrender_build/ - gfx/wr/wr_malloc_size_of/ - js/src/ - - js/src/frontend/binast/ - js/src/frontend/smoosh/ - js/src/rust/shared/ - js/src/wasm/cranelift/