/// <summary> /// Resolves the method if the expression was a member getter (obj.field or type::field). /// </summary> private void resolveGetMember(Context ctx, GetMemberNode node) { _InvocationSource = node.Expression; var type = _InvocationSource != null ? _InvocationSource.Resolve(ctx) : ctx.ResolveType(node.StaticType); checkTypeInSafeMode(ctx, type); if (node.TypeHints != null && node.TypeHints.Count > 0) _TypeHints = node.TypeHints.Select(x => ctx.ResolveType(x, true)).ToArray(); try { // resolve a normal method try { _Method = ctx.ResolveMethod( type, node.MemberName, _ArgTypes, _TypeHints, (idx, types) => ctx.ResolveLambda(Arguments[idx] as LambdaNode, types) ); if (_Method.IsStatic) _InvocationSource = null; return; } catch (KeyNotFoundException) { if (_InvocationSource == null) throw; } // resolve a callable field try { ctx.ResolveField(type, node.MemberName); resolveExpression(ctx, node); return; } catch (KeyNotFoundException) { } // resolve a callable property try { ctx.ResolveProperty(type, node.MemberName); resolveExpression(ctx, node); return; } catch (KeyNotFoundException) { } Arguments = (Arguments[0] is UnitNode) ? new List<NodeBase> {_InvocationSource} : new[] {_InvocationSource}.Union(Arguments).ToList(); var oldArgTypes = _ArgTypes; _ArgTypes = Arguments.Select(a => a.Resolve(ctx)).ToArray(); _InvocationSource = null; try { // resolve a local function that is implicitly used as an extension method _Method = ctx.ResolveMethod( ctx.MainType.TypeInfo, node.MemberName, _ArgTypes, resolver: (idx, types) => ctx.ResolveLambda(Arguments[idx] as LambdaNode, types) ); return; } catch (KeyNotFoundException) { } // resolve a declared extension method // most time-consuming operation, therefore is last checked try { if(!ctx.Options.AllowExtensionMethods) throw new KeyNotFoundException(); _Method = ctx.ResolveExtensionMethod( type, node.MemberName, oldArgTypes, _TypeHints, (idx, types) => ctx.ResolveLambda(Arguments[idx] as LambdaNode, types) ); } catch (KeyNotFoundException) { var msg = node.StaticType != null ? CompilerMessages.TypeStaticMethodNotFound : CompilerMessages.TypeMethodNotFound; error(msg, type, node.MemberName); } } catch (AmbiguousMatchException) { error(CompilerMessages.TypeMethodInvocationAmbiguous, type, node.MemberName); } }
/// <summary> /// Resolves the method as a global function, imported property or a local variable with a delegate. /// </summary> private void resolveGetIdentifier(Context ctx, GetIdentifierNode node) { var nameInfo = ctx.Scope.FindLocal(node.Identifier); if (nameInfo != null) { resolveExpression(ctx, node); return; } try { _Method = ctx.ResolveMethod( ctx.MainType.TypeInfo, node.Identifier, _ArgTypes, resolver: (idx, types) => ctx.ResolveLambda(Arguments[idx] as LambdaNode, types) ); if (_Method == null) throw new KeyNotFoundException(); if(_ArgTypes.Length == 0 && node.Identifier.IsAnyOf(EntityNames.RunMethodName, EntityNames.EntryPointMethodName)) error(CompilerMessages.ReservedFunctionInvocation, node.Identifier); } catch (KeyNotFoundException) { error(CompilerMessages.FunctionNotFound, node.Identifier); } catch (AmbiguousMatchException) { error(CompilerMessages.FunctionInvocationAmbiguous, node.Identifier); } }