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))); }
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)); }