Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,6 @@ Cargo.lock

# Graphiz
*.dot

# Idea
.idea
10 changes: 1 addition & 9 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ rust:
- beta
- nightly
os:
- osx
# - osx
- linux
addons:
apt:
Expand All @@ -29,11 +29,3 @@ script:
travis-cargo test
travis-cargo bench
travis-cargo doc -- --no-deps
after_success:
- touch target/doc/index.html
- travis-cargo --only nightly doc-upload
- travis-cargo coveralls --no-sudo --verify
env:
global:
- TRAVIS_CARGO_NIGHTLY_FEATURE="nightly"
- secure: "DKEIK2vaRCzWGkEv6fpPhkmszMQBD0lTP5PeNBQ4C6vtRWAGtHdqYxFuXtCIwE264tFYj9zoSZo9Bz+fWCOgvX2nQZwX6MRnMB+jaG+8jo0GynQs8L3Ldwj0MgJJ19+teEa5sR3IGZL94BGbG4bMPoUepTJRrGVXMXry38VFLUjLVBSB3pim7ivc2CWr++Y7s5Rdzrf26IrfjSSHHewW/acNZnSsdrivVt6VfziYVJFEEs6VSmR7Camgoc0VNjQLEP2fMYbnbMuQJ+ftQTYpdbdCoH2R+e3VFMLCpdIccE8RycA2mX1KRJXJSGXmtAhQ30brx1IoStHjtLct0NSQd86SVSjRlkDmyG6hGxehWA1V06HnUSLlJMw0hZT07jVpewmjcWfZAWm5Vg/jeC3qWLo/anVpTiH80CUukkCUZyXkKC6ePFfb84Cf8dgdEvxchUKIH6T6Q+/yePkmn2tKepXadgNgHpoJ6Yp89jJl1e+lEFgh1hw2Wy1rsAgwbKFwZ3/fGz6pDqm+vhfelmQhLHKdwERFIoFOhSjizjajD1CbHO+aZQjznguYO34x/MZ70ZyVB2MiIkn4ujsZ6U41KCS51QQa1XIZOVlNmcMx+GmZLg8eC/H/pwSKaM4LS4websJMjwhRw7EU227YzfefSW6krtushgrWa9s8pVacYT8="
13 changes: 3 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,6 @@ categories = ["visualization"]
travis-ci = { repository = "adjivas/ml", branch = "master" }
appveyor = { repository = "adjivas/ml", branch = "master", service = "github" }

[[bin]]
name = "ml"
doc = false
test = false

[lib]
test = false
doctest = true
Expand All @@ -36,11 +31,9 @@ unstable = [] # for building with unstable features on stable Rust
debug = [] # for building with debug messages
travis = ["lints", "nightly"] # for building with travis-cargo

[dependencies.syntex_syntax]
version = "0.59"

[dependencies.syntex_errors]
version = "0.59"
[dependencies]
syn = { features = [ "full", "default", "extra-traits", "derive", "parsing", "printing", "clone-impls", "proc-macro" ], version = "1.0" }
quote = "1.0"

[dependencies.rustc-serialize]
version = "0.3"
Expand Down
51 changes: 21 additions & 30 deletions src/core/item/mod.rs
Original file line number Diff line number Diff line change
@@ -1,52 +1,43 @@
pub mod relation;
pub mod state;
use std::rc::Rc;
use std::{iter, slice};

pub use self::state::ItemState;
use itertools::Itertools;

use std::{slice, iter};
use std::rc::Rc;
use module::path::ModulePath;

use ::syntex_syntax::{ptr, ast};
use ::itertools::Itertools;
pub use self::state::ItemState;

use ::module::path::ModulePath;
pub mod relation;
pub mod state;

/// The structure Item is a iterable collection of abstract elements.

#[derive(Debug, Clone)]
pub struct Item <'a> {
pub struct Item<'a> {
/// Iterator.
it: iter::Peekable<slice::Iter<'a, (ptr::P<ast::Item>, Rc<ModulePath>)>>,
it: iter::Peekable<slice::Iter<'a, (syn::Item, Rc<ModulePath>)>>,
}

