diff --git a/lib/Uno.Net.Sockets/Dns.uno b/lib/Uno.Net.Sockets/Dns.uno index 3bc578816..682208bb8 100644 --- a/lib/Uno.Net.Sockets/Dns.uno +++ b/lib/Uno.Net.Sockets/Dns.uno @@ -12,7 +12,6 @@ namespace Uno.Net [extern(UNIX) Require("Source.Include", "netinet/in.h")] [extern(MSVC) Require("Source.Include", "ws2tcpip.h")] [Require("Source.Include", "vector")] - [ForeignInclude(Language.Java, "java.util.*", "java.net.*")] public class Dns { extern(APPLE || LINUX) static IPAddress[] GetLocalAddresses() @@ -47,6 +46,7 @@ namespace Uno.Net @} [Foreign(Language.Java)] + [ForeignInclude(Language.Java, "java.util.*", "java.net.*")] extern(ANDROID) static bool JavaGetLocalAddresses(List addresses) @{ try diff --git a/lib/UnoCore/src/Uno/Compiler/ExportTargetInterop/Foreign/ForeignAnnotationAttribute.uno b/lib/UnoCore/src/Uno/Compiler/ExportTargetInterop/Foreign/ForeignAnnotationAttribute.uno index 9ebd0c560..b53422461 100644 --- a/lib/UnoCore/src/Uno/Compiler/ExportTargetInterop/Foreign/ForeignAnnotationAttribute.uno +++ b/lib/UnoCore/src/Uno/Compiler/ExportTargetInterop/Foreign/ForeignAnnotationAttribute.uno @@ -6,69 +6,9 @@ namespace Uno.Compiler.ExportTargetInterop public readonly Language Language; public readonly string[] Annotations; - public ForeignAnnotationAttribute(Language language, string[] annotations) + public ForeignAnnotationAttribute(Language language, params string[] annotations) { Language = language; } - - public ForeignAnnotationAttribute(Language language, string annotation0) - : this(language, new string[] { annotation0 }) {} - - public ForeignAnnotationAttribute(Language language, string annotation0, string annotation1) - : this(language, new string[] { annotation0, annotation1 }) {} - - public ForeignAnnotationAttribute(Language language, string annotation0, string annotation1, string annotation2) - : this(language, new string[] { annotation0, annotation1 , annotation2 }) {} - - public ForeignAnnotationAttribute(Language language, string annotation0, string annotation1, string annotation2, string annotation3) - : this(language, new string[] { annotation0, annotation1, annotation2, annotation3}) {} - - public ForeignAnnotationAttribute(Language language, string annotation0, string annotation1, string annotation2, string annotation3, string annotation4) - : this(language, new string[] { annotation0, annotation1, annotation2, annotation3, annotation4}) {} - - public ForeignAnnotationAttribute(Language language, string annotation0, string annotation1, string annotation2, string annotation3, string annotation4, string annotation5) - : this(language, new string[] { annotation0, annotation1, annotation2, annotation3, annotation4, annotation5}) {} - - public ForeignAnnotationAttribute(Language language, string annotation0, string annotation1, string annotation2, string annotation3, string annotation4, string annotation5, string annotation6) - : this(language, new string[] { annotation0, annotation1, annotation2, annotation3, annotation4, annotation5, annotation6}) {} - - public ForeignAnnotationAttribute(Language language, string annotation0, string annotation1, string annotation2, string annotation3, string annotation4, string annotation5, string annotation6, string annotation7) - : this(language, new string[] { annotation0, annotation1, annotation2, annotation3, annotation4, annotation5, annotation6, annotation7}) {} - - public ForeignAnnotationAttribute(Language language, string annotation0, string annotation1, string annotation2, string annotation3, string annotation4, string annotation5, string annotation6, string annotation7, string annotation8) - : this(language, new string[] { annotation0, annotation1, annotation2, annotation3, annotation4, annotation5, annotation6, annotation7, annotation8}) {} - - public ForeignAnnotationAttribute(Language language, string annotation0, string annotation1, string annotation2, string annotation3, string annotation4, string annotation5, string annotation6, string annotation7, string annotation8, string annotation9) - : this(language, new string[] { annotation0, annotation1, annotation2, annotation3, annotation4, annotation5, annotation6, annotation7, annotation8, annotation9}) {} - - public ForeignAnnotationAttribute(Language language, string annotation0, string annotation1, string annotation2, string annotation3, string annotation4, string annotation5, string annotation6, string annotation7, string annotation8, string annotation9, string annotation10) - : this(language, new string[] { annotation0, annotation1, annotation2, annotation3, annotation4, annotation5, annotation6, annotation7, annotation8, annotation9, annotation10}) {} - - public ForeignAnnotationAttribute(Language language, string annotation0, string annotation1, string annotation2, string annotation3, string annotation4, string annotation5, string annotation6, string annotation7, string annotation8, string annotation9, string annotation10, string annotation11) - : this(language, new string[] { annotation0, annotation1, annotation2, annotation3, annotation4, annotation5, annotation6, annotation7, annotation8, annotation9, annotation10, annotation11}) {} - - public ForeignAnnotationAttribute(Language language, string annotation0, string annotation1, string annotation2, string annotation3, string annotation4, string annotation5, string annotation6, string annotation7, string annotation8, string annotation9, string annotation10, string annotation11, string annotation12) - : this(language, new string[] { annotation0, annotation1, annotation2, annotation3, annotation4, annotation5, annotation6, annotation7, annotation8, annotation9, annotation10, annotation11, annotation12}) {} - - public ForeignAnnotationAttribute(Language language, string annotation0, string annotation1, string annotation2, string annotation3, string annotation4, string annotation5, string annotation6, string annotation7, string annotation8, string annotation9, string annotation10, string annotation11, string annotation12, string annotation13) - : this(language, new string[] { annotation0, annotation1, annotation2, annotation3, annotation4, annotation5, annotation6, annotation7, annotation8, annotation9, annotation10, annotation11, annotation12, annotation13}) {} - - public ForeignAnnotationAttribute(Language language, string annotation0, string annotation1, string annotation2, string annotation3, string annotation4, string annotation5, string annotation6, string annotation7, string annotation8, string annotation9, string annotation10, string annotation11, string annotation12, string annotation13, string annotation14) - : this(language, new string[] { annotation0, annotation1, annotation2, annotation3, annotation4, annotation5, annotation6, annotation7, annotation8, annotation9, annotation10, annotation11, annotation12, annotation13, annotation14}) {} - - public ForeignAnnotationAttribute(Language language, string annotation0, string annotation1, string annotation2, string annotation3, string annotation4, string annotation5, string annotation6, string annotation7, string annotation8, string annotation9, string annotation10, string annotation11, string annotation12, string annotation13, string annotation14, string annotation15) - : this(language, new string[] { annotation0, annotation1, annotation2, annotation3, annotation4, annotation5, annotation6, annotation7, annotation8, annotation9, annotation10, annotation11, annotation12, annotation13, annotation14, annotation15}) {} - - public ForeignAnnotationAttribute(Language language, string annotation0, string annotation1, string annotation2, string annotation3, string annotation4, string annotation5, string annotation6, string annotation7, string annotation8, string annotation9, string annotation10, string annotation11, string annotation12, string annotation13, string annotation14, string annotation15, string annotation16) - : this(language, new string[] { annotation0, annotation1, annotation2, annotation3, annotation4, annotation5, annotation6, annotation7, annotation8, annotation9, annotation10, annotation11, annotation12, annotation13, annotation14, annotation15, annotation16}) {} - - public ForeignAnnotationAttribute(Language language, string annotation0, string annotation1, string annotation2, string annotation3, string annotation4, string annotation5, string annotation6, string annotation7, string annotation8, string annotation9, string annotation10, string annotation11, string annotation12, string annotation13, string annotation14, string annotation15, string annotation16, string annotation17) - : this(language, new string[] { annotation0, annotation1, annotation2, annotation3, annotation4, annotation5, annotation6, annotation7, annotation8, annotation9, annotation10, annotation11, annotation12, annotation13, annotation14, annotation15, annotation16, annotation17}) {} - - public ForeignAnnotationAttribute(Language language, string annotation0, string annotation1, string annotation2, string annotation3, string annotation4, string annotation5, string annotation6, string annotation7, string annotation8, string annotation9, string annotation10, string annotation11, string annotation12, string annotation13, string annotation14, string annotation15, string annotation16, string annotation17, string annotation18) - : this(language, new string[] { annotation0, annotation1, annotation2, annotation3, annotation4, annotation5, annotation6, annotation7, annotation8, annotation9, annotation10, annotation11, annotation12, annotation13, annotation14, annotation15, annotation16, annotation17, annotation18}) {} - - public ForeignAnnotationAttribute(Language language, string annotation0, string annotation1, string annotation2, string annotation3, string annotation4, string annotation5, string annotation6, string annotation7, string annotation8, string annotation9, string annotation10, string annotation11, string annotation12, string annotation13, string annotation14, string annotation15, string annotation16, string annotation17, string annotation18, string annotation19) - : this(language, new string[] { annotation0, annotation1, annotation2, annotation3, annotation4, annotation5, annotation6, annotation7, annotation8, annotation9, annotation10, annotation11, annotation12, annotation13, annotation14, annotation15, annotation16, annotation17, annotation18, annotation19}) {} } } diff --git a/lib/UnoCore/src/Uno/Compiler/ExportTargetInterop/Foreign/ForeignDataView.uno b/lib/UnoCore/src/Uno/Compiler/ExportTargetInterop/Foreign/ForeignDataView.uno index b64b2590e..f89211bfa 100644 --- a/lib/UnoCore/src/Uno/Compiler/ExportTargetInterop/Foreign/ForeignDataView.uno +++ b/lib/UnoCore/src/Uno/Compiler/ExportTargetInterop/Foreign/ForeignDataView.uno @@ -6,7 +6,6 @@ using Android.Base.Primitives; namespace Uno.Compiler.ExportTargetInterop { [ForeignTypeName("::NSData*")] - [ForeignInclude(Language.ObjC, "Foundation/Foundation.h")] public extern(FOREIGN_OBJC_SUPPORTED) class ForeignDataView : ObjC.Object { ForeignDataView() { } @@ -36,6 +35,7 @@ namespace Uno.Compiler.ExportTargetInterop } [Foreign(Language.ObjC)] + [ForeignInclude(Language.ObjC, "Foundation/Foundation.h")] static ObjC.Object CreateNSDataFromByteArray(IntPtr rawUnoArray) @{ auto unoArray = (\@{byte[]})rawUnoArray; diff --git a/lib/UnoCore/src/Uno/Compiler/ExportTargetInterop/Foreign/ForeignIncludeAttribute.uno b/lib/UnoCore/src/Uno/Compiler/ExportTargetInterop/Foreign/ForeignIncludeAttribute.uno index dd8061dd1..edcbf5235 100644 --- a/lib/UnoCore/src/Uno/Compiler/ExportTargetInterop/Foreign/ForeignIncludeAttribute.uno +++ b/lib/UnoCore/src/Uno/Compiler/ExportTargetInterop/Foreign/ForeignIncludeAttribute.uno @@ -1,77 +1,15 @@ namespace Uno.Compiler.ExportTargetInterop { - [AttributeUsage(AttributeTargets.Class)] + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Constructor)] public sealed class ForeignIncludeAttribute : Attribute { public readonly Language Language; public readonly string[] Includes; - // look..I know. I'm sorry, but at the time attributes didnt like param args - public ForeignIncludeAttribute(Language language, string[] includes) + public ForeignIncludeAttribute(Language language, params string[] includes) { Language = language; Includes = includes; } - - public ForeignIncludeAttribute(Language language, string include0) - : this(language, new string[] { include0 }) {} - - public ForeignIncludeAttribute(Language language, string include0, string include1) - : this(language, new string[] { include0, include1 }) {} - - public ForeignIncludeAttribute(Language language, string include0, string include1, string include2) - : this(language, new string[] { include0, include1 , include2 }) {} - - public ForeignIncludeAttribute(Language language, string include0, string include1, string include2, string include3) - : this(language, new string[] { include0, include1, include2, include3}) {} - - public ForeignIncludeAttribute(Language language, string include0, string include1, string include2, string include3, string include4) - : this(language, new string[] { include0, include1, include2, include3, include4}) {} - - public ForeignIncludeAttribute(Language language, string include0, string include1, string include2, string include3, string include4, string include5) - : this(language, new string[] { include0, include1, include2, include3, include4, include5}) {} - - public ForeignIncludeAttribute(Language language, string include0, string include1, string include2, string include3, string include4, string include5, string include6) - : this(language, new string[] { include0, include1, include2, include3, include4, include5, include6}) {} - - public ForeignIncludeAttribute(Language language, string include0, string include1, string include2, string include3, string include4, string include5, string include6, string include7) - : this(language, new string[] { include0, include1, include2, include3, include4, include5, include6, include7}) {} - - public ForeignIncludeAttribute(Language language, string include0, string include1, string include2, string include3, string include4, string include5, string include6, string include7, string include8) - : this(language, new string[] { include0, include1, include2, include3, include4, include5, include6, include7, include8}) {} - - public ForeignIncludeAttribute(Language language, string include0, string include1, string include2, string include3, string include4, string include5, string include6, string include7, string include8, string include9) - : this(language, new string[] { include0, include1, include2, include3, include4, include5, include6, include7, include8, include9}) {} - - public ForeignIncludeAttribute(Language language, string include0, string include1, string include2, string include3, string include4, string include5, string include6, string include7, string include8, string include9, string include10) - : this(language, new string[] { include0, include1, include2, include3, include4, include5, include6, include7, include8, include9, include10}) {} - - public ForeignIncludeAttribute(Language language, string include0, string include1, string include2, string include3, string include4, string include5, string include6, string include7, string include8, string include9, string include10, string include11) - : this(language, new string[] { include0, include1, include2, include3, include4, include5, include6, include7, include8, include9, include10, include11}) {} - - public ForeignIncludeAttribute(Language language, string include0, string include1, string include2, string include3, string include4, string include5, string include6, string include7, string include8, string include9, string include10, string include11, string include12) - : this(language, new string[] { include0, include1, include2, include3, include4, include5, include6, include7, include8, include9, include10, include11, include12}) {} - - public ForeignIncludeAttribute(Language language, string include0, string include1, string include2, string include3, string include4, string include5, string include6, string include7, string include8, string include9, string include10, string include11, string include12, string include13) - : this(language, new string[] { include0, include1, include2, include3, include4, include5, include6, include7, include8, include9, include10, include11, include12, include13}) {} - - public ForeignIncludeAttribute(Language language, string include0, string include1, string include2, string include3, string include4, string include5, string include6, string include7, string include8, string include9, string include10, string include11, string include12, string include13, string include14) - : this(language, new string[] { include0, include1, include2, include3, include4, include5, include6, include7, include8, include9, include10, include11, include12, include13, include14}) {} - - public ForeignIncludeAttribute(Language language, string include0, string include1, string include2, string include3, string include4, string include5, string include6, string include7, string include8, string include9, string include10, string include11, string include12, string include13, string include14, string include15) - : this(language, new string[] { include0, include1, include2, include3, include4, include5, include6, include7, include8, include9, include10, include11, include12, include13, include14, include15}) {} - - public ForeignIncludeAttribute(Language language, string include0, string include1, string include2, string include3, string include4, string include5, string include6, string include7, string include8, string include9, string include10, string include11, string include12, string include13, string include14, string include15, string include16) - : this(language, new string[] { include0, include1, include2, include3, include4, include5, include6, include7, include8, include9, include10, include11, include12, include13, include14, include15, include16}) {} - - public ForeignIncludeAttribute(Language language, string include0, string include1, string include2, string include3, string include4, string include5, string include6, string include7, string include8, string include9, string include10, string include11, string include12, string include13, string include14, string include15, string include16, string include17) - : this(language, new string[] { include0, include1, include2, include3, include4, include5, include6, include7, include8, include9, include10, include11, include12, include13, include14, include15, include16, include17}) {} - - public ForeignIncludeAttribute(Language language, string include0, string include1, string include2, string include3, string include4, string include5, string include6, string include7, string include8, string include9, string include10, string include11, string include12, string include13, string include14, string include15, string include16, string include17, string include18) - : this(language, new string[] { include0, include1, include2, include3, include4, include5, include6, include7, include8, include9, include10, include11, include12, include13, include14, include15, include16, include17, include18}) {} - - public ForeignIncludeAttribute(Language language, string include0, string include1, string include2, string include3, string include4, string include5, string include6, string include7, string include8, string include9, string include10, string include11, string include12, string include13, string include14, string include15, string include16, string include17, string include18, string include19) - : this(language, new string[] { include0, include1, include2, include3, include4, include5, include6, include7, include8, include9, include10, include11, include12, include13, include14, include15, include16, include17, include18, include19}) {} - } } diff --git a/src/compiler/api/Domain/IL/Expressions/Expression.cs b/src/compiler/api/Domain/IL/Expressions/Expression.cs index ae8d3e5d5..a20ea553a 100644 --- a/src/compiler/api/Domain/IL/Expressions/Expression.cs +++ b/src/compiler/api/Domain/IL/Expressions/Expression.cs @@ -16,7 +16,12 @@ public abstract class Expression : Statement public Expression Address => !ReturnType.IsReferenceType ? this as AddressOf ?? new AddressOf(this) : ActualValue; public virtual Expression ActualValue => this; public virtual object ConstantValue => null; - public string ConstantString => ConstantValue as string ?? ConstantValue?.ToString(); + public string ConstantString => ConstantValue as string ?? ( + ConstantValue is object[] + ? ToString() // Use disassembler for arrays + : ConstantValue?.ToString() + ); + public override StatementType StatementType => StatementType.Expression; protected Expression(Source src) diff --git a/src/compiler/api/Domain/IL/Expressions/NewArray.cs b/src/compiler/api/Domain/IL/Expressions/NewArray.cs index 251c2afb3..12564a1a1 100644 --- a/src/compiler/api/Domain/IL/Expressions/NewArray.cs +++ b/src/compiler/api/Domain/IL/Expressions/NewArray.cs @@ -13,7 +13,19 @@ public sealed class NewArray : Expression public override DataType ReturnType => ArrayType; - private NewArray(Source src, RefArrayType arrayType, Expression size, Expression[] initializers) + public override object ConstantValue => GetInitalizerConstants(); + + object[] GetInitalizerConstants() + { + var result = new object[Initializers.Length]; + + for (int i = 0; i < result.Length; i++) + result[i] = Initializers[i].ConstantValue; + + return result; + } + + NewArray(Source src, RefArrayType arrayType, Expression size, Expression[] initializers) : base(src) { ArrayType = arrayType; diff --git a/src/compiler/api/Domain/IL/Expressions/NewObject.cs b/src/compiler/api/Domain/IL/Expressions/NewObject.cs index c9d3b2323..61babb81a 100644 --- a/src/compiler/api/Domain/IL/Expressions/NewObject.cs +++ b/src/compiler/api/Domain/IL/Expressions/NewObject.cs @@ -17,18 +17,6 @@ public NewObject(Source src, Constructor ctor, params Expression[] args) Arguments = args; } - public object[] GetArgumentValues() - { - var result = new object[Arguments.Length]; - - for (int i = 0; i < result.Length; i++) - result[i] = Arguments[i] is Constant - ? (Arguments[i] as Constant).Value - : null; - - return result; - } - public override ExpressionType ExpressionType => ExpressionType.NewObject; public override void Disassemble(StringBuilder sb, ExpressionUsage u) diff --git a/src/compiler/backend/unodoc/Builders/Syntax/SyntaxGenerator.cs b/src/compiler/backend/unodoc/Builders/Syntax/SyntaxGenerator.cs index faf92c3d6..efdb46b9e 100644 --- a/src/compiler/backend/unodoc/Builders/Syntax/SyntaxGenerator.cs +++ b/src/compiler/backend/unodoc/Builders/Syntax/SyntaxGenerator.cs @@ -45,27 +45,20 @@ protected string BuildAttributes(NewObject[] attributes, Namescope context) if (attribute.Arguments.Length > 0) { - sb.Append("("); + sb.Append('('); for (var i = 0; i < attribute.Arguments.Length; i++) { - var arg = (Constant)attribute.Arguments[i]; + var arg = attribute.Arguments[i].ConstantValue; var param = attribute.Constructor.Parameters[i]; if (i > 0) sb.Append(", "); sb.Append(param.Name); sb.Append(" = "); - if (arg.Value is string) - { - sb.Append("\"" + arg.Value + "\""); - } - else - { - sb.Append(arg.Value); - } + BuildParameterValue(arg, sb); } - sb.Append(")"); + sb.Append(')'); } sb.AppendLine("]"); @@ -77,6 +70,32 @@ protected string BuildAttributes(NewObject[] attributes, Namescope context) : null; } + static void BuildParameterValue(object arg, StringBuilder sb) + { + if (arg is object[] array) + { + sb.Append("new[] {"); + + for (int i = 0; i < array.Length; i++) + { + if (i > 0) + sb.Append(", "); + + BuildParameterValue(array[i], sb); + } + + sb.Append('}'); + } + else if (arg is string) + { + sb.Append("\"" + arg + "\""); + } + else + { + sb.Append(arg); + } + } + protected string BuildModifiers(List modifiers) { return modifiers.Any() diff --git a/src/compiler/core/IL/Validation/ILVerifier.cs b/src/compiler/core/IL/Validation/ILVerifier.cs index bbbfdfeb4..491708dd6 100644 --- a/src/compiler/core/IL/Validation/ILVerifier.cs +++ b/src/compiler/core/IL/Validation/ILVerifier.cs @@ -446,14 +446,20 @@ void VerifyAttributes(SourceObject owner, NewObject[] attributes) if (!attr.ReturnType.IsSubclassOf(Essentials.Attribute)) Log.Error(attr.Source, ErrorCode.E0000, attr.ReturnType.AttributeString + " cannot be used as an attribute because it does not inherit " + Essentials.Attribute.Quote()); - foreach (var arg in attr.Arguments) - if (arg.ExpressionType != ExpressionType.Constant) - Log.Error(arg.Source, ErrorCode.E0000, "Attribute argument must be constant"); - + VeryfyArgumentsAreConstant(attr.Arguments); VerifyAttributeUsage(attr.Source, owner, attr.ReturnType); } } + void VeryfyArgumentsAreConstant(Expression[] args) + { + foreach (var arg in args) + if (arg.ExpressionType == ExpressionType.NewArray) + VeryfyArgumentsAreConstant(((NewArray)arg).Initializers); + else if (arg.ExpressionType != ExpressionType.Constant) + Log.Error(arg.Source, ErrorCode.E0000, "Attribute argument must be constant or an array of constants"); + } + void VerifyAttributeUsage(Source src, SourceObject owner, DataType attribute) { var targetsObj = attribute.TryGetAttribute(Essentials.AttributeUsageAttribute); diff --git a/src/compiler/core/Syntax/Compilers/Extensions.cs b/src/compiler/core/Syntax/Compilers/Extensions.cs index c1e54db78..cdadf52d0 100644 --- a/src/compiler/core/Syntax/Compilers/Extensions.cs +++ b/src/compiler/core/Syntax/Compilers/Extensions.cs @@ -84,9 +84,8 @@ static AstExpression GetSuffixedTypeExpression(AstExpression type, string suffix public static NewObject TryCompileSuffixedObject(this Compiler compiler, Namescope scope, AstExpression type, string suffix, IReadOnlyList args) { var sym = CompileExpression(compiler, new AstNew(type.Source, GetSuffixedTypeExpression(type, suffix), args), scope); - var result = sym as NewObject; - if (result == null) + if (sym is not NewObject result) { if (!sym.IsInvalid) compiler.Log.Error(type.Source, ErrorCode.I0045, "Compiled expression was not a 'NewObject' node"); @@ -94,23 +93,32 @@ public static NewObject TryCompileSuffixedObject(this Compiler compiler, Namesco return null; } - for (int i = 0; i < result.Arguments.Length; i++) + compiler.MakeSureArgumentsAreConstantOrArray(result.Arguments); + return result; + } + + static void MakeSureArgumentsAreConstantOrArray(this Compiler compiler, Expression[] args) + { + for (int i = 0; i < args.Length; i++) { - if (result.Arguments[i].ExpressionType != ExpressionType.Constant) + if (args[i].ExpressionType == ExpressionType.NewArray) { - var c = compiler.ConstantFolder.TryMakeConstant(result.Arguments[i]); + var newArray = (NewArray)args[i]; + compiler.MakeSureArgumentsAreConstantOrArray(newArray.Initializers); + } + else if (args[i].ExpressionType != ExpressionType.Constant) + { + var c = compiler.ConstantFolder.TryMakeConstant(args[i]); if (c == null) { - compiler.Log.Error(result.Arguments[i].Source, ErrorCode.E0000, "Argument must be a constant value"); + compiler.Log.Error(args[i].Source, ErrorCode.E0000, "Argument must be a constant value or an array of constant values"); continue; } - result.Arguments[i] = c; + args[i] = c; } } - - return result; } public static NewObject[] CompileAttributes(this Compiler compiler, Namescope scope, IReadOnlyList attributes) diff --git a/src/compiler/foreign/ForeignHelpers.cs b/src/compiler/foreign/ForeignHelpers.cs index 14faadf65..859226ff5 100644 --- a/src/compiler/foreign/ForeignHelpers.cs +++ b/src/compiler/foreign/ForeignHelpers.cs @@ -23,7 +23,6 @@ class ForeignHelpers Function _context; Source _source; - public ForeignHelpers(IEnvironment environment, IEssentials essentials, CppBackend backend, IBuildData data) { Environment = environment; @@ -52,9 +51,9 @@ public string GetForeignAttribute(Function f) return null; } - public List GetForeignIncludes(DataType dt, string language, IEnvironment env) + public List GetForeignIncludes(DataType dt, string language) { - var result = new List(); + var result = new HashSet(); if (dt.HasAttribute(Essentials.ForeignIncludeAttribute)) { @@ -63,15 +62,33 @@ public List GetForeignIncludes(DataType dt, string language, IEnvironmen if (attr.ReferencedType == Essentials.ForeignIncludeAttribute && Essentials.Language.Literals[(int)attr.Arguments[0].ConstantValue].Name == language) { - foreach (var arg in attr.Arguments.Skip(1)) + foreach (var arg in (object[])attr.Arguments[1].ConstantValue) { - result.Add(env.Expand(dt.Source, (string)arg.ConstantValue)); + result.Add(Environment.Expand(dt.Source, (string)arg)); } } } } - return result; + foreach (var f in dt.EnumerateFunctions()) + { + if (f.HasAttribute(Essentials.ForeignIncludeAttribute)) + { + foreach (var attr in f.Attributes) + { + if (attr.ReferencedType == Essentials.ForeignIncludeAttribute && + Essentials.Language.Literals[(int)attr.Arguments[0].ConstantValue].Name == language) + { + foreach (var arg in (object[])attr.Arguments[1].ConstantValue) + { + result.Add(Environment.Expand(f.Source, (string)arg)); + } + } + } + } + } + + return result.ToList(); } public List GetForeignAnnotations(Function f, string language) @@ -85,9 +102,9 @@ public List GetForeignAnnotations(Function f, string language) if (attr.ReferencedType == Essentials.ForeignAnnotationAttribute && Essentials.Language.Literals[(int)attr.Arguments[0].ConstantValue].Name == language) { - foreach (var arg in attr.Arguments.Skip(1)) + foreach (var arg in (object[])attr.Arguments[1].ConstantValue) { - result.Add((string)arg.ConstantValue); + result.Add((string)arg); } } } @@ -270,7 +287,6 @@ public bool IsPrimitive(DataType dt) dt == Essentials.UShort; } - public Expression StringExpr(DataType dt, string e) { return new StringExpression(_source, dt, e); diff --git a/src/compiler/foreign/ForeignObjCPass.cs b/src/compiler/foreign/ForeignObjCPass.cs index cf8bddf2e..49fb1b97f 100644 --- a/src/compiler/foreign/ForeignObjCPass.cs +++ b/src/compiler/foreign/ForeignObjCPass.cs @@ -505,7 +505,7 @@ void HandleForeignImports(DataType dt) if (!visitedTypes.Contains(dt)) { visitedTypes.Add(dt); - var includes = Helpers.GetForeignIncludes(dt, "ObjC", Environment); + var includes = Helpers.GetForeignIncludes(dt, "ObjC"); if (includes.Count > 0) Helpers.SourceInclude(includes, dt); } diff --git a/src/compiler/foreign/Java/JavaClass.cs b/src/compiler/foreign/Java/JavaClass.cs index 201934694..48dd8bb11 100644 --- a/src/compiler/foreign/Java/JavaClass.cs +++ b/src/compiler/foreign/Java/JavaClass.cs @@ -35,7 +35,7 @@ public JavaClass(DataType dt, ForeignHelpers helpers, Converters.Converter conve var split = FullName.LastIndexOf(".", StringComparison.Ordinal); _name = FullName.Substring(split + 1); _package = FullName.Substring(0, split); - _usings.AddRange(helpers.GetForeignIncludes(dt, "Java", env)); + _usings.AddRange(helpers.GetForeignIncludes(dt, "Java")); _nested = dt.IsNestedType; } diff --git a/tests/src/ForeignJavaTest/Args.uno b/tests/src/ForeignJavaTest/Args.uno index 9b9c8d109..a3729e5e9 100644 --- a/tests/src/ForeignJavaTest/Args.uno +++ b/tests/src/ForeignJavaTest/Args.uno @@ -8,7 +8,6 @@ public extern(android) class TestClass0 { } -[ForeignInclude(Language.Java, "java.lang.Runnable", "android.app.Activity")] public extern(android) class Args { [Test] @@ -63,6 +62,7 @@ public extern(android) class Args //------------------------------------------------------------ [Foreign(Language.Java)] + [ForeignInclude(Language.Java, "java.lang.Runnable")] public bool CallUnoWithRunable0() @{ java.lang.Runnable rrr = new Runnable() { diff --git a/tests/src/ForeignJavaTest/Arrays.uno b/tests/src/ForeignJavaTest/Arrays.uno index fa5430ac8..b4f611b19 100644 --- a/tests/src/ForeignJavaTest/Arrays.uno +++ b/tests/src/ForeignJavaTest/Arrays.uno @@ -4,7 +4,6 @@ using Uno.Graphics; using Uno.Collections; using Uno.Compiler.ExportTargetInterop; -[ForeignInclude(Language.Java, "java.lang.Runnable", "android.app.Activity")] public extern(android) class Arrays { //------------------------------------------------------------ diff --git a/tests/src/ForeignJavaTest/Fields.uno b/tests/src/ForeignJavaTest/Fields.uno index f5d8e6f3b..36c94e865 100644 --- a/tests/src/ForeignJavaTest/Fields.uno +++ b/tests/src/ForeignJavaTest/Fields.uno @@ -4,7 +4,6 @@ using Uno.Graphics; using Uno.Collections; using Uno.Compiler.ExportTargetInterop; -[ForeignInclude(Language.Java, "java.util.ArrayList")] public extern(android) class Fields { [Test] @@ -76,6 +75,7 @@ public extern(android) class Fields @} [Foreign(Language.Java)] + [ForeignInclude(Language.Java, "java.util.ArrayList")] public extern(android) bool Test7() @{ @{_staticJavaObj:Set(new ArrayList())}; diff --git a/tests/src/ForeignJavaTest/Macros.uno b/tests/src/ForeignJavaTest/Macros.uno index 7970eb38a..db2881740 100644 --- a/tests/src/ForeignJavaTest/Macros.uno +++ b/tests/src/ForeignJavaTest/Macros.uno @@ -4,7 +4,6 @@ using Uno.Graphics; using Uno.Collections; using Uno.Compiler.ExportTargetInterop; -[ForeignInclude(Language.Java, "java.lang.Runnable", "android.app.Activity")] public extern(android) class Macros { [Test] diff --git a/tests/src/ForeignJavaTest/Names.uno b/tests/src/ForeignJavaTest/Names.uno index 6a39741f2..1d97d15af 100644 --- a/tests/src/ForeignJavaTest/Names.uno +++ b/tests/src/ForeignJavaTest/Names.uno @@ -4,7 +4,6 @@ using Uno.Graphics; using Uno.Collections; using Uno.Compiler.ExportTargetInterop; -[ForeignInclude(Language.Java, "java.lang.Runnable", "android.app.Activity")] public extern(android) class Names { [Test] diff --git a/tests/src/ForeignObjCTest/FileInclude.uno b/tests/src/ForeignObjCTest/FileInclude.uno index 70f141dba..9886c8dc4 100644 --- a/tests/src/ForeignObjCTest/FileInclude.uno +++ b/tests/src/ForeignObjCTest/FileInclude.uno @@ -4,10 +4,10 @@ using Uno.Testing; namespace ForeignObjCTest { - [ForeignInclude(Language.ObjC, "FileInclude.h")] public extern(FOREIGN_OBJC_SUPPORTED) class FileInclude { [Foreign(Language.ObjC)] + [ForeignInclude(Language.ObjC, "FileInclude.h")] string StringFromFileInclude() @{ return string_from_file_include(); @} [Test] diff --git a/tests/src/SwiftFileIncludeTest/SwiftFileIncludeTest.uno b/tests/src/SwiftFileIncludeTest/SwiftFileIncludeTest.uno index 526d75161..e65cfaeb3 100644 --- a/tests/src/SwiftFileIncludeTest/SwiftFileIncludeTest.uno +++ b/tests/src/SwiftFileIncludeTest/SwiftFileIncludeTest.uno @@ -4,10 +4,10 @@ using Uno.Testing; namespace SwiftFileIncludeTest { - [ForeignInclude(Language.ObjC, "@(Project.Name)-Swift.h")] public extern(iOS) class SimpleFileInclude { [Foreign(Language.ObjC)] + [ForeignInclude(Language.ObjC, "@(Project.Name)-Swift.h")] string GetTheString() @{ HelloSwiftWorld* x = [[HelloSwiftWorld alloc] init];