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 }; } }
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() }; } }
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 }; } }
/// <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); }