impl <'a>From<iter::Peekable<slice::Iter<'a, (ptr::P<ast::Item>, Rc<ModulePath>)>>> for Item<'a> {

impl<'a> From<iter::Peekable<slice::Iter<'a, (syn::Item, Rc<ModulePath>)>>> for Item<'a> {
/// The constructor method `from` returns a typed and iterable collection of abstract element.
fn from(iter: iter::Peekable<slice::Iter<'a, (ptr::P<ast::Item>, Rc<ModulePath>)>>) -> Item {
Item {
it: iter,
}
fn from(iter: iter::Peekable<slice::Iter<'a, (syn::Item, Rc<ModulePath>)>>) -> Item {
Item { it: iter }
}
}

impl <'a>Iterator for Item<'a> {
impl<'a> Iterator for Item<'a> {
type Item = ItemState<'a>;

/// The method `next` will returns the first abstract elements defined like a structure,
/// enumeration or trait.
fn next(&mut self) -> Option<ItemState<'a>> {
self.it.next().and_then(|item| {
let mut list: Vec<&'a (ptr::P<ast::Item>, Rc<ModulePath>)> = vec!(item);

list.extend(self.it.peeking_take_while(|&&(ref item, _): (&&'a (ptr::P<ast::Item>, Rc<ModulePath>))| {
if let ast::ItemKind::Impl(..) = item.node {
true
} else {
false
}
})
.collect::<Vec<&'a (ptr::P<ast::Item>, Rc<ModulePath>)>>());
Some(ItemState::from(list))
self.it.next().map(|item| {
let mut list: Vec<&'a (syn::Item, Rc<ModulePath>)> = vec![item];

list.extend(
self.it
.peeking_take_while(|(item, _)| matches!(item, syn::Item::Impl(_))),
);
ItemState::from(list)
})
}
}
19 changes: 9 additions & 10 deletions src/core/item/relation.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::ItemState;
use dot::{ArrowShape, Fill, Side};

use ::dot::{Fill, ArrowShape, Side};
use super::ItemState;

/// The enumeration `Relation` is the relationship specification from [UML 2.5](http://www.omg.org/spec/UML/2.5) without generalization.
#[derive(Debug, Copy, Clone)]
Expand All @@ -14,21 +14,20 @@ pub enum Relation {
}

impl Relation {

/// The method `as_style` returns a stylized arrow (See *Table B.2 UML Edges* from [UML 2.5](http://www.omg.org/spec/UML/2.5).
pub fn as_style(&self) -> ArrowShape {
match self {
&Relation::Association => ArrowShape::Vee(Side::Both),
&Relation::Dependency => ArrowShape::Vee(Side::Both),
&Relation::Aggregation => ArrowShape::Diamond(Fill::Open, Side::Both),
&Relation::Composition => ArrowShape::Diamond(Fill::Filled, Side::Both),
&Relation::Realization => ArrowShape::Normal(Fill::Open, Side::Both),
&Relation::None => ArrowShape::NoArrow,
Relation::Association => ArrowShape::Vee(Side::Both),
Relation::Dependency => ArrowShape::Vee(Side::Both),
Relation::Aggregation => ArrowShape::Diamond(Fill::Open, Side::Both),
Relation::Composition => ArrowShape::Diamond(Fill::Filled, Side::Both),
Relation::Realization => ArrowShape::Normal(Fill::Open, Side::Both),
Relation::None => ArrowShape::NoArrow,
}
}
}

impl <'a>From<(&'a ItemState<'a>, &'a ItemState<'a>)> for Relation {
impl<'a> From<(&'a ItemState<'a>, &'a ItemState<'a>)> for Relation {
fn from((left, right): (&'a ItemState<'a>, &'a ItemState<'a>)) -> Relation {
if left.is_composition(right) {
Relation::Composition
Expand Down
108 changes: 63 additions & 45 deletions src/core/item/state/abstraction/enumerate.rs
Original file line number Diff line number Diff line change
@@ -1,71 +1,89 @@
use std::fmt;
use std::rc::Rc;

use ::syntex_syntax::print::pprust::ty_to_string;
use ::syntex_syntax::{codemap, symbol, ast};
use dot::escape_html;
use quote::ToTokens;
use syn::{Field, TypeParam, Variant};

use ::module::path::ModulePath;

use ::dot::escape_html;
use module::path::ModulePath;

/// The structure `Enum` is a enumerate abstract element.

#[derive(Debug, Eq, PartialEq, Clone)]
pub struct Enum<'a> {
pub path: Rc<ModulePath>,
/// Visibility
pub vis: &'a ast::Visibility,
pub name: symbol::InternedString,
pub params: Vec<symbol::InternedString>,
pub variants: Vec<(symbol::InternedString, Vec<String>)>,
pub vis: &'a syn::Visibility,
pub name: String,
pub params: Vec<String>,
pub variants: Vec<(String, Vec<String>)>,
}

impl <'a>From<((&'a ast::Item, &'a Vec<ast::TyParam>, &'a Vec<ast::Variant>), Rc<ModulePath>)> for Enum<'a> {
fn from(((item, ty_params, variants), path): ((&'a ast::Item, &'a Vec<ast::TyParam>, &'a Vec<ast::Variant>), Rc<ModulePath>)) -> Enum<'a> {
impl<'a>
From<(
(&'a syn::ItemEnum, &'a Vec<TypeParam>, &'a Vec<Variant>),
Rc<ModulePath>,
)> for Enum<'a>
{
fn from(
((item, ty_params, variants), path): (
(&'a syn::ItemEnum, &'a Vec<TypeParam>, &'a Vec<Variant>),
Rc<ModulePath>,
),
) -> Enum<'a> {
Enum {
path: path,
path,
vis: &item.vis,
name: item.ident.name.as_str(),
params: ty_params.iter()
.map(|&ast::TyParam {attrs: _, ident: ast::Ident {name, ..}, ..}| name.as_str())
.collect::<Vec<symbol::InternedString>>(),
variants: variants.iter()
.map(|&codemap::Spanned {node: ast::Variant_ {name: ast::Ident {name, ..}, attrs: _, ref data, ..}, ..}| {
if let &ast::VariantData::Tuple(ref struct_field, _) = data {
(name.as_str(),
struct_field.iter()
.filter_map(|&ast::StructField { span: _, ident: _, vis: _, id: _, ref ty, .. }| Some(ty_to_string(&ty)))
.collect::<Vec<String>>())
} else {
(name.as_str(), Vec::new())
}
})
.collect::<Vec<(symbol::InternedString, Vec<String>)>>(),
name: item.ident.to_string(),
params: ty_params
.iter()
.map(|param| param.ident.to_string())
.collect(),
variants: variants
.iter()
.map(|Variant { ident, fields, .. }| {
(
ident.to_string(),
if fields.is_empty() {
vec![]
} else {
fields
.iter()
.map(|Field { ty, .. }| ty.to_token_stream().to_string())
.collect()
},
)
})
.collect(),
}
}
}

impl <'a>fmt::Display for Enum<'a> {
impl<'a> fmt::Display for Enum<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.variants.is_empty() {
write!(f, "&lt;&lt;&lt;Enumeration&gt;&gt;&gt;\n{name}", name = self.name)
write!(
f,
"&lt;&lt;&lt;Enumeration&gt;&gt;&gt;\n{name}",
name = self.name
)
} else {
write!(f, "&lt;&lt;&lt;Enumeration&gt;&gt;&gt;\n{name}|{variants}",
write!(
f,
"&lt;&lt;&lt;Enumeration&gt;&gt;&gt;\n{name}|{variants}",
name = self.name,
variants = escape_html(self.variants.iter()
.map(|&(ref name, ref struct_field): &(symbol::InternedString, Vec<String>)|
if struct_field.is_empty() {
format!("{}", name)
} else {
format!("{}({})", name, struct_field.join(", "))
}
)
.collect::<Vec<String>>()
.join("\n")
.as_str()),
variants = escape_html(
self.variants
.iter()
.map(|(name, struct_field)| if struct_field.is_empty() {
name.to_owned()
} else {
format!("{}({})", name, struct_field.join(", "))
})
.collect::<Vec<String>>()
.join("\n")
.as_str()
),
)
}
}
}


Loading