2012-12-03 18:48:01 -06:00
|
|
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2012-07-25 20:36:18 -05:00
|
|
|
// Detecting language items.
|
|
|
|
//
|
|
|
|
// Language items are items that represent concepts intrinsic to the language
|
|
|
|
// itself. Examples are:
|
|
|
|
//
|
2012-12-11 15:50:04 -06:00
|
|
|
// * Traits that specify "kinds"; e.g. "const", "copy", "owned".
|
2012-07-25 20:36:18 -05:00
|
|
|
//
|
|
|
|
// * Traits that represent operators; e.g. "add", "sub", "index".
|
|
|
|
//
|
|
|
|
// * Functions called by the compiler itself.
|
|
|
|
|
2012-10-15 16:56:42 -05:00
|
|
|
use driver::session::Session;
|
2012-09-04 13:54:36 -05:00
|
|
|
use metadata::csearch::{each_path, get_item_attrs};
|
|
|
|
use metadata::cstore::{iter_crate_data};
|
|
|
|
use metadata::decoder::{dl_def, dl_field, dl_impl};
|
2012-09-07 17:45:11 -05:00
|
|
|
use syntax::ast::{crate, def_fn, def_id, def_ty, lit_str, meta_item};
|
|
|
|
use syntax::ast::{meta_list, meta_name_value, meta_word};
|
2012-09-04 13:54:36 -05:00
|
|
|
use syntax::ast_util::{local_def};
|
|
|
|
use syntax::visit::{default_simple_visitor, mk_simple_visitor};
|
|
|
|
use syntax::visit::{visit_crate, visit_item};
|
2012-07-25 20:36:18 -05:00
|
|
|
|
2012-12-23 16:41:37 -06:00
|
|
|
use core::ptr;
|
2012-09-19 17:13:04 -05:00
|
|
|
use std::map::HashMap;
|
2012-09-04 13:54:36 -05:00
|
|
|
use str_eq = str::eq;
|
2012-07-25 20:36:18 -05:00
|
|
|
|
2012-08-15 20:46:55 -05:00
|
|
|
struct LanguageItems {
|
2012-09-07 17:45:11 -05:00
|
|
|
mut const_trait: Option<def_id>,
|
|
|
|
mut copy_trait: Option<def_id>,
|
2012-12-11 15:50:04 -06:00
|
|
|
mut owned_trait: Option<def_id>,
|
2012-12-11 13:59:45 -06:00
|
|
|
mut durable_trait: Option<def_id>,
|
2012-09-07 17:45:11 -05:00
|
|
|
|
2012-11-05 19:50:01 -06:00
|
|
|
mut drop_trait: Option<def_id>,
|
|
|
|
|
2012-09-07 17:45:11 -05:00
|
|
|
mut add_trait: Option<def_id>,
|
|
|
|
mut sub_trait: Option<def_id>,
|
|
|
|
mut mul_trait: Option<def_id>,
|
|
|
|
mut div_trait: Option<def_id>,
|
|
|
|
mut modulo_trait: Option<def_id>,
|
|
|
|
mut neg_trait: Option<def_id>,
|
|
|
|
mut bitxor_trait: Option<def_id>,
|
|
|
|
mut bitand_trait: Option<def_id>,
|
|
|
|
mut bitor_trait: Option<def_id>,
|
|
|
|
mut shl_trait: Option<def_id>,
|
|
|
|
mut shr_trait: Option<def_id>,
|
|
|
|
mut index_trait: Option<def_id>,
|
|
|
|
|
|
|
|
mut eq_trait: Option<def_id>,
|
|
|
|
mut ord_trait: Option<def_id>,
|
|
|
|
|
2012-09-10 19:22:20 -05:00
|
|
|
mut str_eq_fn: Option<def_id>,
|
2012-09-14 18:49:23 -05:00
|
|
|
mut uniq_str_eq_fn: Option<def_id>,
|
2012-09-25 14:17:20 -05:00
|
|
|
mut annihilate_fn: Option<def_id>,
|
|
|
|
mut log_type_fn: Option<def_id>
|
2012-08-27 16:08:37 -05:00
|
|
|
}
|
|
|
|
|
2012-10-15 16:56:42 -05:00
|
|
|
mod language_items {
|
2012-09-21 20:10:45 -05:00
|
|
|
#[legacy_exports];
|
2012-08-27 16:08:37 -05:00
|
|
|
fn make() -> LanguageItems {
|
|
|
|
LanguageItems {
|
|
|
|
const_trait: None,
|
|
|
|
copy_trait: None,
|
2012-12-11 15:50:04 -06:00
|
|
|
owned_trait: None,
|
2012-12-11 13:59:45 -06:00
|
|
|
durable_trait: None,
|
2012-08-27 16:08:37 -05:00
|
|
|
|
2012-11-05 19:50:01 -06:00
|
|
|
drop_trait: None,
|
|
|
|
|
2012-08-27 16:08:37 -05:00
|
|
|
add_trait: None,
|
|
|
|
sub_trait: None,
|
|
|
|
mul_trait: None,
|
|
|
|
div_trait: None,
|
|
|
|
modulo_trait: None,
|
|
|
|
neg_trait: None,
|
|
|
|
bitxor_trait: None,
|
|
|
|
bitand_trait: None,
|
|
|
|
bitor_trait: None,
|
|
|
|
shl_trait: None,
|
|
|
|
shr_trait: None,
|
|
|
|
index_trait: None,
|
|
|
|
|
|
|
|
eq_trait: None,
|
2012-09-07 17:45:11 -05:00
|
|
|
ord_trait: None,
|
|
|
|
|
2012-09-10 19:22:20 -05:00
|
|
|
str_eq_fn: None,
|
2012-09-14 18:49:23 -05:00
|
|
|
uniq_str_eq_fn: None,
|
2012-09-25 14:17:20 -05:00
|
|
|
annihilate_fn: None,
|
|
|
|
log_type_fn: None
|
2012-08-27 16:08:37 -05:00
|
|
|
}
|
2012-07-25 20:36:18 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-15 16:56:42 -05:00
|
|
|
fn LanguageItemCollector(crate: @crate, session: Session,
|
2012-09-05 17:58:43 -05:00
|
|
|
items: &r/LanguageItems)
|
|
|
|
-> LanguageItemCollector/&r {
|
|
|
|
|
2012-09-19 17:13:04 -05:00
|
|
|
let item_refs = HashMap();
|
2012-09-05 17:58:43 -05:00
|
|
|
|
|
|
|
item_refs.insert(~"const", &mut items.const_trait);
|
|
|
|
item_refs.insert(~"copy", &mut items.copy_trait);
|
2012-12-11 15:50:04 -06:00
|
|
|
item_refs.insert(~"owned", &mut items.owned_trait);
|
2012-12-11 13:59:45 -06:00
|
|
|
item_refs.insert(~"durable", &mut items.durable_trait);
|
2012-09-05 17:58:43 -05:00
|
|
|
|
2012-11-05 19:50:01 -06:00
|
|
|
item_refs.insert(~"drop", &mut items.drop_trait);
|
|
|
|
|
2012-09-05 17:58:43 -05:00
|
|
|
item_refs.insert(~"add", &mut items.add_trait);
|
|
|
|
item_refs.insert(~"sub", &mut items.sub_trait);
|
|
|
|
item_refs.insert(~"mul", &mut items.mul_trait);
|
|
|
|
item_refs.insert(~"div", &mut items.div_trait);
|
|
|
|
item_refs.insert(~"modulo", &mut items.modulo_trait);
|
|
|
|
item_refs.insert(~"neg", &mut items.neg_trait);
|
|
|
|
item_refs.insert(~"bitxor", &mut items.bitxor_trait);
|
|
|
|
item_refs.insert(~"bitand", &mut items.bitand_trait);
|
|
|
|
item_refs.insert(~"bitor", &mut items.bitor_trait);
|
|
|
|
item_refs.insert(~"shl", &mut items.shl_trait);
|
|
|
|
item_refs.insert(~"shr", &mut items.shr_trait);
|
|
|
|
item_refs.insert(~"index", &mut items.index_trait);
|
|
|
|
|
|
|
|
item_refs.insert(~"eq", &mut items.eq_trait);
|
|
|
|
item_refs.insert(~"ord", &mut items.ord_trait);
|
|
|
|
|
2012-09-07 17:45:11 -05:00
|
|
|
item_refs.insert(~"str_eq", &mut items.str_eq_fn);
|
2012-09-10 19:22:20 -05:00
|
|
|
item_refs.insert(~"uniq_str_eq", &mut items.uniq_str_eq_fn);
|
2012-09-14 18:49:23 -05:00
|
|
|
item_refs.insert(~"annihilate", &mut items.annihilate_fn);
|
2012-09-25 14:17:20 -05:00
|
|
|
item_refs.insert(~"log_type", &mut items.log_type_fn);
|
2012-09-07 17:45:11 -05:00
|
|
|
|
2012-09-05 17:58:43 -05:00
|
|
|
LanguageItemCollector {
|
|
|
|
crate: crate,
|
|
|
|
session: session,
|
|
|
|
items: items,
|
|
|
|
item_refs: item_refs
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-15 20:46:55 -05:00
|
|
|
struct LanguageItemCollector {
|
2012-09-06 21:40:15 -05:00
|
|
|
items: &LanguageItems,
|
2012-07-25 20:36:18 -05:00
|
|
|
|
2012-09-06 21:40:15 -05:00
|
|
|
crate: @crate,
|
2012-10-15 16:56:42 -05:00
|
|
|
session: Session,
|
2012-07-25 20:36:18 -05:00
|
|
|
|
2012-09-10 17:38:28 -05:00
|
|
|
item_refs: HashMap<~str,&mut Option<def_id>>,
|
2012-09-07 21:04:40 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl LanguageItemCollector {
|
2012-07-25 20:36:18 -05:00
|
|
|
|
|
|
|
fn match_and_collect_meta_item(item_def_id: def_id,
|
|
|
|
meta_item: meta_item) {
|
2012-08-06 14:34:08 -05:00
|
|
|
match meta_item.node {
|
2012-12-04 12:50:00 -06:00
|
|
|
meta_name_value(ref key, literal) => {
|
2012-08-06 14:34:08 -05:00
|
|
|
match literal.node {
|
2012-07-25 20:36:18 -05:00
|
|
|
lit_str(value) => {
|
2012-12-04 23:13:02 -06:00
|
|
|
self.match_and_collect_item(item_def_id,
|
|
|
|
(*key),
|
|
|
|
*value);
|
2012-07-25 20:36:18 -05:00
|
|
|
}
|
2012-07-18 18:18:02 -05:00
|
|
|
_ => {} // Skip.
|
2012-07-25 20:36:18 -05:00
|
|
|
}
|
|
|
|
}
|
2012-07-18 18:18:02 -05:00
|
|
|
meta_word(*) | meta_list(*) => {} // Skip.
|
2012-07-25 20:36:18 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn match_and_collect_item(item_def_id: def_id, key: ~str, value: ~str) {
|
2012-08-02 17:42:56 -05:00
|
|
|
if key != ~"lang" {
|
2012-08-01 19:30:05 -05:00
|
|
|
return; // Didn't match.
|
2012-07-25 20:36:18 -05:00
|
|
|
}
|
|
|
|
|
2012-08-06 14:34:08 -05:00
|
|
|
match self.item_refs.find(value) {
|
2012-08-20 14:23:37 -05:00
|
|
|
None => {
|
2012-07-25 20:36:18 -05:00
|
|
|
// Didn't match.
|
|
|
|
}
|
2012-08-20 14:23:37 -05:00
|
|
|
Some(item_ref) => {
|
2012-07-25 20:36:18 -05:00
|
|
|
// Check for duplicates.
|
2012-08-06 14:34:08 -05:00
|
|
|
match copy *item_ref {
|
2012-08-20 14:23:37 -05:00
|
|
|
Some(original_def_id)
|
2012-07-25 20:36:18 -05:00
|
|
|
if original_def_id != item_def_id => {
|
|
|
|
|
2012-08-22 19:24:52 -05:00
|
|
|
self.session.err(fmt!("duplicate entry for `%s`",
|
|
|
|
value));
|
2012-07-25 20:36:18 -05:00
|
|
|
}
|
2012-08-20 14:23:37 -05:00
|
|
|
Some(_) | None => {
|
2012-07-25 20:36:18 -05:00
|
|
|
// OK.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Matched.
|
2012-08-20 14:23:37 -05:00
|
|
|
*item_ref = Some(item_def_id);
|
2012-07-25 20:36:18 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn collect_local_language_items() {
|
2012-10-01 14:47:02 -05:00
|
|
|
let this = unsafe { ptr::addr_of(&self) };
|
2012-07-25 20:36:18 -05:00
|
|
|
visit_crate(*self.crate, (), mk_simple_visitor(@{
|
|
|
|
visit_item: |item| {
|
|
|
|
for item.attrs.each |attribute| {
|
|
|
|
unsafe {
|
|
|
|
(*this).match_and_collect_meta_item(local_def(item
|
|
|
|
.id),
|
|
|
|
attribute.node
|
|
|
|
.value);
|
|
|
|
}
|
|
|
|
}
|
2012-09-04 15:29:32 -05:00
|
|
|
},
|
|
|
|
.. *default_simple_visitor()
|
2012-07-25 20:36:18 -05:00
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
fn collect_external_language_items() {
|
|
|
|
let crate_store = self.session.cstore;
|
|
|
|
do iter_crate_data(crate_store) |crate_number, _crate_metadata| {
|
|
|
|
for each_path(crate_store, crate_number) |path_entry| {
|
|
|
|
let def_id;
|
2012-08-06 14:34:08 -05:00
|
|
|
match path_entry.def_like {
|
2012-09-07 17:45:11 -05:00
|
|
|
dl_def(def_ty(did)) | dl_def(def_fn(did, _)) => {
|
2012-07-25 20:36:18 -05:00
|
|
|
def_id = did;
|
|
|
|
}
|
2012-08-03 21:59:04 -05:00
|
|
|
dl_def(_) | dl_impl(_) | dl_field => {
|
2012-07-25 20:36:18 -05:00
|
|
|
// Skip this.
|
2012-09-07 17:32:04 -05:00
|
|
|
loop;
|
2012-07-25 20:36:18 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
do get_item_attrs(crate_store, def_id) |meta_items| {
|
|
|
|
for meta_items.each |meta_item| {
|
2012-09-20 20:15:39 -05:00
|
|
|
self.match_and_collect_meta_item(def_id, **meta_item);
|
2012-07-25 20:36:18 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn check_completeness() {
|
|
|
|
for self.item_refs.each |key, item_ref| {
|
2012-09-19 18:55:01 -05:00
|
|
|
match *item_ref {
|
2012-08-20 14:23:37 -05:00
|
|
|
None => {
|
2012-08-22 19:24:52 -05:00
|
|
|
self.session.err(fmt!("no item found for `%s`", key));
|
2012-07-25 20:36:18 -05:00
|
|
|
}
|
2012-08-20 14:23:37 -05:00
|
|
|
Some(_) => {
|
2012-07-25 20:36:18 -05:00
|
|
|
// OK.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn collect() {
|
|
|
|
self.collect_local_language_items();
|
|
|
|
self.collect_external_language_items();
|
|
|
|
self.check_completeness();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-15 16:56:42 -05:00
|
|
|
fn collect_language_items(crate: @crate, session: Session) -> LanguageItems {
|
|
|
|
let items = language_items::make();
|
2012-07-26 10:51:57 -05:00
|
|
|
let collector = LanguageItemCollector(crate, session, &items);
|
2012-07-25 20:36:18 -05:00
|
|
|
collector.collect();
|
2012-07-26 10:51:57 -05:00
|
|
|
copy items
|
2012-07-25 20:36:18 -05:00
|
|
|
}
|
|
|
|
|