Verified Commit ba23813e authored by Daniel García Moreno's avatar Daniel García Moreno Committed by Jordan Petridis

gir: Parse gir option and generate initial XML

parent dd215fa0
......@@ -172,6 +172,7 @@ dependencies = [
"rustfmt 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.14.7 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
......@@ -554,6 +555,11 @@ name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "xml-rs"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum aho-corasick 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c1c6d463cbe7ed28720b5b489e7c083eeb8f90d08be2a0d6bb9e1ffea9ce1afa"
"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
......@@ -622,3 +628,4 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
"checksum xml-rs 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "541b12c998c5b56aa2b4e6f18f03664eef9a4fd0a246a55594efae6cc2d964b5"
......@@ -21,6 +21,7 @@ quote = { version="0.6" }
rustfmt = "0.10.0"
syn = { version="0.14", features=["full"] }
unicode-xid = "0.0.4"
xml-rs = "0.8.0"
[dev-dependencies]
glib-sys = "0.6.0"
......@@ -2,7 +2,7 @@
use proc_macro2::Ident;
use syn::punctuated::Punctuated;
use syn::{Attribute, Lit};
use syn::{Block, FieldsNamed, FnArg, Path, ReturnType, Type};
use syn::{Block, FieldsNamed, FnArg, Path, ReturnType, Type, LitStr};
pub struct Program {
pub items: Vec<Item>,
......@@ -54,6 +54,7 @@ pub struct Class {
pub name: Ident,
pub extends: Option<Path>,
pub fields: FieldsNamed,
pub gir: Option<LitStr>,
}
// similar to syn::ItemImpl
......
use std::fs::File;
use std::io::prelude::*;
use xml::writer::{EventWriter, EmitterConfig, XmlEvent, Result};
use hir::{Program, Class};
use glib_utils::*;
use gen::names::Names;
// TODO: manage errors
pub fn generate(program: &Program) {
for class in program.classes.iter() {
generate_gir(class);
}
}
pub fn generate_gir(class: &Class) {
if let Some(ref s) = class.gir {
let mut f = File::create(&s.value()).unwrap();
let mut w = EmitterConfig::new()
.perform_indent(true)
.create_writer(&mut f);
let name = class.name.to_string();
let lower_name = lower_case_instance_name(&name).to_string();
let names = Names::new(&class.name, "Class");
w.write(XmlEvent::start_element("repository")
.attr("version", "1.2")
.attr("xmlns", "http://www.gtk.org/introspection/core/1.0")
.attr("xmlns:c", "http://www.gtk.org/introspection/c/1.0")
.attr("xmlns:glib", "http://www.gtk.org/introspection/glib/1.0"));
// TODO: include deps like
// <include name="GLib" version="2.0"/>
w.write(XmlEvent::start_element("namespace")
.attr("name", &name)
.attr("c:identifier-prefixes", &name)
.attr("c:symbol-prefixes", &lower_name)
//.attr("version", "1.0.0")
//.attr("shared-library", "lib.so.0")
);
w.write(XmlEvent::start_element("class")
.attr("name", &name)
.attr("c:type", &name)
.attr("glib:type-name", &name)
.attr("c:symbol-prefix", &lower_name)
.attr("glib:type-struct", &names.vtable().to_string())
.attr("glib:get-type", &names.get_type_fn().to_string())
//.attr("parent", "GObject.Object")
);
// TODO: add methods here
// closing class
w.write(XmlEvent::end_element());
// closing namespace
w.write(XmlEvent::end_element());
// closing repository
w.write(XmlEvent::end_element());
}
}
......@@ -15,6 +15,7 @@ mod properties;
mod signals;
mod signatures;
mod slots;
pub mod gir;
use self::class::ClassContext;
use self::interface::InterfaceContext;
......
......@@ -11,7 +11,7 @@ use std::collections::HashMap;
use proc_macro2::{Delimiter, Group, Ident, Span, TokenStream, TokenTree};
use quote::{ToTokens, TokenStreamExt};
use syn::punctuated::Punctuated;
use syn::{self, parse_str, Block, Field, Path, ReturnType, Type};
use syn::{self, parse_str, Block, Field, Path, ReturnType, Type, LitStr};
use super::ast;
use super::checking::*;
......@@ -34,6 +34,7 @@ pub struct Interfaces<'ast> {
#[cfg_attr(rustfmt, rustfmt_skip)]
pub struct Class<'ast> {
pub gir: Option<LitStr>,
pub name: Ident, // Foo
pub gobject_parent: bool,
pub parent: TokenStream, // Parent
......@@ -180,6 +181,7 @@ impl<'ast> Classes<'ast> {
ast_class.name.clone(),
Class {
name: ast_class.name.clone(),
gir: ast_class.gir.clone(),
gobject_parent: ast_class.extends.is_none(),
parent: tokens_ParentInstance(ast_class),
parent_ffi: tokens_ParentInstanceFfi(ast_class),
......
......@@ -13,6 +13,7 @@ extern crate proc_macro;
extern crate proc_macro2;
extern crate rustfmt;
extern crate unicode_xid;
extern crate xml;
#[macro_use]
extern crate syn;
......@@ -151,7 +152,11 @@ pub fn gobject_gen(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
};
let result: Result<proc_macro2::TokenStream> =
hir::Program::from_ast_program(&ast_program).and_then(|program| Ok(gen::codegen(&program)));
hir::Program::from_ast_program(&ast_program)
.and_then(|program| {
gen::gir::generate(&program);
Ok(gen::codegen(&program))
});
match result {
Ok(tokens) => {
......
......@@ -4,7 +4,7 @@ use proc_macro2::{Ident, TokenStream};
use syn::buffer::Cursor;
use syn::punctuated::Punctuated;
use syn::synom::{PResult, Synom};
use syn::{self, parse_error, FieldsNamed, Path};
use syn::{self, parse_error, FieldsNamed, Path, LitStr};
use ast;
use errors::*;
......@@ -39,6 +39,18 @@ impl Synom for ast::Item {
}
}
named!{parse_gir -> Option<LitStr>,
option!(do_parse!(
punct!(#) >>
name: brackets!(do_parse!(
call!(keyword("generate_gir")) >>
name: parens!(syn!(LitStr)) >>
(name.1)
)) >>
(name.1)
))
}
// class Foo [: SuperClass [, ImplementsIface]*] {
// struct FooPrivate {
// ...
......@@ -50,6 +62,7 @@ impl Synom for ast::Item {
// }
impl Synom for ast::Class {
named!(parse -> Self, do_parse!(
gir: call!(parse_gir) >>
call!(keyword("class")) >>
name: syn!(Ident) >>
extends: option!(do_parse!(
......@@ -59,6 +72,7 @@ impl Synom for ast::Class {
(superclass))) >>
fields: syn!(FieldsNamed) >>
(ast::Class {
gir,
name,
extends,
fields,
......
#![deny(warnings)]
#![feature(proc_macro_non_items, proc_macro_gen)]
extern crate gobject_gen;
#[macro_use]
extern crate glib;
use gobject_gen::gobject_gen;
use std::cell::Cell;
gobject_gen! {
#[generate_gir("Counter.gir")]
class Counter {
f: Cell<u32>,
}
impl Counter {
pub fn add(&self, x: u32) -> u32 {
self.get_priv().f.set(self.get() + x);
self.get()
}
pub fn get(&self) -> u32 {
self.get_priv().f.get()
}
}
}
#[test]
fn test() {
let c: Counter = Counter::new();
println!("Counter has value: {}", c.get());
c.add(2);
c.add(20);
assert_eq!(c.get(), 22);
println!("Counter has value: {}", c.get());
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment