Apply explicit generic type arguments to a class's members. When a type hint includes generic parameters (e.g. `Collection `), this function maps them to the class's `@template` parameters and rewrites all method return types, method parameter types, and property type hints with the concrete types. If the class has no `template_params` or no `type_args` are provided, returns a clone of
(class: &ClassInfo, type_args: &[PhpType])
| 1399 | /// will substitute every occurrence of `TKey` with `int` and `TValue` with `User` |
| 1400 | /// in the class's methods and properties. |
| 1401 | pub(crate) fn apply_generic_args(class: &ClassInfo, type_args: &[PhpType]) -> ClassInfo { |
| 1402 | let subs = build_generic_subs(class, type_args); |
| 1403 | |
| 1404 | if subs.is_empty() { |
| 1405 | return class.clone(); |
| 1406 | } |
| 1407 | |
| 1408 | let mut result = class.clone(); |
| 1409 | for method in result.methods.make_mut() { |
| 1410 | apply_substitution_to_method(Arc::make_mut(method), &subs); |
| 1411 | } |
| 1412 | for property in result.properties.make_mut() { |
| 1413 | apply_substitution_to_property(property, &subs); |
| 1414 | } |
| 1415 | |
| 1416 | // Substitute template params in generic annotations so that |
| 1417 | // downstream consumers (e.g. foreach element-type extraction) |
| 1418 | // see concrete types instead of raw template param names. |
| 1419 | // For example, `@implements IteratorAggregate<TKey, TValue>` |
| 1420 | // becomes `@implements IteratorAggregate<int, Customer>` when |
| 1421 | // TKey=int, TValue=Customer. |
| 1422 | apply_substitution_to_generics(&mut result.implements_generics, &subs); |
| 1423 | apply_substitution_to_generics(&mut result.extends_generics, &subs); |
| 1424 | apply_substitution_to_generics(&mut result.use_generics, &subs); |
| 1425 | |
| 1426 | result |
| 1427 | } |
| 1428 | |
| 1429 | /// Whether a template parameter bound represents a key-like type. |
| 1430 | /// |