Пример #1
0
        internal SSMethodInfo(MethodInfo methodInfo)
        {
            this.Id            = methodInfo.Name;
            this.Signature     = MemberSignature.GetSignature(methodInfo);
            this.DeclaringType = HybTypeCache.GetHybType(methodInfo.DeclaringType);
            this.Target        = new Invokable(methodInfo);

            this.ReturnType = HybTypeCache.GetHybType(methodInfo.ReturnType);
            this.IsVaArg    =
                methodInfo.GetParameters().LastOrDefault()
                ?.IsDefined(typeof(ParamArrayAttribute), false) ?? false;

            var ps = methodInfo.GetParameters();

            this.Parameters = new SSParamInfo[ps.Length];
            for (int i = 0; i < this.Parameters.Length; i++)
            {
                var p = ps[i];
                this.Parameters[i] = new SSParamInfo()
                {
                    Id           = p.Name,
                    DefaultValue = p.HasDefaultValue ? HybInstance.Object(p.DefaultValue) : null,
                    IsParams     = this.IsVaArg && i == this.Parameters.Length - 1
                };
            }
        }
Пример #2
0
        internal SSMethodInfo(Runner runner, string id, HybType declaringType, BaseMethodDeclarationSyntax declaration)
        {
            this.Id        = id;
            this.Signature = MemberSignature.GetSignature(
                runner.Resolver, id, declaration);
            this.DeclaringType = declaringType;
            this.Target        = new Invokable(this, runner, declaration);

            if (declaration is MethodDeclarationSyntax md)
            {
                this.ReturnType = runner.Resolver.GetType($"{md.ReturnType}");
            }
            this.IsVaArg =
                declaration.ParameterList.Parameters.LastOrDefault()
                ?.Modifiers.IsParams() ?? false;

            this.Parameters = new SSParamInfo[declaration.ParameterList.Parameters.Count];
            for (int i = 0; i < this.Parameters.Length; i++)
            {
                var p = declaration.ParameterList.Parameters[i];
                this.Parameters[i] = new SSParamInfo()
                {
                    Id           = p.Identifier.Text,
                    DefaultValue = p.Default != null?runner.RunExpression(p.Default.Value) : null,
                                       IsParams = p.Modifiers.IsParams()
                };
            }
        }
Пример #3
0
        internal SSMethodInfo(Runner runner, string id, HybType declaringType, Invokable body, HybType[] parameterTypes, HybType returnType)
        {
            this.Id            = id;
            this.Signature     = id; // ??
            this.DeclaringType = declaringType;
            this.Target        = body;

            this.ReturnType = returnType;
            this.IsVaArg    = false; // for now

            this.Parameters = new SSParamInfo[parameterTypes.Length];
            for (int i = 0; i < this.Parameters.Length; i++)
            {
                this.Parameters[i] = new SSParamInfo()
                {
                    Id           = $"{i}",
                    DefaultValue = null,
                    IsParams     = false
                };
            }
        }
Пример #4
0
        /// <summary>
        /// Runs invocation expression.
        ///   [Syntax] Console.WriteLine("Hello World");
        ///            Foo(1234);
        /// </summary>
        private HybInstance RunInvocation(InvocationExpressionSyntax node)
        {
            var cache = OptCache.GetOrCreate(node, () =>
            {
                var optNode = new OptInvocationNode();

                return(optNode);
            });

            string      calleeId = "";
            string      targetId = "";
            HybInstance callee   = null;

            SSMethodInfo[] callsite            = null;
            HybType[]      implicitGenericArgs = null;

            var(args, hasRefOrOut) = ResolveArgumentList(node.ArgumentList);

            if (node.Expression is MemberAccessExpressionSyntax ma)
            {
                var leftIsType = false;
                var rightName  = $"{ma.Name.Identifier}";

                implicitGenericArgs = ResolveGenericArgumentsFromName(ma.Name);

                if (ma.Expression is PredefinedTypeSyntax pd)
                {
                    HybType leftType = null;
                    leftIsType = true;
                    leftType   = Resolver.GetType($"{pd}");
                    callsite   = leftType.GetStaticMethods(rightName);
                }
                else if (ma.Expression is IdentifierNameSyntax id)
                {
                    HybType leftType = null;
                    if (Resolver.TryGetType($"{id.Identifier}", out leftType))
                    {
                        leftIsType = true;
                        callsite   = leftType.GetStaticMethods(rightName);
                    }
                    else
                    {
                        callee   = ResolveId(id);
                        callsite = callee.GetMethods(rightName);
                    }

                    calleeId = $"{id.Identifier}";
                }
                else if (ma.Expression is ExpressionSyntax expr)
                {
                    callee   = RunExpression(expr);
                    callsite = callee.GetMethods($"{ma.Name}");
                }

                if (leftIsType == false &&
                    callsite.Length == 0)
                {
                    callsite = ExtResolver.GetCallableExtensions(callee, $"{ma.Name}");

                    args = (new HybInstance[] { callee }).Concat(args).ToArray();
                }

                targetId = $"{ma.Name}";
                //callsite = ResolveMemberAccess(node.Expression as MemberAccessExpressionSyntax);
            }
            else if (node.Expression is SimpleNameSyntax ||
                     node.Expression is MemberBindingExpressionSyntax)
            {
                if (node.Expression is IdentifierNameSyntax ids)
                {
                    HybInstance v;
                    if (TryResolveId(ids.Identifier.Text, out v))
                    {
                        implicitGenericArgs = ResolveGenericArgumentsFromName(ids);
                        callee   = v;
                        callsite = v.GetMethods("Invoke");
                    }
                }
                if (callsite == null)
                {
                    SimpleNameSyntax id = node.Expression as SimpleNameSyntax;
                    if (id == null)
                    {
                        id     = (node.Expression as MemberBindingExpressionSyntax)?.Name;
                        callee = Ctx._bound;
                    }
                    else
                    {
                        callee = Ctx._this;
                    }

                    implicitGenericArgs = ResolveGenericArgumentsFromName(id);
                    callsite            =
                        ResolveLocalMember(id)
                        .Concat(Ctx.Method.DeclaringType.GetStaticMethods(id.Identifier.Text))
                        .ToArray();
                    targetId = id.Identifier.Text;
                }
            }

            if (callsite.Length == 0)
            {
                throw new NoSuchMethodException($"{calleeId}", targetId);
            }

            var method = OverloadingResolver.FindMethodWithArguments(
                Resolver,
                callsite,
                implicitGenericArgs.ToArray(),
                ref args);

            if (method == null)
            {
                throw new SemanticViolationException($"No matching override for `{targetId}`");
            }

            if (callee != null && method.DeclaringType.Parent == callee.GetHybType())
            {
                callee = callee.Parent;
            }

            var target = method.Target;

            if (target.IsCompiled && traps.ContainsKey(target.CompiledMethod))
            {
                target = new Invokable(traps[target.CompiledMethod]);
            }

            var ret = target.Invoke(callee, args, hasRefOrOut);

            // post-invoke
            if (hasRefOrOut)
            {
                var count = 0;
                foreach (var arg in node.ArgumentList.Arguments)
                {
                    if (arg.RefKindKeyword != null)
                    {
                        RunAssign(arg.Expression, args[count]);
                    }
                    count++;
                }
            }

            return(ret);
        }