예제 #1
0
        /// <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);
            }
        }
예제 #2
0
        /// <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);
            }
        }