public CCodeInterfaceMethodAdapterDefinition(ITypeSymbol type, IMethodSymbol interfaceMethod, IMethodSymbol classMethod) : base(interfaceMethod) { this.type = type; var receiver = type == classMethod.ContainingType || (classMethod.IsVirtual || classMethod.IsOverride || classMethod.IsAbstract) ? (Expression) new ThisReference { Type = classMethod.ContainingType } : (Expression) new BaseReference { Type = classMethod.ContainingType, ExplicitType = true }; var call = new Call { ReceiverOpt = receiver, Method = classMethod }; foreach (var argument in interfaceMethod.Parameters.Select(parameterSymbol => new Parameter { ParameterSymbol = parameterSymbol })) { call.Arguments.Add(argument); } var body = !interfaceMethod.ReturnsVoid ? (Statement) new ReturnStatement { ExpressionOpt = call } : (Statement) new ExpressionStatement { Expression = call }; var methodBodyOpt = new MethodBody(Method); if (classMethod.IsGenericMethod) { // set generic types foreach (var typeArgument in classMethod.TypeArguments.Where(t => t.TypeKind == TypeKind.TypeParameter)) { methodBodyOpt.Statements.Add( new TypeDef { TypeExpressionOpt = new TypeExpression { Type = typeArgument.GetFirstConstraintType() ?? new TypeImpl { SpecialType = SpecialType.System_Object } }, Identifier = new TypeExpression { Type = TypeImpl.Wrap(typeArgument, null) } }); } } methodBodyOpt.Statements.Add(body); MethodBodyOpt = methodBodyOpt; }
private static ITypeSymbol GetTypeForVirtualGenericMethod(IMethodSymbol method, ITypeSymbol type, ISymbol containingSymbol) { // new, we need template view if (type.TypeKind == TypeKind.Array) { var sourceArrayType = (IArrayTypeSymbol)type; var arrayType = new ArrayTypeImpl(sourceArrayType); arrayType.ElementType = GetTypeForVirtualGenericMethod(method, sourceArrayType.ElementType, containingSymbol); return(arrayType); } if (type.TypeKind == TypeKind.Pointer) { var sourcePointerType = (IPointerTypeSymbol)type; var pointerType = new PointerTypeImpl(); pointerType.PointedAtType = GetTypeForVirtualGenericMethod(method, sourcePointerType.PointedAtType, containingSymbol); return(pointerType); } if (type.TypeKind == TypeKind.TypeParameter) { for (var i = 0; i < method.TypeParameters.Length; i++) { var typeParameter = method.TypeParameters[i]; if (typeParameter.Name == type.Name) { return(method.TypeArguments[i]); } } return(new TypeImpl { SpecialType = SpecialType.System_Object }); } var namedTypeImpl = new NamedTypeImpl((INamedTypeSymbol)type); namedTypeImpl.ContainingSymbol = containingSymbol; namedTypeImpl.TypeArguments = ImmutableArray.Create( namedTypeImpl.TypeArguments.Select( ta => method.TypeArguments.Contains(ta) ? SetContaningSymbol(TypeImpl.Wrap(ta), containingSymbol) : ta) .OfType <ITypeSymbol>() .ToArray()); return(namedTypeImpl); }
private IEnumerable <CCodeUnit> BuildUnit(ITypeSymbol type, IAssembliesInfoResolver assembliesInfoResolver) { var unit = new CCodeUnit(type); var isNotModule = type.Name != "<Module>"; var isNotInterfaceOrModule = isNotModule && type.TypeKind != TypeKind.Interface; var methodSymbols = type.GetMembers().OfType <IMethodSymbol>().ToList(); var hasStaticConstructor = methodSymbols.Any(m => m.MethodKind == MethodKind.StaticConstructor); foreach (var field in type.GetMembers().OfType <IFieldSymbol>()) { this.BuildField(field, unit, hasStaticConstructor); } foreach (var @event in type.GetMembers().OfType <IEventSymbol>()) { this.BuildField(new FieldImpl(@event), unit, hasStaticConstructor); } if (hasStaticConstructor) { BuildStaticConstructorVariables(type, unit); } if (isNotModule) { ////BuildTypeHolderVariables(type, unit); BuildTypeDescriptorVariables(type, unit); } var constructors = methodSymbols.Where(m => m.MethodKind == MethodKind.Constructor); foreach (var method in constructors) { this.BuildMethod(method, unit); } var finalizationRequired = type.BaseType != null && type.GetMembers().OfType <IMethodSymbol>().Any(m => m.MethodKind == MethodKind.Destructor); var isAtomicType = type.IsAtomicType(); var namedTypeSymbol = (INamedTypeSymbol)type; if (isNotInterfaceOrModule) { unit.Declarations.Add(new CCodeNewOperatorDeclaration(namedTypeSymbol, finalizationRequired)); unit.Declarations.Add(new CCodeNewOperatorDeclaration(namedTypeSymbol, finalizationRequired, debugVersion: true)); unit.Declarations.Add(new CCodeNewOperatorDeclaration(namedTypeSymbol, finalizationRequired, true)); unit.Declarations.Add(new CCodeNewOperatorDeclaration(namedTypeSymbol, finalizationRequired, true, true)); } if (!isAtomicType && type.TypeKind != TypeKind.Interface) { unit.Declarations.Add(new CCodeGetTypeDescriptorDeclaration(namedTypeSymbol)); } if (type.IsPrimitiveValueType() || type.TypeKind == TypeKind.Enum) { unit.Declarations.Add(new CCodeSpecialTypeOrEnumConstructorDeclaration(namedTypeSymbol, false)); } /* * if (type.IsIntPtrType()) * { * unit.Declarations.Add(new CCodeSpecialTypeOrEnumConstructorDeclaration((INamedTypeSymbol)type, true)); * } */ // to support RuntimeType initialization if (type.IsRuntimeType()) { unit.Declarations.Add(new CCodeRuntimeTypeConstructorDeclaration(namedTypeSymbol, true)); } if (type.IsPrimitiveValueType() || type.TypeKind == TypeKind.Enum || type.IsIntPtrType()) { unit.Declarations.Add(new CCodeCastOperatorDeclaration(namedTypeSymbol)); } if (type.TypeKind == TypeKind.Struct) { unit.Declarations.Add(new CCodeArrowOperatorDeclaration(namedTypeSymbol)); } if (isNotInterfaceOrModule) { // add internal infrustructure unit.Declarations.Add(new CCodeGetTypeVirtualMethodDeclaration(namedTypeSymbol)); unit.Definitions.Add(new CCodeGetTypeVirtualMethodDefinition(namedTypeSymbol)); unit.Declarations.Add(new CCodeIsTypeVirtualMethodDeclaration(namedTypeSymbol)); unit.Definitions.Add(new CCodeIsTypeVirtualMethodDefinition(namedTypeSymbol)); unit.Declarations.Add(new CCodeGetInterfaceVirtualMethodDeclaration(namedTypeSymbol)); unit.Definitions.Add(new CCodeGetInterfaceVirtualMethodDefinition(namedTypeSymbol)); if (!type.IsAbstract) { unit.Declarations.Add(new CCodeCloneVirtualMethod(namedTypeSymbol)); unit.Declarations.Add(new CCodeGetSizeVirtualMethod(namedTypeSymbol)); } if (type.SpecialType == SpecialType.System_Object) { unit.Declarations.Add(new CCodeHashVirtualMethod(namedTypeSymbol)); unit.Declarations.Add(new CCodeEqualsVirtualMethod(namedTypeSymbol)); } } if (type.TypeKind == TypeKind.Interface) { unit.Declarations.Add(new CCodeObjectCastOperatorDeclaration(namedTypeSymbol)); } if (type.SpecialType == SpecialType.System_Array) { unit.Declarations.Add(new CCodeNewOperatorPointerDeclaration(namedTypeSymbol)); unit.Declarations.Add(new CCodeGetArrayElementSizeVirtualMethod(namedTypeSymbol)); unit.Declarations.Add(new CCodeIsPrimitiveTypeArrayVirtualMethod(namedTypeSymbol)); } if (type.TypeKind == TypeKind.Interface) { // add all methods from all interfaces foreach (var method in type.EnumerateInterfaceMethods()) { unit.Declarations.Add(new CCodeMethodDeclaration(type, method)); } } foreach (var method in methodSymbols.Where(m => m.MethodKind != MethodKind.Constructor)) { this.BuildMethod(method, unit); } if (isNotModule) { BuildMethodTableVariables(type, unit); ////BuildRuntimeInfoVariables(type, unit); } if (isNotInterfaceOrModule) { // append interface calls foreach (var interfaceMethod in type.EnumerateInterfaceMethods()) { var method = interfaceMethod; var implementationForInterfaceMember = type.FindImplementationForInterfaceMember(interfaceMethod) as IMethodSymbol; if (implementationForInterfaceMember != null && implementationForInterfaceMember.ExplicitInterfaceImplementations.Any(ei => ei.Equals(method))) { continue; } Debug.Assert(implementationForInterfaceMember != null, "Method for interface can't be found"); unit.Declarations.Add(new CCodeInterfaceMethodAdapterDeclaration(type, interfaceMethod, implementationForInterfaceMember)); unit.Definitions.Add(new CCodeInterfaceMethodAdapterDefinition(type, interfaceMethod, implementationForInterfaceMember)); } } yield return(unit); if (!isNotModule) { yield break; } // return type holder class var typeHolderType = (TypeImpl)TypeImpl.Wrap(type); if (!type.IsAnonymousType()) { typeHolderType.Name = typeHolderType.Name + "__type"; typeHolderType.MetadataName = typeHolderType.MetadataName + "__type"; } else { var namedType = (INamedTypeSymbol)type; typeHolderType.Name = namedType.GetAnonymousTypeName() + "__type"; typeHolderType.MetadataName = namedType.GetAnonymousTypeName() + "__type"; } typeHolderType.BaseType = null; typeHolderType.TypeKind = TypeKind.Struct; typeHolderType.Interfaces = ImmutableArray <INamedTypeSymbol> .Empty; typeHolderType.AllInterfaces = ImmutableArray <INamedTypeSymbol> .Empty; typeHolderType.SpecialType = SpecialType.None; var unitTypeHolder = new CCodeUnit(typeHolderType); BuildTypeHolderVariables(typeHolderType, unitTypeHolder); ////BuildMethodTableVariables(typeHolderType, unitTypeHolder); BuildRuntimeInfoVariables(typeHolderType, type, unitTypeHolder); yield return(unitTypeHolder); }
internal void Parse(BoundDelegateCreationExpression boundDelegateCreationExpression) { base.Parse(boundDelegateCreationExpression); var argument = Deserialize(boundDelegateCreationExpression.Argument) as Expression; Debug.Assert(argument != null); if (boundDelegateCreationExpression.MethodOpt != null && !(boundDelegateCreationExpression.Argument is BoundMethodGroup)) { var methodGroup = new MethodGroup { ReceiverOpt = argument, Method = boundDelegateCreationExpression.MethodOpt, TypeArgumentsOpt = boundDelegateCreationExpression.MethodOpt.TypeArguments.Select(t => TypeImpl.Wrap(t)).ToList() }; Arguments.Add(methodGroup); } else { if (argument.Type != null && argument.Type.TypeKind == TypeKind.Delegate) { this.clone = true; this.cloneArgument = argument; } else { var methodGroup = argument as MethodGroup; if (methodGroup != null && boundDelegateCreationExpression.MethodOpt != null) { methodGroup.Method = boundDelegateCreationExpression.MethodOpt; } Arguments.Add(argument); } } }
private IEnumerable <CCodeUnit> BuildUnit(ITypeSymbol type, IAssembliesInfoResolver assembliesInfoResolver) { var namedTypeSymbol = (INamedTypeSymbol)type; var unit = new CCodeUnit(type); var isNotModule = type.Name != "<Module>"; // Class var isNotInterfaceOrModule = isNotModule && type.TypeKind != TypeKind.Interface; var methodSymbols = type.GetMembers().OfType <IMethodSymbol>().ToList(); var hasStaticConstructor = methodSymbols.Any(m => m.MethodKind == MethodKind.StaticConstructor); // to support generic virtual methods #region Virtual Generic methods support var methodsTableType = "__methods_table".ToType(); foreach (var typeParameter in namedTypeSymbol.GetTemplateParameters().Where(t => t.HasConstructorConstraint)) { this.BuildField(new FieldImpl { Type = methodsTableType, Name = "construct_" + typeParameter.Name }, unit, false); } #endregion foreach (var field in type.GetMembers().OfType <IFieldSymbol>()) { this.BuildField(field, unit, hasStaticConstructor); } foreach (var @event in type.GetMembers().OfType <IEventSymbol>()) { this.BuildField(new FieldImpl(@event), unit, hasStaticConstructor); } if (hasStaticConstructor) { BuildStaticConstructorVariables(type, unit); } if (isNotModule) { ////BuildTypeHolderVariables(type, unit); BuildTypeDescriptorVariables(type, unit); } var constructors = methodSymbols.Where(m => m.MethodKind == MethodKind.Constructor); foreach (var method in constructors) { this.BuildMethod(method, unit); } var finalizationRequired = type.BaseType != null && type.GetMembers().OfType <IMethodSymbol>().Any(m => m.MethodKind == MethodKind.Destructor); var isAtomicType = type.IsAtomicType(); if (isNotInterfaceOrModule && !type.IsAbstract) { unit.Declarations.Add(new CCodeNewOperatorDeclaration(namedTypeSymbol, finalizationRequired)); unit.Declarations.Add(new CCodeNewOperatorDeclaration(namedTypeSymbol, finalizationRequired, debugVersion: true)); unit.Declarations.Add(new CCodeNewOperatorDeclaration(namedTypeSymbol, finalizationRequired, true)); unit.Declarations.Add(new CCodeNewOperatorDeclaration(namedTypeSymbol, finalizationRequired, true, true)); } if (!isAtomicType && type.TypeKind != TypeKind.Interface) { unit.Declarations.Add(new CCodeGetTypeDescriptorDeclaration(namedTypeSymbol)); } if (type.IsPrimitiveValueType() || type.TypeKind == TypeKind.Enum) { unit.Declarations.Add(new CCodeSpecialTypeOrEnumConstructorDeclaration(namedTypeSymbol, false)); } /* * if (type.IsIntPtrType()) * { * unit.Declarations.Add(new CCodeSpecialTypeOrEnumConstructorDeclaration((INamedTypeSymbol)type, true)); * } */ // to support RuntimeType initialization if (type.IsRuntimeType()) { unit.Declarations.Add(new CCodeRuntimeTypeConstructorDeclaration(namedTypeSymbol, true)); } if (type.IsPrimitiveValueType() || type.TypeKind == TypeKind.Enum || type.IsIntPtrType()) { unit.Declarations.Add(new CCodeCastOperatorDeclaration(namedTypeSymbol)); } if (type.TypeKind == TypeKind.Struct) { unit.Declarations.Add(new CCodeArrowOperatorDeclaration(namedTypeSymbol)); } if (isNotInterfaceOrModule) { // add internal infrustructure unit.Declarations.Add(new CCodeGetTypeVirtualMethodDeclaration(namedTypeSymbol)); unit.Definitions.Add(new CCodeGetTypeVirtualMethodDefinition(namedTypeSymbol)); unit.Declarations.Add(new CCodeIsTypeVirtualMethodDeclaration(namedTypeSymbol)); unit.Definitions.Add(new CCodeIsTypeVirtualMethodDefinition(namedTypeSymbol)); unit.Declarations.Add(new CCodeGetInterfaceVirtualMethodDeclaration(namedTypeSymbol)); unit.Definitions.Add(new CCodeGetInterfaceVirtualMethodDefinition(namedTypeSymbol)); if (!type.IsAbstract) { unit.Declarations.Add(new CCodeCloneVirtualMethod(namedTypeSymbol)); unit.Declarations.Add(new CCodeGetSizeVirtualMethod(namedTypeSymbol)); } if (type.SpecialType == SpecialType.System_Object) { unit.Declarations.Add(new CCodeHashVirtualMethod(namedTypeSymbol)); unit.Declarations.Add(new CCodeEqualsVirtualMethod(namedTypeSymbol)); } } if (type.TypeKind == TypeKind.Interface) { unit.Declarations.Add(new CCodeObjectCastOperatorDeclaration(namedTypeSymbol)); } if (type.SpecialType == SpecialType.System_Array) { unit.Declarations.Add(new CCodeNewOperatorPointerDeclaration(namedTypeSymbol)); unit.Declarations.Add(new CCodeGetArrayElementSizeVirtualMethod(namedTypeSymbol)); unit.Declarations.Add(new CCodeIsPrimitiveTypeArrayVirtualMethod(namedTypeSymbol)); } if (type.TypeKind == TypeKind.Interface) { // add all methods from all interfaces foreach (var method in type.EnumerateInterfaceMethods()) { unit.Declarations.Add(new CCodeMethodDeclaration(type, method)); } } foreach (var method in methodSymbols.Where(m => m.MethodKind != MethodKind.Constructor)) { this.BuildMethod(method, unit); } // write interface wrappers foreach (var iface in namedTypeSymbol.Interfaces) { unit.Declarations.Add(new CCodeClassDeclaration(new CCodeInterfaceWrapperClass(namedTypeSymbol, iface))); unit.Declarations.Add(new CCodeInterfaceCastOperatorDeclaration(namedTypeSymbol, iface)); } if (isNotModule) { BuildMethodTableVariables(type, unit); ////BuildRuntimeInfoVariables(type, unit); } // transition all methods which have body into source file foreach (var declaration in unit.Declarations.OfType <CCodeMethodDeclaration>().Where(m => m.MethodBodyOpt != null)) { declaration.ToDefinition(unit.Definitions, namedTypeSymbol); } yield return(unit); // TypeHolder if (!isNotModule) { yield break; } // return type holder class var typeHolderType = (TypeImpl)TypeImpl.Wrap(type); if (!type.IsAnonymousType()) { typeHolderType.Name = typeHolderType.Name + "__type"; typeHolderType.MetadataName = typeHolderType.MetadataName + "__type"; } else { var namedType = (INamedTypeSymbol)type; typeHolderType.Name = namedType.GetAnonymousTypeName() + "__type"; typeHolderType.MetadataName = namedType.GetAnonymousTypeName() + "__type"; } typeHolderType.BaseType = null; typeHolderType.TypeKind = TypeKind.Struct; typeHolderType.Interfaces = ImmutableArray <INamedTypeSymbol> .Empty; typeHolderType.AllInterfaces = ImmutableArray <INamedTypeSymbol> .Empty; typeHolderType.SpecialType = SpecialType.None; var unitTypeHolder = new CCodeUnit(typeHolderType); BuildTypeHolderVariables(typeHolderType, unitTypeHolder); ////BuildMethodTableVariables(typeHolderType, unitTypeHolder); BuildRuntimeInfoVariables(typeHolderType, type, unitTypeHolder); yield return(unitTypeHolder); }