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#[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 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(¤t);
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 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 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 #(::rust_jni::__generator::test_jni_argument_type(#argument_names_1);)*
2783 ::rust_jni::__generator::native_method_wrapper(raw_env, |env, token| {
2784 #(
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 ::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 #(::rust_jni::__generator::test_jni_argument_type(#argument_names_1);)*
2846 ::rust_jni::__generator::native_method_wrapper(raw_env, |env, token| {
2847 #(
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 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 ::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 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 #(
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 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 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 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 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 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 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 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 ::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 ::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}