Пример #1
0
        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;
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
                }
            }
        }
Пример #5
0
        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);
        }