mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
Auto merge of #8622 - frewsxcv:url-plugin, r=SimonSapin
Implement 'url!(..)' macro https://github.com/servo/rust-url/issues/136 https://github.com/servo/rust-url/pull/137 <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/8622) <!-- Reviewable:end -->
This commit is contained in:
commit
ea690a2dff
30 changed files with 346 additions and 128 deletions
|
@ -701,7 +701,7 @@ impl<LTF: LayoutTaskFactory, STF: ScriptTaskFactory> Constellation<LTF, STF> {
|
|||
parent_info,
|
||||
window_size,
|
||||
None,
|
||||
LoadData::new(Url::parse("about:failure").unwrap()));
|
||||
LoadData::new(url!("about:failure")));
|
||||
|
||||
self.push_pending_frame(new_pipeline_id, Some(pipeline_id));
|
||||
}
|
||||
|
|
|
@ -16,5 +16,8 @@ git = "https://github.com/Manishearth/rust-clippy"
|
|||
branch = "servo"
|
||||
optional = true
|
||||
|
||||
[dependencies.url]
|
||||
version = "0.2.36"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
|
|
@ -26,6 +26,8 @@ extern crate tenacious;
|
|||
#[cfg(feature = "clippy")]
|
||||
extern crate clippy;
|
||||
|
||||
extern crate url;
|
||||
|
||||
use rustc::plugin::Registry;
|
||||
use syntax::ext::base::*;
|
||||
use syntax::feature_gate::AttributeType::Whitelisted;
|
||||
|
@ -41,6 +43,7 @@ pub mod lints;
|
|||
pub mod reflector;
|
||||
/// Utilities for writing plugins
|
||||
pub mod casing;
|
||||
mod url_plugin;
|
||||
pub mod utils;
|
||||
|
||||
#[plugin_registrar]
|
||||
|
@ -51,6 +54,7 @@ pub fn plugin_registrar(reg: &mut Registry) {
|
|||
reg.register_syntax_extension(intern("derive_HeapSizeOf"), MultiDecorator(box heap_size::expand_heap_size));
|
||||
reg.register_macro("to_lower", casing::expand_lower);
|
||||
reg.register_macro("to_upper", casing::expand_upper);
|
||||
reg.register_macro("url", url_plugin::expand_url);
|
||||
reg.register_late_lint_pass(box lints::transmute_type::TransmutePass);
|
||||
reg.register_late_lint_pass(box lints::unrooted_must_root::UnrootedPass::new());
|
||||
reg.register_late_lint_pass(box lints::privatize::PrivatizePass);
|
||||
|
|
141
components/plugins/url_plugin.rs
Normal file
141
components/plugins/url_plugin.rs
Normal file
|
@ -0,0 +1,141 @@
|
|||
/* 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::error::Error;
|
||||
use syntax;
|
||||
use syntax::ast::{TokenTree, ExprLit, LitStr, Expr};
|
||||
use syntax::codemap::Span;
|
||||
use syntax::ext::base::{ExtCtxt, MacResult, MacEager, DummyResult};
|
||||
use syntax::ext::build::AstBuilder;
|
||||
use syntax::fold::Folder;
|
||||
use syntax::parse;
|
||||
use syntax::parse::token::InternedString;
|
||||
use url::{Url, Host, RelativeSchemeData, SchemeData};
|
||||
|
||||
pub fn expand_url(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
|
||||
-> Box<MacResult + 'static> {
|
||||
let mut parser = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(), tts.to_vec());
|
||||
let query_expr = cx.expander().fold_expr(parser.parse_expr());
|
||||
|
||||
// Ensure a str literal was passed to the macro
|
||||
let query = match parse_str_lit(&query_expr) {
|
||||
Some(query) => query,
|
||||
None => {
|
||||
cx.span_err(query_expr.span, "'url!' expected string literal");
|
||||
return DummyResult::any(sp)
|
||||
},
|
||||
};
|
||||
|
||||
// Parse the str literal
|
||||
let Url { scheme, scheme_data, query, fragment } = match Url::parse(&query) {
|
||||
Ok(url) => url,
|
||||
Err(error) => {
|
||||
cx.span_err(query_expr.span, error.description());
|
||||
return DummyResult::any(sp)
|
||||
}
|
||||
};
|
||||
|
||||
let scheme_data_expr = cx.expr_scheme_data(sp, scheme_data);
|
||||
let query_expr = cx.expr_option_string(sp, query);
|
||||
let fragment_expr = cx.expr_option_string(sp, fragment);
|
||||
|
||||
let url_expr = quote_expr!(cx, {
|
||||
::url::Url {
|
||||
scheme: $scheme.to_owned(),
|
||||
scheme_data: $scheme_data_expr,
|
||||
query: $query_expr,
|
||||
fragment: $fragment_expr,
|
||||
}
|
||||
});
|
||||
|
||||
MacEager::expr(url_expr)
|
||||
}
|
||||
|
||||
fn parse_str_lit(e: &Expr) -> Option<InternedString> {
|
||||
if let ExprLit(ref lit) = e.node {
|
||||
if let LitStr(ref s, _) = lit.node {
|
||||
return Some(s.clone());
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
trait ExtCtxtHelpers {
|
||||
fn expr_scheme_data(&self, sp: Span, scheme_data: SchemeData) -> syntax::ptr::P<Expr>;
|
||||
fn expr_option_string(&self, sp: Span, string: Option<String>) -> syntax::ptr::P<Expr>;
|
||||
fn expr_option_u16(&self, sp: Span, unsigned: Option<u16>) -> syntax::ptr::P<Expr>;
|
||||
fn expr_host(&self, sp: Span, host: Host) -> syntax::ptr::P<Expr>;
|
||||
fn expr_slice_u16(&self, sp: Span, unsigned: &[u16]) -> syntax::ptr::P<Expr>;
|
||||
fn expr_vec_string(&self, sp: Span, strings: Vec<String>) -> syntax::ptr::P<Expr>;
|
||||
}
|
||||
|
||||
impl<'a> ExtCtxtHelpers for ExtCtxt<'a> {
|
||||
fn expr_scheme_data(&self, sp: Span, scheme_data: SchemeData) -> syntax::ptr::P<Expr> {
|
||||
match scheme_data {
|
||||
SchemeData::Relative(
|
||||
RelativeSchemeData { username, password, host, port, default_port, path }) =>
|
||||
{
|
||||
let password_expr = self.expr_option_string(sp, password);
|
||||
let host_expr = self.expr_host(sp, host);
|
||||
let port_expr = self.expr_option_u16(sp, port);
|
||||
let default_port_expr = self.expr_option_u16(sp, default_port);
|
||||
let path_expr = self.expr_vec_string(sp, path);
|
||||
|
||||
quote_expr!(self,
|
||||
::url::SchemeData::Relative(
|
||||
::url::RelativeSchemeData {
|
||||
username: $username.to_owned(),
|
||||
password: $password_expr,
|
||||
host: $host_expr,
|
||||
port: $port_expr,
|
||||
default_port: $default_port_expr,
|
||||
path: $path_expr.to_owned(),
|
||||
}
|
||||
))
|
||||
},
|
||||
SchemeData::NonRelative(ref scheme_data) => {
|
||||
quote_expr!(self, ::url::SchemeData::NonRelative($scheme_data.to_owned()))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn expr_option_string(&self, sp: Span, string: Option<String>) -> syntax::ptr::P<Expr> {
|
||||
match string {
|
||||
Some(string) => quote_expr!(self, Some($string.to_owned())),
|
||||
None => self.expr_none(sp),
|
||||
}
|
||||
}
|
||||
|
||||
fn expr_option_u16(&self, sp: Span, unsigned: Option<u16>) -> syntax::ptr::P<Expr> {
|
||||
match unsigned {
|
||||
Some(unsigned) => quote_expr!(self, Some($unsigned)),
|
||||
None => self.expr_none(sp),
|
||||
}
|
||||
}
|
||||
|
||||
fn expr_host(&self, sp: Span, host: Host) -> syntax::ptr::P<Expr> {
|
||||
match host {
|
||||
Host::Domain(domain) => quote_expr!(self, ::url::Host::Domain(String::from($domain))),
|
||||
Host::Ipv6(address) => {
|
||||
let pieces_expr = self.expr_slice_u16(sp, &address.pieces);
|
||||
quote_expr!(self,
|
||||
::url::Host::Ipv6(
|
||||
::url::Ipv6Address {
|
||||
pieces: $pieces_expr.to_owned()
|
||||
}
|
||||
))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn expr_slice_u16(&self, sp: Span, unsigned: &[u16]) -> syntax::ptr::P<Expr> {
|
||||
let unsigned = unsigned.iter().map(|p| quote_expr!(self, $p)).collect();
|
||||
self.expr_vec_slice(sp, unsigned)
|
||||
}
|
||||
|
||||
fn expr_vec_string(&self, sp: Span, strings: Vec<String>) -> syntax::ptr::P<Expr> {
|
||||
let strings = strings.iter().map(|p| quote_expr!(self, $p.to_owned())).collect();
|
||||
self.expr_vec(sp, strings)
|
||||
}
|
||||
}
|
|
@ -1388,7 +1388,7 @@ impl Document {
|
|||
source: DocumentSource,
|
||||
doc_loader: DocumentLoader)
|
||||
-> Document {
|
||||
let url = url.unwrap_or_else(|| Url::parse("about:blank").unwrap());
|
||||
let url = url.unwrap_or_else(|| url!("about:blank"));
|
||||
|
||||
let (ready_state, domcontentloaded_dispatched) = if source == DocumentSource::FromParser {
|
||||
(DocumentReadyState::Loading, false)
|
||||
|
|
|
@ -124,7 +124,7 @@ impl HTMLIFrameElement {
|
|||
pub fn process_the_iframe_attributes(&self) {
|
||||
let url = match self.get_url() {
|
||||
Some(url) => url.clone(),
|
||||
None => Url::parse("about:blank").unwrap(),
|
||||
None => url!("about:blank"),
|
||||
};
|
||||
|
||||
self.navigate_child_browsing_context(url);
|
||||
|
|
|
@ -1969,7 +1969,7 @@ impl ScriptTask {
|
|||
};
|
||||
|
||||
if load_data.url.scheme == "javascript" {
|
||||
load_data.url = Url::parse("about:blank").unwrap();
|
||||
load_data.url = url!("about:blank");
|
||||
}
|
||||
|
||||
resource_task.send(ControlMsg::Load(NetLoadData {
|
||||
|
|
12
components/servo/Cargo.lock
generated
12
components/servo/Cargo.lock
generated
|
@ -28,6 +28,7 @@ dependencies = [
|
|||
"net_traits 0.0.1",
|
||||
"net_traits_tests 0.0.1",
|
||||
"offscreen_gl_context 0.1.0 (git+https://github.com/ecoal95/rust-offscreen-rendering-context)",
|
||||
"plugin_tests 0.0.1",
|
||||
"profile 0.0.1",
|
||||
"profile_traits 0.0.1",
|
||||
"script 0.0.1",
|
||||
|
@ -1223,6 +1224,7 @@ dependencies = [
|
|||
"msg 0.0.1",
|
||||
"net 0.0.1",
|
||||
"net_traits 0.0.1",
|
||||
"plugins 0.0.1",
|
||||
"time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"util 0.0.1",
|
||||
|
@ -1388,11 +1390,20 @@ name = "pkg-config"
|
|||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "plugin_tests"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"plugins 0.0.1",
|
||||
"url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "plugins"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"tenacious 0.0.11 (git+https://github.com/Manishearth/rust-tenacious)",
|
||||
"url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1770,6 +1781,7 @@ dependencies = [
|
|||
"app_units 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cssparser 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"plugins 0.0.1",
|
||||
"selectors 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"string_cache 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"string_cache_plugin 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
@ -29,6 +29,9 @@ path = "../../tests/unit/net"
|
|||
[dev-dependencies.net_traits_tests]
|
||||
path = "../../tests/unit/net_traits"
|
||||
|
||||
[dev-dependencies.plugin_tests]
|
||||
path = "../../tests/unit/plugin"
|
||||
|
||||
[dev-dependencies.script_tests]
|
||||
path = "../../tests/unit/script"
|
||||
|
||||
|
|
|
@ -112,7 +112,7 @@ fn parse_one_src(context: &ParserContext, input: &mut Parser) -> Result<Source,
|
|||
}
|
||||
let url = try!(input.expect_url());
|
||||
let url = UrlParser::new().base_url(context.base_url).parse(&url).unwrap_or_else(
|
||||
|_error| Url::parse("about:invalid").unwrap());
|
||||
|_error| url!("about:invalid"));
|
||||
|
||||
// Parsing optional format()
|
||||
let format_hints = if input.try(|input| input.expect_function_matching("format")).is_ok() {
|
||||
|
|
|
@ -31,7 +31,7 @@ impl<'a> ParserContext<'a> {
|
|||
impl<'a> ParserContext<'a> {
|
||||
pub fn parse_url(&self, input: &str) -> Url {
|
||||
UrlParser::new().base_url(self.base_url).parse(input)
|
||||
.unwrap_or_else(|_| Url::parse("about:invalid").unwrap())
|
||||
.unwrap_or_else(|_| url!("about:invalid"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,7 +61,7 @@ lazy_static! {
|
|||
Ok(res) => {
|
||||
Stylesheet::from_bytes(
|
||||
&res,
|
||||
Url::parse("chrome:///quirks-mode.css").unwrap(),
|
||||
url!("chrome:///quirks-mode.css"),
|
||||
None,
|
||||
None,
|
||||
Origin::UserAgent)
|
||||
|
|
|
@ -440,7 +440,7 @@ const DEFAULT_USER_AGENT: UserAgent = UserAgent::Desktop;
|
|||
pub fn default_opts() -> Opts {
|
||||
Opts {
|
||||
is_running_problem_test: false,
|
||||
url: Some(Url::parse("about:blank").unwrap()),
|
||||
url: Some(url!("about:blank")),
|
||||
paint_threads: 1,
|
||||
gpu_painting: false,
|
||||
tile_size: 512,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue