Ejemplo n.º 1
0
        internal static PreparedInformations Prepare(
            TranslateContext translateContext,
            Func <ITypeInformation, bool> predictType,
            Func <IMethodInformation, bool> predictMethod)
        {
            IPrepareContext prepareContext = translateContext;

            var allTypes = translateContext.Assembly.Modules.
                           SelectMany(module => module.Types.Concat(module.Types.SelectMany(type => type.NestedTypes))).
                           Where(predictType).
                           Distinct().
                           ToArray();

            // Lookup type references.
            foreach (var type in allTypes)
            {
                // Register used type.
                prepareContext.RegisterType(type, type.CLanguageMemberScope);

                if (type.BaseType != null)
                {
                    prepareContext.RegisterType(type.BaseType, type.CLanguageMemberScope);
                }

                foreach (var interfaceType in type.InterfaceTypes)
                {
                    prepareContext.RegisterType(type.BaseType, type.CLanguageMemberScope);
                }
            }

            // Lookup fields.
            foreach (var field in allTypes.SelectMany(type => type.Fields))
            {
                // Register field type.
                prepareContext.RegisterType(field.FieldType, field.CLanguageMemberScope);

                // Register include file from the native value.
                if (field.NativeValue != null)
                {
                    prepareContext.RegisterImportIncludeFile(field.NativeValue.IncludeFileName);
                }
            }

            // Construct result.
            return(new PreparedInformations(
                       allTypes,
                       (from type in allTypes
                        from method in type.DeclaredMethods
                        where predictMethod(method)
                        let preparedMethod = PrepareMethod(prepareContext, method)
                                             where preparedMethod != null
                                             select preparedMethod).
                       ToDictionary(
                           preparedMethod => preparedMethod.Method,
                           preparedMethod => preparedMethod)));
        }
Ejemplo n.º 2
0
        private static PreparedMethodInformation PrepareMethod(
            IPrepareContext prepareContext,
            IMethodInformation method)
        {
            var returnType = method.ReturnType;
            var parameters = method.Parameters;

            prepareContext.RegisterType(returnType, method.CLanguageMemberScope);
            foreach (var parameter in parameters)
            {
                prepareContext.RegisterType(parameter.TargetType, method.CLanguageMemberScope);
            }

            // Pure abstract method (ignored.)
            if (method.IsVirtual && method.IsAbstract)
            {
                Debug.Assert(!method.HasBody);
                return(null);
            }

            // Delegate constructor (ignored, it will be handled by the AssemblyWriter.)
            if (method.IsConstructor && method.DeclaringType.IsDelegate &&
                (method.Parameters.Length == 3) &&
                method.Parameters[1].TargetType.IsObjectType &&
                method.Parameters[2].TargetType.IsIntPtrType)
            {
                // Debug.Assert(!method.HasBody);  // Depended for the compiler (it has no body for Roslyn)
                return(null);
            }

            // internalcall or DllImport
            if (method.IsExtern)
            {
                Debug.Assert(!method.HasBody);

                if (method.NativeMethod != null)
                {
                    if (string.IsNullOrWhiteSpace(method.NativeMethod.IncludeFileName))
                    {
                        throw new InvalidProgramSequenceException(
                                  "Not given FunctionImport attribute argument. Name={0}",
                                  method.FriendlyName);
                    }

                    // TODO: register library name.
                    prepareContext.RegisterImportIncludeFile(method.NativeMethod.IncludeFileName);
                    if (method.ReturnType.NativeType != null)
                    {
                        prepareContext.RegisterImportIncludeFile(method.ReturnType.NativeType.IncludeFileName);
                    }
                    foreach (var parameter in method.Parameters)
                    {
                        if (parameter.TargetType.NativeType != null)
                        {
                            prepareContext.RegisterImportIncludeFile(parameter.TargetType.NativeType.IncludeFileName);
                        }
                    }
                }
                else if (method.PInvokeInformation != null)
                {
                    if (string.IsNullOrWhiteSpace(method.PInvokeInformation.Module.Name))
                    {
                        throw new InvalidProgramSequenceException(
                                  "Not given DllImport attribute argument. Name={0}",
                                  method.FriendlyName);
                    }

                    // TODO: register library name.
                    //prepareContext.RegisterPrivateIncludeFile(method.PInvokeInformation.Module.Name);
                }

                // Construct dummy information.
                return(new PreparedMethodInformation(
                           method,
                           null,
                           null,
                           null,
                           null,
                           null));
            }

            Debug.Assert(method.HasBody);

            return(PrepareMethodBody(
                       prepareContext,
                       method));
        }