@@ -715,3 +715,93 @@ bool is_valid_java_array(const struct_typet &type)
715
715
length_component_valid &&
716
716
data_component_valid;
717
717
}
718
+
719
+ void get_dependencies_from_generic_parameters_rec (
720
+ const typet &t,
721
+ std::set<irep_idt> &refs)
722
+ {
723
+ // Java generic type that holds different types in its type arguments
724
+ if (is_java_generic_type (t))
725
+ {
726
+ for (const auto type_arg : to_java_generic_type (t).generic_type_arguments ())
727
+ get_dependencies_from_generic_parameters_rec (type_arg, refs);
728
+ }
729
+
730
+ // Java reference type
731
+ else if (t.id () == ID_pointer)
732
+ {
733
+ get_dependencies_from_generic_parameters_rec (t.subtype (), refs);
734
+ }
735
+
736
+ // method type with parameters and return value
737
+ else if (t.id () == ID_code)
738
+ {
739
+ const code_typet &c = to_code_type (t);
740
+ get_dependencies_from_generic_parameters_rec (c.return_type (), refs);
741
+ for (const auto ¶m : c.parameters ())
742
+ get_dependencies_from_generic_parameters_rec (param.type (), refs);
743
+ }
744
+
745
+ // symbol type
746
+ else if (t.id () == ID_symbol)
747
+ {
748
+ const symbol_typet &symbol_type = to_symbol_type (t);
749
+ const irep_idt class_name (symbol_type.get_identifier ());
750
+ if (is_java_array_tag (class_name))
751
+ {
752
+ get_dependencies_from_generic_parameters (
753
+ java_array_element_type (symbol_type), refs);
754
+ }
755
+ else
756
+ refs.insert (strip_java_namespace_prefix (class_name));
757
+ }
758
+ }
759
+
760
+ // / Collect information about generic type parameters from a given
761
+ // / signature. This is used to get information about class dependencies that
762
+ // / must be loaded but only appear as generic type argument, not as a field
763
+ // / reference.
764
+ // / \param signature: the string representation of the signature to analyze
765
+ // / \param refs [out]: the set to insert the names of the found dependencies
766
+ void get_dependencies_from_generic_parameters (
767
+ const std::string &signature,
768
+ std::set<irep_idt> &refs)
769
+ {
770
+ try
771
+ {
772
+ // class signature with bounds
773
+ if (signature[0 ] == ' <' )
774
+ {
775
+ const std::vector<typet> types = java_generic_type_from_string (
776
+ erase_type_arguments (signature), signature);
777
+
778
+ for (const auto &t : types)
779
+ get_dependencies_from_generic_parameters_rec (t, refs);
780
+ }
781
+
782
+ // class signature without bounds and without wildcards
783
+ else if (signature.find (' *' ) == std::string::npos)
784
+ {
785
+ get_dependencies_from_generic_parameters_rec (
786
+ java_type_from_string (signature, erase_type_arguments (signature)),
787
+ refs);
788
+ }
789
+ }
790
+ catch (unsupported_java_class_signature_exceptiont &)
791
+ {
792
+ // skip for now, if we cannot parse it, we cannot detect which additional
793
+ // classes should be loaded as dependencies
794
+ }
795
+ }
796
+
797
+ // / Collect information about generic type parameters from a given type. This is
798
+ // / used to get information about class dependencies that must be loaded but
799
+ // / only appear as generic type argument, not as a field reference.
800
+ // / \param t: the type to analyze
801
+ // / \param refs [out]: the set to insert the names of the found dependencies
802
+ void get_dependencies_from_generic_parameters (
803
+ const typet &t,
804
+ std::set<irep_idt> &refs)
805
+ {
806
+ get_dependencies_from_generic_parameters_rec (t, refs);
807
+ }
0 commit comments