@@ -239,21 +239,77 @@ public static Expr Parse(ParserContext pcon, ISeq form)
239239
240240 static Expr ToHostExpr ( ParserContext pcon , QualifiedMethodExpr qmfexpr , Symbol tag , bool tailPosition , ISeq args )
241241 {
242- // Let's see if we have generic type parameters. We'll ignore this if we are a constructor -- constructors can't be generic.
242+ var source = ( string ) Compiler . SourceVar . deref ( ) ;
243+ var spanMap = ( IPersistentMap ) Compiler . SourceSpanVar . deref ( ) ;
244+
245+
246+ // we have the form (qmfexpr ...args...)
247+ // We need to decide what the pieces are in ...args...
248+
249+ Expr instance = null ;
250+ if ( qmfexpr . Kind == QualifiedMethodExpr . EMethodKind . INSTANCE )
251+ {
252+ instance = Compiler . Analyze ( pcon . EvalOrExpr ( ) , RT . first ( args ) ) ;
253+ args = RT . next ( args ) ;
254+ }
255+
256+ // We handle zero-arity calls separately, similarly to how HostExpr handles them.
257+ // Constructors not included here.
258+ // We are trying to discriminate field access, property access, and method calls on zero arguments.
259+ //
260+ // One special case here: Suppose we have a zero-arity _generic_method call, with type-args provided.
261+ // THis will look like: (Type/StaticMethod (type-args type1 ..)) or (Type/InstanceMEthod instance-expression (type-args type1 ..))
262+ // We check for the arg count before removing the type-args, so these will be handled by the non-zero-arity code.
263+ // That is okay -- because this is generic, it can't be a field or property access, so we can treat it as a method call.
264+
265+ bool isZeroArity = RT . count ( args ) == 0 && qmfexpr . Kind != QualifiedMethodExpr . EMethodKind . CTOR ;
266+
267+ if ( isZeroArity )
268+ {
269+ PropertyInfo pinfo ;
270+ FieldInfo finfo ;
271+
272+ switch ( qmfexpr . Kind )
273+ {
274+ case QualifiedMethodExpr . EMethodKind . INSTANCE :
275+ if ( ( finfo = Reflector . GetField ( qmfexpr . MethodType , qmfexpr . MethodName , false ) ) != null )
276+ return new InstanceFieldExpr ( source , spanMap , tag , instance , qmfexpr . MethodName , finfo , true ) ;
277+ if ( ( pinfo = Reflector . GetProperty ( qmfexpr . MethodType , qmfexpr . MethodName , false ) ) != null )
278+ return new InstancePropertyExpr ( source , spanMap , tag , instance , qmfexpr . MethodName , pinfo , true ) ;
279+ if ( Reflector . GetArityZeroMethod ( qmfexpr . MethodType , qmfexpr . MethodName , false ) != null )
280+ return new InstanceMethodExpr ( source , spanMap , tag , instance , qmfexpr . MethodType , qmfexpr . MethodName , null , new List < HostArg > ( ) , tailPosition ) ;
281+ throw new MissingMemberException ( String . Format ( "No instance field, property, or method taking 0 args named {0} found for {1}" , qmfexpr . MethodName , qmfexpr . MethodType . Name ) ) ;
282+
283+ case QualifiedMethodExpr . EMethodKind . STATIC :
284+ if ( ( finfo = Reflector . GetField ( qmfexpr . MethodType , qmfexpr . MethodName , true ) ) != null )
285+ return new StaticFieldExpr ( source , spanMap , tag , qmfexpr . MethodType , qmfexpr . MethodName , finfo ) ;
286+ if ( ( pinfo = Reflector . GetProperty ( qmfexpr . MethodType , qmfexpr . MethodName , true ) ) != null )
287+ return new StaticPropertyExpr ( source , spanMap , tag , qmfexpr . MethodType , qmfexpr . MethodName , pinfo ) ;
288+ if ( Reflector . GetArityZeroMethod ( qmfexpr . MethodType , qmfexpr . MethodName , true ) != null )
289+ return new StaticMethodExpr ( source , spanMap , tag , qmfexpr . MethodType , qmfexpr . MethodName , null , new List < HostArg > ( ) , tailPosition ) ;
290+ throw new MissingMemberException ( String . Format ( "No static field, property, or method taking 0 args named {0} found for {1}" , qmfexpr . MethodName , qmfexpr . MethodType . Name ) ) ;
291+
292+ default :
293+ // Constructor -- this won't happen, we fall through to the code below.
294+ break ;
295+ }
296+ }
243297
244298
245299 object firstArg = RT . first ( args ) ;
246300 List < Type > genericTypeArgs = null ;
247- ISeq processedArgs = args ;
248301
249302 if ( firstArg is ISeq && RT . first ( firstArg ) is Symbol symbol && symbol . Equals ( HostExpr . TypeArgsSym ) )
250303 {
251304 // We have a type args supplied for a generic method call
252305 // (. thing methodname (type-args type1 ... ) args ...)
253306 genericTypeArgs = HostExpr . ParseGenericMethodTypeArgs ( RT . next ( firstArg ) ) ;
254- processedArgs = RT . next ( args ) ;
307+ args = RT . next ( args ) ;
255308 }
256309
310+
311+
312+
257313 if ( qmfexpr . HintedSig != null )
258314 {
259315 MethodBase method = QualifiedMethodExpr . ResolveHintedMethod ( qmfexpr . MethodType , qmfexpr . MethodName , qmfexpr . Kind , qmfexpr . HintedSig ) ;
@@ -264,31 +320,31 @@ static Expr ToHostExpr(ParserContext pcon, QualifiedMethodExpr qmfexpr, Symbol t
264320 qmfexpr . MethodType ,
265321 ( ConstructorInfo ) method ,
266322 HostExpr . ParseArgs ( pcon , args ) ,
267- ( IPersistentMap ) Compiler . SourceSpanVar . deref ( ) ) ;
323+ spanMap ) ;
268324
269325 case QualifiedMethodExpr . EMethodKind . INSTANCE :
270326 return new InstanceMethodExpr (
271- ( string ) Compiler . SourceVar . deref ( ) ,
272- ( IPersistentMap ) Compiler . SourceSpanVar . deref ( ) ,
327+ source ,
328+ spanMap ,
273329 tag ,
274- Compiler . Analyze ( pcon . EvalOrExpr ( ) , RT . first ( processedArgs ) ) ,
330+ instance ,
275331 qmfexpr . MethodType ,
276332 Compiler . munge ( qmfexpr . MethodName ) ,
277333 ( MethodInfo ) method ,
278334 genericTypeArgs ,
279- HostExpr . ParseArgs ( pcon , RT . next ( processedArgs ) ) ,
335+ HostExpr . ParseArgs ( pcon , args ) ,
280336 tailPosition ) ;
281337
282338 default :
283339 return new StaticMethodExpr (
284- ( string ) Compiler . SourceVar . deref ( ) ,
285- ( IPersistentMap ) Compiler . SourceSpanVar . deref ( ) ,
340+ source ,
341+ spanMap ,
286342 tag ,
287343 qmfexpr . MethodType ,
288344 Compiler . munge ( qmfexpr . MethodName ) ,
289345 ( MethodInfo ) method ,
290346 genericTypeArgs ,
291- HostExpr . ParseArgs ( pcon , processedArgs ) ,
347+ HostExpr . ParseArgs ( pcon , args ) ,
292348 tailPosition ) ;
293349 }
294350 }
@@ -307,11 +363,11 @@ static Expr ToHostExpr(ParserContext pcon, QualifiedMethodExpr qmfexpr, Symbol t
307363 ( string ) Compiler . SourceVar . deref ( ) ,
308364 ( IPersistentMap ) Compiler . SourceSpanVar . deref ( ) ,
309365 tag ,
310- Compiler . Analyze ( pcon . EvalOrExpr ( ) , RT . first ( processedArgs ) ) ,
366+ instance ,
311367 qmfexpr . MethodType ,
312368 Compiler . munge ( qmfexpr . MethodName ) ,
313369 genericTypeArgs ,
314- HostExpr . ParseArgs ( pcon , RT . seq ( RT . next ( processedArgs ) ) ) ,
370+ HostExpr . ParseArgs ( pcon , args ) ,
315371 tailPosition ) ;
316372
317373 default :
@@ -322,13 +378,12 @@ static Expr ToHostExpr(ParserContext pcon, QualifiedMethodExpr qmfexpr, Symbol t
322378 qmfexpr . MethodType ,
323379 Compiler . munge ( qmfexpr . MethodName ) ,
324380 genericTypeArgs ,
325- HostExpr . ParseArgs ( pcon , processedArgs ) ,
381+ HostExpr . ParseArgs ( pcon , args ) ,
326382 tailPosition ) ;
327383 }
328384 }
329385 }
330386
331-
332387 #endregion
333388
334389 #region eval
0 commit comments