public override void LeaveMethodInvocationExpression(Boo.Lang.Compiler.Ast.MethodInvocationExpression node) { ICallableType callable = node.Target.ExpressionType as ICallableType; if (callable != null) { CallableSignature signature = callable.GetSignature(); if (!signature.AcceptVarArgs) { return; } ExpandInvocation(node, signature.Parameters); return; } IMethod method = TypeSystemServices.GetOptionalEntity(node.Target) as IMethod; if (null == method || !method.AcceptVarArgs) { return; } ExpandInvocation(node, method.GetParameters()); }
public virtual void Visit(IType type) { IArrayType arrayType = type as IArrayType; if (arrayType != null) { VisitArrayType(arrayType); } if (type.IsByRef) { VisitByRefType(type); } if (type.ConstructedInfo != null) { VisitConstructedType(type); } else if (type.GenericInfo != null) { foreach (var gp in type.GenericInfo.GenericParameters) { Visit(gp); } } ICallableType callableType = type as ICallableType; if (callableType != null) { VisitCallableType(callableType); } }
private void InitializeClosureDependencies() { foreach (TypedArgument argument in Arguments) { BlockExpression closure = argument.Expression as BlockExpression; if (closure == null) { continue; } // ICallableType callableType = closure.ExpressionType as ICallableType; ICallableType callableType = argument.FormalType as ICallableType; if (callableType == null) { continue; } TypeCollector collector = new TypeCollector(delegate(IType t) { IGenericParameter gp = t as IGenericParameter; return(gp != null && InferredTypes.ContainsKey(gp)); }); foreach (IType inputType in GetParameterTypes(callableType.GetSignature())) { collector.Visit(inputType); } foreach (IGenericParameter gp in collector.Matches) { RecordClosureDependency(closure, gp); } } }
Method CreateBeginInvokeExtension(ICallableType anonymousType, Method beginInvoke, out MethodInvocationExpression mie) { InternalMethod beginInvokeEntity = (InternalMethod)beginInvoke.Entity; Method extension = CodeBuilder.CreateMethod("BeginInvoke", TypeSystemServices.Map(typeof(IAsyncResult)), TypeMemberModifiers.Public | TypeMemberModifiers.Static); extension.Attributes.Add(CodeBuilder.CreateAttribute(Types.ExtensionAttribute)); ParameterDeclaration self = CodeBuilder.CreateParameterDeclaration(0, "self", beginInvokeEntity.DeclaringType); extension.Parameters.Add(self); CodeBuilder.DeclareParameters(extension, 1, anonymousType.GetSignature().Parameters); mie = CodeBuilder.CreateMethodInvocation( CodeBuilder.CreateReference(self), beginInvokeEntity); ParameterDeclarationCollection parameters = extension.Parameters; for (int i = 1; i < parameters.Count; ++i) { mie.Arguments.Add(CodeBuilder.CreateReference(parameters[i])); } extension.Body.Add(new ReturnStatement(mie)); return(extension); }
public virtual void Visit(IType type) { IArrayType arrayType = type as IArrayType; if (arrayType != null) { VisitArrayType(arrayType); } if (type.IsByRef) { VisitByRefType(type); } if (type.ConstructedInfo != null) { VisitConstructedType(type); } ICallableType callableType = type as ICallableType; if (callableType != null) { VisitCallableType(callableType); } }
public override void LeaveMethodInvocationExpression(Boo.Lang.Compiler.Ast.MethodInvocationExpression node) { ICallableType callable = node.Target.ExpressionType as ICallableType; if (callable == null) { return; } CallableSignature signature = callable.GetSignature(); if (!signature.AcceptVarArgs) { return; } if (node.Arguments.Count > 0 && AstUtil.IsExplodeExpression(node.Arguments[-1])) { // explode the arguments node.Arguments.ReplaceAt(-1, ((UnaryExpression)node.Arguments[-1]).Operand); return; } IParameter[] parameters = signature.Parameters; int lenMinusOne = parameters.Length - 1; IType varArgType = parameters[lenMinusOne].Type; ExpressionCollection varArgs = node.Arguments.PopRange(lenMinusOne); node.Arguments.Add(CodeBuilder.CreateArray(varArgType, varArgs)); }
Expression Convert(IType expectedType, Expression argument) { if (IsStandaloneMethodReference(argument)) { if (IsCallableType(expectedType)) { ICallableType argumentType = (ICallableType)GetExpressionType(argument); if (argumentType.GetSignature() != ((ICallableType)expectedType).GetSignature()) { return(Adapt((ICallableType)expectedType, CreateDelegate(GetConcreteExpressionType(argument), argument))); } return(CreateDelegate(expectedType, argument)); } else { return(CreateDelegate(GetConcreteExpressionType(argument), argument)); } } else { if (IsCallableType(expectedType)) { IType argumentType = GetExpressionType(argument); if (Null.Default != argumentType && expectedType != argumentType) { return(Adapt((ICallableType)expectedType, argument)); } } } return(null); }
private static int CalculateCallableScore(ICallableType parameterType, ICallableType argType) { // upcast // parameterType == ICallableType, "ThreadStart" // argumentType == ICallableType, "Anonymous Closure" // RULES: // Number of arguments for argumentType && parameterType == same // Either: all arguments "IsAssignableFrom" // OR // all arguments == exactly (best case scenario) // ExactMatch -- (best case) // UpCast -- "not exact match, but very close" (this is OK) // ImplicitConversion -- "assignable, but wrong number of parameters / whatever" (boo does the normal thing) CallableSignature siggyType = parameterType.GetSignature(); CallableSignature siggyArg = argType.GetSignature(); // Ensuring that these callables have same number of arguments. // def foo(a, b,c) == { a, b, c| print foobar } if (siggyType.Parameters.Length != siggyArg.Parameters.Length) { return(CallableUpCastScore); } for (int i = 0; i < siggyType.Parameters.Length; i++) { if (siggyType.Parameters[i].Type != siggyArg.Parameters[i].Type) { return(CallableImplicitConversionScore); } } return(siggyType.ReturnType == siggyArg.ReturnType ? CallableExactMatchScore : CallableUpCastScore); }
public virtual void VisitCallableType(ICallableType callableType) { CallableSignature sig = callableType.GetSignature(); foreach (IParameter parameter in sig.Parameters) { Visit(parameter.Type); } Visit(sig.ReturnType); }
ClassDefinition GetAdaptor(ICallableType to, ICallableType from) { ClassDefinition adaptor = FindAdaptor(to, from); if (null == adaptor) { adaptor = CreateAdaptor(to, from); } return(adaptor); }
Method CreateBeginInvokeSimplerExtension(ICallableType anonymousType, Method beginInvoke) { MethodInvocationExpression mie; Method overload = CreateBeginInvokeExtension(anonymousType, beginInvoke, out mie); mie.Arguments.Add(CodeBuilder.CreateNullLiteral()); mie.Arguments.Add(CodeBuilder.CreateNullLiteral()); return(overload); }
public string FormatCallableType(ICallableType type) { $FormatCallableType$locals$274 s$ = new $FormatCallableType$locals$274 { $signature = type.GetSignature() }; string str = Builtins.join(new $FormatCallableType$335(this, s$), ", "); string str2 = this.FormatType(s$.$signature.ReturnType); return(new StringBuilder("function(").Append(str).Append("): ").Append(str2).ToString()); }
public ICallableType InferCallableType() { ICallableType contextType = ( GetTypeFromMethodInvocationContext() ?? GetTypeFromDeclarationContext() ?? GetTypeFromBinaryExpressionContext() ?? GetTypeFromCastContext()) as ICallableType; return(contextType); }
ClassDefinition FindAdaptor(ICallableType to, ICallableType from) { foreach (AdaptorRecord record in _adaptors) { if (from == record.From && to == record.To) { return(record.Adaptor); } } return(null); }
Method CreateEventRaiseMethod(Event node, Field backingField) { TypeMemberModifiers modifiers = RemoveAccessiblityModifiers(node.Modifiers); if (node.IsPrivate) { modifiers |= TypeMemberModifiers.Private; } else { modifiers |= TypeMemberModifiers.Protected | TypeMemberModifiers.Internal; } Method method = CodeBuilder.CreateMethod("raise_" + node.Name, TypeSystemServices.VoidType, modifiers); ICallableType type = GetEntity(node.Type) as ICallableType; if (null != type) { int index = CodeBuilder.GetFirstParameterIndex(node); foreach (IParameter parameter in type.GetSignature().Parameters) { method.Parameters.Add( CodeBuilder.CreateParameterDeclaration( index, parameter.Name, parameter.Type, parameter.IsByRef)); ++index; } } MethodInvocationExpression mie = CodeBuilder.CreateMethodInvocation( CodeBuilder.CreateReference(backingField), NameResolutionService.ResolveMethod(GetType(backingField.Type), "Invoke")); foreach (ParameterDeclaration parameter in method.Parameters) { mie.Arguments.Add(CodeBuilder.CreateReference(parameter)); } IfStatement stmt = new IfStatement(node.LexicalInfo); stmt.Condition = CodeBuilder.CreateNotNullTest( CodeBuilder.CreateReference(backingField)); stmt.TrueBlock = new Block(); stmt.TrueBlock.Add(mie); method.Body.Add(stmt); return(method); }
private void InferInputTypesFromContextType(ICallableType type) { CallableSignature sig = type.GetSignature(); for (int i = 0; i < Math.Min(ParameterTypes.Length, sig.Parameters.Length); i++) { if (ParameterTypes[i] != null) { continue; } ParameterTypes[i] = sig.Parameters[i].Type; } }
Method CreateBeginInvokeMethod(ICallableType anonymousType) { Method method = CodeBuilder.CreateRuntimeMethod("BeginInvoke", TypeSystemServices.Map(typeof(IAsyncResult)), anonymousType.GetSignature().Parameters, false); int delta = method.Parameters.Count; method.Parameters.Add( CodeBuilder.CreateParameterDeclaration(delta + 1, "callback", TypeSystemServices.Map(typeof(AsyncCallback)))); method.Parameters.Add( CodeBuilder.CreateParameterDeclaration(delta + 1, "asyncState", TypeSystemServices.ObjectType)); return(method); }
/// <summary> /// Yields the generic parameters used in a (bound) type. /// </summary> public static IEnumerable <IGenericParameter> FindGenericParameters(IType type) { IGenericParameter genericParameter = type as IGenericParameter; if (genericParameter != null) { yield return(genericParameter); yield break; } if (type is IArrayType) { foreach (IGenericParameter gp in FindGenericParameters(type.ElementType)) { yield return(gp); } yield break; } if (type.ConstructedInfo != null) { foreach (IType typeArgument in type.ConstructedInfo.GenericArguments) { foreach (IGenericParameter gp in FindGenericParameters(typeArgument)) { yield return(gp); } } yield break; } ICallableType callableType = type as ICallableType; if (callableType != null) { CallableSignature signature = callableType.GetSignature(); foreach (IGenericParameter gp in FindGenericParameters(signature.ReturnType)) { yield return(gp); } foreach (IParameter parameter in signature.Parameters) { foreach (IGenericParameter gp in FindGenericParameters(parameter.Type)) { yield return(gp); } } yield break; } }
private void InitializeDependencies(IGenericParameter[] genericParameters, CallableSignature signature) { IType[] parameterTypes = GetParameterTypes(signature); foreach (IType parameterType in parameterTypes) { ICallableType callableParameterType = parameterType as ICallableType; if (callableParameterType == null) { continue; } CalculateDependencies(callableParameterType.GetSignature()); } }
public bool AreTypesRelated(IType lhs, IType rhs) { ICallableType ctype = lhs as ICallableType; if (null != ctype) { return(ctype.IsAssignableFrom(rhs) || ctype.IsSubclassOf(rhs)); } return(lhs.IsAssignableFrom(rhs) || (lhs.IsInterface && !rhs.IsFinal) || (rhs.IsInterface && !lhs.IsFinal) || CanBeReachedByDownCastOrPromotion(lhs, rhs)); }
Method CreateBeginInvokeCallbackOnlyExtension(ICallableType anonymousType, Method beginInvoke) { MethodInvocationExpression mie; Method overload = CreateBeginInvokeExtension(anonymousType, beginInvoke, out mie); ParameterDeclaration callback = CodeBuilder.CreateParameterDeclaration(overload.Parameters.Count, "callback", TypeSystemServices.Map(typeof(AsyncCallback))); overload.Parameters.Add(callback); mie.Arguments.Add(CodeBuilder.CreateReference(callback)); mie.Arguments.Add(CodeBuilder.CreateNullLiteral()); return(overload); }
Expression Adapt(ICallableType expected, Expression callable) { ICallableType actual = GetExpressionType(callable) as ICallableType; if (null == actual) { // TODO: should we adapt System.Object, System.Delegate, // System.MulticastDelegate and ICallable as well? return(null); } ClassDefinition adaptor = GetAdaptor(expected, actual); Method adapt = (Method)adaptor.Members["Adapt"]; return(CodeBuilder.CreateMethodInvocation((IMethod)adapt.Entity, callable)); }
private int CalculateArgumentScore(IParameter param, IType parameterType, Node arg) { IType argumentType = GetExpressionTypeOrEntityType(arg); if (param.IsByRef) { if (IsValidByRefArg(param, parameterType, argumentType, arg)) { return(ExactMatchScore); } return(-1); } else if (parameterType == argumentType || (TypeSystemServices.IsSystemObject(argumentType) && TypeSystemServices.IsSystemObject(parameterType))) { return(parameterType is ICallableType ? CallableExactMatchScore : ExactMatchScore); } else if (parameterType.IsAssignableFrom(argumentType)) { ICallableType callableType = parameterType as ICallableType; ICallableType callableArg = argumentType as ICallableType; if (callableType != null && callableArg != null) { return(CalculateCallableScore(callableType, callableArg)); } return(UpCastScore); } else if (TypeSystemServices.FindImplicitConversionOperator(argumentType, parameterType) != null) { return(ImplicitConversionScore); } else if (TypeSystemServices.CanBeReachedByPromotion(parameterType, argumentType)) { if (IsWideningPromotion(parameterType, argumentType)) { return(WideningPromotion); } return(NarrowingPromotion); } else if (TypeSystemServices.CanBeReachedByDowncast(parameterType, argumentType)) { return(DowncastScore); } return(-1); }
private bool InferCallableType(ICallableType formalType, IType actualType, TypeInference inference) { ICallableType callableActualType = actualType as ICallableType; if (callableActualType == null) { return(false); } CallableSignature formalSignature = formalType.GetSignature(); CallableSignature actualSignature = callableActualType.GetSignature(); if (formalSignature.AcceptVarArgs) { if (actualSignature.Parameters.Length < formalSignature.Parameters.Length) { return(false); } } else if (formalSignature.Parameters.Length != actualSignature.Parameters.Length) { return(false); } // Infer return type, maintaining inference direction if (!Infer(formalSignature.ReturnType, actualSignature.ReturnType, inference)) { return(false); } // Infer parameter types, inverting inference direction for (int i = 0; i < formalSignature.Parameters.Length; ++i) { bool inferenceSuccessful = Infer( formalSignature.Parameters[i].Type, actualSignature.Parameters[i].Type, Invert(inference)); if (!inferenceSuccessful) { return(false); } } return(true); }
public bool IsCallableTypeAssignableFrom(ICallableType lhs, IType rhs) { if (lhs == rhs) { return(true); } if (rhs.IsNull()) { return(true); } var other = rhs as ICallableType; if (null == other) { return(false); } CallableSignature lvalue = lhs.GetSignature(); CallableSignature rvalue = other.GetSignature(); if (lvalue == rvalue) { return(true); } IParameter[] lparams = lvalue.Parameters; IParameter[] rparams = rvalue.Parameters; if (lparams.Length < rparams.Length) { return(false); } for (int i = 0; i < rparams.Length; ++i) { if (!CanBeReachedFrom(lparams[i].Type, rparams[i].Type)) { return(false); } } return(CompatibleReturnTypes(lvalue, rvalue)); }
public bool IsCallableTypeAssignableFrom(ICallableType lhs, IType rhs) { if (lhs == rhs || Null.Default == rhs) { return(true); } ICallableType other = rhs as ICallableType; if (null != other) { CallableSignature lvalue = lhs.GetSignature(); CallableSignature rvalue = other.GetSignature(); if (lvalue == rvalue) { return(true); } IParameter[] lparams = lvalue.Parameters; IParameter[] rparams = rvalue.Parameters; if (lparams.Length >= rparams.Length) { for (int i = 0; i < rparams.Length; ++i) { IType lparamType = lparams[i].Type; IType rparamType = rparams[i].Type; if (!AreTypesRelated(lparamType, rparamType)) { return(false); } } if (VoidType != lvalue.ReturnType && VoidType != rvalue.ReturnType) { return(AreTypesRelated(lvalue.ReturnType, rvalue.ReturnType)); } return(true); } } return(false); }
override public void LeaveMethodInvocationExpression(MethodInvocationExpression node) { IParameter[] parameters = null; IMethod entity = node.Target.Entity as IMethod; if (null != entity) { parameters = entity.GetParameters(); } else { ICallableType type = node.Target.ExpressionType as ICallableType; if (null == type) { return; } parameters = type.GetSignature().Parameters; } ConvertMethodInvocation(node, parameters); }
/// <summary> /// Attempts to infer the type of generic parameters that occur in a formal parameter type /// according to its actual argument type. /// </summary> /// <returns>False if inference failed; otherwise, true. </returns> protected bool Infer(IType formalType, IType actualType, TypeInference inference) { // Skip unspecified actual types if (actualType == null) { return(true); } IGenericParameter gp = formalType as IGenericParameter; if (null != gp) { return(InferGenericParameter(gp, actualType, inference)); } ICallableType callableType = formalType as ICallableType; if (null != callableType) { return(InferCallableType(callableType, actualType, inference)); } if (formalType.ConstructedInfo != null) { return(InferConstructedType(formalType, actualType, inference)); } IArrayType arrayType = formalType as IArrayType; if (null != arrayType) { return(InferArrayType(arrayType, actualType, inference)); } if (formalType.IsByRef) { return(Infer(formalType.ElementType, actualType, inference)); } return(InferSimpleType(formalType, actualType, inference)); }
Method CreateBeginInvokeOverload(ICallableType anonymousType, Method beginInvoke, out MethodInvocationExpression mie) { InternalMethod beginInvokeEntity = (InternalMethod)beginInvoke.Entity; Method overload = CodeBuilder.CreateMethod("BeginInvoke", Map(typeof(IAsyncResult)), TypeMemberModifiers.Public | TypeMemberModifiers.Virtual); CodeBuilder.DeclareParameters(overload, 1, anonymousType.GetSignature().Parameters); mie = CodeBuilder.CreateMethodInvocation( CodeBuilder.CreateSelfReference(beginInvokeEntity.DeclaringType), beginInvokeEntity); foreach (ParameterDeclaration parameter in overload.Parameters) { mie.Arguments.Add(CodeBuilder.CreateReference(parameter)); } overload.Body.Add(new ReturnStatement(mie)); return(overload); }
public virtual void VisitCallableType(ICallableType callableType) { if (_inCallableTypes.Contains(callableType)) { return; } _inCallableTypes.Push(callableType); try { CallableSignature sig = callableType.GetSignature(); foreach (IParameter parameter in sig.Parameters) { Visit(parameter.Type); } Visit(sig.ReturnType); } finally { _inCallableTypes.Pop(); } }
public Method CreateEndInvokeMethod(ICallableType anonymousType) { CallableSignature signature = anonymousType.GetSignature(); Method method = CodeBuilder.CreateRuntimeMethod("EndInvoke", signature.ReturnType); int delta = 1; foreach (IParameter p in signature.Parameters) { if (p.IsByRef) { method.Parameters.Add( CodeBuilder.CreateParameterDeclaration(++delta, p.Name, p.Type, true)); } } delta = method.Parameters.Count; method.Parameters.Add( CodeBuilder.CreateParameterDeclaration(delta + 1, "result", TypeSystemServices.Map(typeof(IAsyncResult)))); return method; }
void ProcessCallableTypeInvocation(MethodInvocationExpression node, ICallableType type) { NamedArgumentsNotAllowed(node); if (node.Arguments.Count == 1) { AssertTypeCompatibility(node.Arguments[0], type, GetExpressionType(node.Arguments[0])); node.ParentNode.Replace( node, CodeBuilder.CreateCast( type, node.Arguments[0])); } else { IConstructor ctor = GetCorrectConstructor(node, type, node.Arguments); if (null != ctor) { BindConstructorInvocation(node, ctor); } else { Error(node); } } }
bool AssertParameterTypes(ICallableType method, ExpressionCollection args, int count, bool reportErrors) { IParameter[] parameters = method.GetSignature().Parameters; for (int i=0; i<count; ++i) { IParameter param = parameters[i]; IType parameterType = param.Type; IType argumentType = GetExpressionType(args[i]); if (param.IsByRef) { if (!(args[i] is ReferenceExpression || args[i] is SlicingExpression || (args[i] is SelfLiteralExpression && argumentType.IsValueType))) { if (reportErrors) Error(CompilerErrorFactory.RefArgTakesLValue(args[i])); return false; } if (!CallableResolutionService.IsValidByRefArg(param, parameterType, argumentType, args[i])) { return false; } } else { if (!CanBeReachedFrom(args[i], parameterType, argumentType)) return false; } } return true; }
private void AddInferredClosureParameterTypes(BlockExpression node, ICallableType callableType) { IParameter[] parameters = (callableType == null ? null : callableType.GetSignature().Parameters); for (int i = 0; i < node.Parameters.Count; i++) { ParameterDeclaration pd = node.Parameters[i]; if (pd.Type != null) continue; IType inferredType; if (parameters != null && i < parameters.Length) { inferredType = parameters[i].Type; } else if (pd.IsParamArray) { inferredType = TypeSystemServices.ObjectArrayType; } else { inferredType = TypeSystemServices.ObjectType; } pd.Type = CodeBuilder.CreateTypeReference(inferredType); } }
protected bool CheckVarArgsParameters(ICallableType method, ExpressionCollection args) { return CallableResolutionService.IsValidVargsInvocation(method.GetSignature().Parameters, args); }
protected bool CheckExactArgsParameters(ICallableType method, ExpressionCollection args, bool reportErrors) { if (method.GetSignature().Parameters.Length != args.Count) return false; return AssertParameterTypes(method, args, args.Count, reportErrors); }
public GenericConstructedCallableType(TypeSystemServices tss, ICallableType definition, IType[] arguments) : base(tss, definition, arguments) { }
ClassDefinition FindAdaptor(ICallableType to, ICallableType from) { foreach (AdaptorRecord record in _adaptors) if (from == record.From && to == record.To) return record.Adaptor; return null; }
ClassDefinition CreateAdaptor(ICallableType to, ICallableType from) { BooClassBuilder adaptor = CodeBuilder.CreateClass("$adaptor$" + from.Name + "$" + to.Name + "$" + _adaptors.Count); adaptor.AddBaseType(TypeSystemServices.ObjectType); adaptor.Modifiers = TypeMemberModifiers.Final|TypeMemberModifiers.Internal; Field callable = adaptor.AddField("$from", from); BooMethodBuilder constructor = adaptor.AddConstructor(); ParameterDeclaration param = constructor.AddParameter("from", from); constructor.Body.Add( CodeBuilder.CreateSuperConstructorInvocation(TypeSystemServices.ObjectType)); constructor.Body.Add( CodeBuilder.CreateAssignment( CodeBuilder.CreateReference(callable), CodeBuilder.CreateReference(param))); CallableSignature signature = to.GetSignature(); BooMethodBuilder invoke = adaptor.AddMethod("Invoke", signature.ReturnType); foreach (IParameter parameter in signature.Parameters) { invoke.AddParameter(parameter.Name, parameter.Type, parameter.IsByRef); } MethodInvocationExpression mie = CodeBuilder.CreateMethodInvocation( CodeBuilder.CreateReference(callable), GetInvokeMethod(from)); int fromParameterCount = from.GetSignature().Parameters.Length; for (int i=0; i<fromParameterCount; ++i) { mie.Arguments.Add( CodeBuilder.CreateReference(invoke.Parameters[i])); } if (signature.ReturnType != TypeSystemServices.VoidType && from.GetSignature().ReturnType != TypeSystemServices.VoidType) { invoke.Body.Add(new ReturnStatement(mie)); } else { invoke.Body.Add(mie); } BooMethodBuilder adapt = adaptor.AddMethod("Adapt", to); adapt.Modifiers = TypeMemberModifiers.Static|TypeMemberModifiers.Public; param = adapt.AddParameter("from", from); adapt.Body.Add( new ReturnStatement( CodeBuilder.CreateConstructorInvocation( to.GetConstructors().First(), CodeBuilder.CreateConstructorInvocation( (IConstructor)constructor.Entity, CodeBuilder.CreateReference(param)), CodeBuilder.CreateAddressOfExpression(invoke.Entity)))); RegisterAdaptor(to, from, adaptor.ClassDefinition); return adaptor.ClassDefinition; }
Expression Adapt(ICallableType expected, Expression callable) { ICallableType actual = GetExpressionType(callable) as ICallableType; if (null == actual) { // TODO: should we adapt System.Object, System.Delegate, // System.MulticastDelegate and ICallable as well? return null; } ClassDefinition adaptor = GetAdaptor(expected, actual); Method adapt = (Method)adaptor.Members["Adapt"]; return CodeBuilder.CreateMethodInvocation((IMethod)adapt.Entity, callable); }
Method CreateBeginInvokeMethod(ICallableType anonymousType) { Method method = CodeBuilder.CreateRuntimeMethod("BeginInvoke", TypeSystemServices.Map(typeof(IAsyncResult)), anonymousType.GetSignature().Parameters, false); int delta = method.Parameters.Count; method.Parameters.Add( CodeBuilder.CreateParameterDeclaration(delta + 1, "callback", TypeSystemServices.Map(typeof(AsyncCallback)))); method.Parameters.Add( CodeBuilder.CreateParameterDeclaration(delta + 1, "asyncState", TypeSystemServices.ObjectType)); return method; }
ClassDefinition GetAdaptor(ICallableType to, ICallableType from) { ClassDefinition adaptor = FindAdaptor(to, from); if (null == adaptor) adaptor = CreateAdaptor(to, from); return adaptor; }
public bool IsCallableTypeAssignableFrom(ICallableType lhs, IType rhs) { if (lhs == rhs) return true; if (Null.Default == rhs) return true; var other = rhs as ICallableType; if (null == other) return false; CallableSignature lvalue = lhs.GetSignature(); CallableSignature rvalue = other.GetSignature(); if (lvalue == rvalue) return true; IParameter[] lparams = lvalue.Parameters; IParameter[] rparams = rvalue.Parameters; if (lparams.Length < rparams.Length) return false; for (int i = 0; i < rparams.Length; ++i) if (!CanBeReachedFrom(lparams[i].Type, rparams[i].Type)) return false; return CompatibleReturnTypes(lvalue, rvalue); }
public GenericConstructedCallableType(ICallableType definition, IType[] arguments) : base(definition, arguments) { }
private static int CalculateCallableScore(ICallableType parameterType, ICallableType argType) { // upcast // parameterType == ICallableType, "ThreadStart" // argumentType == ICallableType, "Anonymous Closure" // RULES: // Number of arguments for argumentType && parameterType == same // Either: all arguments "IsAssignableFrom" // OR // all arguments == exactly (best case scenario) // ExactMatch -- (best case) // UpCast -- "not exact match, but very close" (this is OK) // ImplicitConversion -- "assignable, but wrong number of parameters / whatever" (boo does the normal thing) CallableSignature siggyType = parameterType.GetSignature(); CallableSignature siggyArg = argType.GetSignature(); // Ensuring that these callables have same number of arguments. // def foo(a, b,c) == { a, b, c| print foobar } if (siggyType.Parameters.Length != siggyArg.Parameters.Length) { return CallableUpCastScore; } for (int i = 0; i < siggyType.Parameters.Length; i++) { if (siggyType.Parameters[i].Type != siggyArg.Parameters[i].Type) { return CallableImplicitConversionScore; } } return siggyType.ReturnType == siggyArg.ReturnType ? CallableExactMatchScore : CallableUpCastScore; }
ClassDefinition GetAdaptor(ICallableType to, ICallableType from) { return FindAdaptor(to, from) ?? CreateAdaptor(to, from); }
IMethod GetInvokeMethod(ICallableType type) { return NameResolutionService.ResolveMethod(type, "Invoke"); }
private void InferInputTypesFromContextType(ICallableType type) { CallableSignature sig = type.GetSignature(); for (int i = 0; i < Math.Min(ParameterTypes.Length, sig.Parameters.Length); i++) { if (ParameterTypes[i] != null) continue; ParameterTypes[i] = sig.Parameters[i].Type; } }
void RegisterAdaptor(ICallableType to, ICallableType from, ClassDefinition adaptor) { _adaptors.Add(new AdaptorRecord(to, from, adaptor)); TypeSystemServices.GetCompilerGeneratedTypesModule().Members.Add(adaptor); }
protected virtual bool CheckParameters(ICallableType method, ExpressionCollection args, bool reportErrors) { BindNullableParameters(args, method); return AcceptVarArgs(method) ? CheckVarArgsParameters(method, args) : CheckExactArgsParameters(method, args, reportErrors); }
public AdaptorRecord(ICallableType to, ICallableType from, ClassDefinition adaptor) { To = to; From = from; Adaptor = adaptor; }
bool AcceptVarArgs(ICallableType method) { return method.GetSignature().AcceptVarArgs; }
private bool InferCallableType(ICallableType formalType, IType actualType, TypeInference inference) { ICallableType callableActualType = actualType as ICallableType; if (callableActualType == null) return false; CallableSignature formalSignature = formalType.GetSignature(); CallableSignature actualSignature = callableActualType.GetSignature(); if (formalSignature.AcceptVarArgs) { if (actualSignature.Parameters.Length < formalSignature.Parameters.Length) return false; } else if (formalSignature.Parameters.Length != actualSignature.Parameters.Length) { return false; } // Infer return type, maintaining inference direction if (!Infer(formalSignature.ReturnType, actualSignature.ReturnType, inference)) { return false; } // Infer parameter types, inverting inference direction for (int i = 0; i < formalSignature.Parameters.Length; ++i) { bool inferenceSuccessful = Infer( formalSignature.Parameters[i].Type, actualSignature.Parameters[i].Type, Invert(inference)); if (!inferenceSuccessful) return false; } return true; }
bool AssertParameters(Node sourceNode, IEntity sourceEntity, ICallableType method, ExpressionCollection args) { if (CheckParameters(method, args, true)) return true; if (IsLikelyMacroExtensionMethodInvocation(sourceEntity)) Error(CompilerErrorFactory.MacroExpansionError(sourceNode)); else Error(CompilerErrorFactory.MethodSignature(sourceNode, sourceEntity, GetSignature(args))); return false; }
private bool CheckParameters(ICallableType method, ExpressionCollection args, bool reportErrors) { return AcceptVarArgs(method) ? CheckVarArgsParameters(method, args) : CheckExactArgsParameters(method, args, reportErrors); }
void BindNullableParameters(ExpressionCollection args, ICallableType target) { if (null == target) return; IParameter[] parameters = target.GetSignature().Parameters; for (int i = 0; i < parameters.Length; ++i) { if (!TypeSystemServices.IsNullable(parameters[i].Type)) continue; if (TypeSystemServices.IsNullable(GetExpressionType(args[i]))) continue; //already nullable args.Replace(args[i], CreateNullableInstantiation(args[i], parameters[i].Type)); Visit(args[i]); } }
bool AssertParameters(Node sourceNode, IEntity sourceEntity, ICallableType method, ExpressionCollection args) { if (CheckParameters(method, args, true)) return true; Error(CompilerErrorFactory.MethodSignature(sourceNode, sourceEntity.ToString(), GetSignature(args))); return false; }
private void ProcessClosureInMethodInvocation(GenericParameterInferrer inferrer, BlockExpression closure, ICallableType formalType) { var sig = formalType.GetSignature(); var replacer = new TypeReplacer(); var collector = new TypeCollector(delegate(IType t) { IGenericParameter gp = t as IGenericParameter; if (gp == null) return false; return gp.DeclaringEntity == inferrer.GenericMethod; }); collector.Visit(formalType); foreach (var typeParameter in collector.Matches) { var inferredType = inferrer.GetInferredType((IGenericParameter)typeParameter); if (inferredType != null) replacer.Replace(typeParameter, inferredType); } for (var i = 0; i < sig.Parameters.Length; i++) { var pd = closure.Parameters[i]; if (pd.Type != null) continue; pd.Type = CodeBuilder.CreateTypeReference(replacer.MapType(sig.Parameters[i].Type)); } ProcessClosureBody(closure); }
void ProcessDelegateInvocation(MethodInvocationExpression node, ICallableType delegateType) { if (!AssertParameters(node.Target, delegateType, delegateType, node.Arguments)) { Error(node); return; } var invoke = ResolveMethod(delegateType, "Invoke"); node.Target = CodeBuilder.CreateMemberReference(node.Target, invoke); BindExpressionType(node, invoke.ReturnType); }