From fe9f1d155ab674e402cdb1b530df8ecb66bb7dd4 Mon Sep 17 00:00:00 2001 From: Zack Corr Date: Sun, 17 Feb 2013 00:31:57 +1000 Subject: [PATCH] syntax: Implement recursive sorting of meta items. Closes #607 --- src/librustc/back/link.rs | 16 +++++++++++----- src/libsyntax/attr.rs | 30 ++++++++++++++++++++---------- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs index 894e846e11f..bd9c7f1616d 100644 --- a/src/librustc/back/link.rs +++ b/src/librustc/back/link.rs @@ -497,8 +497,7 @@ pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path, let cmh_items = attr::sort_meta_items(cmh_items); - symbol_hasher.reset(); - for cmh_items.each |m| { + fn hash(symbol_hasher: &hash::State, m: &@ast::meta_item) { match m.node { ast::meta_name_value(ref key, value) => { symbol_hasher.write_str(len_and_str((*key))); @@ -507,13 +506,20 @@ pub fn build_link_meta(sess: Session, c: &ast::crate, output: &Path, ast::meta_word(ref name) => { symbol_hasher.write_str(len_and_str((*name))); } - ast::meta_list(_, _) => { - // FIXME (#607): Implement this - fail!(~"unimplemented meta_item variant"); + ast::meta_list(ref name, ref mis) => { + symbol_hasher.write_str(len_and_str((*name))); + for mis.each |m_| { + hash(symbol_hasher, m_); + } } } } + symbol_hasher.reset(); + for cmh_items.each |m| { + hash(symbol_hasher, m); + } + for dep_hashes.each |dh| { symbol_hasher.write_str(len_and_str(*dh)); } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 893647ca9ad..605d944c70d 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -192,13 +192,15 @@ fn eq(a: @ast::meta_item, b: @ast::meta_item) -> bool { } _ => false }, - ast::meta_list(*) => { - - // ~[Fixme-sorting] - // FIXME (#607): Needs implementing - // This involves probably sorting the list by name and - // meta_item variant - fail!(~"unimplemented meta_item variant") + ast::meta_list(ref na, misa) => match b.node { + ast::meta_list(ref nb, misb) => { + if na != nb { return false; } + for misa.each |&mi| { + if !contains(misb, mi) { return false; } + } + true + } + _ => false } } } @@ -253,8 +255,6 @@ pub fn last_meta_item_list_by_name(items: ~[@ast::meta_item], name: ~str) /* Higher-level applications */ -// FIXME (#607): This needs to sort by meta_item variant in addition to -// the item name (See [Fixme-sorting]) pub fn sort_meta_items(+items: ~[@ast::meta_item]) -> ~[@ast::meta_item] { pure fn lteq(ma: &@ast::meta_item, mb: &@ast::meta_item) -> bool { pure fn key(m: &ast::meta_item) -> ~str { @@ -270,7 +270,17 @@ pub fn sort_meta_items(+items: ~[@ast::meta_item]) -> ~[@ast::meta_item] { // This is sort of stupid here, converting to a vec of mutables and back let mut v: ~[@ast::meta_item] = items; std::sort::quick_sort(v, lteq); - v + + // There doesn't seem to be a more optimal way to do this + do v.map |&m| { + match m.node { + ast::meta_list(n, mis) => @spanned { + node: ast::meta_list(n, sort_meta_items(mis)), + .. *m + }, + _ => m + } + } } pub fn remove_meta_items_by_name(items: ~[@ast::meta_item], name: ~str) ->