Merge remote-tracking branch 'upstream/master' into mono-2019-02

This commit is contained in:
Alexander Köplinger 2019-04-15 15:05:36 +02:00
Родитель 8308ec9c67 d4e41445a2
Коммит 455af1ccc1
16 изменённых файлов: 672 добавлений и 458 удалений

12
jenkins/Jenkinsfile поставляемый
Просмотреть файл

@ -458,11 +458,13 @@ timestamps {
stage ('Build') { stage ('Build') {
currentStage = "${STAGE_NAME}" currentStage = "${STAGE_NAME}"
echo ("Building on ${env.NODE_NAME}") echo ("Building on ${env.NODE_NAME}")
withEnv ([ timeout (time: 1, unit: 'HOURS') {
"CURRENT_BRANCH=${branchName}", withEnv ([
"PACKAGE_HEAD_BRANCH=${branchName}" "CURRENT_BRANCH=${branchName}",
]) { "PACKAGE_HEAD_BRANCH=${branchName}"
sh ("${workspace}/xamarin-macios/jenkins/build.sh --configure-flags --enable-xamarin") ]) {
sh ("${workspace}/xamarin-macios/jenkins/build.sh --configure-flags --enable-xamarin")
}
} }
} }

Просмотреть файл

@ -44,17 +44,27 @@ namespace ObjCRuntime {
public BindAsAttribute (Type type) public BindAsAttribute (Type type)
{ {
Type = type; Type = type;
#if BGENERATOR
var nullable = type.IsArray ? TypeManager.GetUnderlyingNullableType (type.GetElementType ()) : TypeManager.GetUnderlyingNullableType (type);
IsNullable = nullable != null;
IsValueType = IsNullable ? nullable.IsValueType : type.IsValueType;
#endif
} }
public Type Type; public Type Type;
public Type OriginalType; public Type OriginalType;
#if BGENERATOR #if BGENERATOR
internal readonly bool IsNullable; Type nullable;
internal readonly bool IsValueType; Type GetNullable (Generator generator)
{
if (nullable == null)
nullable = Type.IsArray ? generator.TypeManager.GetUnderlyingNullableType (Type.GetElementType ()) : generator.TypeManager.GetUnderlyingNullableType (Type);
return nullable;
}
internal bool IsNullable (Generator generator)
{
return GetNullable (generator) != null;
}
internal bool IsValueType (Generator generator)
{
return IsNullable (generator) ? GetNullable (generator).IsValueType : Type.IsValueType;
}
#endif #endif
} }
} }

Просмотреть файл

