Problem
A property declared on a base interface fails to compile when called on a value hinted as a sub-interface. The getter method and members declared directly on the hinted interface both resolve, so only inherited properties break.
(fn [^System.Collections.IDictionary d] (.Count d)) ; fails to compile
(fn [^System.Collections.IDictionary d] (.get_Count d)) ; compiles
Could not find instance method, field, or property Count
for type System.Collections.IDictionary
Count is declared on ICollection; IDictionary inherits it. Confirmed at runtime: .get_Count returns the real count, .Count raises the error. A property inherited from a base class (e.g. .Message on ArgumentException) works, because class reflection flattens the hierarchy and interface reflection does not.
Cause is in magic-compiler/src/magic/analyzer/analyze_host_forms.clj. Method resolution in analyze-host-interop walks (.GetInterfaces target-type), but property resolution is a plain (.GetProperties target-type) with no walk. The (.-X obj) path in analyze-host-field has the same gap (.-Count fails too).
Suggestion
Add a recursive get-all-properties mirroring the existing get-all-methods (walk GetInterfaces() and BaseType, dedupe), and use it at both property sites. Keep .GetProperties plus a name filter (SRE cannot call .GetProperty on a TypeBuilder) and preserve the static/instance binding flags.
Problem
A property declared on a base interface fails to compile when called on a value hinted as a sub-interface. The getter method and members declared directly on the hinted interface both resolve, so only inherited properties break.
Countis declared onICollection;IDictionaryinherits it. Confirmed at runtime:.get_Countreturns the real count,.Countraises the error. A property inherited from a base class (e.g..MessageonArgumentException) works, because class reflection flattens the hierarchy and interface reflection does not.Cause is in
magic-compiler/src/magic/analyzer/analyze_host_forms.clj. Method resolution inanalyze-host-interopwalks(.GetInterfaces target-type), but property resolution is a plain(.GetProperties target-type)with no walk. The(.-X obj)path inanalyze-host-fieldhas the same gap (.-Countfails too).Suggestion
Add a recursive
get-all-propertiesmirroring the existingget-all-methods(walkGetInterfaces()andBaseType, dedupe), and use it at both property sites. Keep.GetPropertiesplus a name filter (SRE cannot call.GetPropertyon aTypeBuilder) and preserve the static/instance binding flags.