@@ -416,8 +416,10 @@ size_t find_closing_semi_colon_for_reference_type(
416
416
// / representation thereof.
417
417
// /
418
418
// / Example use are object types like "Ljava/lang/Integer;", type
419
- // / variables/parameters like "TE;" which require a non-empty \p class_name
420
- // / or generic types like "Ljava/util/List<T>;" or "Ljava/util/List<Integer>;"
419
+ // / variables/parameters like "TE;" which require a non-empty
420
+ // / \p class_name_prefix or generic types like "Ljava/util/List<TE;>;"
421
+ // / or "Ljava/util/List<Ljava/lang/Integer;>;" also requiring
422
+ // / \p class_name_prefix.
421
423
// /
422
424
// / \param src: the string representation as used in the class file
423
425
// / \param class_name_prefix: name of class to append to generic type
@@ -833,3 +835,52 @@ void get_dependencies_from_generic_parameters(
833
835
{
834
836
get_dependencies_from_generic_parameters_rec (t, refs);
835
837
}
838
+
839
+ // / Construct a generic symbol type by extending the symbol type \p type with
840
+ // / generic types extracted from the reference \p base_ref.
841
+ // / This assumes that the class named \p class_name_prefix extends or implements
842
+ // / the class \p type, and that \p base_ref corresponds to a generic class.
843
+ // / For instance since HashMap<K,V> extends Map<K,V> we would call
844
+ // / `java_generic_symbol_typet(symbol_typet("Map"), "Ljava/util/Map<TK;TV;>;",
845
+ // / "java.util.HashMap")` which generates a symbol type with identifier "Map",
846
+ // / and two generic types with identifier "java.util.HashMap::K" and
847
+ // / "java.util.HashMap::V" respectively.
848
+ java_generic_symbol_typet::java_generic_symbol_typet (
849
+ const symbol_typet &type,
850
+ const std::string &base_ref,
851
+ const std::string &class_name_prefix)
852
+ : symbol_typet(type)
853
+ {
854
+ set (ID_C_java_generic_symbol, true );
855
+ const typet &base_type = java_type_from_string (base_ref, class_name_prefix);
856
+ PRECONDITION (is_java_generic_type (base_type));
857
+ const java_generic_typet &gen_base_type = to_java_generic_type (base_type);
858
+ INVARIANT (
859
+ type.get_identifier () == to_symbol_type (gen_base_type.subtype ()).get_identifier (),
860
+ " identifier of " +type.pretty ()+" \n and identifier of type " +
861
+ gen_base_type.subtype ().pretty ()+" \n created by java_type_from_string for " +
862
+ base_ref+" should be equal" );
863
+ generic_types ().insert (
864
+ generic_types ().end (),
865
+ gen_base_type.generic_type_arguments ().begin (),
866
+ gen_base_type.generic_type_arguments ().end ());
867
+ }
868
+
869
+ // / Check if this symbol has the given generic type. If yes, return its index
870
+ // / in the vector of generic types.
871
+ // / \param type The parameter type we are looking for.
872
+ // / \return The index of the type in the vector of generic types.
873
+ optionalt<size_t > java_generic_symbol_typet::generic_type_index (
874
+ const java_generic_parametert &type) const
875
+ {
876
+ const auto &type_variable = type.get_name ();
877
+ const auto &generics = generic_types ();
878
+ for (std::size_t i = 0 ; i < generics.size (); ++i)
879
+ {
880
+ if (
881
+ is_java_generic_parameter (generics[i]) &&
882
+ to_java_generic_parameter (generics[i]).get_name () == type_variable)
883
+ return i;
884
+ }
885
+ return {};
886
+ }
0 commit comments