rust_jni_generator/
lib.rs

1#![recursion_limit = "1024"]
2
3extern crate proc_macro;
4#[macro_use]
5extern crate quote;
6extern crate proc_macro2;
7extern crate rust_jni;
8
9use proc_macro2::*;
10use quote::ToTokens;
11use std::collections::{HashMap, HashSet};
12use std::hash::{Hash, Hasher};
13use std::iter::{self, FromIterator};
14use std::ops::Deref;
15
16/// Generate `rust-jni` wrappers for Java classes and interfaces.
17///
18/// TODO(#76): examples.
19#[proc_macro]
20pub fn java_generate(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
21    let input: TokenStream = input.into();
22    java_generate_impl(input).into()
23}
24
25fn java_generate_impl(input: TokenStream) -> TokenStream {
26    generate(to_generator_data(parse_java_definition(input)))
27}
28
29#[derive(Debug, Clone)]
30struct JavaName(TokenStream);
31
32impl Deref for JavaName {
33    type Target = TokenStream;
34
35    fn deref(&self) -> &TokenStream {
36        &self.0
37    }
38}
39
40impl ToTokens for JavaName {
41    fn to_tokens(&self, stream: &mut TokenStream) {
42        self.0.to_tokens(stream)
43    }
44}
45
46impl Hash for JavaName {
47    fn hash<H: Hasher>(&self, state: &mut H) {
48        self.to_string().hash(state);
49    }
50}
51
52impl PartialEq for JavaName {
53    fn eq(&self, other: &Self) -> bool {
54        format!("{:?}", self) == format!("{:?}", other)
55    }
56}
57
58impl Eq for JavaName {}
59
60#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
61struct FlatMapThreaded<I, F, S> {
62    iterator: I,
63    function: F,
64    state: S,
65}
66
67impl<I, F, S, T> Iterator for FlatMapThreaded<I, F, S>
68where
69    I: Iterator<Item = T>,
70    F: FnMut(&T, &S) -> S,
71{
72    type Item = T;
73
74    fn next(&mut self) -> Option<T> {
75        match self.iterator.next() {
76            None => None,
77            Some(value) => {
78                self.state = (self.function)(&value, &self.state);
79                Some(value)
80            }
81        }
82    }
83}
84
85fn flat_map_threaded<I, T, F, S>(iterator: I, initial: S, function: F) -> FlatMapThreaded<I, F, S>
86where
87    I: Iterator<Item = T>,
88    F: FnMut(&T, &S) -> S,
89{
90    FlatMapThreaded {
91        iterator,
92        function,
93        state: initial,
94    }
95}
96
97impl JavaName {
98    fn from_tokens<'a>(tokens: impl Iterator<Item = &'a TokenTree>) -> JavaName {
99        let tokens = flat_map_threaded(tokens, false, |token, was_identifier| {
100            match (token, was_identifier) {
101                (TokenTree::Ident(_), false) => true,
102                (TokenTree::Punct(punct), true) => {
103                    if punct.as_char() != '.' {
104                        panic!("Expected a dot, got {:?}.", punct);
105                    }
106                    false
107                }
108                (token, true) => {
109                    panic!("Expected a dot, got {:?}.", token);
110                }
111                (token, false) => {
112                    panic!("Expected an identifier, got {:?}.", token);
113                }
114            }
115        }).filter(|token| match token {
116            TokenTree::Ident(_) => true,
117            _ => false,
118        });
119        let tokens = TokenStream::from_iter(tokens.cloned());
120        if tokens.is_empty() {
121            panic!("Expected a Java name, got no tokens.");
122        }
123        JavaName(tokens)
124    }
125
126    fn name(self) -> Ident {
127        match self.0.into_iter().last().unwrap() {
128            TokenTree::Ident(identifier) => identifier,
129            token => panic!("Expected an identifier, got {:?}", token),
130        }
131    }
132
133    fn with_slashes(self) -> String {
134        self.0
135            .into_iter()
136            .map(|token| token.to_string())
137            .collect::<Vec<_>>()
138            .join("/")
139    }
140
141    fn with_underscores(self) -> String {
142        self.0
143            .into_iter()
144            .map(|token| token.to_string())
145            .collect::<Vec<_>>()
146            .join("_")
147    }
148
149    fn with_double_colons(self) -> TokenStream {
150        let mut tokens = vec![];
151        for token in self.0.into_iter() {
152            tokens.extend(quote!{::});
153            tokens.push(token);
154        }
155        TokenStream::from_iter(tokens.iter().cloned())
156    }
157
158    fn with_dots(self) -> TokenStream {
159        let mut tokens = vec![];
160        let mut first = true;
161        for token in self.0.into_iter() {
162            if first {
163                first = false;
164            } else {
165                tokens.extend(quote!{.});
166            }
167            tokens.push(token);
168        }
169        TokenStream::from_iter(tokens.iter().cloned())
170    }
171
172    fn as_primitive_type(&self) -> Option<TokenStream> {
173        let tokens = self.clone().0.into_iter().collect::<Vec<_>>();
174        if tokens.len() == 1 {
175            let token = &tokens[0];
176            if is_identifier(&token, "int") {
177                Some(quote!{i32})
178            } else if is_identifier(&token, "long") {
179                Some(quote!{i64})
180            } else if is_identifier(&token, "char") {
181                Some(quote!{char})
182            } else if is_identifier(&token, "byte") {
183                Some(quote!{u8})
184            } else if is_identifier(&token, "boolean") {
185                Some(quote!{bool})
186            } else if is_identifier(&token, "float") {
187                Some(quote!{f32})
188            } else if is_identifier(&token, "double") {
189                Some(quote!{f64})
190            } else if is_identifier(&token, "void") {
191                Some(quote!{()})
192            } else if is_identifier(&token, "short") {
193                Some(quote!{i64})
194            } else {
195                None
196            }
197        } else {
198            None
199        }
200    }
201
202    fn get_jni_signature(&self) -> String {
203        let tokens = self.clone().0.into_iter().collect::<Vec<_>>();
204        if tokens.len() == 1 {
205            let token = &tokens[0];
206            if is_identifier(&token, "int") {
207                <i32 as rust_jni::JavaType>::__signature().to_owned()
208            } else if is_identifier(&token, "long") {
209                <i64 as rust_jni::JavaType>::__signature().to_owned()
210            } else if is_identifier(&token, "char") {
211                <char as rust_jni::JavaType>::__signature().to_owned()
212            } else if is_identifier(&token, "byte") {
213                <u8 as rust_jni::JavaType>::__signature().to_owned()
214            } else if is_identifier(&token, "boolean") {
215                <bool as rust_jni::JavaType>::__signature().to_owned()
216            } else if is_identifier(&token, "float") {
217                panic!(
218                    "float values are not supported for not. \
219                     See https://github.com/Monnoroch/rust-jni/issues/25 for more details"
220                )
221            } else if is_identifier(&token, "double") {
222                <f64 as rust_jni::JavaType>::__signature().to_owned()
223            } else if is_identifier(&token, "void") {
224                <() as rust_jni::JavaType>::__signature().to_owned()
225            } else if is_identifier(&token, "short") {
226                <i16 as rust_jni::JavaType>::__signature().to_owned()
227            } else {
228                format!("L{}_2", self.clone().with_underscores())
229            }
230        } else {
231            format!("L{}_2", self.clone().with_underscores())
232        }
233    }
234
235    fn as_rust_type(self) -> TokenStream {
236        let primitive = self.as_primitive_type();
237        let with_double_colons = self.with_double_colons();
238        primitive.unwrap_or(quote!{#with_double_colons <'a>})
239    }
240
241    fn as_rust_type_no_lifetime(self) -> TokenStream {
242        let primitive = self.as_primitive_type();
243        let with_double_colons = self.with_double_colons();
244        primitive.unwrap_or(quote!{#with_double_colons})
245    }
246
247    fn as_rust_type_reference(self) -> TokenStream {
248        let primitive = self.as_primitive_type();
249        let with_double_colons = self.with_double_colons();
250        primitive.unwrap_or(quote!{& #with_double_colons <'a>})
251    }
252}
253
254#[derive(Debug, Clone)]
255struct Annotation {
256    name: Ident,
257    value: TokenStream,
258}
259
260impl PartialEq for Annotation {
261    fn eq(&self, other: &Self) -> bool {
262        format!("{:?}", self) == format!("{:?}", other)
263    }
264}
265
266impl Eq for Annotation {}
267
268#[derive(Debug, PartialEq, Eq, Clone)]
269struct MethodArgument {
270    name: Ident,
271    data_type: JavaName,
272}
273
274#[derive(Debug, PartialEq, Eq, Clone)]
275struct JavaInterfaceMethod {
276    name: Ident,
277    return_type: JavaName,
278    arguments: Vec<MethodArgument>,
279    annotations: Vec<Annotation>,
280}
281
282#[derive(Debug, PartialEq, Eq, Clone)]
283struct JavaClassMethod {
284    name: Ident,
285    return_type: JavaName,
286    arguments: Vec<MethodArgument>,
287    public: bool,
288    is_static: bool,
289    annotations: Vec<Annotation>,
290}
291
292#[derive(Debug, Clone)]
293struct JavaNativeMethod {
294    name: Ident,
295    return_type: JavaName,
296    arguments: Vec<MethodArgument>,
297    public: bool,
298    is_static: bool,
299    code: Group,
300    annotations: Vec<Annotation>,
301}
302
303impl PartialEq for JavaNativeMethod {
304    fn eq(&self, other: &Self) -> bool {
305        format!("{:?}", self) == format!("{:?}", other)
306    }
307}
308
309impl Eq for JavaNativeMethod {}
310
311#[derive(Debug, PartialEq, Eq, Clone)]
312struct JavaConstructor {
313    arguments: Vec<MethodArgument>,
314    public: bool,
315    annotations: Vec<Annotation>,
316}
317
318#[derive(Debug, PartialEq, Eq, Clone)]
319struct JavaClass {
320    extends: Option<JavaName>,
321    implements: Vec<JavaName>,
322    methods: Vec<JavaClassMethod>,
323    native_methods: Vec<JavaNativeMethod>,
324    constructors: Vec<JavaConstructor>,
325}
326
327#[derive(Debug, PartialEq, Eq, Clone)]
328struct JavaInterface {
329    methods: Vec<JavaInterfaceMethod>,
330    extends: Vec<JavaName>,
331}
332
333#[derive(Debug, PartialEq, Eq, Clone)]
334enum JavaDefinitionKind {
335    Class(JavaClass),
336    Interface(JavaInterface),
337}
338
339#[derive(Debug, PartialEq, Eq, Clone)]
340struct JavaDefinition {
341    name: JavaName,
342    public: bool,
343    definition: JavaDefinitionKind,
344}
345
346#[derive(Debug, PartialEq, Eq, Clone)]
347struct JavaClassMetadata {
348    extends: Option<JavaName>,
349    implements: Vec<JavaName>,
350}
351
352#[derive(Debug, PartialEq, Eq, Clone)]
353struct JavaInterfaceMetadata {
354    extends: Vec<JavaName>,
355    methods: Vec<JavaInterfaceMethod>,
356}
357
358#[derive(Debug, PartialEq, Eq, Clone)]
359enum JavaDefinitionMetadataKind {
360    Class(JavaClassMetadata),
361    Interface(JavaInterfaceMetadata),
362}
363
364#[derive(Debug, PartialEq, Eq, Clone)]
365struct JavaDefinitionMetadata {
366    name: JavaName,
367    definition: JavaDefinitionMetadataKind,
368}
369
370#[derive(Debug, PartialEq, Eq, Clone)]
371struct Metadata {
372    definitions: Vec<JavaDefinitionMetadata>,
373}
374
375#[derive(Debug, PartialEq, Eq, Clone)]
376struct JavaDefinitions {
377    definitions: Vec<JavaDefinition>,
378    metadata: Metadata,
379}
380
381fn parse_annotation(tokens: &[TokenTree]) -> Annotation {
382    let name = match tokens[0] {
383        TokenTree::Ident(ref identifier) => identifier.clone(),
384        _ => unreachable!(),
385    };
386    let value = match tokens[1] {
387        TokenTree::Group(ref group) => group.stream(),
388        _ => unreachable!(),
389    };
390    Annotation {
391        name,
392        value: TokenStream::from_iter(value.into_iter()),
393    }
394}
395
396fn parse_annotations(tokens: &[TokenTree]) -> Vec<Annotation> {
397    if tokens.len() == 0 {
398        vec![]
399    } else {
400        match tokens[0] {
401            TokenTree::Punct(ref punct) => {
402                if punct.spacing() == Spacing::Alone && punct.as_char() == '@' {
403                    tokens
404                        .split(|token| match token {
405                            TokenTree::Punct(punct) => {
406                                punct.spacing() == Spacing::Alone && punct.as_char() == '@'
407                            }
408                            _ => false,
409                        })
410                        .filter(|slice| !slice.is_empty())
411                        .map(parse_annotation)
412                        .collect()
413                } else {
414                    vec![]
415                }
416            }
417            _ => vec![],
418        }
419    }
420}
421
422fn comma_separated_names(tokens: impl Iterator<Item = TokenTree>) -> Vec<JavaName> {
423    let tokens = tokens.collect::<Vec<_>>();
424    tokens
425        .split(|token| match token {
426            TokenTree::Punct(punct) => punct.spacing() == Spacing::Alone && punct.as_char() == ',',
427            _ => false,
428        })
429        .filter(|slice| !slice.is_empty())
430        .map(|slice| JavaName::from_tokens(slice.iter()))
431        .collect()
432}
433
434fn parse_interface_header(header: &[TokenTree]) -> (JavaName, Vec<JavaName>) {
435    let name = JavaName::from_tokens(
436        header
437            .iter()
438            .take_while(|token| !is_identifier(&token, "extends")),
439    );
440    let extends = comma_separated_names(
441        header
442            .iter()
443            .skip_while(|token| !is_identifier(&token, "extends"))
444            .skip(1)
445            .cloned(),
446    );
447    (name, extends)
448}
449
450fn parse_class_header(header: &[TokenTree]) -> (JavaName, Option<JavaName>, Vec<JavaName>) {
451    let name = JavaName::from_tokens(header.iter().take_while(|token| {
452        !is_identifier(&token, "extends") && !is_identifier(&token, "implements")
453    }));
454    let implements = comma_separated_names(
455        header
456            .iter()
457            .skip_while(|token| !is_identifier(&token, "implements"))
458            .skip(1)
459            .cloned(),
460    );
461    let has_extends = header
462        .iter()
463        .filter(|token| is_identifier(&token, "extends"))
464        .next()
465        .is_some();
466    let extends = if has_extends {
467        Some(JavaName::from_tokens(
468            header
469                .iter()
470                .skip_while(|token| !is_identifier(&token, "extends"))
471                .skip(1)
472                .take_while(|token| !is_identifier(&token, "implements")),
473        ))
474    } else {
475        None
476    };
477    (name, extends, implements)
478}
479
480fn parse_metadata(tokens: TokenStream) -> Metadata {
481    let definitions = tokens.clone().into_iter().collect::<Vec<_>>();
482    let definitions = definitions
483        .split(is_metadata_definition)
484        .filter(|tokens| !tokens.is_empty())
485        .map(|header| {
486            let (token, header) = header.split_first().unwrap();
487            let is_class = is_identifier(&token, "class");
488            let is_interface = is_identifier(&token, "interface");
489            if !is_class && !is_interface {
490                panic!("Expected \"class\" or \"interface\", got {:?}.", token);
491            }
492
493            if is_interface {
494                let (name, extends) = parse_interface_header(header);
495                JavaDefinitionMetadata {
496                    name,
497                    definition: JavaDefinitionMetadataKind::Interface(JavaInterfaceMetadata {
498                        extends,
499                        methods: vec![],
500                    }),
501                }
502            } else {
503                let (name, extends, implements) = parse_class_header(header);
504                JavaDefinitionMetadata {
505                    name,
506                    definition: JavaDefinitionMetadataKind::Class(JavaClassMetadata {
507                        extends,
508                        implements,
509                    }),
510                }
511            }
512        })
513        .zip(definitions.iter().cloned().filter(is_metadata_definition))
514        .map(|(definition, token)| match token {
515            TokenTree::Group(group) => (definition, group.stream()),
516            TokenTree::Punct(_) => (definition, TokenStream::new()),
517            _ => unreachable!(),
518        })
519        .map(|(definition, tokens)| {
520            let java_definition = match definition.definition.clone() {
521                JavaDefinitionMetadataKind::Interface(interface) => {
522                    let methods = tokens.into_iter().collect::<Vec<_>>();
523                    let methods = methods
524                        .split(|token| is_punctuation(token, ';'))
525                        .filter(|tokens| !tokens.is_empty())
526                        .map(parse_interface_method)
527                        .collect::<Vec<_>>();
528                    JavaDefinitionMetadataKind::Interface(JavaInterfaceMetadata {
529                        methods,
530                        ..interface
531                    })
532                }
533                definition => definition,
534            };
535            JavaDefinitionMetadata {
536                definition: java_definition,
537                ..definition
538            }
539        })
540        .collect();
541    Metadata { definitions }
542}
543
544fn is_constructor(tokens: &[TokenTree], class_name: &JavaName) -> bool {
545    let class_name_len = class_name
546        .clone()
547        .with_dots()
548        .into_iter()
549        .collect::<Vec<_>>()
550        .len();
551    if tokens.len() <= class_name_len {
552        return false;
553    }
554    let tokens = &tokens[tokens.len() - class_name_len - 1..tokens.len() - 1];
555    TokenStream::from_iter(tokens.iter().cloned()).to_string()
556        == class_name.clone().with_dots().to_string()
557}
558
559fn parse_method_arguments(token: TokenTree) -> Vec<MethodArgument> {
560    match token {
561        TokenTree::Group(group) => {
562            if group.delimiter() != Delimiter::Parenthesis {
563                panic!("Expected method arguments in parenthesis, got {:?}.", group);
564            }
565            let arguments = group.stream().into_iter().collect::<Vec<_>>();
566            arguments
567                .split(|token| is_punctuation(token, ','))
568                .filter(|tokens| !tokens.is_empty())
569                .map(|tokens| tokens.split_last().unwrap())
570                .map(|(last, others)| {
571                    let name = match last {
572                        TokenTree::Ident(ident) => ident.clone(),
573                        token => panic!("Expected argument name, got {:?}.", token),
574                    };
575                    MethodArgument {
576                        name,
577                        data_type: JavaName::from_tokens(others.iter()),
578                    }
579                })
580                .collect::<Vec<_>>()
581        }
582        token => panic!("Expected method arguments, got {:?}.", token),
583    }
584}
585
586fn parse_method(tokens: &[TokenTree]) -> JavaClassMethod {
587    let public = tokens.iter().any(|token| is_identifier(token, "public"));
588    let is_static = tokens.iter().any(|token| is_identifier(token, "static"));
589    let tokens = tokens
590        .iter()
591        .filter(|token| !is_identifier(token, "public") && !is_identifier(token, "static"))
592        .cloned()
593        .collect::<Vec<_>>();
594    let name = match tokens[tokens.len() - 2].clone() {
595        TokenTree::Ident(ident) => ident,
596        token => panic!("Expected method name, got {:?}.", token),
597    };
598    let annotations = parse_annotations(&tokens[0..tokens.len() - 2]);
599    let return_type = JavaName::from_tokens(
600        tokens[0..tokens.len() - 2]
601            .iter()
602            .skip(3 * annotations.len()),
603    );
604    let arguments = parse_method_arguments(tokens[tokens.len() - 1].clone());
605    JavaClassMethod {
606        public,
607        name,
608        return_type,
609        arguments,
610        is_static,
611        annotations,
612    }
613}
614
615fn parse_interface_method(tokens: &[TokenTree]) -> JavaInterfaceMethod {
616    let tokens = tokens.iter().cloned().collect::<Vec<_>>();
617    let name = match tokens[tokens.len() - 2].clone() {
618        TokenTree::Ident(ident) => ident,
619        token => panic!("Expected method name, got {:?}.", token),
620    };
621    let annotations = parse_annotations(&tokens[0..tokens.len() - 2]);
622    let return_type = JavaName::from_tokens(
623        tokens[0..tokens.len() - 2]
624            .iter()
625            .skip(3 * annotations.len()),
626    );
627    let arguments = parse_method_arguments(tokens[tokens.len() - 1].clone());
628    JavaInterfaceMethod {
629        name,
630        return_type,
631        arguments,
632        annotations,
633    }
634}
635
636fn parse_native_method(tokens: &[TokenTree]) -> JavaNativeMethod {
637    let public = tokens.iter().any(|token| is_identifier(token, "public"));
638    let is_static = tokens.iter().any(|token| is_identifier(token, "static"));
639    let tokens = tokens
640        .iter()
641        .filter(|token| {
642            !is_identifier(token, "public")
643                && !is_identifier(token, "static")
644                && !is_identifier(token, "native")
645        })
646        .cloned()
647        .collect::<Vec<_>>();
648    let code = match tokens[tokens.len() - 1].clone() {
649        TokenTree::Group(group) => {
650            if group.delimiter() == Delimiter::Brace {
651                group
652            } else {
653                panic!("Expected method code in braces, got {:?}.", group)
654            }
655        }
656        token => panic!("Expected method code, got {:?}.", token),
657    };
658    let name = match tokens[tokens.len() - 3].clone() {
659        TokenTree::Ident(ident) => ident,
660        token => panic!("Expected method name, got {:?}.", token),
661    };
662    let annotations = parse_annotations(&tokens[0..tokens.len() - 3]);
663    let return_type = JavaName::from_tokens(
664        tokens[0..tokens.len() - 3]
665            .iter()
666            .skip(3 * annotations.len()),
667    );
668    let arguments = parse_method_arguments(tokens[tokens.len() - 2].clone());
669    JavaNativeMethod {
670        public,
671        name,
672        return_type,
673        arguments,
674        is_static,
675        code,
676        annotations,
677    }
678}
679
680fn parse_constructor(tokens: &[TokenTree]) -> JavaConstructor {
681    let public = tokens.iter().any(|token| is_identifier(token, "public"));
682    let tokens = tokens
683        .iter()
684        .filter(|token| !is_identifier(token, "public"))
685        .cloned()
686        .collect::<Vec<_>>();
687    let annotations = parse_annotations(&tokens[0..tokens.len() - 1]);
688    let arguments = parse_method_arguments(tokens[tokens.len() - 1].clone());
689    JavaConstructor {
690        public,
691        arguments,
692        annotations,
693    }
694}
695
696fn parse_java_definition(input: TokenStream) -> JavaDefinitions {
697    let mut definitions = input.clone().into_iter().collect::<Vec<_>>();
698    let metadata = if definitions.len() > 1
699        && is_identifier(&definitions[definitions.len() - 2], "metadata")
700    {
701        match definitions.pop().unwrap() {
702            TokenTree::Group(group) => {
703                if group.delimiter() == Delimiter::Brace {
704                    let metadata = parse_metadata(group.stream());
705                    definitions.pop().unwrap();
706                    metadata
707                } else {
708                    panic!("Expected braces, got {:?}.", group)
709                }
710            }
711            token => panic!("Expected braces, got {:?}.", token),
712        }
713    } else {
714        Metadata {
715            definitions: vec![],
716        }
717    };
718    let definitions = definitions
719        .split(is_definition)
720        .filter(|tokens| !tokens.is_empty())
721        .map(|header| {
722            let (token, header) = header.split_first().unwrap();
723            let public = is_identifier(&token, "public");
724            let (token, header) = if public {
725                header.split_first().unwrap()
726            } else {
727                (token, header)
728            };
729            let is_class = is_identifier(&token, "class");
730            let is_interface = is_identifier(&token, "interface");
731            if !is_class && !is_interface {
732                panic!("Expected \"class\" or \"interface\", got {:?}.", token);
733            }
734
735            if is_interface {
736                let (name, extends) = parse_interface_header(header);
737                JavaDefinition {
738                    name,
739                    public,
740                    definition: JavaDefinitionKind::Interface(JavaInterface {
741                        methods: vec![],
742                        extends,
743                    }),
744                }
745            } else {
746                let (name, extends, implements) = parse_class_header(header);
747                JavaDefinition {
748                    name,
749                    public,
750                    definition: JavaDefinitionKind::Class(JavaClass {
751                        extends,
752                        implements,
753                        methods: vec![],
754                        native_methods: vec![],
755                        constructors: vec![],
756                    }),
757                }
758            }
759        })
760        .zip(definitions.iter().cloned().filter(is_definition))
761        .map(|(definition, token)| match token {
762            TokenTree::Group(group) => (definition, group.stream()),
763            _ => unreachable!(),
764        })
765        .map(|(definition, tokens)| {
766            let methods = tokens.into_iter().collect::<Vec<_>>();
767            let java_definition = match definition.definition.clone() {
768                JavaDefinitionKind::Class(class) => {
769                    let constructors = methods
770                        .split(|token| is_punctuation(token, ';'))
771                        .filter(|tokens| !tokens.is_empty())
772                        .filter(|tokens| is_constructor(tokens, &definition.name))
773                        .map(parse_constructor)
774                        .collect::<Vec<_>>();
775                    let native_methods = methods
776                        .split(|token| is_punctuation(token, ';'))
777                        .filter(|tokens| !tokens.is_empty())
778                        .filter(|tokens| !is_constructor(tokens, &definition.name))
779                        .filter(|tokens| tokens.iter().any(|token| is_identifier(token, "native")))
780                        .map(parse_native_method)
781                        .collect::<Vec<_>>();
782                    let methods = methods
783                        .split(|token| is_punctuation(token, ';'))
784                        .filter(|tokens| !tokens.is_empty())
785                        .filter(|tokens| !is_constructor(tokens, &definition.name))
786                        .filter(|tokens| !tokens.iter().any(|token| is_identifier(token, "native")))
787                        .map(parse_method)
788                        .collect::<Vec<_>>();
789                    JavaDefinitionKind::Class(JavaClass {
790                        methods,
791                        native_methods,
792                        constructors,
793                        ..class
794                    })
795                }
796                JavaDefinitionKind::Interface(interface) => {
797                    let methods = methods
798                        .split(|token| is_punctuation(token, ';'))
799                        .filter(|tokens| !tokens.is_empty())
800                        .map(parse_interface_method)
801                        .collect::<Vec<_>>();
802                    JavaDefinitionKind::Interface(JavaInterface {
803                        methods,
804                        ..interface
805                    })
806                }
807            };
808            JavaDefinition {
809                definition: java_definition,
810                ..definition
811            }
812        })
813        .collect();
814    JavaDefinitions {
815        definitions,
816        metadata,
817    }
818}
819
820fn is_punctuation(token: &TokenTree, value: char) -> bool {
821    match token {
822        TokenTree::Punct(punct) => punct.spacing() == Spacing::Alone && punct.as_char() == value,
823        _ => false,
824    }
825}
826
827fn is_identifier(token: &TokenTree, name: &str) -> bool {
828    match token {
829        TokenTree::Ident(identifier) => identifier == name,
830        _ => false,
831    }
832}
833
834fn is_definition(token: &TokenTree) -> bool {
835    match token {
836        TokenTree::Group(group) => group.delimiter() == Delimiter::Brace,
837        _ => false,
838    }
839}
840
841fn is_metadata_definition(token: &TokenTree) -> bool {
842    match token {
843        TokenTree::Group(group) => group.delimiter() == Delimiter::Brace,
844        TokenTree::Punct(puntuation) => puntuation.as_char() == ';',
845        _ => false,
846    }
847}
848
849#[cfg(test)]
850mod parse_tests {
851    use super::*;
852
853    #[test]
854    fn empty() {
855        let input = quote!{};
856        assert_eq!(
857            parse_java_definition(input),
858            JavaDefinitions {
859                definitions: vec![],
860                metadata: Metadata {
861                    definitions: vec![],
862                },
863            }
864        );
865    }
866
867    #[test]
868    fn one_class() {
869        let input = quote!{
870            class TestClass1 {}
871        };
872        assert_eq!(
873            parse_java_definition(input),
874            JavaDefinitions {
875                definitions: vec![JavaDefinition {
876                    name: JavaName(quote!{TestClass1}),
877                    public: false,
878                    definition: JavaDefinitionKind::Class(JavaClass {
879                        extends: None,
880                        implements: vec![],
881                        methods: vec![],
882                        native_methods: vec![],
883                        constructors: vec![],
884                    }),
885                }],
886                metadata: Metadata {
887                    definitions: vec![],
888                },
889            }
890        );
891    }
892
893    #[test]
894    fn one_class_extends() {
895        let input = quote!{
896            class TestClass1 extends test1 {}
897        };
898        assert_eq!(
899            parse_java_definition(input),
900            JavaDefinitions {
901                definitions: vec![JavaDefinition {
902                    name: JavaName(quote!{TestClass1}),
903                    public: false,
904                    definition: JavaDefinitionKind::Class(JavaClass {
905                        extends: Some(JavaName(quote!{test1})),
906                        implements: vec![],
907                        methods: vec![],
908                        native_methods: vec![],
909                        constructors: vec![],
910                    }),
911                }],
912                metadata: Metadata {
913                    definitions: vec![],
914                },
915            }
916        );
917    }
918
919    #[test]
920    fn one_class_public() {
921        let input = quote!{
922            public class TestClass1 {}
923        };
924        assert_eq!(
925            parse_java_definition(input),
926            JavaDefinitions {
927                definitions: vec![JavaDefinition {
928                    name: JavaName(quote!{TestClass1}),
929                    public: true,
930                    definition: JavaDefinitionKind::Class(JavaClass {
931                        extends: None,
932                        implements: vec![],
933                        methods: vec![],
934                        native_methods: vec![],
935                        constructors: vec![],
936                    }),
937                }],
938                metadata: Metadata {
939                    definitions: vec![],
940                },
941            }
942        );
943    }
944
945    #[test]
946    fn one_class_packaged() {
947        let input = quote!{
948            class a.b.TestClass1 {}
949        };
950        assert_eq!(
951            parse_java_definition(input),
952            JavaDefinitions {
953                definitions: vec![JavaDefinition {
954                    name: JavaName(quote!{a b TestClass1}),
955                    public: false,
956                    definition: JavaDefinitionKind::Class(JavaClass {
957                        extends: None,
958                        implements: vec![],
959                        methods: vec![],
960                        native_methods: vec![],
961                        constructors: vec![],
962                    }),
963                }],
964                metadata: Metadata {
965                    definitions: vec![],
966                },
967            }
968        );
969    }
970
971    #[test]
972    fn one_class_implements() {
973        let input = quote!{
974            class TestClass1 implements test2, a.b.test3 {}
975        };
976        assert_eq!(
977            parse_java_definition(input),
978            JavaDefinitions {
979                definitions: vec![JavaDefinition {
980                    name: JavaName(quote!{TestClass1}),
981                    public: false,
982                    definition: JavaDefinitionKind::Class(JavaClass {
983                        extends: None,
984                        implements: vec![JavaName(quote!{test2}), JavaName(quote!{a b test3})],
985                        methods: vec![],
986                        native_methods: vec![],
987                        constructors: vec![],
988                    }),
989                }],
990                metadata: Metadata {
991                    definitions: vec![],
992                },
993            }
994        );
995    }
996
997    #[test]
998    fn one_interface() {
999        let input = quote!{
1000            interface TestInterface1 {}
1001        };
1002        assert_eq!(
1003            parse_java_definition(input),
1004            JavaDefinitions {
1005                definitions: vec![JavaDefinition {
1006                    name: JavaName(quote!{TestInterface1}),
1007                    public: false,
1008                    definition: JavaDefinitionKind::Interface(JavaInterface {
1009                        methods: vec![],
1010                        extends: vec![],
1011                    }),
1012                }],
1013                metadata: Metadata {
1014                    definitions: vec![],
1015                },
1016            }
1017        );
1018    }
1019
1020    #[test]
1021    fn one_interface_public() {
1022        let input = quote!{
1023            public interface TestInterface1 {}
1024        };
1025        assert_eq!(
1026            parse_java_definition(input),
1027            JavaDefinitions {
1028                definitions: vec![JavaDefinition {
1029                    name: JavaName(quote!{TestInterface1}),
1030                    public: true,
1031                    definition: JavaDefinitionKind::Interface(JavaInterface {
1032                        methods: vec![],
1033                        extends: vec![],
1034                    }),
1035                }],
1036                metadata: Metadata {
1037                    definitions: vec![],
1038                },
1039            }
1040        );
1041    }
1042
1043    #[test]
1044    fn one_interface_packaged() {
1045        let input = quote!{
1046            interface a.b.TestInterface1 {}
1047        };
1048        assert_eq!(
1049            parse_java_definition(input),
1050            JavaDefinitions {
1051                definitions: vec![JavaDefinition {
1052                    name: JavaName(quote!{a b TestInterface1}),
1053                    public: false,
1054                    definition: JavaDefinitionKind::Interface(JavaInterface {
1055                        methods: vec![],
1056                        extends: vec![],
1057                    }),
1058                }],
1059                metadata: Metadata {
1060                    definitions: vec![],
1061                },
1062            }
1063        );
1064    }
1065
1066    #[test]
1067    fn one_interface_extends() {
1068        let input = quote!{
1069            interface TestInterface1 extends TestInterface2, a.b.TestInterface3 {}
1070        };
1071        assert_eq!(
1072            parse_java_definition(input),
1073            JavaDefinitions {
1074                definitions: vec![JavaDefinition {
1075                    name: JavaName(quote!{TestInterface1}),
1076                    public: false,
1077                    definition: JavaDefinitionKind::Interface(JavaInterface {
1078                        methods: vec![],
1079                        extends: vec![
1080                            JavaName(quote!{TestInterface2}),
1081                            JavaName(quote!{a b TestInterface3}),
1082                        ],
1083                    }),
1084                }],
1085                metadata: Metadata {
1086                    definitions: vec![],
1087                },
1088            }
1089        );
1090    }
1091
1092    #[test]
1093    fn multiple() {
1094        let input = quote!{
1095            interface TestInterface1 {}
1096            interface TestInterface2 {}
1097            class TestClass1 {}
1098            class TestClass2 {}
1099        };
1100        assert_eq!(
1101            parse_java_definition(input),
1102            JavaDefinitions {
1103                definitions: vec![
1104                    JavaDefinition {
1105                        name: JavaName(quote!{TestInterface1}),
1106                        public: false,
1107                        definition: JavaDefinitionKind::Interface(JavaInterface {
1108                            methods: vec![],
1109                            extends: vec![],
1110                        }),
1111                    },
1112                    JavaDefinition {
1113                        name: JavaName(quote!{TestInterface2}),
1114                        public: false,
1115                        definition: JavaDefinitionKind::Interface(JavaInterface {
1116                            methods: vec![],
1117                            extends: vec![],
1118                        }),
1119                    },
1120                    JavaDefinition {
1121                        name: JavaName(quote!{TestClass1}),
1122                        public: false,
1123                        definition: JavaDefinitionKind::Class(JavaClass {
1124                            extends: None,
1125                            implements: vec![],
1126                            methods: vec![],
1127                            native_methods: vec![],
1128                            constructors: vec![],
1129                        }),
1130                    },
1131                    JavaDefinition {
1132                        name: JavaName(quote!{TestClass2}),
1133                        public: false,
1134                        definition: JavaDefinitionKind::Class(JavaClass {
1135                            extends: None,
1136                            implements: vec![],
1137                            methods: vec![],
1138                            native_methods: vec![],
1139                            constructors: vec![],
1140                        }),
1141                    },
1142                ],
1143                metadata: Metadata {
1144                    definitions: vec![],
1145                },
1146            }
1147        );
1148    }
1149
1150    #[test]
1151    fn metadata_empty() {
1152        let input = quote!{
1153            metadata {}
1154        };
1155        assert_eq!(
1156            parse_java_definition(input),
1157            JavaDefinitions {
1158                definitions: vec![],
1159                metadata: Metadata {
1160                    definitions: vec![],
1161                },
1162            }
1163        );
1164    }
1165
1166    #[test]
1167    fn metadata() {
1168        let input = quote!{
1169            metadata {
1170                interface TestInterface1 {}
1171                interface TestInterface2 extends TestInterface1 {}
1172                class TestClass2;
1173                class TestClass1 extends TestClass2 implements TestInterface1, TestInterface2;
1174            }
1175        };
1176        assert_eq!(
1177            parse_java_definition(input),
1178            JavaDefinitions {
1179                definitions: vec![],
1180                metadata: Metadata {
1181                    definitions: vec![
1182                        JavaDefinitionMetadata {
1183                            name: JavaName(quote!{TestInterface1}),
1184                            definition: JavaDefinitionMetadataKind::Interface(
1185                                JavaInterfaceMetadata {
1186                                    extends: vec![],
1187                                    methods: vec![],
1188                                },
1189                            ),
1190                        },
1191                        JavaDefinitionMetadata {
1192                            name: JavaName(quote!{TestInterface2}),
1193                            definition: JavaDefinitionMetadataKind::Interface(
1194                                JavaInterfaceMetadata {
1195                                    extends: vec![JavaName(quote!{TestInterface1})],
1196                                    methods: vec![],
1197                                },
1198                            ),
1199                        },
1200                        JavaDefinitionMetadata {
1201                            name: JavaName(quote!{TestClass2}),
1202                            definition: JavaDefinitionMetadataKind::Class(JavaClassMetadata {
1203                                extends: None,
1204                                implements: vec![],
1205                            }),
1206                        },
1207                        JavaDefinitionMetadata {
1208                            name: JavaName(quote!{TestClass1}),
1209                            definition: JavaDefinitionMetadataKind::Class(JavaClassMetadata {
1210                                extends: Some(JavaName(quote!{TestClass2})),
1211                                implements: vec![
1212                                    JavaName(quote!{TestInterface1}),
1213                                    JavaName(quote!{TestInterface2}),
1214                                ],
1215                            }),
1216                        },
1217                    ],
1218                },
1219            }
1220        );
1221    }
1222
1223    #[test]
1224    #[should_panic(expected = "Expected \"class\" or \"interface\"")]
1225    fn invalid_definition_kind() {
1226        let input = quote!{
1227            invalid 1
1228        };
1229        parse_java_definition(input);
1230    }
1231
1232    #[test]
1233    #[should_panic(expected = "Expected a Java name")]
1234    fn too_few_tokens() {
1235        let input = quote!{
1236            class
1237        };
1238        parse_java_definition(input);
1239    }
1240
1241    #[test]
1242    #[should_panic(expected = "Expected an identifier")]
1243    fn definition_name_not_identifier_after_dot() {
1244        let input = quote!{
1245            class a.1 {}
1246        };
1247        parse_java_definition(input);
1248    }
1249
1250    #[test]
1251    #[should_panic(expected = "Expected a dot")]
1252    fn definition_name_no_dot_after_identifier() {
1253        let input = quote!{
1254            class a b {}
1255        };
1256        parse_java_definition(input);
1257    }
1258
1259    #[test]
1260    #[should_panic(expected = "Expected a dot")]
1261    fn definition_name_not_dot_punctuation() {
1262        let input = quote!{
1263            class a,b {}
1264        };
1265        parse_java_definition(input);
1266    }
1267
1268    #[test]
1269    #[should_panic(expected = "Expected braces")]
1270    fn metadata_not_group() {
1271        let input = quote!{
1272            metadata abc
1273        };
1274        parse_java_definition(input);
1275    }
1276
1277    #[test]
1278    #[should_panic(expected = "Expected braces")]
1279    fn metadata_not_braces_group() {
1280        let input = quote!{
1281            metadata ()
1282        };
1283        parse_java_definition(input);
1284    }
1285
1286    #[test]
1287    #[should_panic(expected = "Expected \"class\" or \"interface\"")]
1288    fn invalid_definition_metadata_kind() {
1289        let input = quote!{
1290            metadata {
1291                abc
1292            }
1293        };
1294        parse_java_definition(input);
1295    }
1296}
1297
1298#[derive(Debug, Clone)]
1299struct ClassMethodGeneratorDefinition {
1300    name: Ident,
1301    java_name: Literal,
1302    return_type: TokenStream,
1303    argument_names: Vec<Ident>,
1304    argument_types: Vec<TokenStream>,
1305    public: TokenStream,
1306}
1307
1308#[derive(Debug, Clone)]
1309struct InterfaceMethodGeneratorDefinition {
1310    name: Ident,
1311    return_type: TokenStream,
1312    argument_names: Vec<Ident>,
1313    argument_types: Vec<TokenStream>,
1314}
1315
1316#[derive(Debug, Clone)]
1317struct InterfaceMethodImplementationGeneratorDefinition {
1318    name: Ident,
1319    return_type: TokenStream,
1320    argument_names: Vec<Ident>,
1321    argument_types: Vec<TokenStream>,
1322    class_cast: TokenStream,
1323}
1324
1325#[derive(Debug, Clone)]
1326struct NativeMethodGeneratorDefinition {
1327    name: Ident,
1328    rust_name: Ident,
1329    java_name: Ident,
1330    return_type: TokenStream,
1331    argument_names: Vec<Ident>,
1332    argument_types: Vec<TokenStream>,
1333    argument_types_no_lifetime: Vec<TokenStream>,
1334    public: TokenStream,
1335    code: Group,
1336}
1337
1338#[derive(Debug, Clone)]
1339struct ConstructorGeneratorDefinition {
1340    name: Ident,
1341    argument_names: Vec<Ident>,
1342    argument_types: Vec<TokenStream>,
1343    public: TokenStream,
1344}
1345
1346#[derive(Debug, Clone)]
1347struct InterfaceImplementationGeneratorDefinition {
1348    interface: TokenStream,
1349    methods: Vec<InterfaceMethodImplementationGeneratorDefinition>,
1350}
1351
1352#[derive(Debug, Clone)]
1353struct ClassGeneratorDefinition {
1354    class: Ident,
1355    public: TokenStream,
1356    super_class: TokenStream,
1357    transitive_extends: Vec<TokenStream>,
1358    implements: Vec<InterfaceImplementationGeneratorDefinition>,
1359    signature: Literal,
1360    full_signature: Literal,
1361    constructors: Vec<ConstructorGeneratorDefinition>,
1362    methods: Vec<ClassMethodGeneratorDefinition>,
1363    static_methods: Vec<ClassMethodGeneratorDefinition>,
1364    native_methods: Vec<NativeMethodGeneratorDefinition>,
1365    static_native_methods: Vec<NativeMethodGeneratorDefinition>,
1366}
1367
1368#[derive(Debug, Clone)]
1369struct InterfaceGeneratorDefinition {
1370    interface: Ident,
1371    public: TokenStream,
1372    extends: Vec<TokenStream>,
1373    methods: Vec<InterfaceMethodGeneratorDefinition>,
1374}
1375
1376#[derive(Debug, Clone)]
1377enum GeneratorDefinition {
1378    Class(ClassGeneratorDefinition),
1379    Interface(InterfaceGeneratorDefinition),
1380}
1381
1382impl PartialEq for GeneratorDefinition {
1383    fn eq(&self, other: &Self) -> bool {
1384        format!("{:?}", self) == format!("{:?}", other)
1385    }
1386}
1387
1388impl Eq for GeneratorDefinition {}
1389
1390#[derive(Debug, PartialEq, Eq, Clone)]
1391struct GeneratorData {
1392    definitions: Vec<GeneratorDefinition>,
1393}
1394
1395fn populate_interface_extends_rec(
1396    interface_extends: &mut HashMap<JavaName, HashSet<JavaName>>,
1397    key: &JavaName,
1398) {
1399    let mut interfaces = interface_extends.get(key).unwrap().clone();
1400    // TODO: this will break in case of cycles.
1401    for interface in interfaces.iter() {
1402        populate_interface_extends_rec(interface_extends, interface)
1403    }
1404    for interface in interfaces.clone().iter() {
1405        interfaces.extend(interface_extends.get(interface).unwrap().iter().cloned());
1406    }
1407    *interface_extends.get_mut(key).unwrap() = interfaces;
1408}
1409
1410fn populate_interface_extends(interface_extends: &mut HashMap<JavaName, HashSet<JavaName>>) {
1411    for key in interface_extends.keys().cloned().collect::<Vec<_>>() {
1412        populate_interface_extends_rec(interface_extends, &key);
1413    }
1414}
1415
1416fn public_token(public: bool) -> TokenStream {
1417    if public {
1418        quote!{pub}
1419    } else {
1420        TokenStream::new()
1421    }
1422}
1423
1424fn annotation_value(annotations: &[Annotation], name: &str) -> Option<TokenStream> {
1425    let values = annotations
1426        .iter()
1427        .filter_map(|annotation| {
1428            if annotation.name == name.to_string() {
1429                Some(annotation.value.clone())
1430            } else {
1431                None
1432            }
1433        })
1434        .collect::<Vec<_>>();
1435    if values.len() > 1 {
1436        panic!(
1437            "Only one @{} annotation per definition can be provided.",
1438            name
1439        );
1440    }
1441    if values.is_empty() {
1442        None
1443    } else {
1444        Some(values[0].clone())
1445    }
1446}
1447
1448fn annotation_value_ident(annotations: &[Annotation], name: &str) -> Option<Ident> {
1449    annotation_value(annotations, name).map(|value| match value.into_iter().next().unwrap() {
1450        TokenTree::Ident(identifier) => identifier,
1451        _ => unreachable!(),
1452    })
1453}
1454
1455fn to_generator_method(method: JavaClassMethod) -> ClassMethodGeneratorDefinition {
1456    let JavaClassMethod {
1457        name,
1458        public,
1459        return_type,
1460        arguments,
1461        annotations,
1462        ..
1463    } = method;
1464    let public = public_token(public);
1465    let java_name = Literal::string(&name.to_string());
1466    ClassMethodGeneratorDefinition {
1467        name: annotation_value_ident(&annotations, "RustName").unwrap_or(name),
1468        java_name,
1469        public,
1470        return_type: return_type.as_rust_type(),
1471        argument_names: arguments
1472            .iter()
1473            .map(|argument| argument.name.clone())
1474            .collect(),
1475        argument_types: arguments
1476            .iter()
1477            .map(|argument| argument.data_type.clone().as_rust_type_reference())
1478            .collect(),
1479    }
1480}
1481
1482fn to_generator_interface_method(
1483    method: JavaInterfaceMethod,
1484) -> InterfaceMethodGeneratorDefinition {
1485    let JavaInterfaceMethod {
1486        name,
1487        return_type,
1488        arguments,
1489        annotations,
1490        ..
1491    } = method;
1492    InterfaceMethodGeneratorDefinition {
1493        name: annotation_value_ident(&annotations, "RustName").unwrap_or(name),
1494        return_type: return_type.as_rust_type(),
1495        argument_names: arguments
1496            .iter()
1497            .map(|argument| argument.name.clone())
1498            .collect(),
1499        argument_types: arguments
1500            .iter()
1501            .map(|argument| argument.data_type.clone().as_rust_type_reference())
1502            .collect(),
1503    }
1504}
1505
1506fn to_generator_interface_method_implementation(
1507    method: JavaInterfaceMethod,
1508    class_methods: &Vec<JavaClassMethod>,
1509    interface: &JavaName,
1510    super_class: &TokenStream,
1511) -> InterfaceMethodImplementationGeneratorDefinition {
1512    let JavaInterfaceMethod {
1513        name,
1514        return_type,
1515        arguments,
1516        annotations,
1517        ..
1518    } = method;
1519    let class_has_method = class_methods.iter().any(|class_method| {
1520        class_method.name == name
1521            && class_method.return_type == return_type
1522            && class_method.arguments == arguments
1523    });
1524    let interface = interface.clone().with_double_colons();
1525    InterfaceMethodImplementationGeneratorDefinition {
1526        name: annotation_value_ident(&annotations, "RustName").unwrap_or(name),
1527        return_type: return_type.as_rust_type(),
1528        argument_names: arguments
1529            .iter()
1530            .map(|argument| argument.name.clone())
1531            .collect(),
1532        argument_types: arguments
1533            .iter()
1534            .map(|argument| argument.data_type.clone().as_rust_type_reference())
1535            .collect(),
1536        class_cast: if class_has_method {
1537            quote!{Self}
1538        } else {
1539            quote!{ <#super_class as #interface> }
1540        },
1541    }
1542}
1543
1544fn to_generator_native_method(
1545    method: JavaNativeMethod,
1546    class_name: &JavaName,
1547) -> NativeMethodGeneratorDefinition {
1548    let JavaNativeMethod {
1549        name,
1550        public,
1551        return_type,
1552        arguments,
1553        code,
1554        annotations,
1555        ..
1556    } = method;
1557    let public = public_token(public);
1558    let signatures = arguments
1559        .iter()
1560        .map(|argument| &argument.data_type)
1561        .map(|name| name.get_jni_signature())
1562        .collect::<Vec<_>>();
1563    let java_name = Ident::new(
1564        &format!(
1565            "Java_{}_{}__{}",
1566            class_name.clone().with_underscores(),
1567            name.to_string(),
1568            signatures.join("")
1569        ),
1570        Span::call_site(),
1571    );
1572    let rust_name = annotation_value_ident(&annotations, "RustName").unwrap_or(name.clone());
1573    NativeMethodGeneratorDefinition {
1574        name,
1575        rust_name,
1576        java_name,
1577        public,
1578        code,
1579        return_type: return_type.as_rust_type(),
1580        argument_names: arguments
1581            .iter()
1582            .map(|argument| argument.name.clone())
1583            .collect(),
1584        argument_types: arguments
1585            .iter()
1586            .map(|argument| argument.data_type.clone().as_rust_type())
1587            .collect(),
1588        argument_types_no_lifetime: arguments
1589            .iter()
1590            .map(|argument| argument.data_type.clone().as_rust_type_no_lifetime())
1591            .collect(),
1592    }
1593}
1594
1595fn to_generator_constructor(constructor: JavaConstructor) -> ConstructorGeneratorDefinition {
1596    let JavaConstructor {
1597        public,
1598        arguments,
1599        annotations,
1600        ..
1601    } = constructor;
1602    let public = public_token(public);
1603    let name = Ident::new("init", Span::call_site());
1604    ConstructorGeneratorDefinition {
1605        name: annotation_value_ident(&annotations, "RustName").unwrap_or(name),
1606        public,
1607        argument_names: arguments
1608            .iter()
1609            .map(|argument| argument.name.clone())
1610            .collect(),
1611        argument_types: arguments
1612            .iter()
1613            .map(|argument| argument.data_type.clone().as_rust_type_reference())
1614            .collect(),
1615    }
1616}
1617
1618fn get_interfaces(name: &Option<JavaName>, definitions: &Vec<JavaDefinition>) -> Vec<JavaName> {
1619    match name {
1620        None => vec![],
1621        Some(ref name) => {
1622            let definition = definitions
1623                .iter()
1624                .filter(|definition| definition.name == *name)
1625                .next();
1626            match definition {
1627                Some(ref definition) => match definition.definition {
1628                    JavaDefinitionKind::Class(ref class) => {
1629                        let mut interfaces = class.implements.clone();
1630                        interfaces.extend(get_interfaces(&class.extends, definitions));
1631                        interfaces
1632                    }
1633                    _ => unreachable!(),
1634                },
1635                None => vec![],
1636            }
1637        }
1638    }
1639}
1640
1641fn to_generator_data(definitions: JavaDefinitions) -> GeneratorData {
1642    let mut extends_map = HashMap::new();
1643    definitions
1644        .definitions
1645        .clone()
1646        .into_iter()
1647        .filter(|definition| match definition.definition {
1648            JavaDefinitionKind::Class(_) => true,
1649            _ => false,
1650        })
1651        .for_each(|definition| {
1652            let JavaDefinition {
1653                name, definition, ..
1654            } = definition;
1655            match definition {
1656                JavaDefinitionKind::Class(class) => {
1657                    let JavaClass { extends, .. } = class;
1658                    extends_map.insert(name, extends.unwrap_or(JavaName(quote!{java lang Object})));
1659                }
1660                _ => unreachable!(),
1661            }
1662        });
1663    definitions
1664        .metadata
1665        .definitions
1666        .clone()
1667        .into_iter()
1668        .filter(|definition| match definition.definition {
1669            JavaDefinitionMetadataKind::Class(_) => true,
1670            _ => false,
1671        })
1672        .for_each(|definition| {
1673            let JavaDefinitionMetadata {
1674                name, definition, ..
1675            } = definition;
1676            match definition {
1677                JavaDefinitionMetadataKind::Class(class) => {
1678                    let JavaClassMetadata { extends, .. } = class;
1679                    extends_map.insert(name, extends.unwrap_or(JavaName(quote!{java lang Object})));
1680                }
1681                _ => unreachable!(),
1682            }
1683        });
1684    let mut interface_extends = HashMap::new();
1685    definitions
1686        .definitions
1687        .clone()
1688        .into_iter()
1689        .filter(|definition| match definition.definition {
1690            JavaDefinitionKind::Interface(_) => true,
1691            _ => false,
1692        })
1693        .for_each(|definition| {
1694            let JavaDefinition {
1695                name, definition, ..
1696            } = definition;
1697            match definition {
1698                JavaDefinitionKind::Interface(interface) => {
1699                    let JavaInterface { extends, .. } = interface;
1700                    let all_extends = interface_extends.entry(name).or_insert(HashSet::new());
1701                    extends.into_iter().for_each(|extends_name| {
1702                        all_extends.insert(extends_name);
1703                    });
1704                }
1705                _ => unreachable!(),
1706            }
1707        });
1708    definitions
1709        .metadata
1710        .definitions
1711        .clone()
1712        .into_iter()
1713        .filter(|definition| match definition.definition {
1714            JavaDefinitionMetadataKind::Interface(_) => true,
1715            _ => false,
1716        })
1717        .for_each(|definition| {
1718            let JavaDefinitionMetadata {
1719                name, definition, ..
1720            } = definition;
1721            match definition {
1722                JavaDefinitionMetadataKind::Interface(interface) => {
1723                    let JavaInterfaceMetadata { extends, .. } = interface;
1724                    let all_extends = interface_extends.entry(name).or_insert(HashSet::new());
1725                    extends.into_iter().for_each(|extends_name| {
1726                        all_extends.insert(extends_name);
1727                    });
1728                }
1729                _ => unreachable!(),
1730            }
1731        });
1732    populate_interface_extends(&mut interface_extends);
1733    GeneratorData {
1734        definitions: definitions
1735            .definitions
1736            .clone()
1737            .into_iter()
1738            .map(|definition| {
1739                let JavaDefinition {
1740                    name,
1741                    public,
1742                    definition,
1743                    ..
1744                } = definition;
1745                let definition_name = name.clone().name();
1746                let public = public_token(public);
1747                match definition {
1748                    JavaDefinitionKind::Class(class) => {
1749                        let JavaClass {
1750                            extends,
1751                            constructors,
1752                            methods,
1753                            native_methods,
1754                            ..
1755                        } = class;
1756                        let mut transitive_extends = vec![];
1757                        let mut current = name.clone();
1758                        loop {
1759                            let super_class = extends_map.get(&current);
1760                            if super_class.is_none() {
1761                                break;
1762                            }
1763                            let super_class = super_class.unwrap();
1764                            transitive_extends.push(super_class.clone().with_double_colons());
1765                            current = super_class.clone();
1766                        }
1767                        let string_signature = name.clone().with_slashes();
1768                        let signature = Literal::string(&string_signature);
1769                        let full_signature = Literal::string(&format!("L{};", string_signature));
1770                        let super_class = extends
1771                            .map(|name| name.with_double_colons())
1772                            .unwrap_or(quote!{::java::lang::Object});
1773                        let implements =
1774                            get_interfaces(&Some(name.clone()), &definitions.definitions);
1775                        let mut implements = implements
1776                            .iter()
1777                            .flat_map(|name| interface_extends.get(&name).unwrap().iter())
1778                            .chain(implements.iter())
1779                            .cloned()
1780                            .collect::<HashSet<_>>()
1781                            .into_iter()
1782                            .collect::<Vec<_>>();
1783                        implements.sort_by(|left, right| left.to_string().cmp(&right.to_string()));
1784                        let mut implements = implements
1785                            .into_iter()
1786                            .map(|name| InterfaceImplementationGeneratorDefinition {
1787                                interface: name.clone().with_double_colons(),
1788                                methods: definitions
1789                                    .definitions
1790                                    .iter()
1791                                    .filter(|definition| definition.name == name)
1792                                    .next()
1793                                    .map(|definition| match definition.definition {
1794                                        JavaDefinitionKind::Interface(ref interface) => interface
1795                                            .methods
1796                                            .clone()
1797                                            .into_iter()
1798                                            .zip(iter::repeat(definition.name.clone())),
1799                                        _ => unreachable!(),
1800                                    })
1801                                    .or(definitions
1802                                        .metadata
1803                                        .definitions
1804                                        .clone()
1805                                        .into_iter()
1806                                        .filter(|definition| definition.name == name)
1807                                        .map(|definition| match definition.definition {
1808                                            JavaDefinitionMetadataKind::Interface(
1809                                                ref interface,
1810                                            ) => interface
1811                                                .methods
1812                                                .clone()
1813                                                .into_iter()
1814                                                .zip(iter::repeat(definition.name.clone())),
1815                                            _ => unreachable!(),
1816                                        })
1817                                        .next())
1818                                    .unwrap()
1819                                    .map(|(method, name)| {
1820                                        to_generator_interface_method_implementation(
1821                                            method,
1822                                            &methods,
1823                                            &name,
1824                                            &super_class,
1825                                        )
1826                                    })
1827                                    .collect(),
1828                            })
1829                            .collect::<Vec<_>>();
1830                        let static_methods = methods
1831                            .iter()
1832                            .filter(|method| method.is_static)
1833                            .cloned()
1834                            .map(to_generator_method)
1835                            .collect();
1836                        let methods = methods
1837                            .iter()
1838                            .filter(|method| !method.is_static)
1839                            .cloned()
1840                            .map(to_generator_method)
1841                            .collect();
1842                        let constructors = constructors
1843                            .into_iter()
1844                            .map(to_generator_constructor)
1845                            .collect();
1846                        let static_native_methods = native_methods
1847                            .iter()
1848                            .filter(|method| method.is_static)
1849                            .cloned()
1850                            .map(|method| to_generator_native_method(method, &name))
1851                            .collect();
1852                        let native_methods = native_methods
1853                            .iter()
1854                            .filter(|method| !method.is_static)
1855                            .cloned()
1856                            .map(|method| to_generator_native_method(method, &name))
1857                            .collect();
1858                        GeneratorDefinition::Class(ClassGeneratorDefinition {
1859                            class: definition_name,
1860                            public,
1861                            super_class,
1862                            transitive_extends,
1863                            implements,
1864                            signature,
1865                            full_signature,
1866                            constructors,
1867                            methods,
1868                            static_methods,
1869                            native_methods,
1870                            static_native_methods,
1871                        })
1872                    }
1873                    JavaDefinitionKind::Interface(interface) => {
1874                        let JavaInterface {
1875                            methods, extends, ..
1876                        } = interface;
1877                        let methods = methods
1878                            .iter()
1879                            .cloned()
1880                            .map(to_generator_interface_method)
1881                            .collect();
1882                        GeneratorDefinition::Interface(InterfaceGeneratorDefinition {
1883                            interface: definition_name,
1884                            public,
1885                            methods,
1886                            extends: extends
1887                                .into_iter()
1888                                .map(|name| name.with_double_colons())
1889                                .collect(),
1890                        })
1891                    }
1892                }
1893            })
1894            .collect(),
1895    }
1896}
1897
1898#[cfg(test)]
1899mod to_generator_data_tests {
1900    use super::*;
1901
1902    #[test]
1903    fn empty() {
1904        assert_eq!(
1905            to_generator_data(JavaDefinitions {
1906                definitions: vec![],
1907                metadata: Metadata {
1908                    definitions: vec![],
1909                },
1910            }),
1911            GeneratorData {
1912                definitions: vec![],
1913            }
1914        );
1915    }
1916
1917    #[test]
1918    fn metadata_only() {
1919        assert_eq!(
1920            to_generator_data(JavaDefinitions {
1921                definitions: vec![],
1922                metadata: Metadata {
1923                    definitions: vec![
1924                        JavaDefinitionMetadata {
1925                            name: JavaName(quote!{c d test1}),
1926                            definition: JavaDefinitionMetadataKind::Interface(
1927                                JavaInterfaceMetadata {
1928                                    methods: vec![],
1929                                    extends: vec![],
1930                                },
1931                            ),
1932                        },
1933                        JavaDefinitionMetadata {
1934                            name: JavaName(quote!{a b test2}),
1935                            definition: JavaDefinitionMetadataKind::Class(JavaClassMetadata {
1936                                extends: None,
1937                                implements: vec![JavaName(quote!{c d test1})],
1938                            }),
1939                        },
1940                    ],
1941                },
1942            }),
1943            GeneratorData {
1944                definitions: vec![],
1945            }
1946        );
1947    }
1948
1949    #[test]
1950    fn one_class() {
1951        assert_eq!(
1952            to_generator_data(JavaDefinitions {
1953                definitions: vec![JavaDefinition {
1954                    name: JavaName(quote!{a b test1}),
1955                    public: false,
1956                    definition: JavaDefinitionKind::Class(JavaClass {
1957                        extends: Some(JavaName(quote!{c d test2})),
1958                        implements: vec![],
1959                        methods: vec![],
1960                        native_methods: vec![],
1961                        constructors: vec![],
1962                    }),
1963                }],
1964                metadata: Metadata {
1965                    definitions: vec![],
1966                },
1967            }),
1968            GeneratorData {
1969                definitions: vec![GeneratorDefinition::Class(ClassGeneratorDefinition {
1970                    class: Ident::new("test1", Span::call_site()),
1971                    public: TokenStream::new(),
1972                    super_class: quote!{::c::d::test2},
1973                    transitive_extends: vec![quote!{::c::d::test2}],
1974                    implements: vec![],
1975                    signature: Literal::string("a/b/test1"),
1976                    full_signature: Literal::string("La/b/test1;"),
1977                    methods: vec![],
1978                    static_methods: vec![],
1979                    native_methods: vec![],
1980                    static_native_methods: vec![],
1981                    constructors: vec![],
1982                })],
1983            }
1984        );
1985    }
1986
1987    #[test]
1988    fn one_class_no_extends() {
1989        assert_eq!(
1990            to_generator_data(JavaDefinitions {
1991                definitions: vec![JavaDefinition {
1992                    name: JavaName(quote!{a b test1}),
1993                    public: false,
1994                    definition: JavaDefinitionKind::Class(JavaClass {
1995                        extends: None,
1996                        implements: vec![],
1997                        methods: vec![],
1998                        native_methods: vec![],
1999                        constructors: vec![],
2000                    }),
2001                }],
2002                metadata: Metadata {
2003                    definitions: vec![],
2004                },
2005            }),
2006            GeneratorData {
2007                definitions: vec![GeneratorDefinition::Class(ClassGeneratorDefinition {
2008                    class: Ident::new("test1", Span::call_site()),
2009                    public: TokenStream::new(),
2010                    super_class: quote!{::java::lang::Object},
2011                    transitive_extends: vec![quote!{::java::lang::Object}],
2012                    implements: vec![],
2013                    signature: Literal::string("a/b/test1"),
2014                    full_signature: Literal::string("La/b/test1;"),
2015                    methods: vec![],
2016                    static_methods: vec![],
2017                    native_methods: vec![],
2018                    static_native_methods: vec![],
2019                    constructors: vec![],
2020                })],
2021            }
2022        );
2023    }
2024
2025    #[test]
2026    fn one_class_extends_recursive() {
2027        assert_eq!(
2028            to_generator_data(JavaDefinitions {
2029                definitions: vec![
2030                    JavaDefinition {
2031                        name: JavaName(quote!{c d test2}),
2032                        public: false,
2033                        definition: JavaDefinitionKind::Class(JavaClass {
2034                            extends: Some(JavaName(quote!{e f test3})),
2035                            implements: vec![],
2036                            methods: vec![],
2037                            native_methods: vec![],
2038                            constructors: vec![],
2039                        }),
2040                    },
2041                    JavaDefinition {
2042                        name: JavaName(quote!{a b test1}),
2043                        public: false,
2044                        definition: JavaDefinitionKind::Class(JavaClass {
2045                            extends: Some(JavaName(quote!{c d test2})),
2046                            implements: vec![],
2047                            methods: vec![],
2048                            native_methods: vec![],
2049                            constructors: vec![],
2050                        }),
2051                    },
2052                ],
2053                metadata: Metadata {
2054                    definitions: vec![
2055                        JavaDefinitionMetadata {
2056                            name: JavaName(quote!{e f test4}),
2057                            definition: JavaDefinitionMetadataKind::Class(JavaClassMetadata {
2058                                extends: None,
2059                                implements: vec![],
2060                            }),
2061                        },
2062                        JavaDefinitionMetadata {
2063                            name: JavaName(quote!{e f test3}),
2064                            definition: JavaDefinitionMetadataKind::Class(JavaClassMetadata {
2065                                extends: Some(JavaName(quote!{e f test4})),
2066                                implements: vec![],
2067                            }),
2068                        },
2069                    ],
2070                },
2071            }),
2072            GeneratorData {
2073                definitions: vec![
2074                    GeneratorDefinition::Class(ClassGeneratorDefinition {
2075                        class: Ident::new("test2", Span::call_site()),
2076                        public: TokenStream::new(),
2077                        super_class: quote!{::e::f::test3},
2078                        transitive_extends: vec![
2079                            quote!{::e::f::test3},
2080                            quote!{::e::f::test4},
2081                            quote!{::java::lang::Object},
2082                        ],
2083                        implements: vec![],
2084                        signature: Literal::string("c/d/test2"),
2085                        full_signature: Literal::string("Lc/d/test2;"),
2086                        methods: vec![],
2087                        static_methods: vec![],
2088                        native_methods: vec![],
2089                        static_native_methods: vec![],
2090                        constructors: vec![],
2091                    }),
2092                    GeneratorDefinition::Class(ClassGeneratorDefinition {
2093                        class: Ident::new("test1", Span::call_site()),
2094                        public: TokenStream::new(),
2095                        super_class: quote!{::c::d::test2},
2096                        transitive_extends: vec![
2097                            quote!{::c::d::test2},
2098                            quote!{::e::f::test3},
2099                            quote!{::e::f::test4},
2100                            quote!{::java::lang::Object},
2101                        ],
2102                        implements: vec![],
2103                        signature: Literal::string("a/b/test1"),
2104                        full_signature: Literal::string("La/b/test1;"),
2105                        methods: vec![],
2106                        static_methods: vec![],
2107                        native_methods: vec![],
2108                        static_native_methods: vec![],
2109                        constructors: vec![],
2110                    }),
2111                ],
2112            }
2113        );
2114    }
2115
2116    #[test]
2117    fn one_class_implements() {
2118        assert_eq!(
2119            to_generator_data(JavaDefinitions {
2120                definitions: vec![
2121                    JavaDefinition {
2122                        name: JavaName(quote!{e f test4}),
2123                        public: false,
2124                        definition: JavaDefinitionKind::Interface(JavaInterface {
2125                            methods: vec![],
2126                            extends: vec![],
2127                        }),
2128                    },
2129                    JavaDefinition {
2130                        name: JavaName(quote!{a b test1}),
2131                        public: false,
2132                        definition: JavaDefinitionKind::Class(JavaClass {
2133                            extends: None,
2134                            implements: vec![
2135                                JavaName(quote!{e f test3}),
2136                                JavaName(quote!{e f test4}),
2137                            ],
2138                            methods: vec![],
2139                            native_methods: vec![],
2140                            constructors: vec![],
2141                        }),
2142                    },
2143                ],
2144                metadata: Metadata {
2145                    definitions: vec![JavaDefinitionMetadata {
2146                        name: JavaName(quote!{e f test3}),
2147                        definition: JavaDefinitionMetadataKind::Interface(JavaInterfaceMetadata {
2148                            extends: vec![],
2149                            methods: vec![],
2150                        }),
2151                    }],
2152                },
2153            }),
2154            GeneratorData {
2155                definitions: vec![
2156                    GeneratorDefinition::Interface(InterfaceGeneratorDefinition {
2157                        interface: Ident::new("test4", Span::call_site()),
2158                        public: TokenStream::new(),
2159                        extends: vec![],
2160                        methods: vec![],
2161                    }),
2162                    GeneratorDefinition::Class(ClassGeneratorDefinition {
2163                        class: Ident::new("test1", Span::call_site()),
2164                        public: TokenStream::new(),
2165                        super_class: quote!{::java::lang::Object},
2166                        transitive_extends: vec![quote!{::java::lang::Object}],
2167                        implements: vec![
2168                            InterfaceImplementationGeneratorDefinition {
2169                                interface: quote!{::e::f::test3},
2170                                methods: vec![],
2171                            },
2172                            InterfaceImplementationGeneratorDefinition {
2173                                interface: quote!{::e::f::test4},
2174                                methods: vec![],
2175                            },
2176                        ],
2177                        signature: Literal::string("a/b/test1"),
2178                        full_signature: Literal::string("La/b/test1;"),
2179                        methods: vec![],
2180                        static_methods: vec![],
2181                        native_methods: vec![],
2182                        static_native_methods: vec![],
2183                        constructors: vec![],
2184                    }),
2185                ],
2186            }
2187        );
2188    }
2189
2190    #[test]
2191    fn one_class_implements_recursive() {
2192        assert_eq!(
2193            to_generator_data(JavaDefinitions {
2194                definitions: vec![
2195                    JavaDefinition {
2196                        name: JavaName(quote!{e f test3}),
2197                        public: false,
2198                        definition: JavaDefinitionKind::Interface(JavaInterface {
2199                            methods: vec![],
2200                            extends: vec![JavaName(quote!{e f test4})],
2201                        }),
2202                    },
2203                    JavaDefinition {
2204                        name: JavaName(quote!{a b test1}),
2205                        public: false,
2206                        definition: JavaDefinitionKind::Class(JavaClass {
2207                            extends: None,
2208                            implements: vec![JavaName(quote!{e f test3})],
2209                            methods: vec![],
2210                            native_methods: vec![],
2211                            constructors: vec![],
2212                        }),
2213                    },
2214                ],
2215                metadata: Metadata {
2216                    definitions: vec![
2217                        JavaDefinitionMetadata {
2218                            name: JavaName(quote!{g h test5}),
2219                            definition: JavaDefinitionMetadataKind::Interface(
2220                                JavaInterfaceMetadata {
2221                                    methods: vec![],
2222                                    extends: vec![],
2223                                },
2224                            ),
2225                        },
2226                        JavaDefinitionMetadata {
2227                            name: JavaName(quote!{e f test4}),
2228                            definition: JavaDefinitionMetadataKind::Interface(
2229                                JavaInterfaceMetadata {
2230                                    methods: vec![],
2231                                    extends: vec![JavaName(quote!{g h test5})],
2232                                },
2233                            ),
2234                        },
2235                    ],
2236                },
2237            }),
2238            GeneratorData {
2239                definitions: vec![
2240                    GeneratorDefinition::Interface(InterfaceGeneratorDefinition {
2241                        interface: Ident::new("test3", Span::call_site()),
2242                        public: TokenStream::new(),
2243                        extends: vec![quote!{::e::f::test4}],
2244                        methods: vec![],
2245                    }),
2246                    GeneratorDefinition::Class(ClassGeneratorDefinition {
2247                        class: Ident::new("test1", Span::call_site()),
2248                        public: TokenStream::new(),
2249                        super_class: quote!{::java::lang::Object},
2250                        transitive_extends: vec![quote!{::java::lang::Object}],
2251                        implements: vec![
2252                            InterfaceImplementationGeneratorDefinition {
2253                                interface: quote!{::e::f::test3},
2254                                methods: vec![],
2255                            },
2256                            InterfaceImplementationGeneratorDefinition {
2257                                interface: quote!{::e::f::test4},
2258                                methods: vec![],
2259                            },
2260                            InterfaceImplementationGeneratorDefinition {
2261                                interface: quote!{::g::h::test5},
2262                                methods: vec![],
2263                            },
2264                        ],
2265                        signature: Literal::string("a/b/test1"),
2266                        full_signature: Literal::string("La/b/test1;"),
2267                        methods: vec![],
2268                        static_methods: vec![],
2269                        native_methods: vec![],
2270                        static_native_methods: vec![],
2271                        constructors: vec![],
2272                    }),
2273                ],
2274            }
2275        );
2276    }
2277
2278    #[test]
2279    fn one_class_implements_recursive_duplicated() {
2280        assert_eq!(
2281            to_generator_data(JavaDefinitions {
2282                definitions: vec![
2283                    JavaDefinition {
2284                        name: JavaName(quote!{g h test4}),
2285                        public: false,
2286                        definition: JavaDefinitionKind::Interface(JavaInterface {
2287                            methods: vec![],
2288                            extends: vec![],
2289                        }),
2290                    },
2291                    JavaDefinition {
2292                        name: JavaName(quote!{e f test3}),
2293                        public: false,
2294                        definition: JavaDefinitionKind::Interface(JavaInterface {
2295                            methods: vec![],
2296                            extends: vec![JavaName(quote!{g h test4})],
2297                        }),
2298                    },
2299                    JavaDefinition {
2300                        name: JavaName(quote!{a b test1}),
2301                        public: false,
2302                        definition: JavaDefinitionKind::Class(JavaClass {
2303                            extends: None,
2304                            implements: vec![
2305                                JavaName(quote!{e f test3}),
2306                                JavaName(quote!{g h test4}),
2307                            ],
2308                            methods: vec![],
2309                            native_methods: vec![],
2310                            constructors: vec![],
2311                        }),
2312                    },
2313                ],
2314                metadata: Metadata {
2315                    definitions: vec![],
2316                },
2317            }),
2318            GeneratorData {
2319                definitions: vec![
2320                    GeneratorDefinition::Interface(InterfaceGeneratorDefinition {
2321                        interface: Ident::new("test4", Span::call_site()),
2322                        public: TokenStream::new(),
2323                        extends: vec![],
2324                        methods: vec![],
2325                    }),
2326                    GeneratorDefinition::Interface(InterfaceGeneratorDefinition {
2327                        interface: Ident::new("test3", Span::call_site()),
2328                        public: TokenStream::new(),
2329                        extends: vec![quote!{::g::h::test4}],
2330                        methods: vec![],
2331                    }),
2332                    GeneratorDefinition::Class(ClassGeneratorDefinition {
2333                        class: Ident::new("test1", Span::call_site()),
2334                        public: TokenStream::new(),
2335                        super_class: quote!{::java::lang::Object},
2336                        transitive_extends: vec![quote!{::java::lang::Object}],
2337                        implements: vec![
2338                            InterfaceImplementationGeneratorDefinition {
2339                                interface: quote!{::e::f::test3},
2340                                methods: vec![],
2341                            },
2342                            InterfaceImplementationGeneratorDefinition {
2343                                interface: quote!{::g::h::test4},
2344                                methods: vec![],
2345                            },
2346                        ],
2347                        signature: Literal::string("a/b/test1"),
2348                        full_signature: Literal::string("La/b/test1;"),
2349                        methods: vec![],
2350                        static_methods: vec![],
2351                        native_methods: vec![],
2352                        static_native_methods: vec![],
2353                        constructors: vec![],
2354                    }),
2355                ],
2356            }
2357        );
2358    }
2359
2360    #[test]
2361    fn one_class_public() {
2362        assert_eq!(
2363            to_generator_data(JavaDefinitions {
2364                definitions: vec![JavaDefinition {
2365                    name: JavaName(quote!{a b test1}),
2366                    public: true,
2367                    definition: JavaDefinitionKind::Class(JavaClass {
2368                        extends: None,
2369                        implements: vec![],
2370                        methods: vec![],
2371                        native_methods: vec![],
2372                        constructors: vec![],
2373                    }),
2374                }],
2375                metadata: Metadata {
2376                    definitions: vec![],
2377                },
2378            }),
2379            GeneratorData {
2380                definitions: vec![GeneratorDefinition::Class(ClassGeneratorDefinition {
2381                    class: Ident::new("test1", Span::call_site()),
2382                    public: quote!{pub},
2383                    super_class: quote!{::java::lang::Object},
2384                    transitive_extends: vec![quote!{::java::lang::Object}],
2385                    implements: vec![],
2386                    signature: Literal::string("a/b/test1"),
2387                    full_signature: Literal::string("La/b/test1;"),
2388                    methods: vec![],
2389                    static_methods: vec![],
2390                    native_methods: vec![],
2391                    static_native_methods: vec![],
2392                    constructors: vec![],
2393                })],
2394            }
2395        );
2396    }
2397
2398    #[test]
2399    fn one_interface() {
2400        assert_eq!(
2401            to_generator_data(JavaDefinitions {
2402                definitions: vec![JavaDefinition {
2403                    name: JavaName(quote!{a b test1}),
2404                    public: false,
2405                    definition: JavaDefinitionKind::Interface(JavaInterface {
2406                        methods: vec![],
2407                        extends: vec![],
2408                    }),
2409                }],
2410                metadata: Metadata {
2411                    definitions: vec![],
2412                },
2413            }),
2414            GeneratorData {
2415                definitions: vec![GeneratorDefinition::Interface(
2416                    InterfaceGeneratorDefinition {
2417                        interface: Ident::new("test1", Span::call_site()),
2418                        public: TokenStream::new(),
2419                        extends: vec![],
2420                        methods: vec![],
2421                    },
2422                )],
2423            }
2424        );
2425    }
2426
2427    #[test]
2428    fn one_interface_extends() {
2429        assert_eq!(
2430            to_generator_data(JavaDefinitions {
2431                definitions: vec![
2432                    JavaDefinition {
2433                        name: JavaName(quote!{e f test3}),
2434                        public: false,
2435                        definition: JavaDefinitionKind::Interface(JavaInterface {
2436                            methods: vec![],
2437                            extends: vec![],
2438                        }),
2439                    },
2440                    JavaDefinition {
2441                        name: JavaName(quote!{a b test1}),
2442                        public: false,
2443                        definition: JavaDefinitionKind::Interface(JavaInterface {
2444                            methods: vec![],
2445                            extends: vec![JavaName(quote!{c d test2}), JavaName(quote!{e f test3})],
2446                        }),
2447                    },
2448                ],
2449                metadata: Metadata {
2450                    definitions: vec![
2451                        JavaDefinitionMetadata {
2452                            name: JavaName(quote!{c d test4}),
2453                            definition: JavaDefinitionMetadataKind::Interface(
2454                                JavaInterfaceMetadata {
2455                                    methods: vec![],
2456                                    extends: vec![],
2457                                },
2458                            ),
2459                        },
2460                        JavaDefinitionMetadata {
2461                            name: JavaName(quote!{c d test2}),
2462                            definition: JavaDefinitionMetadataKind::Interface(
2463                                JavaInterfaceMetadata {
2464                                    methods: vec![],
2465                                    extends: vec![JavaName(quote!{c d test4})],
2466                                },
2467                            ),
2468                        },
2469                    ],
2470                },
2471            }),
2472            GeneratorData {
2473                definitions: vec![
2474                    GeneratorDefinition::Interface(InterfaceGeneratorDefinition {
2475                        interface: Ident::new("test3", Span::call_site()),
2476                        public: TokenStream::new(),
2477                        extends: vec![],
2478                        methods: vec![],
2479                    }),
2480                    GeneratorDefinition::Interface(InterfaceGeneratorDefinition {
2481                        interface: Ident::new("test1", Span::call_site()),
2482                        public: TokenStream::new(),
2483                        extends: vec![quote!{::c::d::test2}, quote!{::e::f::test3}],
2484                        methods: vec![],
2485                    }),
2486                ],
2487            }
2488        );
2489    }
2490
2491    #[test]
2492    fn one_interface_public() {
2493        assert_eq!(
2494            to_generator_data(JavaDefinitions {
2495                definitions: vec![JavaDefinition {
2496                    name: JavaName(quote!{a b test1}),
2497                    public: true,
2498                    definition: JavaDefinitionKind::Interface(JavaInterface {
2499                        methods: vec![],
2500                        extends: vec![],
2501                    }),
2502                }],
2503                metadata: Metadata {
2504                    definitions: vec![],
2505                },
2506            }),
2507            GeneratorData {
2508                definitions: vec![GeneratorDefinition::Interface(
2509                    InterfaceGeneratorDefinition {
2510                        interface: Ident::new("test1", Span::call_site()),
2511                        public: quote!{pub},
2512                        extends: vec![],
2513                        methods: vec![],
2514                    },
2515                )],
2516            }
2517        );
2518    }
2519
2520    #[test]
2521    fn multiple() {
2522        assert_eq!(
2523            to_generator_data(JavaDefinitions {
2524                definitions: vec![
2525                    JavaDefinition {
2526                        name: JavaName(quote!{e f test_if1}),
2527                        public: false,
2528                        definition: JavaDefinitionKind::Interface(JavaInterface {
2529                            methods: vec![],
2530                            extends: vec![],
2531                        }),
2532                    },
2533                    JavaDefinition {
2534                        name: JavaName(quote!{e f test_if2}),
2535                        public: false,
2536                        definition: JavaDefinitionKind::Interface(JavaInterface {
2537                            methods: vec![],
2538                            extends: vec![],
2539                        }),
2540                    },
2541                    JavaDefinition {
2542                        name: JavaName(quote!{a b test1}),
2543                        public: false,
2544                        definition: JavaDefinitionKind::Class(JavaClass {
2545                            extends: None,
2546                            implements: vec![],
2547                            methods: vec![],
2548                            native_methods: vec![],
2549                            constructors: vec![],
2550                        }),
2551                    },
2552                    JavaDefinition {
2553                        name: JavaName(quote!{test2}),
2554                        public: false,
2555                        definition: JavaDefinitionKind::Class(JavaClass {
2556                            extends: None,
2557                            implements: vec![],
2558                            methods: vec![],
2559                            native_methods: vec![],
2560                            constructors: vec![],
2561                        }),
2562                    },
2563                ],
2564                metadata: Metadata {
2565                    definitions: vec![],
2566                },
2567            }),
2568            GeneratorData {
2569                definitions: vec![
2570                    GeneratorDefinition::Interface(InterfaceGeneratorDefinition {
2571                        interface: Ident::new("test_if1", Span::call_site()),
2572                        public: TokenStream::new(),
2573                        extends: vec![],
2574                        methods: vec![],
2575                    }),
2576                    GeneratorDefinition::Interface(InterfaceGeneratorDefinition {
2577                        interface: Ident::new("test_if2", Span::call_site()),
2578                        public: TokenStream::new(),
2579                        extends: vec![],
2580                        methods: vec![],
2581                    }),
2582                    GeneratorDefinition::Class(ClassGeneratorDefinition {
2583                        class: Ident::new("test1", Span::call_site()),
2584                        public: TokenStream::new(),
2585                        super_class: quote!{::java::lang::Object},
2586                        transitive_extends: vec![quote!{::java::lang::Object}],
2587                        implements: vec![],
2588                        signature: Literal::string("a/b/test1"),
2589                        full_signature: Literal::string("La/b/test1;"),
2590                        methods: vec![],
2591                        static_methods: vec![],
2592                        native_methods: vec![],
2593                        static_native_methods: vec![],
2594                        constructors: vec![],
2595                    }),
2596                    GeneratorDefinition::Class(ClassGeneratorDefinition {
2597                        class: Ident::new("test2", Span::call_site()),
2598                        public: TokenStream::new(),
2599                        super_class: quote!{::java::lang::Object},
2600                        transitive_extends: vec![quote!{::java::lang::Object}],
2601                        implements: vec![],
2602                        signature: Literal::string("test2"),
2603                        full_signature: Literal::string("Ltest2;"),
2604                        methods: vec![],
2605                        static_methods: vec![],
2606                        native_methods: vec![],
2607                        static_native_methods: vec![],
2608                        constructors: vec![],
2609                    }),
2610                ],
2611            }
2612        );
2613    }
2614}
2615
2616fn generate(data: GeneratorData) -> TokenStream {
2617    let mut tokens = TokenStream::new();
2618    for definition in data.definitions {
2619        tokens.extend(generate_definition(definition));
2620    }
2621    tokens
2622}
2623
2624fn generate_definition(definition: GeneratorDefinition) -> TokenStream {
2625    match definition {
2626        GeneratorDefinition::Class(class) => generate_class_definition(class),
2627        GeneratorDefinition::Interface(interface) => generate_interface_definition(interface),
2628    }
2629}
2630
2631fn generate_interface_method(method: InterfaceMethodGeneratorDefinition) -> TokenStream {
2632    let InterfaceMethodGeneratorDefinition {
2633        name,
2634        return_type,
2635        argument_names,
2636        argument_types,
2637    } = method;
2638    quote!{
2639        fn #name(
2640            &self,
2641            #(#argument_names: #argument_types,)*
2642            token: &::rust_jni::NoException<'a>,
2643        ) -> ::rust_jni::JavaResult<'a, #return_type>;
2644    }
2645}
2646
2647fn generate_class_method(method: ClassMethodGeneratorDefinition) -> TokenStream {
2648    let ClassMethodGeneratorDefinition {
2649        name,
2650        java_name,
2651        return_type,
2652        public,
2653        argument_names,
2654        argument_types,
2655    } = method;
2656    let argument_names_1 = argument_names.clone();
2657    let argument_types_1 = argument_types.clone();
2658    quote!{
2659        #public fn #name(
2660            &self,
2661            #(#argument_names: #argument_types,)*
2662            token: &::rust_jni::NoException<'a>,
2663        ) -> ::rust_jni::JavaResult<'a, #return_type> {
2664            // Safe because the method name and arguments are correct.
2665            unsafe {
2666                ::rust_jni::__generator::call_method::<_, _, _,
2667                    fn(#(#argument_types_1,)*) -> #return_type
2668                >
2669                (
2670                    self,
2671                    #java_name,
2672                    (#(#argument_names_1,)*),
2673                    token,
2674                )
2675            }
2676        }
2677    }
2678}
2679
2680fn generate_static_class_method(method: ClassMethodGeneratorDefinition) -> TokenStream {
2681    let ClassMethodGeneratorDefinition {
2682        name,
2683        java_name,
2684        return_type,
2685        public,
2686        argument_names,
2687        argument_types,
2688    } = method;
2689    let argument_names_1 = argument_names.clone();
2690    let argument_types_1 = argument_types.clone();
2691    quote!{
2692        #public fn #name(
2693            env: &'a ::rust_jni::JniEnv<'a>,
2694            #(#argument_names: #argument_types,)*
2695            token: &::rust_jni::NoException<'a>,
2696        ) -> ::rust_jni::JavaResult<'a, #return_type> {
2697            // Safe because the method name and arguments are correct.
2698            unsafe {
2699                ::rust_jni::__generator::call_static_method::<Self, _, _,
2700                    fn(#(#argument_types_1,)*) -> #return_type
2701                >
2702                (
2703                    env,
2704                    #java_name,
2705                    (#(#argument_names_1,)*),
2706                    token,
2707                )
2708            }
2709        }
2710    }
2711}
2712
2713fn generate_class_native_method(method: NativeMethodGeneratorDefinition) -> TokenStream {
2714    let NativeMethodGeneratorDefinition {
2715        rust_name,
2716        return_type,
2717        public,
2718        argument_names,
2719        argument_types,
2720        code,
2721        ..
2722    } = method;
2723    quote!{
2724        #public fn #rust_name(
2725            &self,
2726            #(#argument_names: #argument_types,)*
2727            token: &::rust_jni::NoException<'a>,
2728        ) -> ::rust_jni::JavaResult<'a, #return_type> {
2729            #code
2730        }
2731    }
2732}
2733
2734fn generate_static_class_native_method(method: NativeMethodGeneratorDefinition) -> TokenStream {
2735    let NativeMethodGeneratorDefinition {
2736        rust_name,
2737        return_type,
2738        public,
2739        argument_names,
2740        argument_types,
2741        code,
2742        ..
2743    } = method;
2744    quote!{
2745        #public fn #rust_name(
2746            env: &'a ::rust_jni::JniEnv<'a>,
2747            #(#argument_names: #argument_types,)*
2748            token: &::rust_jni::NoException<'a>,
2749        ) -> ::rust_jni::JavaResult<'a, #return_type> {
2750            #code
2751        }
2752    }
2753}
2754
2755fn generate_class_native_method_function(
2756    method: NativeMethodGeneratorDefinition,
2757    class_name: &Ident,
2758) -> TokenStream {
2759    let NativeMethodGeneratorDefinition {
2760        rust_name,
2761        java_name,
2762        return_type,
2763        argument_names,
2764        argument_types_no_lifetime,
2765        ..
2766    } = method;
2767    let argument_names_1 = argument_names.clone();
2768    let argument_names_2 = argument_names.clone();
2769    let argument_names_3 = argument_names.clone();
2770    let argument_types_no_lifetime_1 = argument_types_no_lifetime.clone();
2771    quote!{
2772        #[no_mangle]
2773        #[doc(hidden)]
2774        pub unsafe extern "C" fn #java_name<'a>(
2775            raw_env: *mut ::jni_sys::JNIEnv,
2776            object: ::jni_sys::jobject,
2777            #(#argument_names: <#argument_types_no_lifetime as ::rust_jni::JavaType>::__JniType,)*
2778        ) -> <#return_type as ::rust_jni::JavaType>::__JniType {
2779            // TODO: make sure `#return_type: ::rust_jni::__generator::FromJni`.
2780            // Compile-time check that declared arguments implement the `JniArgumentType`
2781            // trait.
2782            #(::rust_jni::__generator::test_jni_argument_type(#argument_names_1);)*
2783            ::rust_jni::__generator::native_method_wrapper(raw_env, |env, token| {
2784                // Compile-time check that declared arguments implement the `FromJni` trait.
2785                #(
2786                    {
2787                        let value =
2788                            <#argument_types_no_lifetime_1 as ::rust_jni::__generator::FromJni>
2789                                ::__from_jni(env, #argument_names_2);
2790                        ::rust_jni::__generator::test_from_jni_type(&value);
2791                        ::std::mem::forget(value);
2792                    }
2793                )*
2794
2795                let object = <#class_name as ::rust_jni::__generator::FromJni>::__from_jni(env, object);
2796                object
2797                    .#rust_name(
2798                        #(::rust_jni::__generator::FromJni::__from_jni(env, #argument_names_3),)*
2799                        &token,
2800                    )
2801                    .map(|value| {
2802                        let result = ::rust_jni::__generator::ToJni::__to_jni(&value);
2803                        // We don't want to delete the reference to result for object results.
2804                        ::std::mem::forget(value);
2805                        result
2806                    })
2807            })
2808        }
2809    }
2810}
2811
2812fn generate_static_class_native_method_function(
2813    method: NativeMethodGeneratorDefinition,
2814    class_name: &Ident,
2815) -> TokenStream {
2816    let NativeMethodGeneratorDefinition {
2817        name,
2818        rust_name,
2819        java_name,
2820        return_type,
2821        argument_names,
2822        argument_types_no_lifetime,
2823        ..
2824    } = method;
2825    let argument_names_1 = argument_names.clone();
2826    let argument_names_2 = argument_names.clone();
2827    let argument_names_3 = argument_names.clone();
2828    let argument_types_no_lifetime_1 = argument_types_no_lifetime.clone();
2829    let class_mismatch_error = format!(
2830        "Native method {} does not belong to class {}",
2831        name.to_string(),
2832        class_name.to_string()
2833    );
2834    quote!{
2835        #[no_mangle]
2836        #[doc(hidden)]
2837        pub unsafe extern "C" fn #java_name<'a>(
2838            raw_env: *mut ::jni_sys::JNIEnv,
2839            raw_class: ::jni_sys::jclass,
2840            #(#argument_names: <#argument_types_no_lifetime as ::rust_jni::JavaType>::__JniType,)*
2841        ) -> <#return_type as ::rust_jni::JavaType>::__JniType {
2842            // TODO: make sure `#return_type: ::rust_jni::__generator::FromJni`.
2843            // Compile-time check that declared arguments implement the `JniArgumentType`
2844            // trait.
2845            #(::rust_jni::__generator::test_jni_argument_type(#argument_names_1);)*
2846            ::rust_jni::__generator::native_method_wrapper(raw_env, |env, token| {
2847                // Compile-time check that declared arguments implement the `FromJni` trait.
2848                #(
2849                    {
2850                        let value =
2851                            <#argument_types_no_lifetime_1 as ::rust_jni::__generator::FromJni>
2852                                ::__from_jni(env, #argument_names_2);
2853                        ::rust_jni::__generator::test_from_jni_type(&value);
2854                        ::std::mem::forget(value);
2855                    }
2856                )*
2857
2858                let class = #class_name::get_class(env, &token)?;
2859                let raw_class = <::rust_jni::java::lang::Class as ::rust_jni::__generator::FromJni>::__from_jni(env, raw_class);
2860                if !class.is_same_as(&raw_class, &token) {
2861                    // This should never happen, as native method's link name has the class,
2862                    // so it must be bound to a correct clas by the JVM.
2863                    // Still, this is a good test to ensure that the system
2864                    // is in a consistent state.
2865                    panic!(#class_mismatch_error);
2866                }
2867
2868                #class_name::#rust_name(
2869                    env,
2870                    #(::rust_jni::__generator::FromJni::__from_jni(env, #argument_names_3),)*
2871                    &token,
2872                )
2873                .map(|value| {
2874                    let result = ::rust_jni::__generator::ToJni::__to_jni(&value);
2875                    // We don't want to delete the reference to result for object results.
2876                    ::std::mem::forget(value);
2877                    result
2878                })
2879            })
2880        }
2881    }
2882}
2883
2884fn generate_constructor(method: ConstructorGeneratorDefinition) -> TokenStream {
2885    let ConstructorGeneratorDefinition {
2886        name,
2887        public,
2888        argument_names,
2889        argument_types,
2890    } = method;
2891    let argument_names_1 = argument_names.clone();
2892    let argument_types_1 = argument_types.clone();
2893    quote!{
2894        #public fn #name(
2895            env: &'a ::rust_jni::JniEnv<'a>,
2896            #(#argument_names: #argument_types,)*
2897            token: &::rust_jni::NoException<'a>,
2898        ) -> ::rust_jni::JavaResult<'a, Self> {
2899            // Safe because the method name and arguments are correct.
2900            unsafe {
2901                ::rust_jni::__generator::call_constructor::<Self, _, fn(#(#argument_types_1,)*)>
2902                (
2903                    env,
2904                    (#(#argument_names_1,)*),
2905                    token,
2906                )
2907            }
2908        }
2909    }
2910}
2911
2912fn generate_interface_method_implementation(
2913    method: InterfaceMethodImplementationGeneratorDefinition,
2914) -> TokenStream {
2915    let InterfaceMethodImplementationGeneratorDefinition {
2916        name,
2917        argument_names,
2918        argument_types,
2919        return_type,
2920        class_cast,
2921    } = method;
2922    let argument_names_1 = argument_names.clone();
2923    quote!{
2924        fn #name(
2925            &self,
2926            #(#argument_names: #argument_types),*,
2927            token: &::rust_jni::NoException<'a>,
2928        ) -> ::rust_jni::JavaResult<'a, #return_type> {
2929            #class_cast::#name(
2930                self, #(#argument_names_1),*, token
2931            )
2932        }
2933    }
2934}
2935
2936fn generate_interface_implementation(
2937    interface: InterfaceImplementationGeneratorDefinition,
2938    class: &Ident,
2939) -> TokenStream {
2940    let InterfaceImplementationGeneratorDefinition {
2941        interface, methods, ..
2942    } = interface;
2943    let methods = methods
2944        .into_iter()
2945        .map(generate_interface_method_implementation)
2946        .collect::<Vec<_>>();
2947    quote! {
2948        impl<'a> #interface<'a> for #class<'a> {
2949            #(
2950                #methods
2951            )*
2952        }
2953    }
2954}
2955
2956fn generate_class_definition(definition: ClassGeneratorDefinition) -> TokenStream {
2957    let ClassGeneratorDefinition {
2958        class,
2959        public,
2960        super_class,
2961        transitive_extends,
2962        implements,
2963        signature,
2964        full_signature,
2965        constructors,
2966        methods,
2967        static_methods,
2968        native_methods,
2969        static_native_methods,
2970        ..
2971    } = definition;
2972    let multiplied_class = iter::repeat(class.clone());
2973    let multiplied_class_1 = multiplied_class.clone();
2974    let transitive_extends_1 = transitive_extends.clone();
2975    let methods = methods
2976        .into_iter()
2977        .map(generate_class_method)
2978        .collect::<Vec<_>>();
2979    let static_methods = static_methods
2980        .into_iter()
2981        .map(generate_static_class_method)
2982        .collect::<Vec<_>>();
2983    let native_method_functions = native_methods
2984        .clone()
2985        .into_iter()
2986        .map(|method| generate_class_native_method_function(method, &class))
2987        .collect::<Vec<_>>();
2988    let static_native_method_functions = static_native_methods
2989        .clone()
2990        .into_iter()
2991        .map(|method| generate_static_class_native_method_function(method, &class))
2992        .collect::<Vec<_>>();
2993    let native_methods = native_methods
2994        .into_iter()
2995        .map(generate_class_native_method)
2996        .collect::<Vec<_>>();
2997    let static_native_methods = static_native_methods
2998        .into_iter()
2999        .map(generate_static_class_native_method)
3000        .collect::<Vec<_>>();
3001    let constructors = constructors
3002        .into_iter()
3003        .map(generate_constructor)
3004        .collect::<Vec<_>>();
3005    let implementations = implements
3006        .into_iter()
3007        .map(|interface| generate_interface_implementation(interface, &class))
3008        .collect::<Vec<_>>();
3009    quote! {
3010        #[derive(Debug)]
3011        #public struct #class<'env> {
3012            object: #super_class<'env>,
3013        }
3014
3015        impl<'a> ::rust_jni::JavaType for #class<'a> {
3016            #[doc(hidden)]
3017            type __JniType = <::rust_jni::java::lang::Object<'a> as ::rust_jni::JavaType>::__JniType;
3018
3019            #[doc(hidden)]
3020            fn __signature() -> &'static str {
3021                #full_signature
3022            }
3023        }
3024
3025        impl<'a> ::rust_jni::__generator::ToJni for #class<'a> {
3026            unsafe fn __to_jni(&self) -> Self::__JniType {
3027                self.raw_object()
3028            }
3029        }
3030
3031        impl<'a> ::rust_jni::__generator::FromJni<'a> for #class<'a> {
3032            unsafe fn __from_jni(env: &'a ::rust_jni::JniEnv<'a>, value: Self::__JniType) -> Self {
3033                Self {
3034                    object: <#super_class as ::rust_jni::__generator::FromJni<'a>>::__from_jni(env, value),
3035                }
3036            }
3037        }
3038
3039        impl<'a> ::rust_jni::Cast<'a, #class<'a>> for #class<'a> {
3040            #[doc(hidden)]
3041            fn cast<'b>(&'b self) -> &'b #class<'a> {
3042                self
3043            }
3044        }
3045
3046        #(
3047            impl<'a> ::rust_jni::Cast<'a, #transitive_extends<'a>> for #multiplied_class_1<'a> {
3048                #[doc(hidden)]
3049                fn cast<'b>(&'b self) -> &'b #transitive_extends_1<'a> {
3050                    self
3051                }
3052            }
3053        )*
3054
3055        impl<'a> ::std::ops::Deref for #class<'a> {
3056            type Target = #super_class<'a>;
3057
3058            fn deref(&self) -> &Self::Target {
3059                &self.object
3060            }
3061        }
3062
3063        impl<'a> #class<'a> {
3064            pub fn get_class(env: &'a ::rust_jni::JniEnv<'a>, token: &::rust_jni::NoException<'a>)
3065                -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::Class<'a>> {
3066                ::rust_jni::java::lang::Class::find(env, #signature, token)
3067            }
3068
3069            pub fn clone(&self, token: &::rust_jni::NoException<'a>) -> ::rust_jni::JavaResult<'a, Self>
3070            where
3071                Self: Sized,
3072            {
3073                self.object
3074                    .clone(token)
3075                    .map(|object| Self { object })
3076            }
3077
3078            pub fn to_string(&self, token: &::rust_jni::NoException<'a>)
3079                -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::String<'a>> {
3080                self.object.to_string(token)
3081            }
3082
3083            #(
3084                #constructors
3085            )*
3086
3087            #(
3088                #methods
3089            )*
3090
3091            #(
3092                #static_methods
3093            )*
3094
3095            #(
3096                #native_methods
3097            )*
3098
3099            #(
3100                #static_native_methods
3101            )*
3102        }
3103
3104        // TODO: put them into an anonymous module.
3105
3106        #(
3107            #native_method_functions
3108        )*
3109
3110        #(
3111            #static_native_method_functions
3112        )*
3113
3114        impl<'a> ::std::fmt::Display for #class<'a> {
3115            fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
3116                self.object.fmt(formatter)
3117            }
3118        }
3119
3120        impl<'a, T> PartialEq<T> for #class<'a> where T: ::rust_jni::Cast<'a, ::rust_jni::java::lang::Object<'a>> {
3121            fn eq(&self, other: &T) -> bool {
3122                self.object.eq(other)
3123            }
3124        }
3125
3126        impl<'a> Eq for #class<'a> {}
3127
3128        #(
3129            #implementations
3130        )*
3131    }
3132}
3133
3134fn generate_interface_definition(definition: InterfaceGeneratorDefinition) -> TokenStream {
3135    let InterfaceGeneratorDefinition {
3136        interface,
3137        public,
3138        extends,
3139        methods,
3140        ..
3141    } = definition;
3142    let extends = if extends.is_empty() {
3143        TokenStream::new()
3144    } else {
3145        quote!{: #(#extends<'a>)+*}
3146    };
3147    let methods = methods
3148        .into_iter()
3149        .map(generate_interface_method)
3150        .collect::<Vec<_>>();
3151    quote! {
3152        #public trait #interface<'a> #extends {
3153            #(
3154                #methods
3155            )*
3156        }
3157    }
3158}
3159
3160#[cfg(test)]
3161mod generate_tests {
3162    use super::*;
3163
3164    #[test]
3165    fn empty() {
3166        let input = GeneratorData {
3167            definitions: vec![],
3168        };
3169        let expected = quote!{};
3170        assert_tokens_equals(generate(input), expected);
3171    }
3172
3173    #[test]
3174    fn one_class() {
3175        let input = GeneratorData {
3176            definitions: vec![GeneratorDefinition::Class(ClassGeneratorDefinition {
3177                class: Ident::new("test1", Span::call_site()),
3178                public: quote!{test_public},
3179                super_class: quote!{c::d::test2},
3180                transitive_extends: vec![quote!{c::d::test2}],
3181                implements: vec![],
3182                signature: Literal::string("test/sign1"),
3183                full_signature: Literal::string("test/signature1"),
3184                methods: vec![],
3185                static_methods: vec![],
3186                native_methods: vec![],
3187                static_native_methods: vec![],
3188                constructors: vec![],
3189            })],
3190        };
3191        let expected = quote!{
3192            #[derive(Debug)]
3193            test_public struct test1<'env> {
3194                object: c::d::test2<'env>,
3195            }
3196
3197            impl<'a> ::rust_jni::JavaType for test1<'a> {
3198                #[doc(hidden)]
3199                type __JniType = <::rust_jni::java::lang::Object<'a> as ::rust_jni::JavaType>::__JniType;
3200
3201                #[doc(hidden)]
3202                fn __signature() -> &'static str {
3203                    "test/signature1"
3204                }
3205            }
3206
3207            impl<'a> ::rust_jni::__generator::ToJni for test1<'a> {
3208                unsafe fn __to_jni(&self) -> Self::__JniType {
3209                    self.raw_object()
3210                }
3211            }
3212
3213            impl<'a> ::rust_jni::__generator::FromJni<'a> for test1<'a> {
3214                unsafe fn __from_jni(env: &'a ::rust_jni::JniEnv<'a>, value: Self::__JniType) -> Self {
3215                    Self {
3216                        object: <c::d::test2 as ::rust_jni::__generator::FromJni<'a>>::__from_jni(env, value),
3217                    }
3218                }
3219            }
3220
3221            impl<'a> ::rust_jni::Cast<'a, test1<'a>> for test1<'a> {
3222                #[doc(hidden)]
3223                fn cast<'b>(&'b self) -> &'b test1<'a> {
3224                    self
3225                }
3226            }
3227
3228            impl<'a> ::rust_jni::Cast<'a, c::d::test2<'a>> for test1<'a> {
3229                #[doc(hidden)]
3230                fn cast<'b>(&'b self) -> &'b c::d::test2<'a> {
3231                    self
3232                }
3233            }
3234
3235            impl<'a> ::std::ops::Deref for test1<'a> {
3236                type Target = c::d::test2<'a>;
3237
3238                fn deref(&self) -> &Self::Target {
3239                    &self.object
3240                }
3241            }
3242
3243            impl<'a> test1<'a> {
3244                pub fn get_class(env: &'a ::rust_jni::JniEnv<'a>, token: &::rust_jni::NoException<'a>)
3245                    -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::Class<'a>> {
3246                    ::rust_jni::java::lang::Class::find(env, "test/sign1", token)
3247                }
3248
3249                pub fn clone(&self, token: &::rust_jni::NoException<'a>) -> ::rust_jni::JavaResult<'a, Self>
3250                where
3251                    Self: Sized,
3252                {
3253                    self.object
3254                        .clone(token)
3255                        .map(|object| Self { object })
3256                }
3257
3258                pub fn to_string(&self, token: &::rust_jni::NoException<'a>)
3259                    -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::String<'a>> {
3260                    self.object.to_string(token)
3261                }
3262            }
3263
3264            impl<'a> ::std::fmt::Display for test1<'a> {
3265                fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
3266                    self.object.fmt(formatter)
3267                }
3268            }
3269
3270            impl<'a, T> PartialEq<T> for test1<'a> where T: ::rust_jni::Cast<'a, ::rust_jni::java::lang::Object<'a>> {
3271                fn eq(&self, other: &T) -> bool {
3272                    self.object.eq(other)
3273                }
3274            }
3275
3276            impl<'a> Eq for test1<'a> {}
3277        };
3278        assert_tokens_equals(generate(input), expected);
3279    }
3280
3281    #[test]
3282    fn one_class_implements() {
3283        let input = GeneratorData {
3284            definitions: vec![GeneratorDefinition::Class(ClassGeneratorDefinition {
3285                class: Ident::new("test1", Span::call_site()),
3286                public: quote!{test_public},
3287                super_class: quote!{c::d::test2},
3288                transitive_extends: vec![quote!{c::d::test2}],
3289                implements: vec![
3290                    InterfaceImplementationGeneratorDefinition {
3291                        interface: quote!{e::f::test3},
3292                        methods: vec![],
3293                    },
3294                    InterfaceImplementationGeneratorDefinition {
3295                        interface: quote!{e::f::test4},
3296                        methods: vec![],
3297                    },
3298                ],
3299                signature: Literal::string("test/sign1"),
3300                full_signature: Literal::string("test/signature1"),
3301                methods: vec![],
3302                static_methods: vec![],
3303                native_methods: vec![],
3304                static_native_methods: vec![],
3305                constructors: vec![],
3306            })],
3307        };
3308        let expected = quote!{
3309            #[derive(Debug)]
3310            test_public struct test1<'env> {
3311                object: c::d::test2<'env>,
3312            }
3313
3314            impl<'a> ::rust_jni::JavaType for test1<'a> {
3315                #[doc(hidden)]
3316                type __JniType = <::rust_jni::java::lang::Object<'a> as ::rust_jni::JavaType>::__JniType;
3317
3318                #[doc(hidden)]
3319                fn __signature() -> &'static str {
3320                    "test/signature1"
3321                }
3322            }
3323
3324            impl<'a> ::rust_jni::__generator::ToJni for test1<'a> {
3325                unsafe fn __to_jni(&self) -> Self::__JniType {
3326                    self.raw_object()
3327                }
3328            }
3329
3330            impl<'a> ::rust_jni::__generator::FromJni<'a> for test1<'a> {
3331                unsafe fn __from_jni(env: &'a ::rust_jni::JniEnv<'a>, value: Self::__JniType) -> Self {
3332                    Self {
3333                        object: <c::d::test2 as ::rust_jni::__generator::FromJni<'a>>::__from_jni(env, value),
3334                    }
3335                }
3336            }
3337
3338            impl<'a> ::rust_jni::Cast<'a, test1<'a>> for test1<'a> {
3339                #[doc(hidden)]
3340                fn cast<'b>(&'b self) -> &'b test1<'a> {
3341                    self
3342                }
3343            }
3344
3345            impl<'a> ::rust_jni::Cast<'a, c::d::test2<'a>> for test1<'a> {
3346                #[doc(hidden)]
3347                fn cast<'b>(&'b self) -> &'b c::d::test2<'a> {
3348                    self
3349                }
3350            }
3351
3352            impl<'a> ::std::ops::Deref for test1<'a> {
3353                type Target = c::d::test2<'a>;
3354
3355                fn deref(&self) -> &Self::Target {
3356                    &self.object
3357                }
3358            }
3359
3360            impl<'a> test1<'a> {
3361                pub fn get_class(env: &'a ::rust_jni::JniEnv<'a>, token: &::rust_jni::NoException<'a>)
3362                    -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::Class<'a>> {
3363                    ::rust_jni::java::lang::Class::find(env, "test/sign1", token)
3364                }
3365
3366                pub fn clone(&self, token: &::rust_jni::NoException<'a>) -> ::rust_jni::JavaResult<'a, Self>
3367                where
3368                    Self: Sized,
3369                {
3370                    self.object
3371                        .clone(token)
3372                        .map(|object| Self { object })
3373                }
3374
3375                pub fn to_string(&self, token: &::rust_jni::NoException<'a>)
3376                    -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::String<'a>> {
3377                    self.object.to_string(token)
3378                }
3379            }
3380
3381            impl<'a> ::std::fmt::Display for test1<'a> {
3382                fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
3383                    self.object.fmt(formatter)
3384                }
3385            }
3386
3387            impl<'a, T> PartialEq<T> for test1<'a> where T: ::rust_jni::Cast<'a, ::rust_jni::java::lang::Object<'a>> {
3388                fn eq(&self, other: &T) -> bool {
3389                    self.object.eq(other)
3390                }
3391            }
3392
3393            impl<'a> Eq for test1<'a> {}
3394
3395            impl<'a> e::f::test3<'a> for test1<'a> {
3396            }
3397
3398            impl<'a> e::f::test4<'a> for test1<'a> {
3399            }
3400        };
3401        assert_tokens_equals(generate(input), expected);
3402    }
3403
3404    #[test]
3405    fn one_interface() {
3406        let input = GeneratorData {
3407            definitions: vec![GeneratorDefinition::Interface(
3408                InterfaceGeneratorDefinition {
3409                    interface: Ident::new("test1", Span::call_site()),
3410                    public: quote!{test_public},
3411                    extends: vec![],
3412                    methods: vec![],
3413                },
3414            )],
3415        };
3416        let expected = quote!{
3417            test_public trait test1<'a> {
3418            }
3419        };
3420        assert_tokens_equals(generate(input), expected);
3421    }
3422
3423    #[test]
3424    fn one_interface_extends() {
3425        let input = GeneratorData {
3426            definitions: vec![GeneratorDefinition::Interface(
3427                InterfaceGeneratorDefinition {
3428                    interface: Ident::new("test1", Span::call_site()),
3429                    public: TokenStream::new(),
3430                    extends: vec![quote!{c::d::test2}, quote!{e::f::test3}],
3431                    methods: vec![],
3432                },
3433            )],
3434        };
3435        let expected = quote!{
3436            trait test1<'a> : c::d::test2<'a> + e::f::test3<'a> {
3437            }
3438        };
3439        assert_tokens_equals(generate(input), expected);
3440    }
3441
3442    #[test]
3443    fn multiple() {
3444        let input = GeneratorData {
3445            definitions: vec![
3446                GeneratorDefinition::Interface(InterfaceGeneratorDefinition {
3447                    interface: Ident::new("test_if1", Span::call_site()),
3448                    public: TokenStream::new(),
3449                    extends: vec![],
3450                    methods: vec![],
3451                }),
3452                GeneratorDefinition::Interface(InterfaceGeneratorDefinition {
3453                    interface: Ident::new("test_if2", Span::call_site()),
3454                    public: TokenStream::new(),
3455                    extends: vec![],
3456                    methods: vec![],
3457                }),
3458                GeneratorDefinition::Class(ClassGeneratorDefinition {
3459                    class: Ident::new("test1", Span::call_site()),
3460                    public: TokenStream::new(),
3461                    super_class: quote!{c::d::test3},
3462                    transitive_extends: vec![quote!{c::d::test3}],
3463                    implements: vec![],
3464                    signature: Literal::string("test/sign1"),
3465                    full_signature: Literal::string("test/signature1"),
3466                    methods: vec![],
3467                    static_methods: vec![],
3468                    constructors: vec![],
3469                    native_methods: vec![],
3470                    static_native_methods: vec![],
3471                }),
3472                GeneratorDefinition::Class(ClassGeneratorDefinition {
3473                    class: Ident::new("test2", Span::call_site()),
3474                    public: TokenStream::new(),
3475                    super_class: quote!{c::d::test4},
3476                    transitive_extends: vec![quote!{c::d::test4}],
3477                    implements: vec![],
3478                    signature: Literal::string("test/sign2"),
3479                    full_signature: Literal::string("test/signature2"),
3480                    methods: vec![],
3481                    static_methods: vec![],
3482                    native_methods: vec![],
3483                    static_native_methods: vec![],
3484                    constructors: vec![],
3485                }),
3486            ],
3487        };
3488        let expected = quote!{
3489            trait test_if1<'a> {
3490            }
3491
3492            trait test_if2<'a> {
3493            }
3494
3495            #[derive(Debug)]
3496            struct test1<'env> {
3497                object: c::d::test3<'env>,
3498            }
3499
3500            impl<'a> ::rust_jni::JavaType for test1<'a> {
3501                #[doc(hidden)]
3502                type __JniType = <::rust_jni::java::lang::Object<'a> as ::rust_jni::JavaType>::__JniType;
3503
3504                #[doc(hidden)]
3505                fn __signature() -> &'static str {
3506                    "test/signature1"
3507                }
3508            }
3509
3510            impl<'a> ::rust_jni::__generator::ToJni for test1<'a> {
3511                unsafe fn __to_jni(&self) -> Self::__JniType {
3512                    self.raw_object()
3513                }
3514            }
3515
3516            impl<'a> ::rust_jni::__generator::FromJni<'a> for test1<'a> {
3517                unsafe fn __from_jni(env: &'a ::rust_jni::JniEnv<'a>, value: Self::__JniType) -> Self {
3518                    Self {
3519                        object: <c::d::test3 as ::rust_jni::__generator::FromJni<'a>>::__from_jni(env, value),
3520                    }
3521                }
3522            }
3523
3524            impl<'a> ::rust_jni::Cast<'a, test1<'a>> for test1<'a> {
3525                #[doc(hidden)]
3526                fn cast<'b>(&'b self) -> &'b test1<'a> {
3527                    self
3528                }
3529            }
3530
3531            impl<'a> ::rust_jni::Cast<'a, c::d::test3<'a>> for test1<'a> {
3532                #[doc(hidden)]
3533                fn cast<'b>(&'b self) -> &'b c::d::test3<'a> {
3534                    self
3535                }
3536            }
3537
3538            impl<'a> ::std::ops::Deref for test1<'a> {
3539                type Target = c::d::test3<'a>;
3540
3541                fn deref(&self) -> &Self::Target {
3542                    &self.object
3543                }
3544            }
3545
3546            impl<'a> test1<'a> {
3547                pub fn get_class(env: &'a ::rust_jni::JniEnv<'a>, token: &::rust_jni::NoException<'a>)
3548                    -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::Class<'a>> {
3549                    ::rust_jni::java::lang::Class::find(env, "test/sign1", token)
3550                }
3551
3552                pub fn clone(&self, token: &::rust_jni::NoException<'a>) -> ::rust_jni::JavaResult<'a, Self>
3553                where
3554                    Self: Sized,
3555                {
3556                    self.object
3557                        .clone(token)
3558                        .map(|object| Self { object })
3559                }
3560
3561                pub fn to_string(&self, token: &::rust_jni::NoException<'a>)
3562                    -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::String<'a>> {
3563                    self.object.to_string(token)
3564                }
3565            }
3566
3567            impl<'a> ::std::fmt::Display for test1<'a> {
3568                fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
3569                    self.object.fmt(formatter)
3570                }
3571            }
3572
3573            impl<'a, T> PartialEq<T> for test1<'a> where T: ::rust_jni::Cast<'a, ::rust_jni::java::lang::Object<'a>> {
3574                fn eq(&self, other: &T) -> bool {
3575                    self.object.eq(other)
3576                }
3577            }
3578
3579            impl<'a> Eq for test1<'a> {}
3580
3581            #[derive(Debug)]
3582            struct test2<'env> {
3583                object: c::d::test4<'env>,
3584            }
3585
3586            impl<'a> ::rust_jni::JavaType for test2<'a> {
3587                #[doc(hidden)]
3588                type __JniType = <::rust_jni::java::lang::Object<'a> as ::rust_jni::JavaType>::__JniType;
3589
3590                #[doc(hidden)]
3591                fn __signature() -> &'static str {
3592                    "test/signature2"
3593                }
3594            }
3595
3596            impl<'a> ::rust_jni::__generator::ToJni for test2<'a> {
3597                unsafe fn __to_jni(&self) -> Self::__JniType {
3598                    self.raw_object()
3599                }
3600            }
3601
3602            impl<'a> ::rust_jni::__generator::FromJni<'a> for test2<'a> {
3603                unsafe fn __from_jni(env: &'a ::rust_jni::JniEnv<'a>, value: Self::__JniType) -> Self {
3604                    Self {
3605                        object: <c::d::test4 as ::rust_jni::__generator::FromJni<'a>>::__from_jni(env, value),
3606                    }
3607                }
3608            }
3609
3610            impl<'a> ::rust_jni::Cast<'a, test2<'a>> for test2<'a> {
3611                #[doc(hidden)]
3612                fn cast<'b>(&'b self) -> &'b test2<'a> {
3613                    self
3614                }
3615            }
3616
3617            impl<'a> ::rust_jni::Cast<'a, c::d::test4<'a>> for test2<'a> {
3618                #[doc(hidden)]
3619                fn cast<'b>(&'b self) -> &'b c::d::test4<'a> {
3620                    self
3621                }
3622            }
3623
3624            impl<'a> ::std::ops::Deref for test2<'a> {
3625                type Target = c::d::test4<'a>;
3626
3627                fn deref(&self) -> &Self::Target {
3628                    &self.object
3629                }
3630            }
3631
3632            impl<'a> test2<'a> {
3633                pub fn get_class(env: &'a ::rust_jni::JniEnv<'a>, token: &::rust_jni::NoException<'a>)
3634                    -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::Class<'a>> {
3635                    ::rust_jni::java::lang::Class::find(env, "test/sign2", token)
3636                }
3637
3638                pub fn clone(&self, token: &::rust_jni::NoException<'a>) -> ::rust_jni::JavaResult<'a, Self>
3639                where
3640                    Self: Sized,
3641                {
3642                    self.object
3643                        .clone(token)
3644                        .map(|object| Self { object })
3645                }
3646
3647                pub fn to_string(&self, token: &::rust_jni::NoException<'a>)
3648                    -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::String<'a>> {
3649                    self.object.to_string(token)
3650                }
3651            }
3652
3653            impl<'a> ::std::fmt::Display for test2<'a> {
3654                fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
3655                    self.object.fmt(formatter)
3656                }
3657            }
3658
3659            impl<'a, T> PartialEq<T> for test2<'a> where T: ::rust_jni::Cast<'a, ::rust_jni::java::lang::Object<'a>> {
3660                fn eq(&self, other: &T) -> bool {
3661                    self.object.eq(other)
3662                }
3663            }
3664
3665            impl<'a> Eq for test2<'a> {}
3666        };
3667        assert_tokens_equals(generate(input), expected);
3668    }
3669}
3670
3671#[cfg(test)]
3672mod java_generate_tests {
3673    use super::*;
3674
3675    #[test]
3676    fn empty() {
3677        let input = quote!{};
3678        let expected = quote!{};
3679        assert_tokens_equals(java_generate_impl(input), expected);
3680    }
3681
3682    #[test]
3683    fn one_class() {
3684        let input = quote!{
3685            class TestClass1 extends TestClass2 {}
3686        };
3687        let expected = quote!{
3688            #[derive(Debug)]
3689            struct TestClass1<'env> {
3690                object: ::TestClass2<'env>,
3691            }
3692
3693            impl<'a> ::rust_jni::JavaType for TestClass1<'a> {
3694                #[doc(hidden)]
3695                type __JniType = <::rust_jni::java::lang::Object<'a> as ::rust_jni::JavaType>::__JniType;
3696
3697                #[doc(hidden)]
3698                fn __signature() -> &'static str {
3699                    "LTestClass1;"
3700                }
3701            }
3702
3703            impl<'a> ::rust_jni::__generator::ToJni for TestClass1<'a> {
3704                unsafe fn __to_jni(&self) -> Self::__JniType {
3705                    self.raw_object()
3706                }
3707            }
3708
3709            impl<'a> ::rust_jni::__generator::FromJni<'a> for TestClass1<'a> {
3710                unsafe fn __from_jni(env: &'a ::rust_jni::JniEnv<'a>, value: Self::__JniType) -> Self {
3711                    Self {
3712                        object: <::TestClass2 as ::rust_jni::__generator::FromJni<'a>>::__from_jni(env, value),
3713                    }
3714                }
3715            }
3716
3717            impl<'a> ::rust_jni::Cast<'a, TestClass1<'a>> for TestClass1<'a> {
3718                #[doc(hidden)]
3719                fn cast<'b>(&'b self) -> &'b TestClass1<'a> {
3720                    self
3721                }
3722            }
3723
3724            impl<'a> ::rust_jni::Cast<'a, ::TestClass2<'a>> for TestClass1<'a> {
3725                #[doc(hidden)]
3726                fn cast<'b>(&'b self) -> &'b ::TestClass2<'a> {
3727                    self
3728                }
3729            }
3730
3731            impl<'a> ::std::ops::Deref for TestClass1<'a> {
3732                type Target = ::TestClass2<'a>;
3733
3734                fn deref(&self) -> &Self::Target {
3735                    &self.object
3736                }
3737            }
3738
3739            impl<'a> TestClass1<'a> {
3740                pub fn get_class(env: &'a ::rust_jni::JniEnv<'a>, token: &::rust_jni::NoException<'a>)
3741                    -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::Class<'a>> {
3742                    ::rust_jni::java::lang::Class::find(env, "TestClass1", token)
3743                }
3744
3745                pub fn clone(&self, token: &::rust_jni::NoException<'a>) -> ::rust_jni::JavaResult<'a, Self>
3746                where
3747                    Self: Sized,
3748                {
3749                    self.object
3750                        .clone(token)
3751                        .map(|object| Self { object })
3752                }
3753
3754                pub fn to_string(&self, token: &::rust_jni::NoException<'a>)
3755                    -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::String<'a>> {
3756                    self.object.to_string(token)
3757                }
3758            }
3759
3760            impl<'a> ::std::fmt::Display for TestClass1<'a> {
3761                fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
3762                    self.object.fmt(formatter)
3763                }
3764            }
3765
3766            impl<'a, T> PartialEq<T> for TestClass1<'a> where T: ::rust_jni::Cast<'a, ::rust_jni::java::lang::Object<'a>> {
3767                fn eq(&self, other: &T) -> bool {
3768                    self.object.eq(other)
3769                }
3770            }
3771
3772            impl<'a> Eq for TestClass1<'a> {}
3773        };
3774        assert_tokens_equals(java_generate_impl(input), expected);
3775    }
3776
3777    #[test]
3778    fn one_class_implements() {
3779        let input = quote!{
3780            interface a.b.TestInterface1 {}
3781            interface a.b.TestInterface2 {}
3782            class TestClass1 extends TestClass2 implements a.b.TestInterface1, a.b.TestInterface2 {}
3783        };
3784        let expected = quote!{
3785            trait TestInterface1<'a> {
3786            }
3787
3788            trait TestInterface2<'a> {
3789            }
3790
3791            #[derive(Debug)]
3792            struct TestClass1<'env> {
3793                object: ::TestClass2<'env>,
3794            }
3795
3796            impl<'a> ::rust_jni::JavaType for TestClass1<'a> {
3797                #[doc(hidden)]
3798                type __JniType = <::rust_jni::java::lang::Object<'a> as ::rust_jni::JavaType>::__JniType;
3799
3800                #[doc(hidden)]
3801                fn __signature() -> &'static str {
3802                    "LTestClass1;"
3803                }
3804            }
3805
3806            impl<'a> ::rust_jni::__generator::ToJni for TestClass1<'a> {
3807                unsafe fn __to_jni(&self) -> Self::__JniType {
3808                    self.raw_object()
3809                }
3810            }
3811
3812            impl<'a> ::rust_jni::__generator::FromJni<'a> for TestClass1<'a> {
3813                unsafe fn __from_jni(env: &'a ::rust_jni::JniEnv<'a>, value: Self::__JniType) -> Self {
3814                    Self {
3815                        object: <::TestClass2 as ::rust_jni::__generator::FromJni<'a>>::__from_jni(env, value),
3816                    }
3817                }
3818            }
3819
3820            impl<'a> ::rust_jni::Cast<'a, TestClass1<'a>> for TestClass1<'a> {
3821                #[doc(hidden)]
3822                fn cast<'b>(&'b self) -> &'b TestClass1<'a> {
3823                    self
3824                }
3825            }
3826
3827            impl<'a> ::rust_jni::Cast<'a, ::TestClass2<'a>> for TestClass1<'a> {
3828                #[doc(hidden)]
3829                fn cast<'b>(&'b self) -> &'b ::TestClass2<'a> {
3830                    self
3831                }
3832            }
3833
3834            impl<'a> ::std::ops::Deref for TestClass1<'a> {
3835                type Target = ::TestClass2<'a>;
3836
3837                fn deref(&self) -> &Self::Target {
3838                    &self.object
3839                }
3840            }
3841
3842            impl<'a> TestClass1<'a> {
3843                pub fn get_class(env: &'a ::rust_jni::JniEnv<'a>, token: &::rust_jni::NoException<'a>)
3844                    -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::Class<'a>> {
3845                    ::rust_jni::java::lang::Class::find(env, "TestClass1", token)
3846                }
3847
3848                pub fn clone(&self, token: &::rust_jni::NoException<'a>) -> ::rust_jni::JavaResult<'a, Self>
3849                where
3850                    Self: Sized,
3851                {
3852                    self.object
3853                        .clone(token)
3854                        .map(|object| Self { object })
3855                }
3856
3857                pub fn to_string(&self, token: &::rust_jni::NoException<'a>)
3858                    -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::String<'a>> {
3859                    self.object.to_string(token)
3860                }
3861            }
3862
3863            impl<'a> ::std::fmt::Display for TestClass1<'a> {
3864                fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
3865                    self.object.fmt(formatter)
3866                }
3867            }
3868
3869            impl<'a, T> PartialEq<T> for TestClass1<'a> where T: ::rust_jni::Cast<'a, ::rust_jni::java::lang::Object<'a>> {
3870                fn eq(&self, other: &T) -> bool {
3871                    self.object.eq(other)
3872                }
3873            }
3874
3875            impl<'a> Eq for TestClass1<'a> {}
3876
3877            impl<'a> ::a::b::TestInterface1<'a> for TestClass1<'a> {
3878            }
3879
3880            impl<'a> ::a::b::TestInterface2<'a> for TestClass1<'a> {
3881            }
3882        };
3883        assert_tokens_equals(java_generate_impl(input), expected);
3884    }
3885
3886    #[test]
3887    fn one_class_packaged() {
3888        let input = quote!{
3889            class a.b.TestClass1 extends c.d.TestClass2 {}
3890        };
3891        let expected = quote!{
3892            #[derive(Debug)]
3893            struct TestClass1<'env> {
3894                object: ::c::d::TestClass2<'env>,
3895            }
3896
3897            impl<'a> ::rust_jni::JavaType for TestClass1<'a> {
3898                #[doc(hidden)]
3899                type __JniType = <::rust_jni::java::lang::Object<'a> as ::rust_jni::JavaType>::__JniType;
3900
3901                #[doc(hidden)]
3902                fn __signature() -> &'static str {
3903                    "La/b/TestClass1;"
3904                }
3905            }
3906
3907            impl<'a> ::rust_jni::__generator::ToJni for TestClass1<'a> {
3908                unsafe fn __to_jni(&self) -> Self::__JniType {
3909                    self.raw_object()
3910                }
3911            }
3912
3913            impl<'a> ::rust_jni::__generator::FromJni<'a> for TestClass1<'a> {
3914                unsafe fn __from_jni(env: &'a ::rust_jni::JniEnv<'a>, value: Self::__JniType) -> Self {
3915                    Self {
3916                        object: <::c::d::TestClass2 as ::rust_jni::__generator::FromJni<'a>>::__from_jni(env, value),
3917                    }
3918                }
3919            }
3920
3921            impl<'a> ::rust_jni::Cast<'a, TestClass1<'a>> for TestClass1<'a> {
3922                #[doc(hidden)]
3923                fn cast<'b>(&'b self) -> &'b TestClass1<'a> {
3924                    self
3925                }
3926            }
3927
3928            impl<'a> ::rust_jni::Cast<'a, ::c::d::TestClass2<'a>> for TestClass1<'a> {
3929                #[doc(hidden)]
3930                fn cast<'b>(&'b self) -> &'b ::c::d::TestClass2<'a> {
3931                    self
3932                }
3933            }
3934
3935            impl<'a> ::std::ops::Deref for TestClass1<'a> {
3936                type Target = ::c::d::TestClass2<'a>;
3937
3938                fn deref(&self) -> &Self::Target {
3939                    &self.object
3940                }
3941            }
3942
3943            impl<'a> TestClass1<'a> {
3944                pub fn get_class(env: &'a ::rust_jni::JniEnv<'a>, token: &::rust_jni::NoException<'a>)
3945                    -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::Class<'a>> {
3946                    ::rust_jni::java::lang::Class::find(env, "a/b/TestClass1", token)
3947                }
3948
3949                pub fn clone(&self, token: &::rust_jni::NoException<'a>) -> ::rust_jni::JavaResult<'a, Self>
3950                where
3951                    Self: Sized,
3952                {
3953                    self.object
3954                        .clone(token)
3955                        .map(|object| Self { object })
3956                }
3957
3958                pub fn to_string(&self, token: &::rust_jni::NoException<'a>)
3959                    -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::String<'a>> {
3960                    self.object.to_string(token)
3961                }
3962            }
3963
3964            impl<'a> ::std::fmt::Display for TestClass1<'a> {
3965                fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
3966                    self.object.fmt(formatter)
3967                }
3968            }
3969
3970            impl<'a, T> PartialEq<T> for TestClass1<'a> where T: ::rust_jni::Cast<'a, ::rust_jni::java::lang::Object<'a>> {
3971                fn eq(&self, other: &T) -> bool {
3972                    self.object.eq(other)
3973                }
3974            }
3975
3976            impl<'a> Eq for TestClass1<'a> {}
3977        };
3978        assert_tokens_equals(java_generate_impl(input), expected);
3979    }
3980
3981    #[test]
3982    fn one_class_public() {
3983        let input = quote!{
3984            public class TestClass1 extends TestClass2 {}
3985        };
3986        let expected = quote!{
3987            #[derive(Debug)]
3988            pub struct TestClass1<'env> {
3989                object: ::TestClass2<'env>,
3990            }
3991
3992            impl<'a> ::rust_jni::JavaType for TestClass1<'a> {
3993                #[doc(hidden)]
3994                type __JniType = <::rust_jni::java::lang::Object<'a> as ::rust_jni::JavaType>::__JniType;
3995
3996                #[doc(hidden)]
3997                fn __signature() -> &'static str {
3998                    "LTestClass1;"
3999                }
4000            }
4001
4002            impl<'a> ::rust_jni::__generator::ToJni for TestClass1<'a> {
4003                unsafe fn __to_jni(&self) -> Self::__JniType {
4004                    self.raw_object()
4005                }
4006            }
4007
4008            impl<'a> ::rust_jni::__generator::FromJni<'a> for TestClass1<'a> {
4009                unsafe fn __from_jni(env: &'a ::rust_jni::JniEnv<'a>, value: Self::__JniType) -> Self {
4010                    Self {
4011                        object: <::TestClass2 as ::rust_jni::__generator::FromJni<'a>>::__from_jni(env, value),
4012                    }
4013                }
4014            }
4015
4016            impl<'a> ::rust_jni::Cast<'a, TestClass1<'a>> for TestClass1<'a> {
4017                #[doc(hidden)]
4018                fn cast<'b>(&'b self) -> &'b TestClass1<'a> {
4019                    self
4020                }
4021            }
4022
4023            impl<'a> ::rust_jni::Cast<'a, ::TestClass2<'a>> for TestClass1<'a> {
4024                #[doc(hidden)]
4025                fn cast<'b>(&'b self) -> &'b ::TestClass2<'a> {
4026                    self
4027                }
4028            }
4029
4030            impl<'a> ::std::ops::Deref for TestClass1<'a> {
4031                type Target = ::TestClass2<'a>;
4032
4033                fn deref(&self) -> &Self::Target {
4034                    &self.object
4035                }
4036            }
4037
4038            impl<'a> TestClass1<'a> {
4039                pub fn get_class(env: &'a ::rust_jni::JniEnv<'a>, token: &::rust_jni::NoException<'a>)
4040                    -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::Class<'a>> {
4041                    ::rust_jni::java::lang::Class::find(env, "TestClass1", token)
4042                }
4043
4044                pub fn clone(&self, token: &::rust_jni::NoException<'a>) -> ::rust_jni::JavaResult<'a, Self>
4045                where
4046                    Self: Sized,
4047                {
4048                    self.object
4049                        .clone(token)
4050                        .map(|object| Self { object })
4051                }
4052
4053                pub fn to_string(&self, token: &::rust_jni::NoException<'a>)
4054                    -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::String<'a>> {
4055                    self.object.to_string(token)
4056                }
4057            }
4058
4059            impl<'a> ::std::fmt::Display for TestClass1<'a> {
4060                fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
4061                    self.object.fmt(formatter)
4062                }
4063            }
4064
4065            impl<'a, T> PartialEq<T> for TestClass1<'a> where T: ::rust_jni::Cast<'a, ::rust_jni::java::lang::Object<'a>> {
4066                fn eq(&self, other: &T) -> bool {
4067                    self.object.eq(other)
4068                }
4069            }
4070
4071            impl<'a> Eq for TestClass1<'a> {}
4072        };
4073        assert_tokens_equals(java_generate_impl(input), expected);
4074    }
4075
4076    #[test]
4077    fn one_interface() {
4078        let input = quote!{
4079            interface TestInterface1 {}
4080        };
4081        let expected = quote!{
4082            trait TestInterface1<'a> {
4083            }
4084        };
4085        assert_tokens_equals(java_generate_impl(input), expected);
4086    }
4087
4088    #[test]
4089    fn one_interface_packaged() {
4090        let input = quote!{
4091            interface a.b.TestInterface1 {}
4092        };
4093        let expected = quote!{
4094            trait TestInterface1<'a> {
4095            }
4096        };
4097        assert_tokens_equals(java_generate_impl(input), expected);
4098    }
4099
4100    #[test]
4101    fn one_interface_public() {
4102        let input = quote!{
4103            public interface TestInterface1 {}
4104        };
4105        let expected = quote!{
4106            pub trait TestInterface1<'a> {
4107            }
4108        };
4109        assert_tokens_equals(java_generate_impl(input), expected);
4110    }
4111
4112    #[test]
4113    fn one_interface_extends() {
4114        let input = quote!{
4115            interface TestInterface2 {}
4116            interface TestInterface3 {}
4117            interface TestInterface1 extends TestInterface2, TestInterface3 {}
4118        };
4119        let expected = quote!{
4120            trait TestInterface2<'a> {
4121            }
4122
4123            trait TestInterface3<'a> {
4124            }
4125
4126            trait TestInterface1<'a>: ::TestInterface2<'a> + ::TestInterface3<'a> {
4127            }
4128        };
4129        assert_tokens_equals(java_generate_impl(input), expected);
4130    }
4131
4132    #[test]
4133    fn multiple() {
4134        let input = quote!{
4135            interface TestInterface1 {}
4136            interface TestInterface2 {}
4137            class TestClass1 {}
4138            class TestClass2 {}
4139
4140            metadata {
4141                interface TestInterface3 {}
4142                class TestClass3;
4143            }
4144        };
4145        let expected = quote!{
4146            trait TestInterface1<'a> {
4147            }
4148
4149            trait TestInterface2<'a> {
4150            }
4151
4152            #[derive(Debug)]
4153            struct TestClass1<'env> {
4154                object: ::java::lang::Object<'env>,
4155            }
4156
4157            impl<'a> ::rust_jni::JavaType for TestClass1<'a> {
4158                #[doc(hidden)]
4159                type __JniType = <::rust_jni::java::lang::Object<'a> as ::rust_jni::JavaType>::__JniType;
4160
4161                #[doc(hidden)]
4162                fn __signature() -> &'static str {
4163                    "LTestClass1;"
4164                }
4165            }
4166
4167            impl<'a> ::rust_jni::__generator::ToJni for TestClass1<'a> {
4168                unsafe fn __to_jni(&self) -> Self::__JniType {
4169                    self.raw_object()
4170                }
4171            }
4172
4173            impl<'a> ::rust_jni::__generator::FromJni<'a> for TestClass1<'a> {
4174                unsafe fn __from_jni(env: &'a ::rust_jni::JniEnv<'a>, value: Self::__JniType) -> Self {
4175                    Self {
4176                        object: <::java::lang::Object as ::rust_jni::__generator::FromJni<'a>>::__from_jni(env, value),
4177                    }
4178                }
4179            }
4180
4181            impl<'a> ::rust_jni::Cast<'a, TestClass1<'a>> for TestClass1<'a> {
4182                #[doc(hidden)]
4183                fn cast<'b>(&'b self) -> &'b TestClass1<'a> {
4184                    self
4185                }
4186            }
4187
4188            impl<'a> ::rust_jni::Cast<'a, ::java::lang::Object<'a>> for TestClass1<'a> {
4189                #[doc(hidden)]
4190                fn cast<'b>(&'b self) -> &'b ::java::lang::Object<'a> {
4191                    self
4192                }
4193            }
4194
4195            impl<'a> ::std::ops::Deref for TestClass1<'a> {
4196                type Target = ::java::lang::Object<'a>;
4197
4198                fn deref(&self) -> &Self::Target {
4199                    &self.object
4200                }
4201            }
4202
4203            impl<'a> TestClass1<'a> {
4204                pub fn get_class(env: &'a ::rust_jni::JniEnv<'a>, token: &::rust_jni::NoException<'a>)
4205                    -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::Class<'a>> {
4206                    ::rust_jni::java::lang::Class::find(env, "TestClass1", token)
4207                }
4208
4209                pub fn clone(&self, token: &::rust_jni::NoException<'a>) -> ::rust_jni::JavaResult<'a, Self>
4210                where
4211                    Self: Sized,
4212                {
4213                    self.object
4214                        .clone(token)
4215                        .map(|object| Self { object })
4216                }
4217
4218                pub fn to_string(&self, token: &::rust_jni::NoException<'a>)
4219                    -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::String<'a>> {
4220                    self.object.to_string(token)
4221                }
4222            }
4223
4224            impl<'a> ::std::fmt::Display for TestClass1<'a> {
4225                fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
4226                    self.object.fmt(formatter)
4227                }
4228            }
4229
4230            impl<'a, T> PartialEq<T> for TestClass1<'a> where T: ::rust_jni::Cast<'a, ::rust_jni::java::lang::Object<'a>> {
4231                fn eq(&self, other: &T) -> bool {
4232                    self.object.eq(other)
4233                }
4234            }
4235
4236            impl<'a> Eq for TestClass1<'a> {}
4237
4238            #[derive(Debug)]
4239            struct TestClass2<'env> {
4240                object: ::java::lang::Object<'env>,
4241            }
4242
4243            impl<'a> ::rust_jni::JavaType for TestClass2<'a> {
4244                #[doc(hidden)]
4245                type __JniType = <::rust_jni::java::lang::Object<'a> as ::rust_jni::JavaType>::__JniType;
4246
4247                #[doc(hidden)]
4248                fn __signature() -> &'static str {
4249                    "LTestClass2;"
4250                }
4251            }
4252
4253            impl<'a> ::rust_jni::__generator::ToJni for TestClass2<'a> {
4254                unsafe fn __to_jni(&self) -> Self::__JniType {
4255                    self.raw_object()
4256                }
4257            }
4258
4259            impl<'a> ::rust_jni::__generator::FromJni<'a> for TestClass2<'a> {
4260                unsafe fn __from_jni(env: &'a ::rust_jni::JniEnv<'a>, value: Self::__JniType) -> Self {
4261                    Self {
4262                        object: <::java::lang::Object as ::rust_jni::__generator::FromJni<'a>>::__from_jni(env, value),
4263                    }
4264                }
4265            }
4266
4267            impl<'a> ::rust_jni::Cast<'a, TestClass2<'a>> for TestClass2<'a> {
4268                #[doc(hidden)]
4269                fn cast<'b>(&'b self) -> &'b TestClass2<'a> {
4270                    self
4271                }
4272            }
4273
4274            impl<'a> ::rust_jni::Cast<'a, ::java::lang::Object<'a>> for TestClass2<'a> {
4275                #[doc(hidden)]
4276                fn cast<'b>(&'b self) -> &'b ::java::lang::Object<'a> {
4277                    self
4278                }
4279            }
4280
4281            impl<'a> ::std::ops::Deref for TestClass2<'a> {
4282                type Target = ::java::lang::Object<'a>;
4283
4284                fn deref(&self) -> &Self::Target {
4285                    &self.object
4286                }
4287            }
4288
4289            impl<'a> TestClass2<'a> {
4290                pub fn get_class(env: &'a ::rust_jni::JniEnv<'a>, token: &::rust_jni::NoException<'a>)
4291                    -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::Class<'a>> {
4292                    ::rust_jni::java::lang::Class::find(env, "TestClass2", token)
4293                }
4294
4295                pub fn clone(&self, token: &::rust_jni::NoException<'a>) -> ::rust_jni::JavaResult<'a, Self>
4296                where
4297                    Self: Sized,
4298                {
4299                    self.object
4300                        .clone(token)
4301                        .map(|object| Self { object })
4302                }
4303
4304                pub fn to_string(&self, token: &::rust_jni::NoException<'a>)
4305                    -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::String<'a>> {
4306                    self.object.to_string(token)
4307                }
4308            }
4309
4310            impl<'a> ::std::fmt::Display for TestClass2<'a> {
4311                fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
4312                    self.object.fmt(formatter)
4313                }
4314            }
4315
4316            impl<'a, T> PartialEq<T> for TestClass2<'a> where T: ::rust_jni::Cast<'a, ::rust_jni::java::lang::Object<'a>> {
4317                fn eq(&self, other: &T) -> bool {
4318                    self.object.eq(other)
4319                }
4320            }
4321
4322            impl<'a> Eq for TestClass2<'a> {}
4323        };
4324        assert_tokens_equals(java_generate_impl(input), expected);
4325    }
4326
4327    #[test]
4328    fn integration() {
4329        let input = quote!{
4330            public interface a.b.TestInterface3 {
4331                long primitiveInterfaceFunc3(int arg1, char arg2);
4332                a.b.TestClass3 objectInterfaceFunc3(a.b.TestClass3 arg);
4333            }
4334
4335            public interface a.b.TestInterface4 extends c.d.TestInterface2, a.b.TestInterface3 {
4336                @RustName(primitive_func_3)
4337                long primitiveFunc3(int arg1, char arg2);
4338                @RustName(object_func_3)
4339                c.d.TestClass2 objectFunc3(a.b.TestClass3 arg);
4340            }
4341
4342            public class a.b.TestClass3 extends c.d.TestClass2 implements e.f.TestInterface1, a.b.TestInterface4 {
4343                @RustName(init)
4344                public a.b.TestClass3(int arg1, a.b.TestClass3 arg2);
4345
4346                @RustName(primitive_func_3)
4347                long primitiveFunc3(int arg1, char arg2);
4348                @RustName(object_func_3)
4349                public c.d.TestClass2 objectFunc3(a.b.TestClass3 arg);
4350
4351                @RustName(primitive_static_func_3)
4352                static long primitiveStaticFunc3(int arg1, char arg2);
4353                @RustName(object_static_func_3)
4354                public static c.d.TestClass2 objectStaticFunc3(a.b.TestClass3 arg);
4355
4356                @RustName(primitive_native_func_3)
4357                public native long primitiveNativeFunc3(int arg1, char arg2) {
4358                    println!("{:?} {:?} {:?} {:?}", arg1, arg2, token, self);
4359                    Ok(0)
4360                };
4361                native a.b.TestClass3 objectNativeFunc3(a.b.TestClass3 arg) {
4362                    println!("{:?} {:?} {:?}", arg, token, self);
4363                    Ok(arg)
4364                };
4365
4366                @RustName(primitive_static_native_func_3)
4367                static native long primitiveStaticNativeFunc3(int arg1, char arg2) {
4368                    println!("{:?} {:?} {:?} {:?}", arg1, arg2, token, env);
4369                    Ok(0)
4370                };
4371                public static native a.b.TestClass3 objectStaticNativeFunc3(a.b.TestClass3 arg) {
4372                    println!("{:?} {:?} {:?}", arg, token, env);
4373                    Ok(arg)
4374                };
4375
4376                long primitiveInterfaceFunc3(int arg1, char arg2);
4377                a.b.TestClass3 objectInterfaceFunc3(a.b.TestClass3 arg);
4378            }
4379
4380            metadata {
4381                interface e.f.TestInterface1 {
4382                    @RustName(primitive_interface_func_1)
4383                    long primitiveInterfaceFunc1(int arg1, char arg2);
4384                }
4385                interface c.d.TestInterface2 extends e.f.TestInterface1 {}
4386
4387                class c.d.TestClass1;
4388                class c.d.TestClass2 extends c.d.TestClass1 implements e.f.TestInterface1;
4389            }
4390        };
4391        let expected = quote!{
4392            pub trait TestInterface3<'a> {
4393                fn primitiveInterfaceFunc3(
4394                    &self,
4395                    arg1: i32,
4396                    arg2: char,
4397                    token: &::rust_jni::NoException<'a>,
4398                ) -> ::rust_jni::JavaResult<'a, i64>;
4399
4400                fn objectInterfaceFunc3(
4401                    &self,
4402                    arg: &::a::b::TestClass3<'a>,
4403                    token: &::rust_jni::NoException<'a>,
4404                ) -> ::rust_jni::JavaResult<'a, ::a::b::TestClass3<'a> >;
4405            }
4406
4407            pub trait TestInterface4<'a>: ::c::d::TestInterface2<'a> + ::a::b::TestInterface3<'a> {
4408                fn primitive_func_3(
4409                    &self,
4410                    arg1: i32,
4411                    arg2: char,
4412                    token: &::rust_jni::NoException<'a>,
4413                ) -> ::rust_jni::JavaResult<'a, i64>;
4414
4415                fn object_func_3(
4416                    &self,
4417                    arg: &::a::b::TestClass3<'a>,
4418                    token: &::rust_jni::NoException<'a>,
4419                ) -> ::rust_jni::JavaResult<'a, ::c::d::TestClass2<'a> >;
4420            }
4421
4422            #[derive(Debug)]
4423            pub struct TestClass3<'env> {
4424                object: ::c::d::TestClass2<'env>,
4425            }
4426
4427            impl<'a> ::rust_jni::JavaType for TestClass3<'a> {
4428                #[doc(hidden)]
4429                type __JniType = <::rust_jni::java::lang::Object<'a> as ::rust_jni::JavaType>::__JniType;
4430
4431                #[doc(hidden)]
4432                fn __signature() -> &'static str {
4433                    "La/b/TestClass3;"
4434                }
4435            }
4436
4437            impl<'a> ::rust_jni::__generator::ToJni for TestClass3<'a> {
4438                unsafe fn __to_jni(&self) -> Self::__JniType {
4439                    self.raw_object()
4440                }
4441            }
4442
4443            impl<'a> ::rust_jni::__generator::FromJni<'a> for TestClass3<'a> {
4444                unsafe fn __from_jni(env: &'a ::rust_jni::JniEnv<'a>, value: Self::__JniType) -> Self {
4445                    Self {
4446                        object: <::c::d::TestClass2 as ::rust_jni::__generator::FromJni<'a>>::__from_jni(env, value),
4447                    }
4448                }
4449            }
4450
4451            impl<'a> ::rust_jni::Cast<'a, TestClass3<'a>> for TestClass3<'a> {
4452                #[doc(hidden)]
4453                fn cast<'b>(&'b self) -> &'b TestClass3<'a> {
4454                    self
4455                }
4456            }
4457
4458            impl<'a> ::rust_jni::Cast<'a, ::c::d::TestClass2<'a>> for TestClass3<'a> {
4459                #[doc(hidden)]
4460                fn cast<'b>(&'b self) -> &'b ::c::d::TestClass2<'a> {
4461                    self
4462                }
4463            }
4464
4465            impl<'a> ::rust_jni::Cast<'a, ::c::d::TestClass1<'a>> for TestClass3<'a> {
4466                #[doc(hidden)]
4467                fn cast<'b>(&'b self) -> &'b ::c::d::TestClass1<'a> {
4468                    self
4469                }
4470            }
4471
4472            impl<'a> ::rust_jni::Cast<'a, ::java::lang::Object<'a>> for TestClass3<'a> {
4473                #[doc(hidden)]
4474                fn cast<'b>(&'b self) -> &'b ::java::lang::Object<'a> {
4475                    self
4476                }
4477            }
4478
4479            impl<'a> ::std::ops::Deref for TestClass3<'a> {
4480                type Target = ::c::d::TestClass2<'a>;
4481
4482                fn deref(&self) -> &Self::Target {
4483                    &self.object
4484                }
4485            }
4486
4487            impl<'a> TestClass3<'a> {
4488                pub fn get_class(env: &'a ::rust_jni::JniEnv<'a>, token: &::rust_jni::NoException<'a>)
4489                    -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::Class<'a>> {
4490                    ::rust_jni::java::lang::Class::find(env, "a/b/TestClass3", token)
4491                }
4492
4493                pub fn clone(&self, token: &::rust_jni::NoException<'a>) -> ::rust_jni::JavaResult<'a, Self>
4494                where
4495                    Self: Sized,
4496                {
4497                    self.object
4498                        .clone(token)
4499                        .map(|object| Self { object })
4500                }
4501
4502                pub fn to_string(&self, token: &::rust_jni::NoException<'a>)
4503                    -> ::rust_jni::JavaResult<'a, ::rust_jni::java::lang::String<'a>> {
4504                    self.object.to_string(token)
4505                }
4506
4507                pub fn init(
4508                    env: &'a ::rust_jni::JniEnv<'a>,
4509                    arg1: i32,
4510                    arg2: &::a::b::TestClass3<'a>,
4511                    token: &::rust_jni::NoException<'a>,
4512                ) -> ::rust_jni::JavaResult<'a, Self> {
4513                    // Safe because the method name and arguments are correct.
4514                    unsafe {
4515                        ::rust_jni::__generator::call_constructor::<Self, _, fn(i32, &::a::b::TestClass3<'a>,)>
4516                        (
4517                            env,
4518                            (arg1, arg2,),
4519                            token,
4520                        )
4521                    }
4522                }
4523
4524                fn primitive_func_3(
4525                    &self,
4526                    arg1: i32,
4527                    arg2: char,
4528                    token: &::rust_jni::NoException<'a>,
4529                ) -> ::rust_jni::JavaResult<'a, i64> {
4530                    // Safe because the method name and arguments are correct.
4531                    unsafe {
4532                        ::rust_jni::__generator::call_method::<_, _, _,
4533                            fn(i32, char,) -> i64
4534                        >
4535                        (
4536                            self,
4537                            "primitiveFunc3",
4538                            (arg1, arg2,),
4539                            token,
4540                        )
4541                    }
4542                }
4543
4544                pub fn object_func_3(
4545                    &self,
4546                    arg: &::a::b::TestClass3<'a>,
4547                    token: &::rust_jni::NoException<'a>,
4548                ) -> ::rust_jni::JavaResult<'a, ::c::d::TestClass2<'a> > {
4549                    // Safe because the method name and arguments are correct.
4550                    unsafe {
4551                        ::rust_jni::__generator::call_method::<_, _, _,
4552                            fn(&::a::b::TestClass3<'a>,) -> ::c::d::TestClass2<'a>
4553                        >
4554                        (
4555                            self,
4556                            "objectFunc3",
4557                            (arg,),
4558                            token,
4559                        )
4560                    }
4561                }
4562
4563                fn primitiveInterfaceFunc3(
4564                    &self,
4565                    arg1: i32,
4566                    arg2: char,
4567                    token: &::rust_jni::NoException<'a>,
4568                ) -> ::rust_jni::JavaResult<'a, i64> {
4569                    // Safe because the method name and arguments are correct.
4570                    unsafe {
4571                        ::rust_jni::__generator::call_method::<_, _, _,
4572                            fn(i32, char,) -> i64
4573                        >
4574                        (
4575                            self,
4576                            "primitiveInterfaceFunc3",
4577                            (arg1, arg2,),
4578                            token,
4579                        )
4580                    }
4581                }
4582
4583                fn objectInterfaceFunc3(
4584                    &self,
4585                    arg: &::a::b::TestClass3<'a>,
4586                    token: &::rust_jni::NoException<'a>,
4587                ) -> ::rust_jni::JavaResult<'a, ::a::b::TestClass3<'a> > {
4588                    // Safe because the method name and arguments are correct.
4589                    unsafe {
4590                        ::rust_jni::__generator::call_method::<_, _, _,
4591                            fn(&::a::b::TestClass3<'a>,) -> ::a::b::TestClass3<'a>
4592                        >
4593                        (
4594                            self,
4595                            "objectInterfaceFunc3",
4596                            (arg,),
4597                            token,
4598                        )
4599                    }
4600                }
4601
4602                fn primitive_static_func_3(
4603                    env: &'a ::rust_jni::JniEnv<'a>,
4604                    arg1: i32,
4605                    arg2: char,
4606                    token: &::rust_jni::NoException<'a>,
4607                ) -> ::rust_jni::JavaResult<'a, i64> {
4608                    // Safe because the method name and arguments are correct.
4609                    unsafe {
4610                        ::rust_jni::__generator::call_static_method::<Self, _, _,
4611                            fn(i32, char,) -> i64
4612                        >
4613                        (
4614                            env,
4615                            "primitiveStaticFunc3",
4616                            (arg1, arg2,),
4617                            token,
4618                        )
4619                    }
4620                }
4621
4622                pub fn object_static_func_3(
4623                    env: &'a ::rust_jni::JniEnv<'a>,
4624                    arg: &::a::b::TestClass3<'a>,
4625                    token: &::rust_jni::NoException<'a>,
4626                ) -> ::rust_jni::JavaResult<'a, ::c::d::TestClass2<'a> > {
4627                    // Safe because the method name and arguments are correct.
4628                    unsafe {
4629                        ::rust_jni::__generator::call_static_method::<Self, _, _,
4630                            fn(&::a::b::TestClass3<'a>,) -> ::c::d::TestClass2<'a>
4631                        >
4632                        (
4633                            env,
4634                            "objectStaticFunc3",
4635                            (arg,),
4636                            token,
4637                        )
4638                    }
4639                }
4640
4641                pub fn primitive_native_func_3(
4642                    &self,
4643                    arg1: i32,
4644                    arg2: char,
4645                    token: &::rust_jni::NoException<'a>,
4646                ) -> ::rust_jni::JavaResult<'a, i64> {
4647                    {
4648                        println!("{:?} {:?} {:?} {:?}", arg1, arg2, token, self);
4649                        Ok(0)
4650                    }
4651                }
4652
4653                fn objectNativeFunc3(
4654                    &self,
4655                    arg: ::a::b::TestClass3<'a>,
4656                    token: &::rust_jni::NoException<'a>,
4657                ) -> ::rust_jni::JavaResult<'a, ::a::b::TestClass3<'a> > {
4658                    {
4659                        println!("{:?} {:?} {:?}", arg, token, self);
4660                        Ok(arg)
4661                    }
4662                }
4663
4664                fn primitive_static_native_func_3(
4665                    env: &'a ::rust_jni::JniEnv<'a>,
4666                    arg1: i32,
4667                    arg2: char,
4668                    token: &::rust_jni::NoException<'a>,
4669                ) -> ::rust_jni::JavaResult<'a, i64> {
4670                    {
4671                        println!("{:?} {:?} {:?} {:?}", arg1, arg2, token, env);
4672                        Ok(0)
4673                    }
4674                }
4675
4676                pub fn objectStaticNativeFunc3(
4677                    env: &'a ::rust_jni::JniEnv<'a>,
4678                    arg: ::a::b::TestClass3<'a>,
4679                    token: &::rust_jni::NoException<'a>,
4680                ) -> ::rust_jni::JavaResult<'a, ::a::b::TestClass3<'a> > {
4681                    {
4682                        println!("{:?} {:?} {:?}", arg, token, env);
4683                        Ok(arg)
4684                    }
4685                }
4686            }
4687
4688            #[no_mangle]
4689            #[doc(hidden)]
4690            pub unsafe extern "C" fn Java_a_b_TestClass3_primitiveNativeFunc3__IC<'a>(
4691                raw_env: *mut ::jni_sys::JNIEnv,
4692                object: ::jni_sys::jobject,
4693                arg1: <i32 as ::rust_jni::JavaType>::__JniType,
4694                arg2: <char as ::rust_jni::JavaType>::__JniType,
4695            ) -> <i64 as ::rust_jni::JavaType>::__JniType {
4696                ::rust_jni::__generator::test_jni_argument_type(arg1);
4697                ::rust_jni::__generator::test_jni_argument_type(arg2);
4698                ::rust_jni::__generator::native_method_wrapper(raw_env, |env, token| {
4699                    {
4700                        let value =
4701                            <i32 as ::rust_jni::__generator::FromJni>
4702                                ::__from_jni(env, arg1);
4703                        ::rust_jni::__generator::test_from_jni_type(&value);
4704                        ::std::mem::forget(value);
4705                    }
4706                    {
4707                        let value =
4708                            <char as ::rust_jni::__generator::FromJni>
4709                                ::__from_jni(env, arg2);
4710                        ::rust_jni::__generator::test_from_jni_type(&value);
4711                        ::std::mem::forget(value);
4712                    }
4713
4714                    let object = <TestClass3 as ::rust_jni::__generator::FromJni>::__from_jni(env, object);
4715                    object
4716                        .primitive_native_func_3(
4717                            ::rust_jni::__generator::FromJni::__from_jni(env, arg1),
4718                            ::rust_jni::__generator::FromJni::__from_jni(env, arg2),
4719                            &token,
4720                        )
4721                        .map(|value| {
4722                            let result = ::rust_jni::__generator::ToJni::__to_jni(&value);
4723                            // We don't want to delete the reference to result for object results.
4724                            ::std::mem::forget(value);
4725                            result
4726                        })
4727                })
4728            }
4729
4730            #[no_mangle]
4731            #[doc(hidden)]
4732            pub unsafe extern "C" fn Java_a_b_TestClass3_objectNativeFunc3__La_b_TestClass3_2<'a>(
4733                raw_env: *mut ::jni_sys::JNIEnv,
4734                object: ::jni_sys::jobject,
4735                arg: <::a::b::TestClass3 as ::rust_jni::JavaType>::__JniType,
4736            ) -> <::a::b::TestClass3<'a> as ::rust_jni::JavaType>::__JniType {
4737                ::rust_jni::__generator::test_jni_argument_type(arg);
4738                ::rust_jni::__generator::native_method_wrapper(raw_env, |env, token| {
4739                    {
4740                        let value =
4741                            <::a::b::TestClass3 as ::rust_jni::__generator::FromJni>
4742                                ::__from_jni(env, arg);
4743                        ::rust_jni::__generator::test_from_jni_type(&value);
4744                        ::std::mem::forget(value);
4745                    }
4746
4747                    let object = <TestClass3 as ::rust_jni::__generator::FromJni>::__from_jni(env, object);
4748                    object
4749                        .objectNativeFunc3(
4750                            ::rust_jni::__generator::FromJni::__from_jni(env, arg),
4751                            &token,
4752                        )
4753                        .map(|value| {
4754                            let result = ::rust_jni::__generator::ToJni::__to_jni(&value);
4755                            // We don't want to delete the reference to result for object results.
4756                            ::std::mem::forget(value);
4757                            result
4758                        })
4759                })
4760            }
4761
4762            #[no_mangle]
4763            #[doc(hidden)]
4764            pub unsafe extern "C" fn Java_a_b_TestClass3_primitiveStaticNativeFunc3__IC<'a>(
4765                raw_env: *mut ::jni_sys::JNIEnv,
4766                raw_class: ::jni_sys::jclass,
4767                arg1: <i32 as ::rust_jni::JavaType>::__JniType,
4768                arg2: <char as ::rust_jni::JavaType>::__JniType,
4769            ) -> <i64 as ::rust_jni::JavaType>::__JniType {
4770                ::rust_jni::__generator::test_jni_argument_type(arg1);
4771                ::rust_jni::__generator::test_jni_argument_type(arg2);
4772                ::rust_jni::__generator::native_method_wrapper(raw_env, |env, token| {
4773                    {
4774                        let value =
4775                            <i32 as ::rust_jni::__generator::FromJni>
4776                                ::__from_jni(env, arg1);
4777                        ::rust_jni::__generator::test_from_jni_type(&value);
4778                        ::std::mem::forget(value);
4779                    }
4780                    {
4781                        let value =
4782                            <char as ::rust_jni::__generator::FromJni>
4783                                ::__from_jni(env, arg2);
4784                        ::rust_jni::__generator::test_from_jni_type(&value);
4785                        ::std::mem::forget(value);
4786                    }
4787
4788                    let class = TestClass3::get_class(env, &token)?;
4789                    let raw_class = <::rust_jni::java::lang::Class as ::rust_jni::__generator::FromJni>::__from_jni(env, raw_class);
4790                    if !class.is_same_as(&raw_class, &token) {
4791                        panic!("Native method primitiveStaticNativeFunc3 does not belong to class TestClass3");
4792                    }
4793
4794                    TestClass3::primitive_static_native_func_3(
4795                        env,
4796                        ::rust_jni::__generator::FromJni::__from_jni(env, arg1),
4797                        ::rust_jni::__generator::FromJni::__from_jni(env, arg2),
4798                        &token,
4799                    )
4800                    .map(|value| {
4801                        let result = ::rust_jni::__generator::ToJni::__to_jni(&value);
4802                        ::std::mem::forget(value);
4803                        result
4804                    })
4805                })
4806            }
4807
4808            #[no_mangle]
4809            #[doc(hidden)]
4810            pub unsafe extern "C" fn Java_a_b_TestClass3_objectStaticNativeFunc3__La_b_TestClass3_2<'a>(
4811                raw_env: *mut ::jni_sys::JNIEnv,
4812                raw_class: ::jni_sys::jclass,
4813                arg: <::a::b::TestClass3 as ::rust_jni::JavaType>::__JniType,
4814            ) -> <::a::b::TestClass3<'a> as ::rust_jni::JavaType>::__JniType {
4815                ::rust_jni::__generator::test_jni_argument_type(arg);
4816                ::rust_jni::__generator::native_method_wrapper(raw_env, |env, token| {
4817                    {
4818                        let value =
4819                            <::a::b::TestClass3 as ::rust_jni::__generator::FromJni>
4820                                ::__from_jni(env, arg);
4821                        ::rust_jni::__generator::test_from_jni_type(&value);
4822                        ::std::mem::forget(value);
4823                    }
4824
4825                    let class = TestClass3::get_class(env, &token)?;
4826                    let raw_class = <::rust_jni::java::lang::Class as ::rust_jni::__generator::FromJni>::__from_jni(env, raw_class);
4827                    if !class.is_same_as(&raw_class, &token) {
4828                        panic!("Native method objectStaticNativeFunc3 does not belong to class TestClass3");
4829                    }
4830
4831                    TestClass3::objectStaticNativeFunc3(
4832                        env,
4833                        ::rust_jni::__generator::FromJni::__from_jni(env, arg),
4834                        &token,
4835                    )
4836                    .map(|value| {
4837                        let result = ::rust_jni::__generator::ToJni::__to_jni(&value);
4838                        ::std::mem::forget(value);
4839                        result
4840                    })
4841                })
4842            }
4843
4844            impl<'a> ::std::fmt::Display for TestClass3<'a> {
4845                fn fmt(&self, formatter: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
4846                    self.object.fmt(formatter)
4847                }
4848            }
4849
4850            impl<'a, T> PartialEq<T> for TestClass3<'a> where T: ::rust_jni::Cast<'a, ::rust_jni::java::lang::Object<'a>> {
4851                fn eq(&self, other: &T) -> bool {
4852                    self.object.eq(other)
4853                }
4854            }
4855
4856            impl<'a> Eq for TestClass3<'a> {}
4857
4858
4859            impl<'a> ::a::b::TestInterface3<'a> for TestClass3<'a> {
4860                fn primitiveInterfaceFunc3(
4861                    &self,
4862                    arg1: i32,
4863                    arg2: char,
4864                    token: &::rust_jni::NoException<'a>,
4865                ) -> ::rust_jni::JavaResult<'a, i64> {
4866                    Self::primitiveInterfaceFunc3(self, arg1, arg2, token)
4867                }
4868
4869                fn objectInterfaceFunc3(
4870                    &self,
4871                    arg: &::a::b::TestClass3<'a>,
4872                    token: &::rust_jni::NoException<'a>,
4873                ) -> ::rust_jni::JavaResult<'a, ::a::b::TestClass3<'a> > {
4874                    Self::objectInterfaceFunc3(self, arg, token)
4875                }
4876            }
4877
4878            impl<'a> ::a::b::TestInterface4<'a> for TestClass3<'a> {
4879                fn primitive_func_3(
4880                    &self,
4881                    arg1: i32,
4882                    arg2: char,
4883                    token: &::rust_jni::NoException<'a>,
4884                ) -> ::rust_jni::JavaResult<'a, i64> {
4885                    Self::primitive_func_3(self, arg1, arg2, token)
4886                }
4887
4888                fn object_func_3(
4889                    &self,
4890                    arg: &::a::b::TestClass3<'a>,
4891                    token: &::rust_jni::NoException<'a>,
4892                ) -> ::rust_jni::JavaResult<'a, ::c::d::TestClass2<'a> > {
4893                    Self::object_func_3(self, arg, token)
4894                }
4895            }
4896
4897            impl<'a> ::c::d::TestInterface2<'a> for TestClass3<'a> {
4898            }
4899
4900            impl<'a> ::e::f::TestInterface1<'a> for TestClass3<'a> {
4901                fn primitive_interface_func_1(
4902                    &self,
4903                    arg1: i32,
4904                    arg2: char,
4905                    token: &::rust_jni::NoException<'a>,
4906                ) -> ::rust_jni::JavaResult<'a, i64> {
4907                    < ::c::d::TestClass2 as ::e::f::TestInterface1 >
4908                        ::primitive_interface_func_1(self, arg1, arg2, token)
4909                }
4910            }
4911        };
4912        assert_tokens_equals(java_generate_impl(input), expected);
4913    }
4914}
4915
4916#[cfg(test)]
4917fn assert_tokens_equals(left: TokenStream, right: TokenStream) {
4918    assert_eq!(format!("{:?}", left), format!("{:?}", right),);
4919}