Completed
Details
Assignee
UnassignedUnassignedReporter
Alex MillerAlex MillerLabels
Approval
OkPatch
Code and TestPriority
MajorAffects versions
Fix versions
Details
Details
Assignee
Unassigned
UnassignedReporter
Alex Miller
Alex MillerLabels
Approval
Ok
Patch
Code and Test
Priority

Affects versions
Fix versions
Created February 18, 2014 at 10:33 PM
Updated February 28, 2014 at 1:52 PM
Resolved February 28, 2014 at 1:52 PM
The (.-foo instance) syntax will properly resolve to either a field or a no-arg method if the type of instance is known. However, in the reflective case, it will only resolve to a method. This behavior should match the non-reflective case. The method case always be forced by using (. foo (method)).
user> (definterface I (a [])) user.I user> (deftype T [a] I (a [_] "method")) user.T user> (def t (->T "field")) #'user/t user=> (. ^T t a) ;; as expected (prefer method) "method" user=> (. ^T t -a) ;; as expected (prefer field) "field" user> (. t a) ;; as expected (prefer method) "method" user> (. t -a) ;; WRONG - should return "field" "method"
Approach: This case falls into Reflector.invokeNoArgInstanceMember() (this is the only place this method is used). InstanceFieldExpr now takes another flag (requireField) which will be set to true if "-field" and false if "field". InstanceFieldExpr will invoke (or emit) a call to Reflector.invokeNoArgInstanceMember() which now takes the same flag. If the flag is set to true, it first looks only for a field, otherwise it looks for a method and falls back to field which throws an error if necessary. I added a new invokeNoArgInstanceMember() with an arity to match the old arity - existing bytecode compiled on older Clojure versions will be trying to call this arity.
Patch: clj-1363-v3.patch
Screened by: