Refactor conversion templates into classes #79
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This patch, split from #78, promotes conversion templates (
Bindgen::Call::Result#conversion) to their own class hierarchy. This allows templates to perform complex substitutions thatUtil.templatecannot achieve.The main issue with
Util.templateis that it only supports simple string substitutions (e.g.%.to_unsafe,Converter.unwrap(%)). Passing a wrapper-Procto aCrystalProcis an example that cannot be expressed in this way:Proc, which takes binding types and returns a binding type;Proctakes and returns wrapper types.Procneeds to convert each argument to its wrapper type, invoke_proc_, then convert the return value to its binding type;Procitself needs to be converted into its binding type (CrystalProc).Since the conversion must occur every time a wrapper-
Procis passed to the binding, the best place to perform the conversion is through the template facility, rather than in aCall::Body. However, as noted in the original bug report, suchProcconversions are already properly handled in the jumptables (Processor::VirtualOverride::JumptableHook), just not in theQtprocessor. Therefore, the template for wrapper-Procs actually ends up usingCallBuilder::CrystalFromCppdirectly; it works because thatCall::Bodygenerates an expression, rather than a complete code block.Apart from
Proc, I expect that some other generic types will also require extra conversions beyondUtil.template's capability. This is why I suggested thatSlicemay also use this feature as well.Template::NoneandTemplate::Sequenceare utility templates that either perform no substitutions at all, or chain multiple templates together. They make the composition of templates more concise. (Now that I think about it,Bindgen::Call::Result#conversionitself could be anArray(Template::Base)too, although#followed_bywill be replaced with array concatenation.)