@ -822,17 +822,17 @@ namespace Registrar {
var mi = (System.Reflection.MethodInfo) Method; var mi = (System.Reflection.MethodInfo) Method;
bool is_stret; bool is_stret;
#if __WATCHOS__ #if __WATCHOS__
is_stret = Runtime.Arch == Arch.DEVICE ? Stret.ArmNeedStret (NativeReturnType) : Stret.X86NeedStret (NativeReturnType); is_stret = Runtime.Arch == Arch.DEVICE ? Stret.ArmNeedStret (NativeReturnType, null) : Stret.X86NeedStret (NativeReturnType, null);
#elif MONOMAC #elif MONOMAC
is_stret = IntPtr.Size == 8 ? Stret.X86_64NeedStret (NativeReturnType) : Stret.X86NeedStret (NativeReturnType); is_stret = IntPtr.Size == 8 ? Stret.X86_64NeedStret (NativeReturnType, null) : Stret.X86NeedStret (NativeReturnType, null);
#elif __IOS__ #elif __IOS__
if (Runtime.Arch == Arch.DEVICE) { if (Runtime.Arch == Arch.DEVICE) {
is_stret = IntPtr.Size == 4 && Stret.ArmNeedStret (NativeReturnType); is_stret = IntPtr.Size == 4 && Stret.ArmNeedStret (NativeReturnType, null);
} else { } else {
is_stret = IntPtr.Size == 4 ? Stret.X86NeedStret (NativeReturnType) : Stret.X86_64NeedStret (NativeReturnType); is_stret = IntPtr.Size == 4 ? Stret.X86NeedStret (NativeReturnType, null) : Stret.X86_64NeedStret (NativeReturnType, null);
} }
#elif __TVOS__ #elif __TVOS__
is_stret = Runtime.Arch == Arch.SIMULATOR && Stret.X86_64NeedStret (NativeReturnType); is_stret = Runtime.Arch == Arch.SIMULATOR && Stret.X86_64NeedStret (NativeReturnType, null);
#else #else
#error unknown architecture #error unknown architecture
#endif #endif

Просмотреть файл

@ -27,6 +27,7 @@ using IKVM.Reflection;
using Type = IKVM.Reflection.Type; using Type = IKVM.Reflection.Type;
#else #else
using System.Reflection; using System.Reflection;
using Generator = System.Object;
#endif #endif
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -37,7 +38,6 @@ namespace ObjCRuntime
class Stret class Stret
{ {
#if BGENERATOR #if BGENERATOR
static bool isUnified = BindingTouch.Unified;
#elif __UNIFIED__ #elif __UNIFIED__
const bool isUnified = true; const bool isUnified = true;
#else #else
@ -50,11 +50,11 @@ namespace ObjCRuntime
return members <= 4; return members <= 4;
} }
static bool IsHomogeneousAggregateBaseType_Armv7k (Type t) static bool IsHomogeneousAggregateBaseType_Armv7k (Type t, Generator generator)
{ {
// https://github.com/llvm-mirror/clang/blob/82f6d5c9ae84c04d6e7b402f72c33638d1fb6bc8/lib/CodeGen/TargetInfo.cpp#L5500-L5514 // https://github.com/llvm-mirror/clang/blob/82f6d5c9ae84c04d6e7b402f72c33638d1fb6bc8/lib/CodeGen/TargetInfo.cpp#L5500-L5514
#if BGENERATOR #if BGENERATOR
if (t == TypeManager.System_Float || t == TypeManager.System_Double || t == TypeManager.System_nfloat) if (t == generator.TypeManager.System_Float || t == generator.TypeManager.System_Double || t == generator.TypeManager.System_nfloat)
return true; return true;
#else #else
if (t == typeof (float) || t == typeof (double) || t == typeof (nfloat)) if (t == typeof (float) || t == typeof (double) || t == typeof (nfloat))
@ -64,7 +64,7 @@ namespace ObjCRuntime
return false; return false;
} }
static bool IsHomogeneousAggregate_Armv7k (List<Type> fieldTypes) static bool IsHomogeneousAggregate_Armv7k (List<Type> fieldTypes, Generator generator)
{ {
// Very simplified version of https://github.com/llvm-mirror/clang/blob/82f6d5c9ae84c04d6e7b402f72c33638d1fb6bc8/lib/CodeGen/TargetInfo.cpp#L4051 // Very simplified version of https://github.com/llvm-mirror/clang/blob/82f6d5c9ae84c04d6e7b402f72c33638d1fb6bc8/lib/CodeGen/TargetInfo.cpp#L4051
// since C# supports a lot less types than clang does. // since C# supports a lot less types than clang does.
@ -75,7 +75,7 @@ namespace ObjCRuntime
if (!IsHomogeneousAggregateSmallEnough_Armv7k (fieldTypes [0], fieldTypes.Count)) if (!IsHomogeneousAggregateSmallEnough_Armv7k (fieldTypes [0], fieldTypes.Count))
return false; return false;
if (!IsHomogeneousAggregateBaseType_Armv7k (fieldTypes [0])) if (!IsHomogeneousAggregateBaseType_Armv7k (fieldTypes [0], generator))
return false; return false;
for (int i = 1; i < fieldTypes.Count; i++) { for (int i = 1; i < fieldTypes.Count; i++) {
@ -86,36 +86,39 @@ namespace ObjCRuntime
return true; return true;
} }
static bool IsMagicTypeOrCorlibType (Type t) static bool IsMagicTypeOrCorlibType (Type t, Generator generator)
{ {
switch (t.Name) { switch (t.Name) {
case "nint": case "nint":
case "nuint": case "nuint":
case "nfloat": case "nfloat":
#if BGENERATOR
var isUnified = generator.UnifiedAPI;
#endif
if (!isUnified) if (!isUnified)
return false; return false;
if (t.Namespace != "System") if (t.Namespace != "System")
return false; return false;
#if BGENERATOR #if BGENERATOR
return t.Assembly == TypeManager.PlatformAssembly; return t.Assembly == generator.TypeManager.PlatformAssembly;
#else #else
return t.Assembly == typeof (NSObject).Assembly; return t.Assembly == typeof (NSObject).Assembly;
#endif #endif
default: default:
#if BGENERATOR #if BGENERATOR
return t.Assembly == TypeManager.CorlibAssembly; return t.Assembly == generator.TypeManager.CorlibAssembly;
#else #else
return t.Assembly == typeof (object).Assembly; return t.Assembly == typeof (object).Assembly;
#endif #endif
} }
} }
public static bool ArmNeedStret (Type returnType) public static bool ArmNeedStret (Type returnType, Generator generator)
{ {
bool has32bitArm; bool has32bitArm;
#if BGENERATOR #if BGENERATOR
has32bitArm = BindingTouch.CurrentPlatform != PlatformName.TvOS && BindingTouch.CurrentPlatform != PlatformName.MacOSX; has32bitArm = generator.CurrentPlatform != PlatformName.TvOS && generator.CurrentPlatform != PlatformName.MacOSX;
#elif MONOMAC || __TVOS__ #elif MONOMAC || __TVOS__
has32bitArm = false; has32bitArm = false;
#else #else
@ -126,15 +129,15 @@ namespace ObjCRuntime
Type t = returnType; Type t = returnType;
if (!t.IsValueType || t.IsEnum || IsMagicTypeOrCorlibType (t)) if (!t.IsValueType || t.IsEnum || IsMagicTypeOrCorlibType (t, generator))
return false; return false;
var fieldTypes = new List<Type> (); var fieldTypes = new List<Type> ();
var size = GetValueTypeSize (t, fieldTypes, false); var size = GetValueTypeSize (t, fieldTypes, false, generator);
bool isWatchOS; bool isWatchOS;
#if BGENERATOR #if BGENERATOR
isWatchOS = BindingTouch.CurrentPlatform == PlatformName.WatchOS; isWatchOS = generator.CurrentPlatform == PlatformName.WatchOS;
#elif __WATCHOS__ #elif __WATCHOS__
isWatchOS = true; isWatchOS = true;
#else #else
@ -149,13 +152,13 @@ namespace ObjCRuntime
return false; return false;
// Except homogeneous aggregates, which are not stret either. // Except homogeneous aggregates, which are not stret either.
if (IsHomogeneousAggregate_Armv7k (fieldTypes)) if (IsHomogeneousAggregate_Armv7k (fieldTypes, generator))
return false; return false;
} }
bool isiOS; bool isiOS;
#if BGENERATOR #if BGENERATOR
isiOS = BindingTouch.CurrentPlatform == PlatformName.iOS; isiOS = generator.CurrentPlatform == PlatformName.iOS;
#elif __IOS__ #elif __IOS__
isiOS = true; isiOS = true;
#else #else
@ -184,15 +187,15 @@ namespace ObjCRuntime
return true; return true;
} }
public static bool X86NeedStret (Type returnType) public static bool X86NeedStret (Type returnType, Generator generator)
{ {
Type t = returnType; Type t = returnType;
if (!t.IsValueType || t.IsEnum || IsMagicTypeOrCorlibType (t)) if (!t.IsValueType || t.IsEnum || IsMagicTypeOrCorlibType (t, generator))
return false; return false;
var fieldTypes = new List<Type> (); var fieldTypes = new List<Type> ();
var size = GetValueTypeSize (t, fieldTypes, false); var size = GetValueTypeSize (t, fieldTypes, false, generator);
if (size > 8) if (size > 8)
return true; return true;
@ -203,21 +206,24 @@ namespace ObjCRuntime
return false; return false;
} }
public static bool X86_64NeedStret (Type returnType) public static bool X86_64NeedStret (Type returnType, Generator generator)
{ {
#if BGENERATOR
var isUnified = generator.UnifiedAPI;
#endif
if (!isUnified) if (!isUnified)
return false; return false;
Type t = returnType; Type t = returnType;
if (!t.IsValueType || t.IsEnum || IsMagicTypeOrCorlibType (t)) if (!t.IsValueType || t.IsEnum || IsMagicTypeOrCorlibType (t, generator))
return false; return false;
var fieldTypes = new List<Type> (); var fieldTypes = new List<Type> ();
return GetValueTypeSize (t, fieldTypes, true) > 16; return GetValueTypeSize (t, fieldTypes, true, generator) > 16;
} }
static int GetValueTypeSize (Type type, List<Type> fieldTypes, bool is_64_bits) static int GetValueTypeSize (Type type, List<Type> fieldTypes, bool is_64_bits, Generator generator)
{ {
int size = 0; int size = 0;
int maxElementSize = 1; int maxElementSize = 1;
@ -226,16 +232,16 @@ namespace ObjCRuntime
// Find the maximum of "field size + field offset" for each field. // Find the maximum of "field size + field offset" for each field.
foreach (var field in type.GetFields (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { foreach (var field in type.GetFields (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) {
#if BGENERATOR #if BGENERATOR
var fieldOffset = AttributeManager.GetCustomAttribute<FieldOffsetAttribute> (field); var fieldOffset = generator.AttributeManager.GetCustomAttribute<FieldOffsetAttribute> (field);
#else #else
var fieldOffset = (FieldOffsetAttribute) Attribute.GetCustomAttribute (field, typeof (FieldOffsetAttribute)); var fieldOffset = (FieldOffsetAttribute) Attribute.GetCustomAttribute (field, typeof (FieldOffsetAttribute));
#endif #endif
var elementSize = 0; var elementSize = 0;
GetValueTypeSize (type, field.FieldType, fieldTypes, is_64_bits, ref elementSize, ref maxElementSize); GetValueTypeSize (type, field.FieldType, fieldTypes, is_64_bits, ref elementSize, ref maxElementSize, generator);
size = Math.Max (size, elementSize + fieldOffset.Value); size = Math.Max (size, elementSize + fieldOffset.Value);
} }
} else { } else {
GetValueTypeSize (type, type, fieldTypes, is_64_bits, ref size, ref maxElementSize); GetValueTypeSize (type, type, fieldTypes, is_64_bits, ref size, ref maxElementSize, generator);
} }
if (size % maxElementSize != 0) if (size % maxElementSize != 0)
@ -252,7 +258,7 @@ namespace ObjCRuntime
return size += add; return size += add;
} }
static void GetValueTypeSize (Type original_type, Type type, List<Type> field_types, bool is_64_bits, ref int size, ref int max_element_size) static void GetValueTypeSize (Type original_type, Type type, List<Type> field_types, bool is_64_bits, ref int size, ref int max_element_size, Generator generator)
{ {
// FIXME: // FIXME:
// SIMD types are not handled correctly here (they need 16-bit alignment). // SIMD types are not handled correctly here (they need 16-bit alignment).
@ -298,12 +304,12 @@ namespace ObjCRuntime
// composite struct // composite struct
foreach (var field in type.GetFields (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { foreach (var field in type.GetFields (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) {
#if BGENERATOR #if BGENERATOR
var marshalAs = AttributeManager.GetCustomAttribute<MarshalAsAttribute> (field); var marshalAs = generator.AttributeManager.GetCustomAttribute<MarshalAsAttribute> (field);
#else #else
var marshalAs = (MarshalAsAttribute) Attribute.GetCustomAttribute (field, typeof (MarshalAsAttribute)); var marshalAs = (MarshalAsAttribute) Attribute.GetCustomAttribute (field, typeof (MarshalAsAttribute));
#endif #endif
if (marshalAs == null) { if (marshalAs == null) {
GetValueTypeSize (original_type, field.FieldType, field_types, is_64_bits, ref size, ref max_element_size); GetValueTypeSize (original_type, field.FieldType, field_types, is_64_bits, ref size, ref max_element_size, generator);
continue; continue;
} }
@ -311,7 +317,7 @@ namespace ObjCRuntime
switch (marshalAs.Value) { switch (marshalAs.Value) {
case UnmanagedType.ByValArray: case UnmanagedType.ByValArray:
var types = new List<Type> (); var types = new List<Type> ();
GetValueTypeSize (original_type, field.FieldType.GetElementType (), types, is_64_bits, ref type_size, ref max_element_size); GetValueTypeSize (original_type, field.FieldType.GetElementType (), types, is_64_bits, ref type_size, ref max_element_size, generator);
multiplier = marshalAs.SizeConst; multiplier = marshalAs.SizeConst;
break; break;
case UnmanagedType.U1: case UnmanagedType.U1:
@ -341,15 +347,15 @@ namespace ObjCRuntime
} }
} }
public static bool NeedStret (Type returnType) public static bool NeedStret (Type returnType, Generator generator)
{ {
if (X86NeedStret (returnType)) if (X86NeedStret (returnType, generator))
return true; return true;
if (X86_64NeedStret (returnType)) if (X86_64NeedStret (returnType, generator))
return true; return true;
if (ArmNeedStret (returnType)) if (ArmNeedStret (returnType, generator))
return true; return true;
return false; return false;

Просмотреть файл

@ -38,27 +38,30 @@ using ObjCRuntime;
using Foundation; using Foundation;
using Xamarin.Utils; using Xamarin.Utils;
class BindingTouch { public class BindingTouch {
static TargetFramework? target_framework; TargetFramework? target_framework;
public static PlatformName CurrentPlatform; public PlatformName CurrentPlatform;
public static bool Unified; public bool BindThirdPartyLibrary = true;
public static bool skipSystemDrawing; public bool Unified;
public static string outfile; public bool skipSystemDrawing;
public string outfile;
static string baselibdll; string baselibdll;
static string attributedll; string attributedll;
static string compiler = "/Library/Frameworks/Mono.framework/Versions/Current/bin/csc";
static List<string> libs = new List<string> (); List<string> libs = new List<string> ();
public static Universe universe; public Universe universe;
public TypeManager TypeManager = new TypeManager ();
public Frameworks Frameworks;
public AttributeManager AttributeManager;
public static TargetFramework TargetFramework { public TargetFramework TargetFramework {
get { return target_framework.Value; } get { return target_framework.Value; }
} }
public static string ToolName { public static string ToolName {
get { return Path.GetFileNameWithoutExtension (System.Reflection.Assembly.GetEntryAssembly ().Location); } get { return "bgen"; }
} }
static void ShowHelp (OptionSet os) static void ShowHelp (OptionSet os)
@ -69,17 +72,17 @@ class BindingTouch {
os.WriteOptionDescriptions (Console.Out); os.WriteOptionDescriptions (Console.Out);
} }
static int Main (string [] args) public static int Main (string [] args)
{ {
try { try {
return Main2 (args); return Main2 (args);
} catch (Exception ex) { } catch (Exception ex) {
ErrorHelper.Show (ex); ErrorHelper.Show (ex, false);
return 1; return 1;
} }
} }
static string GetAttributeLibraryPath () string GetAttributeLibraryPath ()
{ {
if (!string.IsNullOrEmpty (attributedll)) if (!string.IsNullOrEmpty (attributedll))
return attributedll; return attributedll;
@ -112,7 +115,7 @@ class BindingTouch {
} }
} }
static IEnumerable<string> GetLibraryDirectories () IEnumerable<string> GetLibraryDirectories ()
{ {
switch (CurrentPlatform) { switch (CurrentPlatform) {
case PlatformName.iOS: case PlatformName.iOS:
@ -147,7 +150,7 @@ class BindingTouch {
yield return lib; yield return lib;
} }
static string LocateAssembly (string name) string LocateAssembly (string name)
{ {
foreach (var asm in universe.GetAssemblies ()) { foreach (var asm in universe.GetAssemblies ()) {
if (asm.GetName ().Name == name) if (asm.GetName ().Name == name)
@ -166,7 +169,7 @@ class BindingTouch {
throw new FileNotFoundException ($"Could not find the assembly '{name}' in any of the directories: {string.Join (", ", GetLibraryDirectories ())}"); throw new FileNotFoundException ($"Could not find the assembly '{name}' in any of the directories: {string.Join (", ", GetLibraryDirectories ())}");
} }
static string GetSDKRoot () string GetSDKRoot ()
{ {
switch (CurrentPlatform) { switch (CurrentPlatform) {
case PlatformName.iOS: case PlatformName.iOS:
@ -186,7 +189,7 @@ class BindingTouch {
} }
} }
static void SetTargetFramework (string fx) void SetTargetFramework (string fx)
{ {
TargetFramework tf; TargetFramework tf;
if (!TargetFramework.TryParse (fx, out tf)) if (!TargetFramework.TryParse (fx, out tf))
@ -197,7 +200,7 @@ class BindingTouch {
throw ErrorHelper.CreateError (70, "Invalid target framework: {0}. Valid target frameworks are: {1}.", target_framework.Value, string.Join (" ", TargetFramework.ValidFrameworks.Select ((v) => v.ToString ()).ToArray ())); throw ErrorHelper.CreateError (70, "Invalid target framework: {0}. Valid target frameworks are: {1}.", target_framework.Value, string.Join (" ", TargetFramework.ValidFrameworks.Select ((v) => v.ToString ()).ToArray ()));
} }
public static string NamespacePlatformPrefix { public string NamespacePlatformPrefix {
get { get {
switch (CurrentPlatform) { switch (CurrentPlatform) {
case PlatformName.MacOSX: case PlatformName.MacOSX:
@ -212,6 +215,12 @@ class BindingTouch {
} }
static int Main2 (string [] args) static int Main2 (string [] args)
{
var touch = new BindingTouch ();
return touch.Main3 (args);
}
int Main3 (string [] args)
{ {
bool show_help = false; bool show_help = false;
bool zero_copy = false; bool zero_copy = false;
@ -235,6 +244,9 @@ class BindingTouch {
var defines = new List<string> (); var defines = new List<string> ();
string generate_file_list = null; string generate_file_list = null;
bool process_enums = false; bool process_enums = false;
string compiler = "/Library/Frameworks/Mono.framework/Versions/Current/bin/csc";
ErrorHelper.ClearWarningLevels ();
var os = new OptionSet () { var os = new OptionSet () {
{ "h|?|help", "Displays the help", v => show_help = true }, { "h|?|help", "Displays the help", v => show_help = true },
@ -246,7 +258,7 @@ class BindingTouch {
{ "sourceonly=", "Only generates the source", v => generate_file_list = v }, { "sourceonly=", "Only generates the source", v => generate_file_list = v },
{ "ns=", "Sets the namespace for storing helper classes", v => ns = v }, { "ns=", "Sets the namespace for storing helper classes", v => ns = v },
{ "unsafe", "Sets the unsafe flag for the build", v=> unsafef = true }, { "unsafe", "Sets the unsafe flag for the build", v=> unsafef = true },
{ "core", "Use this to build product assemblies", v => Generator.BindThirdPartyLibrary = false }, { "core", "Use this to build product assemblies", v => BindThirdPartyLibrary = false },
{ "r=", "Adds a reference", v => references.Add (v) }, { "r=", "Adds a reference", v => references.Add (v) },
{ "lib=", "Adds the directory to the search path for the compiler", v => libs.Add (StringUtils.Quote (v)) }, { "lib=", "Adds the directory to the search path for the compiler", v => libs.Add (StringUtils.Quote (v)) },
{ "compiler=", "Sets the compiler to use (Obsolete) ", v => compiler = v, true }, { "compiler=", "Sets the compiler to use (Obsolete) ", v => compiler = v, true },
@ -512,11 +524,14 @@ class BindingTouch {
return 1; return 1;
} }
AttributeManager = new AttributeManager (this);
Frameworks = new Frameworks (CurrentPlatform);
Assembly corlib_assembly = universe.LoadFile (LocateAssembly ("mscorlib")); Assembly corlib_assembly = universe.LoadFile (LocateAssembly ("mscorlib"));
Assembly platform_assembly = baselib; Assembly platform_assembly = baselib;
Assembly system_assembly = universe.LoadFile (LocateAssembly ("System")); Assembly system_assembly = universe.LoadFile (LocateAssembly ("System"));
Assembly binding_assembly = universe.LoadFile (GetAttributeLibraryPath ()); Assembly binding_assembly = universe.LoadFile (GetAttributeLibraryPath ());
TypeManager.Initialize (api, corlib_assembly, platform_assembly, system_assembly, binding_assembly); TypeManager.Initialize (this, api, corlib_assembly, platform_assembly, system_assembly, binding_assembly);
foreach (var linkWith in AttributeManager.GetCustomAttributes<LinkWithAttribute> (api)) { foreach (var linkWith in AttributeManager.GetCustomAttributes<LinkWithAttribute> (api)) {
if (!linkwith.Contains (linkWith.LibraryName)) { if (!linkwith.Contains (linkWith.LibraryName)) {
@ -549,18 +564,19 @@ class BindingTouch {
} }
var nsManager = new NamespaceManager ( var nsManager = new NamespaceManager (
this,
NamespacePlatformPrefix, NamespacePlatformPrefix,
ns == null ? firstApiDefinitionName : ns, ns == null ? firstApiDefinitionName : ns,
skipSystemDrawing skipSystemDrawing
); );
var g = new Generator (nsManager, public_mode, external, debug, types.ToArray (), strong_dictionaries.ToArray ()){ var g = new Generator (this, nsManager, public_mode, external, debug, types.ToArray (), strong_dictionaries.ToArray ()){
BaseDir = basedir != null ? basedir : tmpdir, BaseDir = basedir != null ? basedir : tmpdir,
ZeroCopyStrings = zero_copy, ZeroCopyStrings = zero_copy,
InlineSelectors = inline_selectors ?? (Unified && CurrentPlatform != PlatformName.MacOSX), InlineSelectors = inline_selectors ?? (Unified && CurrentPlatform != PlatformName.MacOSX),
}; };
if (!Unified && !Generator.BindThirdPartyLibrary) { if (!Unified && !BindThirdPartyLibrary) {
foreach (var mi in baselib.GetType (nsManager.CoreObjCRuntime + ".Messaging").GetMethods ()){ foreach (var mi in baselib.GetType (nsManager.CoreObjCRuntime + ".Messaging").GetMethods ()){
if (mi.Name.IndexOf ("_objc_msgSend", StringComparison.Ordinal) != -1) if (mi.Name.IndexOf ("_objc_msgSend", StringComparison.Ordinal) != -1)
g.RegisterMethodName (mi.Name); g.RegisterMethodName (mi.Name);

Просмотреть файл

@ -55,7 +55,11 @@ public static class ErrorHelper {
Disable = 1, Disable = 1,
} }
static public int Verbosity { get; set; } [ThreadStatic]
static int verbosity;
static public int Verbosity { get { return verbosity; } set { verbosity = value; } }
[ThreadStatic]
static Dictionary<int, WarningLevel> warning_levels; static Dictionary<int, WarningLevel> warning_levels;
public static ProductException CreateError (int code, string message, params object[] args) public static ProductException CreateError (int code, string message, params object[] args)
@ -63,18 +67,26 @@ public static class ErrorHelper {
return new ProductException (code, true, message, args); return new ProductException (code, true, message, args);
} }
static public void Show (Exception e) static public void Show (Exception e, bool rethrow_errors = true)
{ {
List<Exception> exceptions = new List<Exception> (); List<Exception> exceptions = new List<Exception> ();
bool error = false; bool error = false;
CollectExceptions (e, exceptions); CollectExceptions (e, exceptions);
foreach (var ex in exceptions) if (rethrow_errors) {
error |= ShowInternal (ex); foreach (var ex in exceptions) {
if (ex is ProductException pe && !pe.Error)
continue;
error = true;
break;
}
if (error)
throw e;
}
if (error) foreach (var ex in exceptions)
Environment.Exit (1); ShowInternal (ex);
} }
static void CollectExceptions (Exception ex, List<Exception> exceptions) static void CollectExceptions (Exception ex, List<Exception> exceptions)
@ -156,4 +168,9 @@ public static class ErrorHelper {
else else
warning_levels [-1] = level; // code -1: all codes. warning_levels [-1] = level; // code -1: all codes.
} }
public static void ClearWarningLevels ()
{
warning_levels?.Clear ();
}
} }

Просмотреть файл

@ -26,7 +26,7 @@ Console.WriteLine ("partial class Frameworks {");
for (int i = 0; i < names.Length; i++) { for (int i = 0; i < names.Length; i++) {
var name = names [i]; var name = names [i];
var frameworks = allframeworks [i]; var frameworks = allframeworks [i];
Console.Write ($"\tstatic readonly HashSet<string> {name} = new HashSet<string> {{\""); Console.Write ($"\treadonly HashSet<string> {name} = new HashSet<string> {{\"");
Console.Write (string.Join ("\", \"", frameworks)); Console.Write (string.Join ("\", \"", frameworks));
Console.WriteLine ("\"};"); Console.WriteLine ("\"};");
} }
@ -34,8 +34,8 @@ for (int i = 0; i < names.Length; i++) {
var allArray = all.ToArray (); var allArray = all.ToArray ();
Array.Sort (allArray); Array.Sort (allArray);
foreach (var fw in allArray) foreach (var fw in allArray)
Console.WriteLine ($"\tstatic bool? _{fw.Replace (".", "")};"); Console.WriteLine ($"\tbool? _{fw.Replace (".", "")};");
foreach (var fw in allArray) foreach (var fw in allArray)
Console.WriteLine ($"\tpublic static bool Have{fw} {{ get {{ if (!_{fw}.HasValue) _{fw} = GetValue (\"{fw}\"); return _{fw}.Value; }} }}"); Console.WriteLine ($"\tpublic bool Have{fw} {{ get {{ if (!_{fw}.HasValue) _{fw} = GetValue (\"{fw}\"); return _{fw}.Value; }} }}");
Console.WriteLine ("}"); Console.WriteLine ("}");
Environment.Exit (0); Environment.Exit (0);

Просмотреть файл

@ -5,11 +5,19 @@ using IKVM.Reflection;
using Type = IKVM.Reflection.Type; using Type = IKVM.Reflection.Type;
using PlatformName = ObjCRuntime.PlatformName; using PlatformName = ObjCRuntime.PlatformName;
public static class AttributeManager public class AttributeManager
{ {
public BindingTouch BindingTouch;
TypeManager TypeManager { get { return BindingTouch.TypeManager; } }
public AttributeManager (BindingTouch binding_touch)
{
BindingTouch = binding_touch;
}
// This method gets the System.Type for a IKVM.Reflection.Type to a System.Type. // This method gets the System.Type for a IKVM.Reflection.Type to a System.Type.
// It knows about our mock attribute logic, so it will return the corresponding non-mocked System.Type for a mocked IKVM.Reflection.Type. // It knows about our mock attribute logic, so it will return the corresponding non-mocked System.Type for a mocked IKVM.Reflection.Type.
static System.Type ConvertType (Type type, ICustomAttributeProvider provider) System.Type ConvertType (Type type, ICustomAttributeProvider provider)
{ {
System.Type rv; System.Type rv;
if (type.Assembly == TypeManager.CorlibAssembly) { if (type.Assembly == TypeManager.CorlibAssembly) {
@ -49,7 +57,7 @@ public static class AttributeManager
// This method gets the IKVM.Reflection.Type for a System.Type. // This method gets the IKVM.Reflection.Type for a System.Type.
// It knows about our mock attribute logic, so it will return the mocked IKVM.Reflection.Type for a mocked System.Type. // It knows about our mock attribute logic, so it will return the mocked IKVM.Reflection.Type for a mocked System.Type.
static Type ConvertType (System.Type type, ICustomAttributeProvider provider) Type ConvertType (System.Type type, ICustomAttributeProvider provider)
{ {
Type rv; Type rv;
if (type.Assembly == typeof (int).Assembly) { if (type.Assembly == typeof (int).Assembly) {
@ -126,7 +134,7 @@ public static class AttributeManager
} }
} }
static IEnumerable<T> CreateAttributeInstance <T> (CustomAttributeData attribute, ICustomAttributeProvider provider) where T : System.Attribute IEnumerable<T> CreateAttributeInstance <T> (CustomAttributeData attribute, ICustomAttributeProvider provider) where T : System.Attribute
{ {
var convertedAttributes = ConvertOldAttributes (attribute); var convertedAttributes = ConvertOldAttributes (attribute);
if (convertedAttributes.Any ()) if (convertedAttributes.Any ())
@ -212,7 +220,7 @@ public static class AttributeManager
return ((T) instance).Yield (); return ((T) instance).Yield ();
} }
static T [] FilterAttributes<T> (IList<CustomAttributeData> attributes, ICustomAttributeProvider provider) where T : System.Attribute T [] FilterAttributes<T> (IList<CustomAttributeData> attributes, ICustomAttributeProvider provider) where T : System.Attribute
{ {
if (attributes == null || attributes.Count == 0) if (attributes == null || attributes.Count == 0)
return Array.Empty<T> (); return Array.Empty<T> ();
@ -232,7 +240,7 @@ public static class AttributeManager
return Array.Empty<T> (); return Array.Empty<T> ();
} }
public static T [] GetCustomAttributes<T> (ICustomAttributeProvider provider) where T : System.Attribute public T [] GetCustomAttributes<T> (ICustomAttributeProvider provider) where T : System.Attribute
{ {
return FilterAttributes<T> (GetIKVMAttributes (provider), provider); return FilterAttributes<T> (GetIKVMAttributes (provider), provider);
} }
@ -263,7 +271,7 @@ public static class AttributeManager
return false; return false;
} }
public static bool HasAttribute<T> (ICustomAttributeProvider provider) where T : Attribute public bool HasAttribute<T> (ICustomAttributeProvider provider) where T : Attribute
{ {
var attribute_type = ConvertType (typeof (T), provider); var attribute_type = ConvertType (typeof (T), provider);
var attribs = GetIKVMAttributes (provider); var attribs = GetIKVMAttributes (provider);
@ -281,7 +289,7 @@ public static class AttributeManager
return false; return false;
} }
public static T GetCustomAttribute<T> (ICustomAttributeProvider provider) where T : System.Attribute public T GetCustomAttribute<T> (ICustomAttributeProvider provider) where T : System.Attribute
{ {
if (provider is null) if (provider is null)
return null; return null;

Просмотреть файл

@ -75,7 +75,7 @@ public partial class Generator {
var fa = AttributeManager.GetCustomAttribute<FieldAttribute> (f); var fa = AttributeManager.GetCustomAttribute<FieldAttribute> (f);
if (fa == null) if (fa == null)
continue; continue;
if (f.IsUnavailable ()) if (f.IsUnavailable (this))
continue; continue;
if (fa.SymbolName == null) if (fa.SymbolName == null)
null_field = new Tuple<FieldInfo, FieldAttribute> (f, fa); null_field = new Tuple<FieldInfo, FieldAttribute> (f, fa);

Просмотреть файл

@ -55,7 +55,7 @@ public partial class Generator {
var intptrctor_visibility = filter.IntPtrCtorVisibility; var intptrctor_visibility = filter.IntPtrCtorVisibility;
if (intptrctor_visibility == MethodAttributes.PrivateScope) { if (intptrctor_visibility == MethodAttributes.PrivateScope) {
// since it was not generated code we never fixed the .ctor(IntPtr) visibility for unified // since it was not generated code we never fixed the .ctor(IntPtr) visibility for unified
if (Generator.XamcoreVersion >= 3) { if (XamcoreVersion >= 3) {
intptrctor_visibility = MethodAttributes.FamORAssem; intptrctor_visibility = MethodAttributes.FamORAssem;
} else { } else {
intptrctor_visibility = MethodAttributes.Public; intptrctor_visibility = MethodAttributes.Public;
@ -106,7 +106,7 @@ public partial class Generator {
// properties // properties
foreach (var p in type.GetProperties (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) { foreach (var p in type.GetProperties (BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) {
if (p.IsUnavailable ()) if (p.IsUnavailable (this))
continue; continue;
print (""); print ("");

Просмотреть файл

@ -3,135 +3,138 @@ using System;
using IKVM.Reflection; using IKVM.Reflection;
using Type = IKVM.Reflection.Type; using Type = IKVM.Reflection.Type;
public static class TypeManager { public class TypeManager {
public static Type System_Attribute; BindingTouch BindingTouch;
public static Type System_Boolean; Frameworks Frameworks { get { return BindingTouch.Frameworks; } }
public static Type System_Byte;
public static Type System_Delegate;
public static Type System_Double;
public static Type System_Float;
public static Type System_Int16;
public static Type System_Int32;
public static Type System_Int64;
public static Type System_IntPtr;
public static Type System_Object;
public static Type System_SByte;
public static Type System_String;
public static Type System_String_Array;
public static Type System_UInt16;
public static Type System_UInt32;
public static Type System_UInt64;
public static Type System_Void;
public static Type System_nint; public Type System_Attribute;
public static Type System_nuint; public Type System_Boolean;
public static Type System_nfloat; public Type System_Byte;
public Type System_Delegate;
public Type System_Double;
public Type System_Float;
public Type System_Int16;
public Type System_Int32;
public Type System_Int64;
public Type System_IntPtr;
public Type System_Object;
public Type System_SByte;
public Type System_String;
public Type System_String_Array;
public Type System_UInt16;
public Type System_UInt32;
public Type System_UInt64;
public Type System_Void;
public Type System_nint;
public Type System_nuint;
public Type System_nfloat;
/* fundamental */ /* fundamental */
public static Type NSObject; public Type NSObject;
public static Type INativeObject; public Type INativeObject;
/* objcruntime */ /* objcruntime */
public static Type BlockLiteral; public Type BlockLiteral;
public static Type Class; public Type Class;
public static Type Protocol; public Type Protocol;
public static Type Selector; public Type Selector;
public static Type Constants; public Type Constants;
/* Different binding types */ /* Different binding types */
public static Type DictionaryContainerType; public Type DictionaryContainerType;
public static Type ABAddressBook; public Type ABAddressBook;
public static Type ABPerson; public Type ABPerson;
public static Type ABRecord; public Type ABRecord;
public static Type AudioBuffers; public Type AudioBuffers;
public static Type AudioComponent; public Type AudioComponent;
public static Type AudioUnit; public Type AudioUnit;
public static Type AURenderEventEnumerator; public Type AURenderEventEnumerator;
public static Type AVCaptureWhiteBalanceGains; public Type AVCaptureWhiteBalanceGains;
public static Type CATransform3D; public Type CATransform3D;
public static Type CFRunLoop; public Type CFRunLoop;
public static Type CGAffineTransform; public Type CGAffineTransform;
public static Type CGColor; public Type CGColor;
public static Type CGColorSpace; public Type CGColorSpace;
public static Type CGContext; public Type CGContext;
public static Type CGPDFDocument; public Type CGPDFDocument;
public static Type CGPDFPage; public Type CGPDFPage;
public static Type CGGradient; public Type CGGradient;
public static Type CGImage; public Type CGImage;
public static Type CGLayer; public Type CGLayer;
public static Type CGLContext; public Type CGLContext;
public static Type CGLPixelFormat; public Type CGLPixelFormat;
public static Type CGPath; public Type CGPath;
public static Type CGVector; public Type CGVector;
public static Type CLLocationCoordinate2D; public Type CLLocationCoordinate2D;
public static Type CMAudioFormatDescription; public Type CMAudioFormatDescription;
public static Type CMClock; public Type CMClock;
public static Type CMFormatDescription; public Type CMFormatDescription;
public static Type CMSampleBuffer; public Type CMSampleBuffer;
public static Type CMTime; public Type CMTime;
public static Type CMTimebase; public Type CMTimebase;
public static Type CMTimeMapping; public Type CMTimeMapping;
public static Type CMTimeRange; public Type CMTimeRange;
public static Type CMVideoFormatDescription; public Type CMVideoFormatDescription;
public static Type CVImageBuffer; public Type CVImageBuffer;
public static Type CVPixelBuffer; public Type CVPixelBuffer;
public static Type CVPixelBufferPool; public Type CVPixelBufferPool;
public static Type DispatchQueue; public Type DispatchQueue;
public static Type DispatchData; public Type DispatchData;
public static Type MidiEndpoint; public Type MidiEndpoint;
public static Type MKCoordinateSpan; public Type MKCoordinateSpan;
public static Type MTAudioProcessingTap; public Type MTAudioProcessingTap;
public static Type MusicSequence; public Type MusicSequence;
public static Type NSNumber; public Type NSNumber;
public static Type NSRange; public Type NSRange;
public static Type NSString; public Type NSString;
public static Type NSValue; public Type NSValue;
public static Type NSZone; public Type NSZone;
public static Type SCNMatrix4; public Type SCNMatrix4;
public static Type SCNVector3; public Type SCNVector3;
public static Type SCNVector4; public Type SCNVector4;
public static Type SecAccessControl; public Type SecAccessControl;
public static Type SecIdentity; public Type SecIdentity;
public static Type SecTrust; public Type SecTrust;
public static Type SecProtocolMetadata; public Type SecProtocolMetadata;
public static Type SecProtocolOptions; public Type SecProtocolOptions;
public static Type SecTrust2; public Type SecTrust2;
public static Type SecIdentity2; public Type SecIdentity2;
public static Type UIEdgeInsets; public Type UIEdgeInsets;
public static Type UIOffset; public Type UIOffset;
public static Type NSDirectionalEdgeInsets; public Type NSDirectionalEdgeInsets;
public static Type CoreGraphics_CGPoint; public Type CoreGraphics_CGPoint;
public static Type CoreGraphics_CGRect; public Type CoreGraphics_CGRect;
public static Type CoreGraphics_CGSize; public Type CoreGraphics_CGSize;
static Assembly api_assembly; Assembly api_assembly;
static Assembly corlib_assembly; Assembly corlib_assembly;
static Assembly platform_assembly; Assembly platform_assembly;
static Assembly system_assembly; Assembly system_assembly;
static Assembly binding_assembly; Assembly binding_assembly;
public static Assembly CorlibAssembly { public Assembly CorlibAssembly {
get { return corlib_assembly; } get { return corlib_assembly; }
} }
public static Assembly PlatformAssembly { public Assembly PlatformAssembly {
get { return platform_assembly; } get { return platform_assembly; }
set { platform_assembly = value; } set { platform_assembly = value; }
} }
public static Assembly SystemAssembly { public Assembly SystemAssembly {
get { return system_assembly; } get { return system_assembly; }
} }
public static Assembly BindingAssembly { public Assembly BindingAssembly {
get { return binding_assembly; } get { return binding_assembly; }
} }
static Type Lookup (Assembly assembly, string @namespace, string @typename, bool inexistentOK = false) Type Lookup (Assembly assembly, string @namespace, string @typename, bool inexistentOK = false)
{ {
string fullname; string fullname;
string nsManagerPrefix = null; string nsManagerPrefix = null;
@ -154,7 +157,7 @@ public static class TypeManager {
return rv; return rv;
} }
public static Type GetUnderlyingNullableType (Type type) public Type GetUnderlyingNullableType (Type type)
{ {
if (!type.IsConstructedGenericType) if (!type.IsConstructedGenericType)
return null; return null;
@ -182,8 +185,10 @@ public static class TypeManager {
return type.GetEnumUnderlyingType (); return type.GetEnumUnderlyingType ();
} }
public static void Initialize (Assembly api, Assembly corlib, Assembly platform, Assembly system, Assembly binding) public void Initialize (BindingTouch binding_touch, Assembly api, Assembly corlib, Assembly platform, Assembly system, Assembly binding)
{ {
BindingTouch = binding_touch;
api_assembly = api; api_assembly = api;
corlib_assembly = corlib; corlib_assembly = corlib;
platform_assembly = platform; platform_assembly = platform;
@ -210,7 +215,7 @@ public static class TypeManager {
System_UInt64 = Lookup (corlib_assembly, "System", "UInt64"); System_UInt64 = Lookup (corlib_assembly, "System", "UInt64");
System_Void = Lookup (corlib_assembly, "System", "Void"); System_Void = Lookup (corlib_assembly, "System", "Void");
if (Generator.UnifiedAPI) { if (BindingTouch.Unified) {
System_nint = Lookup (platform_assembly, "System", "nint"); System_nint = Lookup (platform_assembly, "System", "nint");
System_nuint = Lookup (platform_assembly, "System", "nuint"); System_nuint = Lookup (platform_assembly, "System", "nuint");
System_nfloat = Lookup (platform_assembly, "System", "nfloat"); System_nfloat = Lookup (platform_assembly, "System", "nfloat");
@ -226,7 +231,7 @@ public static class TypeManager {
Protocol = Lookup (platform_assembly, "ObjCRuntime", "Protocol"); Protocol = Lookup (platform_assembly, "ObjCRuntime", "Protocol");
Selector = Lookup (platform_assembly, "ObjCRuntime", "Selector"); Selector = Lookup (platform_assembly, "ObjCRuntime", "Selector");
if (Generator.UnifiedAPI) { if (BindingTouch.Unified) {
Constants = Lookup (platform_assembly, "ObjCRuntime", "Constants"); Constants = Lookup (platform_assembly, "ObjCRuntime", "Constants");
} else { } else {
Constants = Lookup (platform_assembly, "", "Constants"); Constants = Lookup (platform_assembly, "", "Constants");
@ -297,10 +302,10 @@ public static class TypeManager {
MKCoordinateSpan = Lookup (platform_assembly, "MapKit", "MKCoordinateSpan", true /* isn't in XM/Classic */); MKCoordinateSpan = Lookup (platform_assembly, "MapKit", "MKCoordinateSpan", true /* isn't in XM/Classic */);
if (Frameworks.HaveMediaToolbox) if (Frameworks.HaveMediaToolbox)
MTAudioProcessingTap = Lookup (platform_assembly, "MediaToolbox", "MTAudioProcessingTap"); MTAudioProcessingTap = Lookup (platform_assembly, "MediaToolbox", "MTAudioProcessingTap");
NSNumber = Lookup (Generator.BindThirdPartyLibrary ? platform_assembly : api_assembly, "Foundation", "NSNumber"); NSNumber = Lookup (binding_touch.BindThirdPartyLibrary ? platform_assembly : api_assembly, "Foundation", "NSNumber");
NSRange = Lookup (platform_assembly, "Foundation", "NSRange"); NSRange = Lookup (platform_assembly, "Foundation", "NSRange");
NSString = Lookup (platform_assembly, "Foundation", "NSString"); NSString = Lookup (platform_assembly, "Foundation", "NSString");
NSValue = Lookup (Generator.BindThirdPartyLibrary ? platform_assembly : api_assembly, "Foundation", "NSValue"); NSValue = Lookup (binding_touch.BindThirdPartyLibrary ? platform_assembly : api_assembly, "Foundation", "NSValue");
NSZone = Lookup (platform_assembly, "Foundation", "NSZone"); NSZone = Lookup (platform_assembly, "Foundation", "NSZone");
SCNVector3 = Lookup (platform_assembly, "SceneKit", "SCNVector3"); SCNVector3 = Lookup (platform_assembly, "SceneKit", "SCNVector3");
SCNVector4 = Lookup (platform_assembly, "SceneKit", "SCNVector4"); SCNVector4 = Lookup (platform_assembly, "SceneKit", "SCNVector4");
@ -318,7 +323,7 @@ public static class TypeManager {
NSDirectionalEdgeInsets = Lookup (platform_assembly, "UIKit", "NSDirectionalEdgeInsets"); NSDirectionalEdgeInsets = Lookup (platform_assembly, "UIKit", "NSDirectionalEdgeInsets");
} }
if (Generator.UnifiedAPI) { if (BindingTouch.Unified) {
CoreGraphics_CGRect = Lookup (platform_assembly, "CoreGraphics", "CGRect"); CoreGraphics_CGRect = Lookup (platform_assembly, "CoreGraphics", "CGRect");
CoreGraphics_CGPoint = Lookup (platform_assembly, "CoreGraphics", "CGPoint"); CoreGraphics_CGPoint = Lookup (platform_assembly, "CoreGraphics", "CGPoint");
CoreGraphics_CGSize = Lookup (platform_assembly, "CoreGraphics", "CGSize"); CoreGraphics_CGSize = Lookup (platform_assembly, "CoreGraphics", "CGSize");

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -8,6 +8,8 @@
<AssemblyName>bgen</AssemblyName> <AssemblyName>bgen</AssemblyName>
<RootNamespace>bgen</RootNamespace> <RootNamespace>bgen</RootNamespace>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion> <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<BuildDir Condition="'$(BUILD_DIR)' != ''">$(BUILD_DIR)\</BuildDir>
<BuildDir Condition="'$(BUILD_DIR)' == ''">build\</BuildDir>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>True</DebugSymbols> <DebugSymbols>True</DebugSymbols>
@ -356,7 +358,7 @@
<Compile Include="..\src\ObjCRuntime\Stret.cs"/> <Compile Include="..\src\ObjCRuntime\Stret.cs"/>
<Compile Include="..\tools\common\TargetFramework.cs"/> <Compile Include="..\tools\common\TargetFramework.cs"/>
<Compile Include="..\tools\common\StringUtils.cs"/> <Compile Include="..\tools\common\StringUtils.cs"/>
<Compile Include="build\generator-frameworks.g.cs"/> <Compile Include="$(BuildDir)generator-frameworks.g.cs"/>
<Compile Include="..\external\mono\mcs\class\Mono.Options\Mono.Options\Options.cs"/> <Compile Include="..\external\mono\mcs\class\Mono.Options\Mono.Options\Options.cs"/>
<Compile Include="..\src\Foundation\AdviceAttribute.cs"/> <Compile Include="..\src\Foundation\AdviceAttribute.cs"/>
<Compile Include="..\src\Foundation\ExportAttribute.cs"/> <Compile Include="..\src\Foundation\ExportAttribute.cs"/>

Просмотреть файл

@ -18,6 +18,7 @@ namespace Xamarin.Tests
AssemblyDefinition assembly; AssemblyDefinition assembly;
public Profile Profile; public Profile Profile;
public bool InProcess = true; // if executed using an in-process bgen. Ignored if using the classic bgen (for XM/Classic), in which case we'll always use the out-of-process bgen.
public bool ProcessEnums; public bool ProcessEnums;
public List<string> ApiDefinitions = new List<string> (); public List<string> ApiDefinitions = new List<string> ();
@ -29,6 +30,7 @@ namespace Xamarin.Tests
public string ResponseFile; public string ResponseFile;
public string WarnAsError; // Set to empty string to pass /warnaserror, set to non-empty string to pass /warnaserror:<nonemptystring> public string WarnAsError; // Set to empty string to pass /warnaserror, set to non-empty string to pass /warnaserror:<nonemptystring>
public string NoWarn; // Set to empty string to pass /nowarn, set to non-empty string to pass /nowarn:<nonemptystring> public string NoWarn; // Set to empty string to pass /nowarn, set to non-empty string to pass /nowarn:<nonemptystring>
public string Out;
protected override string ToolPath { get { return Profile == Profile.macOSClassic ? Configuration.BGenClassicPath : Configuration.BGenPath; } } protected override string ToolPath { get { return Profile == Profile.macOSClassic ? Configuration.BGenClassicPath : Configuration.BGenPath; } }
protected override string MessagePrefix { get { return "BI"; } } protected override string MessagePrefix { get { return "BI"; } }
@ -54,9 +56,9 @@ namespace Xamarin.Tests
} }
} }
string BuildArguments () string [] BuildArgumentArray ()
{ {
var sb = new StringBuilder (); var sb = new List<string> ();
var targetFramework = (string) null; var targetFramework = (string) null;
switch (Profile) { switch (Profile) {
@ -88,54 +90,78 @@ namespace Xamarin.Tests
} }
if (!string.IsNullOrEmpty (targetFramework)) if (!string.IsNullOrEmpty (targetFramework))
sb.Append (" --target-framework=").Append (targetFramework); sb.Add ($"--target-framework={targetFramework}");
foreach (var ad in ApiDefinitions) foreach (var ad in ApiDefinitions)
sb.Append (" --api=").Append (StringUtils.Quote (ad)); sb.Add ($"--api={ad}");
foreach (var s in Sources) foreach (var s in Sources)
sb.Append (" -s=").Append (StringUtils.Quote (s)); sb.Add ($"-s={s}");
foreach (var r in References) foreach (var r in References)
sb.Append (" -r=").Append (StringUtils.Quote (r)); sb.Add ($"-r={r}");
if (!string.IsNullOrEmpty (TmpDirectory)) if (!string.IsNullOrEmpty (TmpDirectory))
sb.Append (" --tmpdir=").Append (StringUtils.Quote (TmpDirectory)); sb.Add ($"--tmpdir={TmpDirectory}");
if (!string.IsNullOrEmpty (ResponseFile)) if (!string.IsNullOrEmpty (ResponseFile))
sb.Append (" @").Append (StringUtils.Quote (ResponseFile)); sb.Add ($"@{ResponseFile}");
if (!string.IsNullOrEmpty (Out))
sb.Add ($"--out={Out}");
if (ProcessEnums) if (ProcessEnums)
sb.Append (" --process-enums"); sb.Add ("--process-enums");
if (Defines != null) { if (Defines != null) {
foreach (var d in Defines) foreach (var d in Defines)
sb.Append (" -d ").Append (StringUtils.Quote (d)); sb.Add ($"-d={d}");
} }
if (WarnAsError != null) { if (WarnAsError != null) {
sb.Append (" --warnaserror"); var arg = "--warnaserror";
if (WarnAsError.Length > 0) if (WarnAsError.Length > 0)
sb.Append (":").Append (StringUtils.Quote (WarnAsError)); arg += ":" + WarnAsError;
sb.Add (arg);
} }
if (NoWarn != null) { if (NoWarn != null) {
sb.Append (" --nowarn"); var arg = "--nowarn";
if (NoWarn.Length > 0) if (NoWarn.Length > 0)
sb.Append (":").Append (StringUtils.Quote (NoWarn)); arg += ":" + NoWarn;
sb.Add (arg);
} }
sb.Add ("-v");
return sb.ToString (); return sb.ToArray ();
} }
public void AssertExecute (string message) public void AssertExecute (string message)
{ {
Assert.AreEqual (0, Execute (BuildArguments (), always_show_output: true), message); Assert.AreEqual (0, Execute (), message);
} }
public void AssertExecuteError (string message) public void AssertExecuteError (string message)
{ {
Assert.AreNotEqual (0, Execute (BuildArguments ()), message); Assert.AreNotEqual (0, Execute (), message);
}
int Execute ()
{
var arguments = BuildArgumentArray ();
var in_process = InProcess && Profile != Profile.macOSClassic;
if (in_process) {
int rv;
ThreadStaticTextWriter.ReplaceConsole (Output);
try {
rv = BindingTouch.Main (arguments);
} finally {
ThreadStaticTextWriter.RestoreConsole ();
}
Console.WriteLine (Output);
ParseMessages ();
return rv;
}
return Execute (string.Join (" ", StringUtils.Quote (arguments)), always_show_output: true);
} }
public void AssertApiCallsMethod (string caller_namespace, string caller_type, string caller_method, string @called_method, string message) public void AssertApiCallsMethod (string caller_namespace, string caller_type, string caller_method, string @called_method, string message)
@ -252,7 +278,7 @@ namespace Xamarin.Tests
void LoadAssembly () void LoadAssembly ()
{ {
if (assembly == null) if (assembly == null)
assembly = AssemblyDefinition.ReadAssembly (Path.Combine (TmpDirectory, Path.GetFileNameWithoutExtension (ApiDefinitions [0]).Replace ('-', '_') + ".dll")); assembly = AssemblyDefinition.ReadAssembly (Out ?? (Path.Combine (TmpDirectory, Path.GetFileNameWithoutExtension (ApiDefinitions [0]).Replace ('-', '_') + ".dll")));
} }
void EnsureTempDir () void EnsureTempDir ()
@ -270,6 +296,7 @@ namespace Xamarin.Tests
ApiDefinitions.Add (api); ApiDefinitions.Add (api);
} }
WorkingDirectory = TmpDirectory; WorkingDirectory = TmpDirectory;
Out = Path.Combine (WorkingDirectory, "api0.dll");
} }
public static string [] GetDefaultDefines (Profile profile) public static string [] GetDefaultDefines (Profile profile)
@ -288,4 +315,92 @@ namespace Xamarin.Tests
} }
} }
} }
// This class will replace stdout/stderr with its own thread-static storage for stdout/stderr.
// This means we're capturing stdout/stderr per thread.
class ThreadStaticTextWriter : TextWriter
{
[ThreadStatic]
static TextWriter current_writer;
static ThreadStaticTextWriter instance = new ThreadStaticTextWriter ();
static object lock_obj = new object ();
static int counter;
static TextWriter original_stdout;
static TextWriter original_stderr;
public static void ReplaceConsole (StringBuilder sb)
{
lock (lock_obj) {
if (counter == 0) {
original_stdout = Console.Out;
original_stderr = Console.Error;
Console.SetOut (instance);
Console.SetError (instance);
}
counter++;
current_writer = new StringWriter (sb);
}
}
public static void RestoreConsole ()
{
lock (lock_obj) {
current_writer.Dispose ();
current_writer = null;
counter--;
if (counter == 0) {
Console.SetOut (original_stdout);
Console.SetError (original_stderr);
original_stdout = null;
original_stderr = null;
}
}
}
ThreadStaticTextWriter ()
{
}
public TextWriter CurrentWriter {
get {
if (current_writer == null)
return original_stdout;
return current_writer;
}
}
public override Encoding Encoding => Encoding.UTF8;
public override void WriteLine ()
{
lock (lock_obj)
CurrentWriter.WriteLine ();
}
public override void Write (char value)
{
lock (lock_obj)
CurrentWriter.Write (value);
}
public override void Write (string value)
{
lock (lock_obj)
CurrentWriter.Write (value);
}
public override void Write (char [] buffer)
{
lock (lock_obj)
CurrentWriter.Write (buffer);
}
public override void WriteLine (string value)
{
lock (lock_obj)
CurrentWriter.WriteLine (value);
}
}
} }

Просмотреть файл

@ -73,5 +73,11 @@
<ItemGroup> <ItemGroup>
<Folder Include="tests\" /> <Folder Include="tests\" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\generator.csproj">
<Project>{D2EE02C0-9BFD-477D-AC92-4DE2D8490790}</Project>
<Name>generator</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
</Project> </Project>

Просмотреть файл

@ -167,19 +167,20 @@ all-local:: $(BUNDLE_ZIP) $(APIDIFF_DIR)/api-diff.html
# Rules to re-create the reference infos from the curretn stable 'bundle.zip. assemblies # Rules to re-create the reference infos from the curretn stable 'bundle.zip. assemblies
# split the URL in words based on the path separator, and then chose the 6th word (the hash) in the bundle zip filename # split the URL in words based on the path separator, and then chose the 6th word (the hash) in the bundle zip filename
BUNDLE_ZIP=bundle-$(word 6,$(subst /, ,$(APIDIFF_REFERENCES))).zip BUNDLE_ZIP=$(APIDIFF_DIR)/bundle-$(word 6,$(subst /, ,$(APIDIFF_REFERENCES))).zip
$(BUNDLE_ZIP): $(BUNDLE_ZIP):
# download to a temporary filename so interrupted downloads won't prevent re-downloads. # download to a temporary filename so interrupted downloads won't prevent re-downloads.
$(Q_GEN) curl -L $(APIDIFF_REFERENCES) > $@.tmp $(Q_GEN) curl -L $(APIDIFF_REFERENCES) > $@.tmp
$(Q) mv $@.tmp $@ $(Q) mv $@.tmp $@
.unzip.stamp: $(BUNDLE_ZIP) UNZIP_STAMP=$(APIDIFF_DIR)/.unzip.stamp
$(UNZIP_STAMP): $(BUNDLE_ZIP)
$(Q) rm -Rf temp $(Q) rm -Rf temp
$(Q_GEN) unzip -d temp $(BUNDLE_ZIP) $(Q_GEN) unzip -d temp $(BUNDLE_ZIP)
$(Q) touch $@ $(Q) touch $@
# the semi-colon at the end means an empty recipe, and is required for make to consider pattern rules # the semi-colon at the end means an empty recipe, and is required for make to consider pattern rules
temp/%.dll: .unzip.stamp ; temp/%.dll: $(UNZIP_STAMP) ;
IOS_REFS = $(foreach file,$(IOS_ASSEMBLIES),$(APIDIFF_DIR)/updated-references/xi/$(file).xml) IOS_REFS = $(foreach file,$(IOS_ASSEMBLIES),$(APIDIFF_DIR)/updated-references/xi/$(file).xml)
MAC_REFS = $(foreach file,$(MAC_ASSEMBLIES),$(APIDIFF_DIR)/updated-references/xm/$(file).xml) MAC_REFS = $(foreach file,$(MAC_ASSEMBLIES),$(APIDIFF_DIR)/updated-references/xm/$(file).xml)
@ -221,7 +222,7 @@ verify-reference-assemblies-mac: $(APIDIFF_DIR)/temp/native-32/Xamarin.Mac.xml $
clean-local:: clean-local::
rm -rf temp references diff *.exe* api-diff.html rm -rf temp references diff *.exe* api-diff.html
rm -rf *.dll* bundle-*.zip .unzip.stamp rm -rf *.dll* bundle-*.zip $(UNZIP_STAMP)
rm -rf ios-*.md tvos-*.md watchos-*.md macos-*.md rm -rf ios-*.md tvos-*.md watchos-*.md macos-*.md
DIRS += $(APIDIFF_DIR)/temp $(APIDIFF_DIR)/diff DIRS += $(APIDIFF_DIR)/temp $(APIDIFF_DIR)/diff
@ -291,7 +292,7 @@ ifdef INCLUDE_TVOS
@echo "@MonkeyWrench: AddFile: $(CURDIR)/diff/ios-to-tvos.html" @echo "@MonkeyWrench: AddFile: $(CURDIR)/diff/ios-to-tvos.html"
endif endif
endif endif
$(Q) $(MAKE) .unzip.stamp $(Q) $(MAKE) $(UNZIP_STAMP)
$(Q) $(MAKE) all -j8 $(Q) $(MAKE) all -j8
$(Q) $(MAKE) -j8 ios-markdown tvos-markdown watchos-markdown macos-markdown $(Q) $(MAKE) -j8 ios-markdown tvos-markdown watchos-markdown macos-markdown
$(Q) $(CP) api-diff.html index.html $(Q) $(CP) api-diff.html index.html