diff --git a/Xamarin.Forms.Build.Tasks/BuildException.cs b/Xamarin.Forms.Build.Tasks/BuildException.cs
index 706fabd240c..ab52966752e 100644
--- a/Xamarin.Forms.Build.Tasks/BuildException.cs
+++ b/Xamarin.Forms.Build.Tasks/BuildException.cs
@@ -88,6 +88,7 @@ class BuildExceptionCode
public static BuildExceptionCode ResourceMissing = new BuildExceptionCode("XFC0124", nameof(ResourceMissing), "");
public static BuildExceptionCode ResourceDictDuplicateKey = new BuildExceptionCode("XFC0125", nameof(ResourceDictDuplicateKey), "");
public static BuildExceptionCode ResourceDictMissingKey = new BuildExceptionCode("XFC0126", nameof(ResourceDictMissingKey), "");
+ public static BuildExceptionCode XKeyNotLiteral = new BuildExceptionCode("XFC0127", nameof(XKeyNotLiteral), "");
public string Code { get; private set; }
public string ErrorMessageKey { get; private set; }
diff --git a/Xamarin.Forms.Build.Tasks/ErrorMessages.Designer.cs b/Xamarin.Forms.Build.Tasks/ErrorMessages.Designer.cs
index bbda8f5015b..e26a3aa9054 100644
--- a/Xamarin.Forms.Build.Tasks/ErrorMessages.Designer.cs
+++ b/Xamarin.Forms.Build.Tasks/ErrorMessages.Designer.cs
@@ -10,48 +10,35 @@
namespace Xamarin.Forms.Build.Tasks {
using System;
+ using System.Reflection;
- ///
- /// A strongly-typed resource class, for looking up localized strings, etc.
- ///
- // This class was auto-generated by the StronglyTypedResourceBuilder
- // class via a tool like ResGen or Visual Studio.
- // To add or remove a member, edit your .ResX file then rerun ResGen
- // with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class ErrorMessages {
- private static global::System.Resources.ResourceManager resourceMan;
+ private static System.Resources.ResourceManager resourceMan;
- private static global::System.Globalization.CultureInfo resourceCulture;
+ private static System.Globalization.CultureInfo resourceCulture;
- [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal ErrorMessages() {
}
- ///
- /// Returns the cached ResourceManager instance used by this class.
- ///
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Resources.ResourceManager ResourceManager {
+ [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static System.Resources.ResourceManager ResourceManager {
get {
- if (object.ReferenceEquals(resourceMan, null)) {
- global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Xamarin.Forms.Build.Tasks.ErrorMessages", typeof(ErrorMessages).Assembly);
+ if (object.Equals(null, resourceMan)) {
+ System.Resources.ResourceManager temp = new System.Resources.ResourceManager("Xamarin.Forms.Build.Tasks.ErrorMessages", typeof(ErrorMessages).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
- ///
- /// Overrides the current thread's CurrentUICulture property for all
- /// resource lookups using this strongly typed resource class.
- ///
- [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
- internal static global::System.Globalization.CultureInfo Culture {
+ [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
@@ -60,319 +47,220 @@ internal ErrorMessages() {
}
}
- ///
- /// Looks up a localized string similar to No Add() method defined on "{0}{1}"..
- ///
internal static string AdderMissing {
get {
return ResourceManager.GetString("AdderMissing", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Binding: Indexer did not contain arguments..
- ///
internal static string BindingIndexerEmpty {
get {
return ResourceManager.GetString("BindingIndexerEmpty", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Binding: Indexer did not contain closing bracket..
- ///
internal static string BindingIndexerNotClosed {
get {
return ResourceManager.GetString("BindingIndexerNotClosed", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Binding: "{0}" cannot be parsed as an index for a "{1}"..
- ///
internal static string BindingIndexerParse {
get {
return ResourceManager.GetString("BindingIndexerParse", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Binding: Unsupported indexer index type: "{0}"..
- ///
internal static string BindingIndexerTypeUnsupported {
get {
return ResourceManager.GetString("BindingIndexerTypeUnsupported", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Binding: Property "{0}" not found on "{1}"..
- ///
internal static string BindingPropertyNotFound {
get {
return ResourceManager.GetString("BindingPropertyNotFound", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Missing a "public static Get{0}" method or a public instance property getter for the attached property "{1}.{0}Property"..
- ///
internal static string BPMissingGetter {
get {
return ResourceManager.GetString("BPMissingGetter", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to The name of the BindableProperty {0} does not end with "Property".
- ///
internal static string BPName {
get {
return ResourceManager.GetString("BPName", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Missing default constructor for "{0}"..
- ///
internal static string ConstructorDefaultMissing {
get {
return ResourceManager.GetString("ConstructorDefaultMissing", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Missing constructor for "{0}" with matching x:Arguments..
- ///
internal static string ConstructorXArgsMissing {
get {
return ResourceManager.GetString("ConstructorXArgsMissing", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Cannot set the content of "{0}" as it doesn't have a [ContentProperty] attribute..
- ///
internal static string ContentPropertyAttributeMissing {
get {
return ResourceManager.GetString("ContentPropertyAttributeMissing", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Cannot convert value "{0}" to "{1}"..
- ///
internal static string Conversion {
get {
return ResourceManager.GetString("Conversion", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Enum value not found for "{0}"..
- ///
internal static string EnumValueMissing {
get {
return ResourceManager.GetString("EnumValueMissing", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Invalid Xaml "{0}"..
- ///
internal static string InvalidXaml {
get {
return ResourceManager.GetString("InvalidXaml", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Markup expression not closed..
- ///
internal static string MarkupNotClosed {
get {
return ResourceManager.GetString("MarkupNotClosed", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Error while parsing markup expression..
- ///
internal static string MarkupParsingFailed {
get {
return ResourceManager.GetString("MarkupParsingFailed", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to No property, BindableProperty, or event found for "{0}", or mismatching type between value and property..
- ///
internal static string MemberResolution {
get {
return ResourceManager.GetString("MemberResolution", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to No static method found for "{0}::{1} ({2})"..
- ///
internal static string MethodStaticMissing {
get {
return ResourceManager.GetString("MethodStaticMissing", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to EventHandler "{0}" with correct signature not found in type "{1}"..
- ///
internal static string MissingEventHandler {
get {
return ResourceManager.GetString("MissingEventHandler", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to An element with the name "{0}" already exists in this NameScope..
- ///
internal static string NamescopeDuplicate {
get {
return ResourceManager.GetString("NamescopeDuplicate", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Missing mandatory property "{0}" on "{1}"..
- ///
internal static string PropertyMissing {
get {
return ResourceManager.GetString("PropertyMissing", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Cannot resolve property "{0}" on type "{1} (property missing, or missing accessors)"..
- ///
internal static string PropertyResolution {
get {
return ResourceManager.GetString("PropertyResolution", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to "A resource with the key "{0}" is already present in the ResourceDictionary..
- ///
internal static string ResourceDictDuplicateKey {
get {
return ResourceManager.GetString("ResourceDictDuplicateKey", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Resources in ResourceDictionary require a x:Key attribute..
- ///
internal static string ResourceDictMissingKey {
get {
return ResourceManager.GetString("ResourceDictMissingKey", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Resource "{0}" not found..
- ///
internal static string ResourceMissing {
get {
return ResourceManager.GetString("ResourceMissing", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Multi-valued enums are not valid on sbyte enum types..
- ///
internal static string SByteEnums {
get {
return ResourceManager.GetString("SByteEnums", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to StyleSheet require either a Source or a content..
- ///
internal static string StyleSheetNoSourceOrContent {
get {
return ResourceManager.GetString("StyleSheetNoSourceOrContent", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Source property is not a string literal..
- ///
internal static string StyleSheetSourceNotALiteral {
get {
return ResourceManager.GetString("StyleSheetSourceNotALiteral", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to StyleSheet can not have both a Source and a content..
- ///
internal static string StyleSheetSourceOrContent {
get {
return ResourceManager.GetString("StyleSheetSourceOrContent", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Style property or Content is not a string literal..
- ///
internal static string StyleSheetStyleNotALiteral {
get {
return ResourceManager.GetString("StyleSheetStyleNotALiteral", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Cannot resolve type "{0}"..
- ///
internal static string TypeResolution {
get {
return ResourceManager.GetString("TypeResolution", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to x:DataType expects a string literal, an {{x:Type}} markup or {{x:Nul}l}..
- ///
internal static string XDataTypeSyntax {
get {
return ResourceManager.GetString("XDataTypeSyntax", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Undeclared xmlns prefix "{0}"..
- ///
internal static string XmlnsUndeclared {
get {
return ResourceManager.GetString("XmlnsUndeclared", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to x:Static: unable to find a public -- or accessible internal -- static field, static property, const or enum value named "{0}" in "{1}"..
- ///
internal static string XStaticResolution {
get {
return ResourceManager.GetString("XStaticResolution", resourceCulture);
}
}
- ///
- /// Looks up a localized string similar to Syntax for x:Static is "[Member=][prefix:]typeName.staticMemberName"..
- ///
internal static string XStaticSyntax {
get {
return ResourceManager.GetString("XStaticSyntax", resourceCulture);
}
}
+
+ internal static string XKeyNotLiteral {
+ get {
+ return ResourceManager.GetString("XKeyNotLiteral", resourceCulture);
+ }
+ }
}
}
diff --git a/Xamarin.Forms.Build.Tasks/ErrorMessages.resx b/Xamarin.Forms.Build.Tasks/ErrorMessages.resx
index 568464e4d9a..b127c2cb14f 100644
--- a/Xamarin.Forms.Build.Tasks/ErrorMessages.resx
+++ b/Xamarin.Forms.Build.Tasks/ErrorMessages.resx
@@ -244,5 +244,9 @@
Syntax for x:Static is "[Member=][prefix:]typeName.staticMemberName".
+
+
+ x:Key expects a string literal.
+
\ No newline at end of file
diff --git a/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs b/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs
index 78725effbf0..9a8883187f3 100644
--- a/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs
+++ b/Xamarin.Forms.Build.Tasks/SetPropertiesVisitor.cs
@@ -1429,7 +1429,8 @@ static bool CanAddToResourceDictionary(VariableDefinition parent, TypeReference
if (node.Properties.ContainsKey(XmlName.xKey))
{
- var key = (node.Properties[XmlName.xKey] as ValueNode).Value as string;
+ var valueNode = node.Properties[XmlName.xKey] as ValueNode ?? throw new BuildException(XKeyNotLiteral, lineInfo, null);
+ var key = (valueNode).Value as string;
if (!resourceNamesInUse.TryGetValue(parent, out var names))
resourceNamesInUse[parent] = (names = new List());
if (names.Contains(key))
@@ -1482,7 +1483,8 @@ static IEnumerable AddToResourceDictionary(VariableDefinition paren
if (node.Properties.ContainsKey(XmlName.xKey))
{
var names = resourceNamesInUse[parent];
- var key = (node.Properties[XmlName.xKey] as ValueNode).Value as string;
+ var valueNode = node.Properties[XmlName.xKey] as ValueNode ?? throw new BuildException(XKeyNotLiteral, lineInfo, null);
+ var key = (valueNode).Value as string;
names.Add(key);
// IL_0014: ldstr "key"
diff --git a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.cs.xlf b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.cs.xlf
index 2e0f63ff566..7cbd7bf8dcc 100644
--- a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.cs.xlf
+++ b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.cs.xlf
@@ -162,6 +162,11 @@
x:DataType očekává řetězcový literál, značku {{x:Type}} nebo {{x:Nul}l}.
+
+ x:Key expects a string literal.
+ x:Key expects a string literal.
+
+ x:Static: unable to find a public -- or accessible internal -- static field, static property, const or enum value named "{0}" in "{1}".x:Static: nejde najít veřejné nebo přístupné interní statické pole, statickou vlastnost, konstantu nebo hodnotu výčtu s názvem {0} v typu {1}.
diff --git a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.de.xlf b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.de.xlf
index b07ac7bd8d4..56eac6f37c1 100644
--- a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.de.xlf
+++ b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.de.xlf
@@ -162,6 +162,11 @@
x:DataType erwartet ein Zeichenfolgenliteral, ein {{x:Type}}-Markup oder {{x:Nul}l}.
+
+ x:Key expects a string literal.
+ x:Key expects a string literal.
+
+ x:Static: unable to find a public -- or accessible internal -- static field, static property, const or enum value named "{0}" in "{1}".x:Static: Ein öffentliches – oder zugängliches internes – statisches Feld, eine statische Eigenschaft oder ein const- oder enum-Wert mit dem Namen "{0}" wurde in "{1}" nicht gefunden.
diff --git a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.es.xlf b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.es.xlf
index 54f4aae7f6d..d015bba319d 100644
--- a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.es.xlf
+++ b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.es.xlf
@@ -162,6 +162,11 @@
x:DataType espera un literal de cadena, una marca {{x:Type}} o {{x:Nul}l}.
+
+ x:Key expects a string literal.
+ x:Key expects a string literal.
+
+ x:Static: unable to find a public -- or accessible internal -- static field, static property, const or enum value named "{0}" in "{1}".x:Static: no puede encontrar un campo estático público (o interno accesible), una propiedad estática o un valor constante o de enumeración llamados "{0}" en "{1}".
diff --git a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.fr.xlf b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.fr.xlf
index 5ee01736932..dd6e4350143 100644
--- a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.fr.xlf
+++ b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.fr.xlf
@@ -162,6 +162,11 @@
x:DataType attend un littéral de chaîne, une balise {{x:Type}} ou {{x:Nul}l}.
+
+ x:Key expects a string literal.
+ x:Key expects a string literal.
+
+ x:Static: unable to find a public -- or accessible internal -- static field, static property, const or enum value named "{0}" in "{1}".x:Static : impossible de localiser un champ statique public (ou interne et accessible), une propriété statique, une valeur const ou une valeur enum portant le nom "{0}" dans "{1}".
diff --git a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.it.xlf b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.it.xlf
index 8c806d9e7ee..c4380946866 100644
--- a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.it.xlf
+++ b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.it.xlf
@@ -162,6 +162,11 @@
Con x:DataType è previsto un valore letterale stringa, un markup {{x:Type}} oppure {{x:Nul}l}.
+
+ x:Key expects a string literal.
+ x:Key expects a string literal.
+
+ x:Static: unable to find a public -- or accessible internal -- static field, static property, const or enum value named "{0}" in "{1}".x:Static: non è possibile trovare un valore di campo statico pubblico o interno accessibile, di proprietà statica, di costante o di enumerazione denominato "{0}" in "{1}".
diff --git a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.ja.xlf b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.ja.xlf
index 6df19ec3c48..6cb313abae9 100644
--- a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.ja.xlf
+++ b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.ja.xlf
@@ -162,6 +162,11 @@
x:DataType には、文字列リテラル、{{x:Type}} マークアップ、または {{x:Nul}l} を指定する必要があります。
+
+ x:Key expects a string literal.
+ x:Key expects a string literal.
+
+ x:Static: unable to find a public -- or accessible internal -- static field, static property, const or enum value named "{0}" in "{1}".x:Static: "{1}" に、"{0}" という名前のパブリックな (またはアクセス可能な内部の) 静的フィールド、静的プロパティ、const、または列挙値が見つかりません。
diff --git a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.ko.xlf b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.ko.xlf
index c372adc185b..91d664cd0a0 100644
--- a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.ko.xlf
+++ b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.ko.xlf
@@ -162,6 +162,11 @@
x:DataType에는 {{x:Type}} 태그 또는 {{x:Nul}l} 문자열 리터럴이 필요합니다.
+
+ x:Key expects a string literal.
+ x:Key expects a string literal.
+
+ x:Static: unable to find a public -- or accessible internal -- static field, static property, const or enum value named "{0}" in "{1}".x:Static: "{1}"에서 이름이 "{0}"인 public 또는 액세스 가능한 내부 정적 필드, 정적 속성, 상수 또는 열거형 값을 찾을 수 없습니다.
diff --git a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.pl.xlf b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.pl.xlf
index 6d7459fea77..d20887f84b4 100644
--- a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.pl.xlf
+++ b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.pl.xlf
@@ -162,6 +162,11 @@
Argument x:DataType oczekuje literału ciągu, znacznika {{x:Type}} lub {{x:Nul}l}.
+
+ x:Key expects a string literal.
+ x:Key expects a string literal.
+
+ x:Static: unable to find a public -- or accessible internal -- static field, static property, const or enum value named "{0}" in "{1}".x:Static: nie można odnaleźć publicznego — lub dostępnego wewnętrznie — pola statycznego, właściwości statycznej, stałej lub wartości wyliczenia o nazwie „{0}” w typie „{1}”.
diff --git a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.pt-BR.xlf b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.pt-BR.xlf
index d25512046e9..a3d8e626569 100644
--- a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.pt-BR.xlf
+++ b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.pt-BR.xlf
@@ -162,6 +162,11 @@
O x:DataType espera um literal de cadeia de caracteres, uma marcação {{x:Type}} ou um {{x:Nul}l}.
+
+ x:Key expects a string literal.
+ x:Key expects a string literal.
+
+ x:Static: unable to find a public -- or accessible internal -- static field, static property, const or enum value named "{0}" in "{1}".O x:Static: não pôde encontrar um campo estático, uma propriedade estática, um valor const ou enumerado público (ou interno acessível) denominado "{0}" em "{1}".
diff --git a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.ru.xlf b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.ru.xlf
index e8b7c0eab7f..a556605f7e0 100644
--- a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.ru.xlf
+++ b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.ru.xlf
@@ -162,6 +162,11 @@
x:DataType ожидает строковый литерал, разметку {{x:Type}} или {{x:Nul}l}.
+
+ x:Key expects a string literal.
+ x:Key expects a string literal.
+
+ x:Static: unable to find a public -- or accessible internal -- static field, static property, const or enum value named "{0}" in "{1}".x:Static: не удается найти статическое поле, статическое свойство, константу или значение перечисления с именем "{0}" в "{1}", которые являлись бы открытыми или были бы доступны внутренне.
diff --git a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.tr.xlf b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.tr.xlf
index 05731f2fa0c..e1eca33056a 100644
--- a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.tr.xlf
+++ b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.tr.xlf
@@ -162,6 +162,11 @@
x:DataType için bir dize sabit değeri, {{x:Type}} işaretlemesi veya {{x:Nul}l} bekleniyor.
+
+ x:Key expects a string literal.
+ x:Key expects a string literal.
+
+ x:Static: unable to find a public -- or accessible internal -- static field, static property, const or enum value named "{0}" in "{1}".x:Static: "{1}" içinde "{0}" adlı genel -- veya erişilebilir, dahili -- statik alan, statik özellik, sabit veya sabit listesi değeri bulunamıyor.
diff --git a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.zh-Hans.xlf b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.zh-Hans.xlf
index 13105c7dc9d..0ed5bcfa322 100644
--- a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.zh-Hans.xlf
+++ b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.zh-Hans.xlf
@@ -162,6 +162,11 @@
x:DataType 需要字符串文本、{{x:Type}} 标记或 {{x:Nul}l}。
+
+ x:Key expects a string literal.
+ x:Key expects a string literal.
+
+ x:Static: unable to find a public -- or accessible internal -- static field, static property, const or enum value named "{0}" in "{1}".x:Static: 在“{1}”中找不到公共(或可访问的内部)静态字段、静态属性、常量或枚举值“{0}”。
diff --git a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.zh-Hant.xlf b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.zh-Hant.xlf
index 7845a86ca7f..38e5bd1dc7f 100644
--- a/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.zh-Hant.xlf
+++ b/Xamarin.Forms.Build.Tasks/xlf/ErrorMessages.zh-Hant.xlf
@@ -162,6 +162,11 @@
x:DataType 需要字串常值、{{x:Type}} 標記或 {{x:Nul}l}。
+
+ x:Key expects a string literal.
+ x:Key expects a string literal.
+
+ x:Static: unable to find a public -- or accessible internal -- static field, static property, const or enum value named "{0}" in "{1}".x:Static: 在 "{1}" 中找不到名為 "{0}" 的公用 (或可存取內部) 靜態欄位、靜態屬性、常數或列舉值。
diff --git a/Xamarin.Forms.Xaml.UnitTests/SetStyleIdFromXName.xaml.cs b/Xamarin.Forms.Xaml.UnitTests/SetStyleIdFromXName.xaml.cs
index a8757942869..5428111ff1d 100644
--- a/Xamarin.Forms.Xaml.UnitTests/SetStyleIdFromXName.xaml.cs
+++ b/Xamarin.Forms.Xaml.UnitTests/SetStyleIdFromXName.xaml.cs
@@ -6,11 +6,7 @@ namespace Xamarin.Forms.Xaml.UnitTests
{
public partial class SetStyleIdFromXName : ContentPage
{
- public SetStyleIdFromXName()
- {
- InitializeComponent();
- }
-
+ public SetStyleIdFromXName() => InitializeComponent();
public SetStyleIdFromXName(bool useCompiledXaml)
{
//this stub will be replaced at compile time
@@ -19,17 +15,8 @@ public SetStyleIdFromXName(bool useCompiledXaml)
[TestFixture]
public class Tests
{
- [SetUp]
- public void Setup()
- {
- Device.PlatformServices = new MockPlatformServices();
- }
-
- [TearDown]
- public void TearDown()
- {
- Device.PlatformServices = null;
- }
+ [SetUp] public void Setup() => Device.PlatformServices = new MockPlatformServices();
+ [TearDown] public void TearDown() => Device.PlatformServices = null;
[TestCase(false), TestCase(true)]
public void SetStyleId(bool useCompiledXaml)
diff --git a/Xamarin.Forms.Xaml.UnitTests/XStaticException.xaml.cs b/Xamarin.Forms.Xaml.UnitTests/XStaticException.xaml.cs
index 5cb02a119ff..952444f9388 100644
--- a/Xamarin.Forms.Xaml.UnitTests/XStaticException.xaml.cs
+++ b/Xamarin.Forms.Xaml.UnitTests/XStaticException.xaml.cs
@@ -29,23 +29,8 @@ public class Tests
// - An enumeration value
// All other cases should throw
- [SetUp]
- public void Setup()
- {
- Device.PlatformServices = new MockPlatformServices();
-
- //there's a test not resetting the values correctly, but can't find which one...
-#pragma warning disable 0618
- Xamarin.Forms.Internals.ResourceLoader.ExceptionHandler = null;
- Xamarin.Forms.Xaml.Internals.XamlLoader.DoNotThrowOnExceptions = false;
-#pragma warning restore 0618
- }
-
- [TearDown]
- public void TearDown()
- {
- Device.PlatformServices = null;
- }
+ [SetUp] public void Setup() => Device.PlatformServices = new MockPlatformServices();
+ [TearDown] public void TearDown() => Device.PlatformServices = null;
[TestCase(false)]
[TestCase(true)]
diff --git a/Xamarin.Forms.Xaml.UnitTests/XamlLoaderGetXamlForTypeTests.xaml.cs b/Xamarin.Forms.Xaml.UnitTests/XamlLoaderGetXamlForTypeTests.xaml.cs
index 2aca4333d17..1cc93a5b0f7 100644
--- a/Xamarin.Forms.Xaml.UnitTests/XamlLoaderGetXamlForTypeTests.xaml.cs
+++ b/Xamarin.Forms.Xaml.UnitTests/XamlLoaderGetXamlForTypeTests.xaml.cs
@@ -30,6 +30,20 @@ public void SetUp()
#pragma warning restore 0618
}
+ [TearDown]
+ public void TearDown()
+ {
+ Device.PlatformServices = null;
+ XamlLoader.FallbackTypeResolver = null;
+ XamlLoader.ValueCreatedCallback = null;
+ XamlLoader.InstantiationFailedCallback = null;
+#pragma warning disable 0618
+ Xamarin.Forms.Internals.ResourceLoader.ExceptionHandler = null;
+ Xamarin.Forms.Xaml.Internals.XamlLoader.DoNotThrowOnExceptions = false;
+#pragma warning restore 0618
+
+ }
+
[TestCase(false)]
[TestCase(true)]
public void XamlContentIsReplaced(bool useCompiledXaml)
diff --git a/Xamarin.Forms.Xaml.UnitTests/xKeyLiteral.xaml b/Xamarin.Forms.Xaml.UnitTests/xKeyLiteral.xaml
new file mode 100644
index 00000000000..b04b1a940aa
--- /dev/null
+++ b/Xamarin.Forms.Xaml.UnitTests/xKeyLiteral.xaml
@@ -0,0 +1,8 @@
+
+
+
+
+ #96d1ff
+
+
+
diff --git a/Xamarin.Forms.Xaml.UnitTests/xKeyLiteral.xaml.cs b/Xamarin.Forms.Xaml.UnitTests/xKeyLiteral.xaml.cs
new file mode 100644
index 00000000000..3c924f6f298
--- /dev/null
+++ b/Xamarin.Forms.Xaml.UnitTests/xKeyLiteral.xaml.cs
@@ -0,0 +1,38 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT License.
+using System;
+using System.Collections.Generic;
+using NUnit.Framework;
+using Xamarin.Forms;
+using Xamarin.Forms.Build.Tasks;
+using Xamarin.Forms.Core.UnitTests;
+
+namespace Xamarin.Forms.Xaml.UnitTests
+{
+ [XamlCompilation(XamlCompilationOptions.Skip)]
+ public partial class xKeyLiteral : ContentPage
+ {
+ public xKeyLiteral() => InitializeComponent();
+ public xKeyLiteral(bool useCompiledXaml)
+ {
+ //this stub will be replaced at compile time
+ }
+
+ [TestFixture]
+ class Tests
+ {
+ [SetUp] public void Setup() => Device.PlatformServices = new MockPlatformServices();
+ [TearDown] public void TearDown() => Device.PlatformServices = null;
+
+ [Test]
+ //this requirement might change, see https://github.com/xamarin/Xamarin.Forms/issues/12425
+ public void xKeyRequireStringLiteral([Values(false, true)] bool useCompiledXaml)
+ {
+ if (useCompiledXaml)
+ Assert.Throws(() => MockCompiler.Compile(typeof(xKeyLiteral)));
+ else
+ Assert.Throws(() => new xKeyLiteral(useCompiledXaml));
+ }
+ }
+ }
+}
diff --git a/Xamarin.Forms.Xaml/ApplyPropertiesVisitor.cs b/Xamarin.Forms.Xaml/ApplyPropertiesVisitor.cs
index 0e451f029bc..b580103c2f1 100644
--- a/Xamarin.Forms.Xaml/ApplyPropertiesVisitor.cs
+++ b/Xamarin.Forms.Xaml/ApplyPropertiesVisitor.cs
@@ -46,9 +46,8 @@ public void Visit(ValueNode node, INode parentNode)
if (!Values.TryGetValue(parentNode, out var source) && Context.ExceptionHandler != null)
return;
- XmlName propertyName;
- if (TryGetPropertyName(node, parentNode, out propertyName))
+ if (TryGetPropertyName(node, parentNode, out XmlName propertyName))
{
if (TrySetRuntimeName(propertyName, source, value, node))
return;
@@ -82,8 +81,7 @@ public void Visit(MarkupNode node, INode parentNode)
public void Visit(ElementNode node, INode parentNode)
{
- XmlName propertyName;
- if (TryGetPropertyName(node, parentNode, out propertyName) && propertyName == XmlName._CreateContent)
+ if (TryGetPropertyName(node, parentNode, out XmlName propertyName) && propertyName == XmlName._CreateContent)
{
var s0 = Values[parentNode];
if (s0 is ElementTemplate)
@@ -97,8 +95,7 @@ public void Visit(ElementNode node, INode parentNode)
propertyName = XmlName.Empty;
//Simplify ListNodes with single elements
- var pList = parentNode as ListNode;
- if (pList != null && pList.CollectionItems.Count == 1)
+ if (parentNode is ListNode pList && pList.CollectionItems.Count == 1)
{
propertyName = pList.XmlName;
parentNode = parentNode.Parent;
@@ -127,7 +124,15 @@ public void Visit(ElementNode node, INode parentNode)
ProvideValue(ref value, node, source, XmlName.Empty);
string contentProperty;
Exception xpe = null;
- var xKey = node.Properties.ContainsKey(XmlName.xKey) ? ((ValueNode)node.Properties[XmlName.xKey]).Value as string : null;
+
+ string xKey = null;
+ if (xpe == null && node.Properties.ContainsKey(XmlName.xKey))
+ {
+ if ((node.Properties[XmlName.xKey] is ValueNode valueNode))
+ xKey = valueNode.Value as string;
+ if (xKey == null)
+ xpe = new XamlParseException("x:Key expects a string literal.", node as IXmlLineInfo);
+ }
//ResourceDictionary
if (xpe == null && TryAddToResourceDictionary(source as ResourceDictionary, value, xKey, node, out xpe))
@@ -168,10 +173,17 @@ public void Visit(ElementNode node, INode parentNode)
if (Skips.Contains(parentList.XmlName))
return;
Exception xpe = null;
- var xKey = node.Properties.ContainsKey(XmlName.xKey) ? ((ValueNode)node.Properties[XmlName.xKey]).Value as string : null;
+ string xKey = null;
+ if (xpe == null && node.Properties.ContainsKey(XmlName.xKey))
+ {
+ if ((node.Properties[XmlName.xKey] is ValueNode valueNode))
+ xKey = valueNode.Value as string;
+ if (xKey == null)
+ xpe = new XamlParseException("x:Key expects a string literal.", node as IXmlLineInfo);
+ }
var collection = GetPropertyValue(source, parentList.XmlName, Context.RootElement, parentList, out _, out _) as IEnumerable;
- if (collection == null)
+ if (xpe == null && collection == null)
xpe = new XamlParseException($"Property {parentList.XmlName.LocalName} is null or is not IEnumerable", node);
if (xpe == null && TryAddToResourceDictionary(collection as ResourceDictionary, value, xKey, node, out xpe))
diff --git a/Xamarin.Forms.Xaml/FillResourceDictionariesVisitor.cs b/Xamarin.Forms.Xaml/FillResourceDictionariesVisitor.cs
index 7ee5c389e54..7a03fc48831 100644
--- a/Xamarin.Forms.Xaml/FillResourceDictionariesVisitor.cs
+++ b/Xamarin.Forms.Xaml/FillResourceDictionariesVisitor.cs
@@ -8,10 +8,7 @@ namespace Xamarin.Forms.Xaml
{
class FillResourceDictionariesVisitor : IXamlNodeVisitor
{
- public FillResourceDictionariesVisitor(HydrationContext context)
- {
- Context = context;
- }
+ public FillResourceDictionariesVisitor(HydrationContext context) => Context = context;
HydrationContext Context { get; }
Dictionary Values => Context.Values;
@@ -53,12 +50,12 @@ public void Visit(ElementNode node, INode parentNode)
}
//Only proceed further if the node is a keyless RD
- if (parentNode is IElementNode
+ if ( parentNode is IElementNode
&& Context.Types.TryGetValue((IElementNode)parentNode, out var parentType)
&& typeof(ResourceDictionary).IsAssignableFrom(parentType)
&& !((IElementNode)parentNode).Properties.ContainsKey(XmlName.xKey))
node.Accept(new ApplyPropertiesVisitor(Context, stopOnResourceDictionary: false), parentNode);
- else if (parentNode is ListNode
+ else if ( parentNode is ListNode
&& typeof(ResourceDictionary).IsAssignableFrom(Context.Types[((IElementNode)parentNode.Parent)])
&& !((IElementNode)parentNode.Parent).Properties.ContainsKey(XmlName.xKey))
node.Accept(new ApplyPropertiesVisitor(Context, stopOnResourceDictionary: false), parentNode);
@@ -74,15 +71,14 @@ public void Visit(ListNode node, INode parentNode)
public bool SkipChildren(INode node, INode parentNode)
{
- var enode = node as ElementNode;
- if (enode is null)
+ if (!(node is ElementNode))
return false;
- if (parentNode is IElementNode
+ if ( parentNode is IElementNode
&& Context.Types.TryGetValue((IElementNode)parentNode, out var parentType)
&& typeof(ResourceDictionary).IsAssignableFrom(parentType)
&& !((IElementNode)parentNode).Properties.ContainsKey(XmlName.xKey))
return true;
- if (parentNode is ListNode
+ if ( parentNode is ListNode
&& typeof(ResourceDictionary).IsAssignableFrom(Context.Types[((IElementNode)parentNode.Parent)])
&& !((IElementNode)parentNode.Parent).Properties.ContainsKey(XmlName.xKey))
return true;