提交 efbbb51e 编写于 作者: B bors

auto merge of #15691 : jbclements/rust/method-field-cleanup, r=alexcrichton

This patch applies the excellent suggestion of @pnkfelix to group the helper methods for method field access into a Trait, making the code much more readable, and much more similar to the way it was before.
......@@ -43,6 +43,7 @@
use syntax::ast_map;
use syntax::ast_util::*;
use syntax::ast_util;
use syntax::ast_util::PostExpansionMethod;
use syntax::attr;
use syntax::attr::AttrMetaMethods;
use syntax::diagnostic::SpanHandler;
......@@ -798,7 +799,7 @@ fn encode_info_for_method(ecx: &EncodeContext,
} else {
encode_symbol(ecx, ebml_w, m.def_id.node);
}
encode_method_argument_names(ebml_w, method_fn_decl(&*ast_method));
encode_method_argument_names(ebml_w, &*ast_method.pe_fn_decl());
}
ebml_w.end_tag();
......@@ -1240,7 +1241,7 @@ fn add_to_index(item: &Item, ebml_w: &Encoder,
encode_method_sort(ebml_w, 'p');
encode_inlined_item(ecx, ebml_w,
IIMethodRef(def_id, true, &*m));
encode_method_argument_names(ebml_w, method_fn_decl(m));
encode_method_argument_names(ebml_w, m.pe_fn_decl());
}
}
......
......@@ -31,6 +31,7 @@
use util::ppaux::ty_to_string;
use syntax::{ast, ast_map, ast_util, codemap, fold};
use syntax::ast_util::PostExpansionMethod;
use syntax::codemap::Span;
use syntax::fold::Folder;
use syntax::parse::token;
......@@ -136,7 +137,7 @@ pub fn decode_inlined_item(cdata: &cstore::crate_metadata,
let ident = match ii {
ast::IIItem(i) => i.ident,
ast::IIForeign(i) => i.ident,
ast::IIMethod(_, _, m) => ast_util::method_ident(&*m),
ast::IIMethod(_, _, m) => m.pe_ident(),
};
debug!("Fn named: {}", token::get_ident(ident));
debug!("< Decoded inlined fn: {}::{}",
......
......@@ -22,8 +22,7 @@
use std::collections::HashSet;
use syntax::ast;
use syntax::ast_map;
use syntax::ast_util;
use syntax::ast_util::{local_def, is_local};
use syntax::ast_util::{local_def, is_local, PostExpansionMethod};
use syntax::attr::AttrMetaMethods;
use syntax::attr;
use syntax::codemap;
......@@ -213,7 +212,7 @@ fn visit_node(&mut self, node: &ast_map::Node) {
visit::walk_trait_method(self, &*trait_method, ctxt);
}
ast_map::NodeMethod(method) => {
visit::walk_block(self, ast_util::method_body(&*method), ctxt);
visit::walk_block(self, method.pe_body(), ctxt);
}
ast_map::NodeForeignItem(foreign_item) => {
visit::walk_foreign_item(self, &*foreign_item, ctxt);
......@@ -521,8 +520,7 @@ fn visit_struct_field(&mut self, field: &ast::StructField, _: ()) {
// Overwrite so that we don't warn the trait method itself.
fn visit_trait_method(&mut self, trait_method: &ast::TraitMethod, _: ()) {
match *trait_method {
ast::Provided(ref method) => visit::walk_block(self,
ast_util::method_body(&**method), ()),
ast::Provided(ref method) => visit::walk_block(self, method.pe_body(), ()),
ast::Required(_) => ()
}
}
......
......@@ -17,7 +17,7 @@
use util::ppaux;
use syntax::ast;
use syntax::ast_util;
use syntax::ast_util::PostExpansionMethod;
use syntax::codemap::Span;
use syntax::visit;
use syntax::visit::Visitor;
......@@ -95,7 +95,7 @@ fn visit_fn(&mut self, fn_kind: &visit::FnKind, fn_decl: &ast::FnDecl,
visit::FkItemFn(_, _, fn_style, _) =>
(true, fn_style == ast::UnsafeFn),
visit::FkMethod(_, _, method) =>
(true, ast_util::method_fn_style(method) == ast::UnsafeFn),
(true, method.pe_fn_style() == ast::UnsafeFn),
_ => (false, false),
};
......
......@@ -26,8 +26,7 @@
use syntax::ast;
use syntax::ast_map;
use syntax::ast_util;
use syntax::ast_util::{is_local, local_def};
use syntax::ast_util::{is_local, local_def, PostExpansionMethod};
use syntax::attr;
use syntax::codemap::Span;
use syntax::parse::token;
......@@ -264,10 +263,10 @@ fn visit_item(&mut self, item: &ast::Item, _: ()) {
if public_ty || public_trait {
for method in methods.iter() {
let meth_public = match ast_util::method_explicit_self(&**method).node {
let meth_public = match method.pe_explicit_self().node {
ast::SelfStatic => public_ty,
_ => true,
} && ast_util::method_vis(&**method) == ast::Public;
} && method.pe_vis() == ast::Public;
if meth_public || tr.is_some() {
self.exported_items.insert(method.id);
}
......@@ -457,8 +456,8 @@ fn def_privacy(&self, did: ast::DefId) -> PrivacyResult {
let imp = self.tcx.map.get_parent_did(closest_private_id);
match ty::impl_trait_ref(self.tcx, imp) {
Some(..) => return Allowable,
_ if ast_util::method_vis(&**m) == ast::Public => return Allowable,
_ => ast_util::method_vis(&**m)
_ if m.pe_vis() == ast::Public => return Allowable,
_ => m.pe_vis()
}
}
Some(ast_map::NodeTraitMethod(_)) => {
......@@ -1079,7 +1078,7 @@ fn check_sane_privacy(&self, item: &ast::Item) {
"visibility qualifiers have no effect on trait \
impls");
for m in methods.iter() {
check_inherited(m.span, ast_util::method_vis(&**m), "");
check_inherited(m.span, m.pe_vis(), "");
}
}
......@@ -1111,7 +1110,7 @@ fn check_sane_privacy(&self, item: &ast::Item) {
for m in methods.iter() {
match *m {
ast::Provided(ref m) => {
check_inherited(m.span, ast_util::method_vis(&**m),
check_inherited(m.span, m.pe_vis(),
"unnecessary visibility");
}
ast::Required(ref m) => {
......@@ -1149,7 +1148,7 @@ fn check_inherited(tcx: &ty::ctxt, sp: Span, vis: ast::Visibility) {
match item.node {
ast::ItemImpl(_, _, _, ref methods) => {
for m in methods.iter() {
check_inherited(tcx, m.span, ast_util::method_vis(&**m));
check_inherited(tcx, m.span, m.pe_vis());
}
}
ast::ItemForeignMod(ref fm) => {
......@@ -1175,7 +1174,7 @@ fn check_inherited(tcx: &ty::ctxt, sp: Span, vis: ast::Visibility) {
match *m {
ast::Required(..) => {}
ast::Provided(ref m) => check_inherited(tcx, m.span,
ast_util::method_vis(&**m)),
m.pe_vis()),
}
}
}
......@@ -1345,7 +1344,7 @@ fn visit_item(&mut self, item: &ast::Item, _: ()) {
// methods will be visible as `Public::foo`.
let mut found_pub_static = false;
for method in methods.iter() {
if ast_util::method_explicit_self(&**method).node == ast::SelfStatic &&
if method.pe_explicit_self().node == ast::SelfStatic &&
self.exported_items.contains(&method.id) {
found_pub_static = true;
visit::walk_method_helper(self, &**method, ());
......
......@@ -26,7 +26,7 @@
use syntax::abi;
use syntax::ast;
use syntax::ast_map;
use syntax::ast_util::is_local;
use syntax::ast_util::{is_local, PostExpansionMethod};
use syntax::ast_util;
use syntax::attr::{InlineAlways, InlineHint, InlineNever, InlineNone};
use syntax::attr;
......@@ -68,7 +68,7 @@ fn item_might_be_inlined(item: &ast::Item) -> bool {
fn method_might_be_inlined(tcx: &ty::ctxt, method: &ast::Method,
impl_src: ast::DefId) -> bool {
if attributes_specify_inlining(method.attrs.as_slice()) ||
generics_require_inlining(ast_util::method_generics(&*method)) {
generics_require_inlining(method.pe_generics()) {
return true
}
if is_local(impl_src) {
......@@ -200,7 +200,7 @@ fn def_id_represents_local_inlined_item(&self, def_id: ast::DefId) -> bool {
}
}
Some(ast_map::NodeMethod(method)) => {
if generics_require_inlining(ast_util::method_generics(&*method)) ||
if generics_require_inlining(method.pe_generics()) ||
attributes_specify_inlining(method.attrs.as_slice()) {
true
} else {
......@@ -316,14 +316,14 @@ fn propagate_node(&mut self, node: &ast_map::Node,
// Keep going, nothing to get exported
}
ast::Provided(ref method) => {
visit::walk_block(self, ast_util::method_body(&**method), ())
visit::walk_block(self, method.pe_body(), ())
}
}
}
ast_map::NodeMethod(method) => {
let did = self.tcx.map.get_parent_did(search_item);
if method_might_be_inlined(self.tcx, &*method, did) {
visit::walk_block(self, ast_util::method_body(&*method), ())
visit::walk_block(self, method.pe_body(), ())
}
}
// Nothing to recurse on for these
......
......@@ -22,8 +22,7 @@
use syntax::ast::*;
use syntax::ast;
use syntax::ast_util;
use syntax::ast_util::{local_def};
use syntax::ast_util::{local_def, PostExpansionMethod};
use syntax::ast_util::{walk_pat, trait_method_to_ty_method};
use syntax::ext::mtwt;
use syntax::parse::token::special_names;
......@@ -1299,20 +1298,20 @@ fn build_reduced_graph_for_item(&mut self,
// For each method...
for method in methods.iter() {
// Add the method to the module.
let ident = ast_util::method_ident(&**method);
let ident = method.pe_ident();
let method_name_bindings =
self.add_child(ident,
new_parent.clone(),
ForbidDuplicateValues,
method.span);
let def = match ast_util::method_explicit_self(&**method).node {
let def = match method.pe_explicit_self().node {
SelfStatic => {
// Static methods become
// `def_static_method`s.
DefStaticMethod(local_def(method.id),
FromImpl(local_def(
item.id)),
ast_util::method_fn_style(&**method))
method.pe_fn_style())
}
_ => {
// Non-static methods become
......@@ -1321,7 +1320,7 @@ fn build_reduced_graph_for_item(&mut self,
}
};
let is_public = ast_util::method_vis(&**method) == ast::Public;
let is_public = method.pe_vis() == ast::Public;
method_name_bindings.define_value(def,
method.span,
is_public);
......@@ -4004,15 +4003,14 @@ fn resolve_struct(&mut self,
fn resolve_method(&mut self,
rib_kind: RibKind,
method: &Method) {
let method_generics = ast_util::method_generics(method);
let method_generics = method.pe_generics();
let type_parameters = HasTypeParameters(method_generics,
FnSpace,
method.id,
rib_kind);
self.resolve_function(rib_kind, Some(ast_util::method_fn_decl(method)),
type_parameters,
ast_util::method_body(method));
self.resolve_function(rib_kind, Some(method.pe_fn_decl()), type_parameters,
method.pe_body());
}
fn with_current_self_type<T>(&mut self, self_type: &Ty, f: |&mut Resolver| -> T) -> T {
......@@ -4083,7 +4081,7 @@ fn resolve_implementation(&mut self,
fn check_trait_method(&self, method: &Method) {
// If there is a TraitRef in scope for an impl, then the method must be in the trait.
for &(did, ref trait_ref) in self.current_trait_ref.iter() {
let method_name = ast_util::method_ident(method).name;
let method_name = method.pe_ident().name;
if self.method_map.borrow().find(&(method_name, did)).is_none() {
let path_str = self.path_idents_to_string(&trait_ref.path);
......
......@@ -43,6 +43,7 @@
use syntax::ast;
use syntax::ast_util;
use syntax::ast_util::PostExpansionMethod;
use syntax::ast::{NodeId,DefId};
use syntax::ast_map::NodeItem;
use syntax::attr;
......@@ -333,7 +334,7 @@ fn process_method(&mut self, method: &ast::Method, e:DxrVisitorEnv) {
},
};
qualname.push_str(get_ident(ast_util::method_ident(&*method)).get());
qualname.push_str(get_ident(method.pe_ident()).get());
let qualname = qualname.as_slice();
// record the decl for this def (if it has one)
......@@ -349,18 +350,17 @@ fn process_method(&mut self, method: &ast::Method, e:DxrVisitorEnv) {
decl_id,
scope_id);
let m_decl = ast_util::method_fn_decl(&*method);
self.process_formals(&m_decl.inputs, qualname, e);
self.process_formals(&method.pe_fn_decl().inputs, qualname, e);
// walk arg and return types
for arg in m_decl.inputs.iter() {
for arg in method.pe_fn_decl().inputs.iter() {
self.visit_ty(&*arg.ty, e);
}
self.visit_ty(m_decl.output, e);
self.visit_ty(method.pe_fn_decl().output, e);
// walk the fn body
self.visit_block(ast_util::method_body(&*method), DxrVisitorEnv::new_nested(method.id));
self.visit_block(method.pe_body(), DxrVisitorEnv::new_nested(method.id));
self.process_generic_params(ast_util::method_generics(&*method),
self.process_generic_params(method.pe_generics(),
method.span,
qualname,
method.id,
......
......@@ -207,6 +207,7 @@ struct List {
use syntax::util::interner::Interner;
use syntax::codemap::{Span, Pos};
use syntax::{abi, ast, codemap, ast_util, ast_map};
use syntax::ast_util::PostExpansionMethod;
use syntax::owned_slice::OwnedSlice;
use syntax::parse::token;
use syntax::parse::token::special_idents;
......@@ -1138,10 +1139,10 @@ pub fn create_function_debug_context(cx: &CrateContext,
}
}
ast_map::NodeMethod(ref method) => {
(ast_util::method_ident(&**method),
ast_util::method_fn_decl(&**method),
ast_util::method_generics(&**method),
ast_util::method_body(&**method),
(method.pe_ident(),
method.pe_fn_decl(),
method.pe_generics(),
method.pe_body(),
method.span,
true)
}
......@@ -1167,10 +1168,10 @@ pub fn create_function_debug_context(cx: &CrateContext,
ast_map::NodeTraitMethod(ref trait_method) => {
match **trait_method {
ast::Provided(ref method) => {
(ast_util::method_ident(&**method),
ast_util::method_fn_decl(&**method),
ast_util::method_generics(&**method),
ast_util::method_body(&**method),
(method.pe_ident(),
method.pe_fn_decl(),
method.pe_generics(),
method.pe_body(),
method.span,
true)
}
......
......@@ -16,7 +16,7 @@
use middle::ty;
use syntax::ast;
use syntax::ast_util::local_def;
use syntax::ast_util::{local_def, PostExpansionMethod};
use syntax::ast_util;
pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
......@@ -128,12 +128,11 @@ pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
let impl_tpt = ty::lookup_item_type(ccx.tcx(), impl_did);
let unparameterized =
impl_tpt.generics.types.is_empty() &&
ast_util::method_generics(&*mth).ty_params.is_empty();
mth.pe_generics().ty_params.is_empty();
if unparameterized {
let llfn = get_item_val(ccx, mth.id);
trans_fn(ccx, ast_util::method_fn_decl(&*mth),
ast_util::method_body(&*mth), llfn,
trans_fn(ccx, &*mth.pe_fn_decl(), &*mth.pe_body(), llfn,
&param_substs::empty(), mth.id, []);
}
local_def(mth.id)
......
......@@ -37,7 +37,8 @@
use std::gc::Gc;
use syntax::abi::Rust;
use syntax::parse::token;
use syntax::{ast, ast_map, visit, ast_util};
use syntax::{ast, ast_map, visit};
use syntax::ast_util::PostExpansionMethod;
/**
The main "translation" pass for methods. Generates code
......@@ -65,10 +66,9 @@ pub fn trans_impl(ccx: &CrateContext,
return;
}
for method in methods.iter() {
if ast_util::method_generics(&**method).ty_params.len() == 0u {
if method.pe_generics().ty_params.len() == 0u {
let llfn = get_item_val(ccx, method.id);
trans_fn(ccx, ast_util::method_fn_decl(&**method),
ast_util::method_body(&**method),
trans_fn(ccx, method.pe_fn_decl(), method.pe_body(),
llfn, &param_substs::empty(), method.id, []);
} else {
let mut v = TransItemVisitor{ ccx: ccx };
......@@ -160,7 +160,7 @@ pub fn trans_static_method_callee(bcx: &Block,
ast_map::NodeTraitMethod(method) => {
let ident = match *method {
ast::Required(ref m) => m.ident,
ast::Provided(ref m) => ast_util::method_ident(&**m)
ast::Provided(ref m) => m.pe_ident()
};
ident.name
}
......
......@@ -25,8 +25,7 @@
use syntax::abi;
use syntax::ast;
use syntax::ast_map;
use syntax::ast_util;
use syntax::ast_util::local_def;
use syntax::ast_util::{local_def, PostExpansionMethod};
use std::hash::{sip, Hash};
pub fn monomorphic_fn(ccx: &CrateContext,
......@@ -182,8 +181,7 @@ pub fn monomorphic_fn(ccx: &CrateContext,
ast_map::NodeMethod(mth) => {
let d = mk_lldecl();
set_llvm_fn_attrs(mth.attrs.as_slice(), d);
trans_fn(ccx, ast_util::method_fn_decl(&*mth),
ast_util::method_body(&*mth), d, &psubsts, mth.id, []);
trans_fn(ccx, &*mth.pe_fn_decl(), &*mth.pe_body(), d, &psubsts, mth.id, []);
d
}
ast_map::NodeTraitMethod(method) => {
......@@ -191,8 +189,8 @@ pub fn monomorphic_fn(ccx: &CrateContext,
ast::Provided(mth) => {
let d = mk_lldecl();
set_llvm_fn_attrs(mth.attrs.as_slice(), d);
trans_fn(ccx, ast_util::method_fn_decl(&*mth),
ast_util::method_body(&*mth), d, &psubsts, mth.id, []);
trans_fn(ccx, &*mth.pe_fn_decl(), &*mth.pe_body(), d,
&psubsts, mth.id, []);
d
}
_ => {
......
......@@ -125,7 +125,7 @@
use syntax::ast::{Provided, Required};
use syntax::ast;
use syntax::ast_map;
use syntax::ast_util::local_def;
use syntax::ast_util::{local_def, PostExpansionMethod};
use syntax::ast_util;
use syntax::attr;
use syntax::codemap::Span;
......@@ -757,16 +757,14 @@ fn check_method_body(ccx: &CrateCtxt,
let method_def_id = local_def(method.id);
let method_ty = ty::method(ccx.tcx, method_def_id);
let method_generics = &method_ty.generics;
let m_body = ast_util::method_body(&*method);
let param_env = ty::construct_parameter_environment(ccx.tcx,
method_generics,
m_body.id);
method.pe_body().id);
let fty = ty::node_id_to_type(ccx.tcx, method.id);
check_bare_fn(ccx, ast_util::method_fn_decl(&*method),
m_body, method.id, fty, param_env);
check_bare_fn(ccx, method.pe_fn_decl(), method.pe_body(), method.id, fty, param_env);
}
fn check_impl_methods_against_trait(ccx: &CrateCtxt,
......@@ -794,7 +792,7 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
compare_impl_method(ccx.tcx,
&*impl_method_ty,
impl_method.span,
ast_util::method_body(&**impl_method).id,
impl_method.pe_body().id,
&**trait_method_ty,
&impl_trait_ref.substs);
}
......@@ -817,7 +815,7 @@ fn check_impl_methods_against_trait(ccx: &CrateCtxt,
for trait_method in trait_methods.iter() {
let is_implemented =
impl_methods.iter().any(
|m| ast_util::method_ident(&**m).name == trait_method.ident.name);
|m| m.pe_ident().name == trait_method.ident.name);
let is_provided =
provided_methods.iter().any(
|m| m.ident.name == trait_method.ident.name);
......
......@@ -57,8 +57,7 @@
use syntax::ast::{TraitTyParamBound, UnboxedFnTyParamBound};
use syntax::ast;
use syntax::ast_map;
use syntax::ast_util;
use syntax::ast_util::{local_def, method_ident, split_trait_methods};
use syntax::ast_util::{local_def, split_trait_methods, PostExpansionMethod};
use syntax::codemap::Span;
use syntax::codemap;
use syntax::owned_slice::OwnedSlice;
......@@ -214,11 +213,8 @@ pub fn ensure_trait_methods(ccx: &CrateCtxt,
&ast::Provided(ref m) => {
ty_method_of_trait_method(
ccx, trait_id, &trait_def.generics,
&m.id, &ast_util::method_ident(&**m),
ast_util::method_explicit_self(&**m),
ast_util::method_generics(&**m),
&ast_util::method_fn_style(&**m),
ast_util::method_fn_decl(&**m))
&m.id, &m.pe_ident(), m.pe_explicit_self(),
m.pe_generics(), &m.pe_fn_style(), m.pe_fn_decl())
}
});
......@@ -334,7 +330,7 @@ fn convert_methods(ccx: &CrateCtxt,
let tcx = ccx.tcx;
let mut seen_methods = HashSet::new();
for m in ms.iter() {
if !seen_methods.insert(ast_util::method_ident(&**m).repr(tcx)) {
if !seen_methods.insert(m.pe_ident().repr(ccx.tcx)) {
tcx.sess.span_err(m.span, "duplicate method in trait impl");
}
......@@ -346,9 +342,9 @@ fn convert_methods(ccx: &CrateCtxt,
rcvr_visibility));
let fty = ty::mk_bare_fn(tcx, mty.fty.clone());
debug!("method {} (id {}) has type {}",
method_ident(&**m).repr(tcx),
m.pe_ident().repr(ccx.tcx),
m.id,
fty.repr(tcx));
fty.repr(ccx.tcx));
tcx.tcache.borrow_mut().insert(
local_def(m.id),
Polytype {
......@@ -369,24 +365,23 @@ fn ty_of_method(ccx: &CrateCtxt,
rcvr_visibility: ast::Visibility)
-> ty::Method
{
let fty = astconv::ty_of_method(ccx, m.id, ast_util::method_fn_style(&*m),
let fty = astconv::ty_of_method(ccx, m.id, m.pe_fn_style(),
untransformed_rcvr_ty,
*ast_util::method_explicit_self(&*m),
ast_util::method_fn_decl(&*m));
*m.pe_explicit_self(), m.pe_fn_decl());
// if the method specifies a visibility, use that, otherwise
// inherit the visibility from the impl (so `foo` in `pub impl
// { fn foo(); }` is public, but private in `priv impl { fn
// foo(); }`).
let method_vis = ast_util::method_vis(&*m).inherit_from(rcvr_visibility);
let method_vis = m.pe_vis().inherit_from(rcvr_visibility);
let m_ty_generics =
ty_generics_for_fn_or_method(ccx, ast_util::method_generics(&*m),
ty_generics_for_fn_or_method(ccx, m.pe_generics(),
(*rcvr_ty_generics).clone());
ty::Method::new(ast_util::method_ident(&*m),
ty::Method::new(m.pe_ident(),
m_ty_generics,
fty,
ast_util::method_explicit_self(&*m).node,
m.pe_explicit_self().node,
method_vis,
local_def(m.id),
container,
......
......@@ -84,7 +84,7 @@
use syntax::ast;
use syntax::ast_map;
use syntax::ast_util;
use syntax::ast_util::name_to_dummy_lifetime;
use syntax::ast_util::{name_to_dummy_lifetime, PostExpansionMethod};
use syntax::owned_slice::OwnedSlice;
use syntax::codemap;
use syntax::parse::token;
......@@ -700,11 +700,8 @@ fn give_suggestion(&self, same_regions: &[SameRegions]) {
}
}
ast_map::NodeMethod(ref m) => {
Some((ast_util::method_fn_decl(&**m),
ast_util::method_generics(&**m),
ast_util::method_fn_style(&**m),
ast_util::method_ident(&**m),
Some(ast_util::method_explicit_self(&**m).node), m.span))
Some((m.pe_fn_decl(), m.pe_generics(), m.pe_fn_style(),
m.pe_ident(), Some(m.pe_explicit_self().node), m.span))
},
_ => None
},
......@@ -1455,7 +1452,7 @@ fn lifetimes_in_scope(tcx: &ty::ctxt,
_ => None
},
ast_map::NodeMethod(m) => {
taken.push_all(ast_util::method_generics(&*m).lifetimes.as_slice());
taken.push_all(m.pe_generics().lifetimes.as_slice());
Some(m.id)
},
_ => None
......
......@@ -14,6 +14,7 @@
use syntax;
use syntax::ast;
use syntax::ast_util;
use syntax::ast_util::PostExpansionMethod;
use syntax::attr;
use syntax::attr::{AttributeMethods, AttrMetaMethods};
use syntax::codemap::Pos;
......@@ -695,30 +696,30 @@ pub struct Method {
impl Clean<Item> for ast::Method {
fn clean(&self) -> Item {
let fn_decl = ast_util::method_fn_decl(self);
let inputs = match ast_util::method_explicit_self(self).node {
ast::SelfStatic => fn_decl.inputs.as_slice(),
_ => fn_decl.inputs.slice_from(1)
let all_inputs = &self.pe_fn_decl().inputs;
let inputs = match self.pe_explicit_self().node {
ast::SelfStatic => all_inputs.as_slice(),
_ => all_inputs.slice_from(1)
};
let decl = FnDecl {
inputs: Arguments {
values: inputs.iter().map(|x| x.clean()).collect(),
},
output: (fn_decl.output.clean()),
cf: fn_decl.cf.clean(),
output: (self.pe_fn_decl().output.clean()),
cf: self.pe_fn_decl().cf.clean(),
attrs: Vec::new()
};
Item {
name: Some(ast_util::method_ident(self).clean()),
name: Some(self.pe_ident().clean()),
attrs: self.attrs.clean().move_iter().collect(),
source: self.span.clean(),
def_id: ast_util::local_def(self.id),
visibility: ast_util::method_vis(self).clean(),
visibility: self.pe_vis().clean(),
stability: get_stability(ast_util::local_def(self.id)),
inner: MethodItem(Method {
generics: ast_util::method_generics(self).clean(),
self_: ast_util::method_explicit_self(self).node.clean(),
fn_style: ast_util::method_fn_style(self).clone(),
generics: self.pe_generics().clean(),
self_: self.pe_explicit_self().node.clean(),
fn_style: self.pe_fn_style().clone(),
decl: decl,
}),
}
......
......@@ -26,7 +26,7 @@
use ast;
use ast_map::{Node};
use ast_map;
use ast_util;
use ast_util::PostExpansionMethod;
use codemap::Span;
use visit;
......@@ -152,13 +152,13 @@ pub fn to_fn_parts<'a>(&'a self) -> FnParts<'a> {
pub fn body<'a>(&'a self) -> P<Block> {
self.handle(|i: ItemFnParts| i.body,
|m: &'a ast::Method| ast_util::method_body(m),
|m: &'a ast::Method| m.pe_body(),
|c: ClosureParts| c.body)
}
pub fn decl<'a>(&'a self) -> P<FnDecl> {
self.handle(|i: ItemFnParts| i.decl,
|m: &'a ast::Method| ast_util::method_fn_decl(m),
|m: &'a ast::Method| m.pe_fn_decl(),
|c: ClosureParts| c.decl)
}
......@@ -182,7 +182,7 @@ pub fn kind<'a>(&'a self) -> visit::FnKind<'a> {
visit::FkFnBlock
};
let method = |m: &'a ast::Method| {
visit::FkMethod(ast_util::method_ident(m), ast_util::method_generics(m), m)
visit::FkMethod(m.pe_ident(), m.pe_generics(), m)
};
self.handle(item, method, closure)
}
......
......@@ -742,16 +742,48 @@ pub fn static_has_significant_address(mutbl: ast::Mutability,
inline == InlineNever || inline == InlineNone
}
/// Macro invocations are guaranteed not to occur after expansion is complete.
/// extracting fields of a method requires a dynamic check to make sure that it's
/// not a macro invocation, though this check is guaranteed to succeed, assuming
/// Extracting fields of a method requires a dynamic check to make sure that it's
/// not a macro invocation. This check is guaranteed to succeed, assuming
/// that the invocations are indeed gone.
macro_rules! method_field_extractor {
($fn_name:ident, $field_ty:ty, $field_pat:pat, $result:ident) => {
/// Returns the ident of a Method. To be used after expansion is complete
pub fn $fn_name<'a>(method: &'a ast::Method) -> $field_ty {
match method.node {
pub trait PostExpansionMethod {
fn pe_ident(&self) -> ast::Ident;
fn pe_generics<'a>(&'a self) -> &'a ast::Generics;
fn pe_explicit_self<'a>(&'a self) -> &'a ast::ExplicitSelf;
fn pe_fn_style(&self) -> ast::FnStyle;
fn pe_fn_decl(&self) -> P<ast::FnDecl>;
fn pe_body(&self) -> P<ast::Block>;
fn pe_vis(&self) -> ast::Visibility;
}
/// can't use the standard cfg(stage0) tricks here, because the error occurs in
/// parsing, before cfg gets a chance to save the day. (yes, interleaved parsing
/// / expansion / configuring would solve this problem...)
// NOTE: remove after next snapshot
/// to be more specific: after a snapshot, swap out the "PRE" stuff, and
// swap in the "POST" stuff.
/// PRE
macro_rules! mf_method_body{
($slf:ident, $field_pat:pat, $result:ident) => {
match $slf.node {
$field_pat => $result,
MethMac(_) => {
fail!("expected an AST without macro invocations");
}
}
}
}
/// POST
/*
#[cfg(not(stage0))]
macro_rules! mf_method{
($meth_name:ident, $field_ty:ty, $field_pat:pat, $result:ident) => {
fn $meth_name<'a>(&'a self) -> $field_ty {
match self.node {
$field_pat => $result,
MethMac(_) => {
fail!("expected an AST without macro invocations");
......@@ -759,20 +791,49 @@ pub fn $fn_name<'a>(method: &'a ast::Method) -> $field_ty {
}
}
}
}*/
// PRE
impl PostExpansionMethod for Method {
fn pe_ident(&self) -> ast::Ident {
mf_method_body!(self,MethDecl(ident,_,_,_,_,_,_),ident)
}
fn pe_generics<'a>(&'a self) -> &'a ast::Generics {
mf_method_body!(self,MethDecl(_,ref generics,_,_,_,_,_),generics)
}
fn pe_explicit_self<'a>(&'a self) -> &'a ast::ExplicitSelf {
mf_method_body!(self,MethDecl(_,_,ref explicit_self,_,_,_,_),explicit_self)
}
fn pe_fn_style(&self) -> ast::FnStyle{
mf_method_body!(self,MethDecl(_,_,_,fn_style,_,_,_),fn_style)
}
fn pe_fn_decl(&self) -> P<ast::FnDecl> {
mf_method_body!(self,MethDecl(_,_,_,_,decl,_,_),decl)
}
fn pe_body(&self) -> P<ast::Block> {
mf_method_body!(self,MethDecl(_,_,_,_,_,body,_),body)
}
fn pe_vis(&self) -> ast::Visibility {
mf_method_body!(self,MethDecl(_,_,_,_,_,_,vis),vis)
}
}
// Note: this is unhygienic in the lifetime 'a. In order to fix this, we'd have to
// add :lifetime as a macro argument type, so that the 'a could be supplied by the macro
// invocation.
pub method_field_extractor!(method_ident,ast::Ident,MethDecl(ident,_,_,_,_,_,_),ident)
pub method_field_extractor!(method_generics,&'a ast::Generics,
MethDecl(_,ref generics,_,_,_,_,_),generics)
pub method_field_extractor!(method_explicit_self,&'a ast::ExplicitSelf,
MethDecl(_,_,ref explicit_self,_,_,_,_),explicit_self)
pub method_field_extractor!(method_fn_style,ast::FnStyle,MethDecl(_,_,_,fn_style,_,_,_),fn_style)
pub method_field_extractor!(method_fn_decl,P<ast::FnDecl>,MethDecl(_,_,_,_,decl,_,_),decl)
pub method_field_extractor!(method_body,P<ast::Block>,MethDecl(_,_,_,_,_,body,_),body)
pub method_field_extractor!(method_vis,ast::Visibility,MethDecl(_,_,_,_,_,_,vis),vis)
// POST
/*
#[cfg(not(stage0))]
impl PostExpansionMethod for Method {
mf_method!(pe_ident,ast::Ident,MethDecl(ident,_,_,_,_,_,_),ident)
mf_method!(pe_generics,&'a ast::Generics,
MethDecl(_,ref generics,_,_,_,_,_),generics)
mf_method!(pe_explicit_self,&'a ast::ExplicitSelf,
MethDecl(_,_,ref explicit_self,_,_,_,_),explicit_self)
mf_method!(pe_fn_style,ast::FnStyle,MethDecl(_,_,_,fn_style,_,_,_),fn_style)
mf_method!(pe_fn_decl,P<ast::FnDecl>,MethDecl(_,_,_,_,decl,_,_),decl)
mf_method!(pe_body,P<ast::Block>,MethDecl(_,_,_,_,_,body,_),body)
mf_method!(pe_vis,ast::Visibility,MethDecl(_,_,_,_,_,_,vis),vis)
}
*/
#[cfg(test)]
mod test {
......@@ -799,4 +860,3 @@ fn ident_to_segment(id : &Ident) -> PathSegment {
.iter().map(ident_to_segment).collect::<Vec<PathSegment>>().as_slice()));
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册