@@ -150,33 +150,81 @@ TypeDef FindSimpleType(DkmProcess* process, std::string_view const& typeNamespac
150150 return type;
151151}
152152
153- TypeSig FindType (DkmProcess* process, std::string_view const & typeName )
153+ std::vector<std::string> ParseTypeName ( std::string_view name )
154154{
155- auto paramIndex = typeName.find (' <' );
156- if (paramIndex == std::string_view::npos)
155+ DWORD count;
156+ HSTRING* parts;
157+ auto wide_name = winrt::to_hstring (name);
158+ winrt::check_hresult (::RoParseTypeName (static_cast <HSTRING>(get_abi (wide_name)), &count, &parts));
159+
160+ winrt::com_array<winrt::hstring> wide_parts{ parts, count, winrt::take_ownership_from_abi };
161+ std::vector<std::string> result;
162+ for (auto && part : wide_parts)
157163 {
158- return TypeSig{ FindSimpleType (process, typeName). coded_index <TypeDefOrRef>() } ;
164+ result. push_back ( winrt::to_string (part)) ;
159165 }
160- else
166+ return result;
167+ }
168+
169+ template <std::input_iterator iter, std::sentinel_for<iter> sent>
170+ TypeSig ResolveGenericTypePart (DkmProcess* process, iter& it, sent const & end)
171+ {
172+ constexpr std::pair<std::string_view, ElementType> elementNames[] = {
173+ {" Boolean" , ElementType::Boolean},
174+ {" Int8" , ElementType::I1},
175+ {" Int16" , ElementType::I2},
176+ {" Int32" , ElementType::I4},
177+ {" Int64" , ElementType::I8},
178+ {" UInt8" , ElementType::U1},
179+ {" UInt16" , ElementType::U2},
180+ {" UInt32" , ElementType::U4},
181+ {" UInt64" , ElementType::U8},
182+ {" Single" , ElementType::R4},
183+ {" Double" , ElementType::R8},
184+ {" String" , ElementType::String},
185+ {" Object" , ElementType::Object}
186+ };
187+ std::string_view partName = *it;
188+ auto basic_type_pos = std::find_if (std::begin (elementNames), std::end (elementNames), [&partName](auto && elem) { return elem.first == partName; });
189+ if (basic_type_pos != std::end (elementNames))
190+ {
191+ return TypeSig{ basic_type_pos->second };
192+ }
193+
194+ TypeDef type = FindSimpleType (process, partName);
195+ auto tickPos = partName.rfind (' `' );
196+ if (tickPos == std::string_view::basic_string_view::npos)
161197 {
162- XLANG_ASSERT (typeName.back () == ' >' );
163- return TypeSig{ FindSimpleType (process, typeName.substr (0 , paramIndex)).coded_index <TypeDefOrRef>() };
164- // TODO: Assemble the GenericTypeInstSig
198+ return TypeSig{ type.coded_index <TypeDefOrRef>() };
165199 }
200+
201+ int paramCount = 0 ;
202+ std::from_chars (partName.data () + tickPos + 1 , partName.data () + partName.size (), paramCount);
203+ std::vector<TypeSig> genericArgs;
204+ for (int i = 0 ; i < paramCount; ++i)
205+ {
206+ genericArgs.push_back (ResolveGenericTypePart (process, ++it, end));
207+ }
208+ return TypeSig{ GenericTypeInstSig{ type.coded_index <TypeDefOrRef>(), std::move (genericArgs) } };
166209}
167210
168- TypeSig FindType (DkmProcess* process, std::string_view const & typeNamespace, std::string_view const & typeName)
211+ TypeSig ResolveGenericType (DkmProcess* process, std::string_view genericName)
212+ {
213+ auto parts = ParseTypeName (genericName);
214+ auto begin = parts.begin ();
215+ return ResolveGenericTypePart (process, begin, parts.end ());
216+ }
217+
218+ TypeSig FindType (DkmProcess* process, std::string_view const & typeName)
169219{
170220 auto paramIndex = typeName.find (' <' );
171221 if (paramIndex == std::string_view::npos)
172222 {
173- return TypeSig{ FindSimpleType (process, typeNamespace, typeName).coded_index <TypeDefOrRef>() };
223+ return TypeSig{ FindSimpleType (process, typeName).coded_index <TypeDefOrRef>() };
174224 }
175225 else
176226 {
177- XLANG_ASSERT (typeName.back () == ' >' );
178- return TypeSig{ FindSimpleType (process, typeNamespace, typeName.substr (0 , paramIndex)).coded_index <TypeDefOrRef>() };
179- // TODO: Assemble the GenericTypeInstSig
227+ return ResolveGenericType (process, typeName);
180228 }
181229}
182230
0 commit comments