#region license // Copyright (c) 2004, Rodrigo B. de Oliveira (rbo@acm.org) // All rights reserved. // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * Neither the name of Rodrigo B. de Oliveira nor the names of its // contributors may be used to endorse or promote products derived from this // software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #endregion namespace Boo.Lang.Compiler.TypeSystem { using System; using System.Collections; using System.Reflection; using System.Text; using Boo.Lang.Compiler.Ast; using Attribute = Boo.Lang.Compiler.Ast.Attribute; using Module = Boo.Lang.Compiler.Ast.Module; public class TypeSystemServices { public DuckTypeImpl DuckType; public ExternalType IQuackFuType; public ExternalType ExceptionType; public ExternalType ApplicationExceptionType; public ExternalType MulticastDelegateType; public ExternalType DelegateType; public ExternalType IntPtrType; public ExternalType UIntPtrType; public ExternalType ObjectType; public ExternalType ValueTypeType; public ExternalType EnumType; public ExternalType RegexType; public ExternalType ArrayType; public ExternalType TypeType; public IArrayType ObjectArrayType; public ExternalType VoidType; public ExternalType StringType; public ExternalType BoolType; public ExternalType CharType; public ExternalType SByteType; public ExternalType ByteType; public ExternalType ShortType; public ExternalType UShortType; public ExternalType IntType; public ExternalType UIntType; public ExternalType LongType; public ExternalType ULongType; public ExternalType SingleType; public ExternalType DoubleType; public ExternalType DecimalType; public ExternalType TimeSpanType; public ExternalType DateTimeType; public ExternalType RuntimeServicesType; public ExternalType BuiltinsType; public ExternalType ListType; public ExternalType HashType; public ExternalType ICallableType; public ExternalType IEnumerableType; public ExternalType IEnumeratorType; #if NET_2_0 public ExternalType IEnumerableGenericType; public ExternalType IEnumeratorGenericType; #endif public ExternalType ICollectionType; public ExternalType IListType; public ExternalType IDictionaryType; public ExternalType SystemAttribute; protected Hashtable _primitives = new Hashtable(); protected Hashtable _entityCache = new Hashtable(); protected Hashtable _arrayCache = new Hashtable(); protected Hashtable _anonymousCallableTypes = new Hashtable(); public static readonly IType ErrorEntity = Error.Default; public readonly BooCodeBuilder CodeBuilder; StringBuilder _buffer = new StringBuilder(); Module _compilerGeneratedTypesModule; Module _compilerGeneratedExtensionsModule; ClassDefinition _compilerGeneratedExtensionsClass; CompilerContext _context; public TypeSystemServices() : this(new CompilerContext()) { } public TypeSystemServices(CompilerContext context) { if (null == context) { throw new ArgumentNullException("context"); } _context = context; CodeBuilder = new BooCodeBuilder(this); Cache(typeof(Builtins.duck), DuckType = new DuckTypeImpl(this)); Cache(IQuackFuType = new ExternalType(this, typeof(IQuackFu))); Cache(VoidType = new VoidTypeImpl(this)); Cache(ObjectType = new ExternalType(this, Types.Object)); Cache(RegexType = new ExternalType(this, Types.Regex)); Cache(ValueTypeType = new ExternalType(this, typeof(ValueType))); Cache(EnumType = new ExternalType(this, typeof(Enum))); Cache(ArrayType = new ExternalType(this, Types.Array)); Cache(TypeType = new ExternalType(this, Types.Type)); Cache(StringType = new ExternalType(this, Types.String)); Cache(BoolType = new ExternalType(this, Types.Bool)); Cache(SByteType = new ExternalType(this, Types.SByte)); Cache(CharType = new ExternalType(this, Types.Char)); Cache(ShortType = new ExternalType(this, Types.Short)); Cache(IntType = new ExternalType(this, Types.Int)); Cache(LongType = new ExternalType(this, Types.Long)); Cache(ByteType = new ExternalType(this, Types.Byte)); Cache(UShortType = new ExternalType(this, Types.UShort)); Cache(UIntType = new ExternalType(this, Types.UInt)); Cache(ULongType = new ExternalType(this, Types.ULong)); Cache(SingleType = new ExternalType(this, Types.Single)); Cache(DoubleType = new ExternalType(this, Types.Double)); Cache(DecimalType = new ExternalType(this, Types.Decimal)); Cache(TimeSpanType = new ExternalType(this, Types.TimeSpan)); Cache(DateTimeType = new ExternalType(this, Types.DateTime)); Cache(RuntimeServicesType = new ExternalType(this, Types.RuntimeServices)); Cache(BuiltinsType = new ExternalType(this, Types.Builtins)); Cache(ListType = new ExternalType(this, Types.List)); Cache(HashType = new ExternalType(this, Types.Hash)); Cache(ICallableType = new ExternalType(this, Types.ICallable)); Cache(IEnumerableType = new ExternalType(this, Types.IEnumerable)); Cache(IEnumeratorType = new ExternalType(this, typeof(IEnumerator))); Cache(ICollectionType = new ExternalType(this, Types.ICollection)); Cache(IListType = new ExternalType(this, Types.IList)); Cache(IDictionaryType = new ExternalType(this, Types.IDictionary)); Cache(ApplicationExceptionType = new ExternalType(this, Types.ApplicationException)); Cache(ExceptionType = new ExternalType(this, Types.Exception)); Cache(IntPtrType = new ExternalType(this, Types.IntPtr)); Cache(UIntPtrType = new ExternalType(this, Types.UIntPtr)); Cache(MulticastDelegateType = new ExternalType(this, Types.MulticastDelegate)); Cache(DelegateType = new ExternalType(this, Types.Delegate)); Cache(SystemAttribute = new ExternalType(this, typeof(System.Attribute))); #if NET_2_0 Cache(IEnumerableGenericType = new ExternalType(this, typeof(System.Collections.Generic.IEnumerable<>))); Cache(IEnumeratorGenericType = new ExternalType(this, typeof(System.Collections.Generic.IEnumerator<>))); #endif ObjectArrayType = GetArrayType(ObjectType, 1); PreparePrimitives(); PrepareBuiltinFunctions(); } public CompilerContext Context { get { return _context; } } public IType GetMostGenericType(IType current, IType candidate) { if (current.IsAssignableFrom(candidate)) { return current; } if (candidate.IsAssignableFrom(current)) { return candidate; } if (IsNumberOrBool(current) && IsNumberOrBool(candidate)) { return GetPromotedNumberType(current, candidate); } if (IsCallableType(current) && IsCallableType(candidate)) { return ICallableType; } if (current.IsClass && candidate.IsClass) { if (current == ObjectType || candidate == ObjectType) { return ObjectType; } if (current.GetTypeDepth() < candidate.GetTypeDepth()) { return GetMostGenericType(current.BaseType, candidate); } return GetMostGenericType(current, candidate.BaseType); } return ObjectType; } public IType GetPromotedNumberType(IType left, IType right) { if (left == DecimalType || right == DecimalType) { return DecimalType; } if (left == DoubleType || right == DoubleType) { return DoubleType; } if (left == SingleType || right == SingleType) { return SingleType; } if (left == ULongType) { if (right == SByteType || right == ShortType || right == IntType || right == LongType) { // This is against the C# spec but allows expressions like: // ulong x = 4 // y = x + 1 // y will be long. // C# disallows mixing ulongs and signed numbers // but in the above case it promotes the constant to ulong // and the result is ulong. // Since its too late here to promote the constant, // maybe we should return LongType. I didn't chose ULongType // because in other cases returns . return LongType; } return ULongType; } if (right == ULongType) { if (left == SByteType || left == ShortType || left == IntType || left == LongType) { // This is against the C# spec but allows expressions like: // ulong x = 4 // y = 1 + x // y will be long. // C# disallows mixing ulongs and signed numbers // but in the above case it promotes the constant to ulong // and the result is ulong. // Since its too late here to promote the constant, // maybe we should return LongType. I didn't chose ULongType // because in other cases returns . return LongType; } return ULongType; } if (left == LongType || right == LongType) { return LongType; } if (left == UIntType) { if (right == SByteType || right == ShortType || right == IntType) { // This is allowed per C# spec and y is long: // uint x = 4 // y = x + 1 // C# promotes to also // but in the above case it promotes the constant to uint first // and the result of "x + 1" is uint. // Since its too late here to promote the constant, // "y = x + 1" will be long in boo. return LongType; } return UIntType; } if (right == UIntType) { if (left == SByteType || left == ShortType || left == IntType) { // This is allowed per C# spec and y is long: // uint x = 4 // y = 1 + x // C# promotes to also // but in the above case it promotes the constant to uint first // and the result of "1 + x" is uint. // Since its too late here to promote the constant, // "y = x + 1" will be long in boo. return LongType; } return UIntType; } if (left == IntType || right == IntType || left == ShortType || right == ShortType || left == UShortType || right == UShortType || left == ByteType || right == ByteType || left == SByteType || right == SByteType) { return IntType; } return left; } public static bool IsReadOnlyField(IField field) { return field.IsInitOnly || field.IsLiteral; } public bool IsCallable(IType type) { return (TypeType == type) || IsCallableType(type) || IsDuckType(type); } public bool IsDuckTyped(Expression expression) { IType type = expression.ExpressionType; return null != type && this.IsDuckType(type); } public bool IsQuackBuiltin(Expression node) { return IsQuackBuiltin(GetOptionalEntity(node)); } public bool IsQuackBuiltin(IEntity entity) { return BuiltinFunction.Quack == entity; } public bool IsDuckType(IType type) { if (null == type) { throw new ArgumentNullException("type"); } return ( (type == DuckType) || KnowsQuackFu(type) || (_context.Parameters.Ducky && (type == ObjectType))); } public bool KnowsQuackFu(IType type) { return type.IsSubclassOf(IQuackFuType); } bool IsCallableType(IType type) { return (ICallableType.IsAssignableFrom(type)) || (type is ICallableType); } public AnonymousCallableType GetCallableType(IMethod method) { CallableSignature signature = new CallableSignature(method); return GetCallableType(signature); } public AnonymousCallableType GetCallableType(CallableSignature signature) { AnonymousCallableType type = (AnonymousCallableType)_anonymousCallableTypes[signature]; if (null == type) { type = new AnonymousCallableType(this, signature); _anonymousCallableTypes.Add(signature, type); } return type; } public IType GetConcreteCallableType(Node sourceNode, CallableSignature signature) { AnonymousCallableType type = GetCallableType(signature); return GetConcreteCallableType(sourceNode, type); } public IType GetEnumeratorItemType(IType iteratorType) { if (iteratorType.IsArray) return ((IArrayType)iteratorType).GetElementType(); if (StringType == iteratorType) return CharType; if (iteratorType.IsClass) { IType enumeratorItemType = GetEnumeratorItemTypeFromAttribute(iteratorType); if (null != enumeratorItemType) { return enumeratorItemType; } } #if NET_2_0 IType genericItemType = GetEnumeratorItemTypeFromGenericEnumerable(iteratorType); if (null != genericItemType) { return genericItemType; } #endif return ObjectType; } public IType GetExpressionType(Expression node) { IType type = node.ExpressionType; if (null == type) { throw CompilerErrorFactory.InvalidNode(node); } return type; } public IType GetConcreteExpressionType(Expression expression) { IType type = GetExpressionType(expression); AnonymousCallableType anonymousType = type as AnonymousCallableType; if (null != anonymousType) { IType concreteType = GetConcreteCallableType(expression, anonymousType); expression.ExpressionType = concreteType; return concreteType; } return type; } public void MapToConcreteExpressionTypes(ExpressionCollection items) { foreach (Expression item in items) { GetConcreteExpressionType(item); } } public ClassDefinition GetCompilerGeneratedExtensionsClass() { if (null == _compilerGeneratedExtensionsClass) { BooClassBuilder builder = CodeBuilder.CreateClass("CompilerGeneratedExtensions"); builder.Modifiers = TypeMemberModifiers.Final|TypeMemberModifiers.Transient|TypeMemberModifiers.Public; builder.AddBaseType(ObjectType); BooMethodBuilder ctor = builder.AddConstructor(); ctor.Modifiers = TypeMemberModifiers.Private; ctor.Body.Add( CodeBuilder.CreateSuperConstructorInvocation(ObjectType)); ClassDefinition cd = builder.ClassDefinition; Module module = GetCompilerGeneratedExtensionsModule(); module.Members.Add(cd); ((ModuleEntity)module.Entity).InitializeModuleClass(cd); _compilerGeneratedExtensionsClass = cd; } return _compilerGeneratedExtensionsClass; } public Module GetCompilerGeneratedExtensionsModule() { if (null == _compilerGeneratedExtensionsModule) { _compilerGeneratedExtensionsModule = NewModule(null); } return _compilerGeneratedExtensionsModule; } public void AddCompilerGeneratedType(TypeDefinition type) { GetCompilerGeneratedTypesModule().Members.Add(type); } public Module GetCompilerGeneratedTypesModule() { if (null == _compilerGeneratedTypesModule) { _compilerGeneratedTypesModule = NewModule("CompilerGenerated"); } return _compilerGeneratedTypesModule; } private Module NewModule(string ns) { Module module = new Module(); if (null != ns) module.Namespace = new NamespaceDeclaration(ns); module.Entity = new ModuleEntity(_context.NameResolutionService, this, module); _context.CompileUnit.Modules.Add(module); return module; } public ClassDefinition CreateCallableDefinition(string name) { ClassDefinition cd = new ClassDefinition(); cd.BaseTypes.Add(CodeBuilder.CreateTypeReference(this.MulticastDelegateType)); cd.BaseTypes.Add(CodeBuilder.CreateTypeReference(this.ICallableType)); cd.Name = name; cd.Modifiers = TypeMemberModifiers.Final; cd.Members.Add(CreateCallableConstructor()); cd.Members.Add(CreateCallMethod()); cd.Entity = new InternalCallableType(this, cd); return cd; } Method CreateCallMethod() { Method method = new Method("Call"); method.Modifiers = TypeMemberModifiers.Public|TypeMemberModifiers.Virtual; method.Parameters.Add(CodeBuilder.CreateParameterDeclaration(1, "args", ObjectArrayType)); method.ReturnType = CodeBuilder.CreateTypeReference(ObjectType); method.Entity = new InternalMethod(this, method); return method; } Constructor CreateCallableConstructor() { Constructor constructor = new Constructor(); constructor.Modifiers = TypeMemberModifiers.Public; constructor.ImplementationFlags = MethodImplementationFlags.Runtime; constructor.Parameters.Add( CodeBuilder.CreateParameterDeclaration(1, "instance", ObjectType)); constructor.Parameters.Add( CodeBuilder.CreateParameterDeclaration(2, "method", IntPtrType)); constructor.Entity = new InternalConstructor(this, constructor); return constructor; } 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) || FindImplicitConversionOperator(rhs,lhs) != null; } public IMethod FindExplicitConversionOperator(IType fromType, IType toType) { return FindConversionOperator("op_Explicit", fromType, toType); } public IMethod FindImplicitConversionOperator(IType fromType, IType toType) { return FindConversionOperator("op_Implicit", fromType, toType); } public IMethod FindConversionOperator(string name, IType fromType, IType toType) { while (fromType != this.ObjectType) { IMethod method = FindConversionOperator(name, fromType, toType, fromType.GetMembers()); if (null != method) return method; method = FindConversionOperator(name, fromType, toType, toType.GetMembers()); if (null != method) return method; method = FindConversionOperator(name, fromType, toType, FindExtension(fromType, name)); if (null != method) return method; fromType = fromType.BaseType; if (null == fromType) break; } return null; } private IEntity[] FindExtension(IType fromType, string name) { IEntity extension = _context.NameResolutionService.ResolveExtension(fromType, name); if (null == extension) return Ambiguous.NoEntities; Ambiguous a = extension as Ambiguous; if (null != a) return a.Entities; return new IEntity[] { extension }; } IMethod FindConversionOperator(string name, IType fromType, IType toType, IEntity[] candidates) { foreach (IEntity entity in candidates) { if (EntityType.Method != entity.EntityType || name != entity.Name) continue; IMethod method = (IMethod)entity; if (IsConversionOperator(method, fromType, toType)) return method; } return null; } bool IsConversionOperator(IMethod method, IType fromType, IType toType) { if (!method.IsStatic) return false; if (method.ReturnType != toType) return false; IParameter[] parameters = method.GetParameters(); return (1 == parameters.Length && fromType == parameters[0].Type); } 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 1) { IEntity[] tags = new IEntity[info.Length]; for (int i=0; i 0) { return Map(info[0]); } return null; } public IEntity Map(MemberInfo mi) { IEntity tag = (IEntity)_entityCache[GetCacheKey(mi)]; if (null == tag) { switch (mi.MemberType) { case MemberTypes.Method: { return Map((MethodInfo)mi); } case MemberTypes.Constructor: { return Map((ConstructorInfo)mi); } case MemberTypes.Field: { tag = new ExternalField(this, (FieldInfo)mi); break; } case MemberTypes.Property: { tag = new ExternalProperty(this, (PropertyInfo)mi); break; } case MemberTypes.Event: { tag = new ExternalEvent(this, (EventInfo)mi); break; } case MemberTypes.NestedType: { return Map((Type)mi); } default: { throw new NotImplementedException(mi.ToString()); } } _entityCache.Add(GetCacheKey(mi), tag); } return tag; } public string GetSignature(IEntityWithParameters method) { return GetSignature(method, true); } public string GetSignature(IEntityWithParameters method, bool includeFullName) { _buffer.Length = 0; if (includeFullName) { _buffer.Append(method.FullName); } else { _buffer.Append(method.Name); } _buffer.Append("("); IParameter[] parameters = method.GetParameters(); for (int i=0; i 0) { _buffer.Append(", "); } if (method.AcceptVarArgs && i == parameters.Length-1) { _buffer.Append('*'); } _buffer.Append(parameters[i].Type); } _buffer.Append(")"); return _buffer.ToString(); } public object GetCacheKey(MemberInfo mi) { return mi; } public IEntity ResolvePrimitive(string name) { return (IEntity)_primitives[name]; } public bool IsPrimitive(string name) { return _primitives.ContainsKey(name); } /// /// checks if the passed type will be equivalente to /// System.Object in runtime (accounting for the presence /// of duck typing). /// public bool IsSystemObject(IType type) { return type == ObjectType || type == DuckType; } protected virtual void PreparePrimitives() { AddPrimitiveType("duck", DuckType); AddPrimitiveType("void", VoidType); AddPrimitiveType("bool", BoolType); AddPrimitiveType("char", CharType); AddPrimitiveType("date", DateTimeType); AddPrimitiveType("timespan", TimeSpanType); AddPrimitiveType("string", StringType); AddPrimitiveType("object", ObjectType); AddPrimitiveType("regex", RegexType); AddPrimitiveType("sbyte", SByteType); AddPrimitiveType("byte", ByteType); AddPrimitiveType("short", ShortType); AddPrimitiveType("ushort", UShortType); AddPrimitiveType("int", IntType); AddPrimitiveType("uint", UIntType); AddPrimitiveType("long", LongType); AddPrimitiveType("ulong", ULongType); AddPrimitiveType("single", SingleType); AddPrimitiveType("double", DoubleType); AddPrimitiveType("decimal", DecimalType); AddPrimitiveType("callable", ICallableType); } protected virtual void PrepareBuiltinFunctions() { AddBuiltin(BuiltinFunction.Len); AddBuiltin(BuiltinFunction.AddressOf); AddBuiltin(BuiltinFunction.Eval); AddBuiltin(BuiltinFunction.Switch); } protected void AddPrimitiveType(string name, ExternalType type) { _primitives[name] = type; type.PrimitiveName = name; } protected void AddBuiltin(BuiltinFunction function) { _primitives[function.Name] = function; } void Cache(ExternalType tag) { _entityCache[tag.ActualType] = tag; } void Cache(object key, IType tag) { _entityCache[key] = tag; } Method CreateBeginInvokeMethod(ICallableType anonymousType) { Method method = CodeBuilder.CreateRuntimeMethod("BeginInvoke", Map(typeof(IAsyncResult)), anonymousType.GetSignature().Parameters, false); int delta=method.Parameters.Count; method.Parameters.Add( CodeBuilder.CreateParameterDeclaration(delta+1, "callback", Map(typeof(AsyncCallback)))); method.Parameters.Add( CodeBuilder.CreateParameterDeclaration(delta+1, "asyncState", ObjectType)); return method; } Method CreateBeginInvokeExtension(ICallableType anonymousType, Method beginInvoke, out MethodInvocationExpression mie) { InternalMethod beginInvokeEntity = (InternalMethod)beginInvoke.Entity; Method extension = CodeBuilder.CreateMethod("BeginInvoke", 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 FindConstructedTypes(IType type, IType definition) { while (type != null) { if (type.GenericTypeInfo != null && type.GenericTypeInfo.GenericDefinition == definition) { yield return type; } foreach (IType interfaceType in type.GetInterfaces()) { foreach (IType match in FindConstructedTypes(interfaceType, definition)) { yield return match; } } type = type.BaseType; } } #endif public virtual IType GetConcreteCallableType(Node sourceNode, AnonymousCallableType anonymousType) { if (null == anonymousType.ConcreteType) { anonymousType.ConcreteType = CreateConcreteCallableType(sourceNode, anonymousType); } return anonymousType.ConcreteType; } protected virtual IType CreateConcreteCallableType(Node sourceNode, AnonymousCallableType anonymousType) { Module module = GetCompilerGeneratedTypesModule(); string name = string.Format("___callable{0}", module.Members.Count); ClassDefinition cd = CreateCallableDefinition(name); cd.Modifiers |= TypeMemberModifiers.Public; cd.LexicalInfo = sourceNode.LexicalInfo; cd.Members.Add(CreateInvokeMethod(anonymousType)); Method beginInvoke = CreateBeginInvokeMethod(anonymousType); cd.Members.Add(beginInvoke); cd.Members.Add(CreateEndInvokeMethod(anonymousType)); _compilerGeneratedTypesModule.Members.Add(cd); CreateCallableTypeBeginInvokeExtensions(anonymousType, beginInvoke); return (IType)cd.Entity; } private void CreateCallableTypeBeginInvokeExtensions(AnonymousCallableType anonymousType, Method beginInvoke) { ClassDefinition extensions = GetCompilerGeneratedExtensionsClass(); extensions.Members.Add(CreateBeginInvokeCallbackOnlyExtension(anonymousType, beginInvoke)); extensions.Members.Add(CreateBeginInvokeSimplerExtension(anonymousType, beginInvoke)); } private static void InvalidNode(Node node) { throw CompilerErrorFactory.InvalidNode(node); } public class DuckTypeImpl : ExternalType { public DuckTypeImpl(TypeSystemServices typeSystemServices) : base(typeSystemServices, Types.Object) { } } #region VoidTypeImpl class VoidTypeImpl : ExternalType { internal VoidTypeImpl(TypeSystemServices typeSystemServices) : base(typeSystemServices, Types.Void) { } override public bool Resolve(List targetList, string name, EntityType flags) { return false; } override public bool IsSubclassOf(IType other) { return false; } override public bool IsAssignableFrom(IType other) { return false; } } #endregion } }