diff --git a/docs/area-owners.md b/docs/area-owners.md
index d6bcf5391850ca..e1889072f9f736 100644
--- a/docs/area-owners.md
+++ b/docs/area-owners.md
@@ -8,7 +8,7 @@ This list is for this **dotnet/runtime** repo. The **dotnet/aspnetcore** repo ha
## Areas
-Note: Editing this file doesn't update the mapping used by `@msftbot` for area-specific issue/PR notifications. That configuration is part of the [`fabricbot.json`](../.github/fabricbot.json) file, and many areas use GitHub teams for those notifications. If you're a community member interested in receiving area-specific issue/PR notifications, you won't appear in this table or be added to those GitHub teams, but you can create a PR that updates `fabricbot.json` to add yourself to those notifications. See [automation.md](infra/automation.md) for more information on the schema and tools used by FabricBot.
+Note: Editing this file doesn't update the mapping used by `@dotnet-policy-service` for area-specific issue/PR notifications. That configuration is part of the [`resourceManagement.yml`](../.github/policies/resourceManagement.yml) file, and many areas use GitHub teams for those notifications. If you're a community member interested in receiving area-specific issue/PR notifications, you won't appear in this table or be added to those GitHub teams, but you can create a PR that updates `resourceManagement.yml` to add yourself to those notifications. See [automation.md](infra/automation.md) for more information.
| Area | Lead | Owners (area experts to tag in PRs and issues) | Notes |
|------------------------------------------------|----------------------|------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
diff --git a/docs/design/coreclr/botr/profiling.md b/docs/design/coreclr/botr/profiling.md
index 3100666ac25769..35d57b37c1c166 100644
--- a/docs/design/coreclr/botr/profiling.md
+++ b/docs/design/coreclr/botr/profiling.md
@@ -68,10 +68,10 @@ The other interface involved for profiling is _ICorProfilerInfo_. The profiler
The picture so far describes what happens once the application and profiler are running. But how are the two connected together when an application is started? The CLR makes the connection during its initialization in each process. It decides whether to connect to a profiler, and which profiler that should be, depending upon the value for two environment variables, checked one after the other:
-- Cor\_Enable\_Profiling - only connect with a profiler if this environment variable exists and is set to a non-zero value.
-- Cor\_Profiler - connect with the profiler with this CLSID or ProgID (which must have been stored previously in the Registry). The Cor\_Profiler environment variable is defined as a string:
- - set Cor\_Profiler={32E2F4DA-1BEA-47ea-88F9-C5DAF691C94A}, or
- - set Cor\_Profiler="MyProfiler"
+- CORECLR\_ENABLE\_PROFILING - only connect with a profiler if this environment variable exists and is set to a non-zero value.
+- CORECLR\_PROFILER - connect with the profiler with this CLSID or ProgID (which must have been stored previously in the Registry). The CORECLR\_PROFILER environment variable is defined as a string:
+ - set CORECLR\_PROFILER={32E2F4DA-1BEA-47ea-88F9-C5DAF691C94A}, or
+ - set CORECLR\_PROFILER="MyProfiler"
- The profiler class is the one that implements _ICorProfilerCallback/ICorProfilerCallback2_. It is required that a profiler implement ICorProfilerCallback2; if it does not, it will not be loaded.
When both checks above pass, the CLR creates an instance of the profiler in a similar fashion to _CoCreateInstance_. The profiler is not loaded through a direct call to _CoCreateInstance_ so that a call to _CoInitialize_ may be avoided, which requires setting the threading model. It then calls the _ICorProfilerCallback::Initialize_ method in the profiler. The signature of this method is:
@@ -235,7 +235,7 @@ Profiling is enabled through environment variables, and since NT Services are st
MyComputer -> Properties -> Advanced -> EnvironmentVariables -> System Variables
-Both **Cor\_Enable\_Profiling** and **COR\_PROFILER have to be set** , and the user must ensure that the Profiler DLL is registered. Then, the target machine should be re-booted so that the NT Services pick up those changes. Note that this will enable profiling on a system-wide basis. So, to prevent every managed application that is run subsequently from being profiled, the user should delete those system environment variables after the re-boot.
+Both **CORECLR\_ENABLE\_PROFILING** and **CORECLR\_PROFILER have to be set** , and the user must ensure that the Profiler DLL is registered. Then, the target machine should be re-booted so that the NT Services pick up those changes. Note that this will enable profiling on a system-wide basis. So, to prevent every managed application that is run subsequently from being profiled, the user should delete those system environment variables after the re-boot.
Profiling API – High-Level Description
======================================
diff --git a/docs/design/datacontracts/CodeVersions.md b/docs/design/datacontracts/CodeVersions.md
index 27f0814c37dd34..c903bd84007cbc 100644
--- a/docs/design/datacontracts/CodeVersions.md
+++ b/docs/design/datacontracts/CodeVersions.md
@@ -40,6 +40,9 @@ public virtual bool CodeVersionManagerSupportsMethod(TargetPointer methodDesc);
// Return the instruction pointer corresponding to the start of the given native code version
public virtual TargetCodePointer GetNativeCode(NativeCodeVersionHandle codeVersionHandle);
+
+// Gets the GCStressCodeCopy pointer if available, otherwise returns TargetPointer.Null
+public virtual TargetPointer GetGCStressCodeCopy(NativeCodeVersionHandle codeVersionHandle);
```
### Extension Methods
```csharp
@@ -61,6 +64,7 @@ Data descriptors used:
| NativeCodeVersionNode | NativeCode | indicates an explicit native code version node |
| NativeCodeVersionNode | Flags | `NativeCodeVersionNodeFlags` flags, see below |
| NativeCodeVersionNode | VersionId | Version ID corresponding to the parent IL code version |
+| NativeCodeVersionNode | GCCoverageInfo | GCStress debug info, if supported |
| ILCodeVersioningState | FirstVersionNode | pointer to the first `ILCodeVersionNode` |
| ILCodeVersioningState | ActiveVersionKind | an `ILCodeVersionKind` value indicating which fields of the active version are value |
| ILCodeVersioningState | ActiveVersionNode | if the active version is explicit, the NativeCodeVersionNode for the active version |
@@ -68,6 +72,7 @@ Data descriptors used:
| ILCodeVersioningState | ActiveVersionMethodDef | if the active version is synthetic or unknown, the MethodDef token for the method |
| ILCodeVersionNode | VersionId | Version ID of the node |
| ILCodeVersionNode | Next | Pointer to the next `ILCodeVersionNode`|
+| GCCoverageInfo | SavedCode | Pointer to the GCCover saved code copy, if supported |
The flag indicates that the default version of the code for a method desc is active:
```csharp
@@ -249,3 +254,11 @@ bool ICodeVersions.CodeVersionManagerSupportsMethod(TargetPointer methodDescAddr
return true;
}
```
+
+### Finding GCStress Code Copy
+```csharp
+public virtual TargetPointer GetGCStressCodeCopy(NativeCodeVersionHandle codeVersionHandle);
+```
+
+1. If `codeVersionHandle` is synthetic, use the `IRuntimeTypeSystem` to find the GCStressCodeCopy.
+2. If `codeVersionHandle` is explicit, read the `NativeCodeVersionNode` for the `GCCoverageInfo` pointer. This value only exists in some builds. If the value doesn't exist or is a nullptr, return `TargetPointer.Null`. Otherwise return the `SavedCode` pointer from the `GCCoverageInfo` struct.
diff --git a/docs/design/datacontracts/RuntimeTypeSystem.md b/docs/design/datacontracts/RuntimeTypeSystem.md
index 84726124483c73..b1d65b7c825273 100644
--- a/docs/design/datacontracts/RuntimeTypeSystem.md
+++ b/docs/design/datacontracts/RuntimeTypeSystem.md
@@ -159,6 +159,8 @@ partial interface IRuntimeTypeSystem : IContract
// Get an instruction pointer that can be called to cause the MethodDesc to be executed
public virtual TargetCodePointer GetNativeCode(MethodDescHandle methodDesc);
+ // Gets the GCStressCodeCopy pointer if available, otherwise returns TargetPointer.Null
+ public virtual TargetPointer GetGCStressCodeCopy(MethodDescHandle methodDesc);
}
```
@@ -638,6 +640,7 @@ We depend on the following data descriptors:
| `MethodDesc` | `Slot` | The method's slot |
| `MethodDesc` | `Flags` | The method's flags |
| `MethodDesc` | `Flags3AndTokenRemainder` | More flags for the method, and the low bits of the method's token's RID |
+| `MethodDesc` | `GCCoverageInfo` | The method's GCCover debug info, if supported |
| `MethodDescCodeData` | `VersioningState` | The IL versioning state associated with a method descriptor
| `MethodDescChunk` | `MethodTable` | The method table set of methods belongs to |
| `MethodDescChunk` | `Next` | The next chunk of methods |
@@ -654,6 +657,7 @@ We depend on the following data descriptors:
| `StoredSigMethodDesc` | `cSig` | Count of bytes in the metadata signature |
| `StoredSigMethodDesc` | `ExtendedFlags` | Flags field for the `StoredSigMethodDesc` |
| `DynamicMethodDesc` | `MethodName` | Pointer to Null-terminated UTF8 string describing the Method desc |
+| `GCCoverageInfo` | `SavedCode` | Pointer to the GCCover saved code copy, if supported |
The contract depends on the following other contracts
diff --git a/docs/design/features/globalization-hybrid-mode.md b/docs/design/features/globalization-hybrid-mode.md
index 1dec94595b1c45..9840c30fed0bba 100644
--- a/docs/design/features/globalization-hybrid-mode.md
+++ b/docs/design/features/globalization-hybrid-mode.md
@@ -11,382 +11,6 @@ Hybrid has lower priority than Invariant. To switch on the mode set the property
Hybrid mode does not use ICU data for some functions connected with globalization but relies on functions native to the platform. Because native APIs do not fully cover all the functionalities we currently support and because ICU data can be excluded from the ICU datafile only in batches defined by ICU filters, not all functions will work the same way or not all will be supported. To see what to expect after switching on `HybridGlobalization`, read the following paragraphs.
-### WASM
-
-For WebAssembly in Browser we are using Web API instead of some ICU data. Ideally, we would use `System.Runtime.InteropServices.JavaScript` to call JS code from inside of C# but we cannot reference any assemblies from inside of `System.Private.CoreLib`. That is why we are using iCalls instead. The host support depends on used Web API functions support - see **dependencies** in each section.
-
-Hybrid has higher priority than sharding or custom modes, described in globalization-icu-wasm.md.
-
-**HashCode**
-
-Affected public APIs:
-- System.Globalization.CompareInfo.GetHashCode
-
-For invariant culture all `CompareOptions` are available.
-
-For non-invariant cultures following `CompareOptions` are available:
-- `CompareOption.None`
-- `CompareOption.IgnoreCase`
-
-The remaining combinations for non-invariant cultures throw `PlatformNotSupportedException`.
-
-**SortKey**
-
-Affected public APIs:
-- System.Globalization.CompareInfo.GetSortKey
-- System.Globalization.CompareInfo.GetSortKeyLength
-
-For invariant culture all `CompareOptions` are available.
-
-For non-invariant cultures `PlatformNotSupportedException` is thrown.
-
-Indirectly affected APIs (the list might not be complete):
-- Microsoft.VisualBasic.Collection.Add
-- System.Collections.Hashtable.Add
-- System.Collections.Hashtable.GetHash
-- System.Collections.CaseInsensitiveHashCodeProvider.GetHashCode
-- System.Collections.Specialized.NameObjectCollectionBase.BaseAdd
-- System.Collections.Specialized.NameValueCollection.Add
-- System.Collections.Specialized.NameObjectCollectionBase.BaseGet
-- System.Collections.Specialized.NameValueCollection.Get
-- System.Collections.Specialized.NameObjectCollectionBase.BaseRemove
-- System.Collections.Specialized.NameValueCollection.Remove
-- System.Collections.Specialized.OrderedDictionary.Add
-- System.Collections.Specialized.NameObjectCollectionBase.BaseSet
-- System.Collections.Specialized.NameValueCollection.Set
-- System.Data.DataColumnCollection.Add
-- System.Collections.Generic.HashSet
-- System.Collections.Generic.Dictionary
-- System.Net.Mail.MailAddress.GetHashCode
-- System.Xml.Xsl.XslCompiledTransform.Transform
-
-**Case change**
-
-Affected public APIs:
-- System.Globalization.TextInfo.ToLower,
-- System.Globalization.TextInfo.ToUpper,
-- System.Globalization.TextInfo.ToTitleCase.
-
-Case change with invariant culture uses `toUpperCase` / `toLoweCase` functions that do not guarantee a full match with the original invariant culture.
-Hybrid case change, same as ICU-based, does not support code points expansion e.g. "straße" -> "STRAßE".
-
-- Final sigma behavior correction:
-
-ICU-based case change does not respect final-sigma rule, but hybrid does, so "ΒΌΛΟΣ" -> "βόλος", not "βόλοσ".
-
-Dependencies:
-- [String.prototype.toUpperCase()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toUpperCase)
-- [String.prototype.toLoweCase()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLowerCase)
-- [String.prototype.toLocaleUpperCase()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLocaleUpperCase)
-- [String.prototype.toLocaleLoweCase()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLocaleLowerCase)
-
-**String comparison**
-
-Affected public APIs:
-- System.Globalization.CompareInfo.Compare,
-- System.String.Compare,
-- System.String.Equals.
-Indirectly affected APIs (the list might not be complete):
-- Microsoft.VisualBasic.Strings.InStrRev
-- Microsoft.VisualBasic.Strings.Replace
-- Microsoft.VisualBasic.Strings.InStr
-- Microsoft.VisualBasic.Strings.Split
-- Microsoft.VisualBasic.Strings.StrComp
-- Microsoft.VisualBasic.CompilerServices.LikeOperator.LikeObject
-- Microsoft.VisualBasic.CompilerServices.LikeOperator.LikeString
-- Microsoft.VisualBasic.CompilerServices.ObjectType.ObjTst
-- Microsoft.VisualBasic.CompilerServices.ObjectType.LikeObj
-- Microsoft.VisualBasic.CompilerServices.StringType.StrLike
-- Microsoft.VisualBasic.CompilerServices.Operators.ConditionalCompareObjectEqual
-- Microsoft.VisualBasic.CompilerServices.StringType.StrLike
-- Microsoft.VisualBasic.CompilerServices.StringType.StrLikeText
-- Microsoft.VisualBasic.CompilerServices.StringType.StrCmp
-- System.Data.DataSet.ReadXml
-- System.Data.DataTableCollection.Add
-
-Dependencies:
-- [String.prototype.localeCompare()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare)
-
-The number of `CompareOptions` and `StringComparison` combinations is limited. Originally supported combinations can be found [here for CompareOptions](https://learn.microsoft.com/dotnet/api/system.globalization.compareoptions) and [here for StringComparison](https://learn.microsoft.com/dotnet/api/system.stringcomparison).
-
-
-- `IgnoreWidth` is not supported because there is no equivalent in Web API. Throws `PlatformNotSupportedException`.
-``` JS
-let high = String.fromCharCode(65281) // %uff83 = テ
-let low = String.fromCharCode(12486) // %u30c6 = テ
-high.localeCompare(low, "ja-JP", { sensitivity: "case" }) // -1 ; case: a ≠ b, a = á, a ≠ A; expected: 0
-
-let wide = String.fromCharCode(65345) // %uFF41 = a
-let narrow = "a"
-wide.localeCompare(narrow, "en-US", { sensitivity: "accent" }) // 0; accent: a ≠ b, a ≠ á, a = A; expected: -1
-```
-
-For comparison where "accent" sensitivity is used, ignoring some type of character widths is applied and cannot be switched off (see: point about `IgnoreCase`).
-
-- `IgnoreKanaType`:
-
-It is always switched on for comparison with locale "ja-JP", even if this comparison option was not set explicitly.
-
-``` JS
-let hiragana = String.fromCharCode(12353) // %u3041 = ぁ
-let katakana = String.fromCharCode(12449) // %u30A1 = ァ
-let enCmp = hiragana.localeCompare(katakana, "en-US") // -1
-let jaCmp = hiragana.localeCompare(katakana, "ja-JP") // 0
-```
-
-For locales different than "ja-JP" it cannot be used separately (no equivalent in Web API) - throws `PlatformNotSupportedException`.
-
-- `None`:
-
-No equivalent in Web API for "ja-JP" locale. See previous point about `IgnoreKanaType`. For "ja-JP" it throws `PlatformNotSupportedException`.
-
-- `IgnoreCase`, `CurrentCultureIgnoreCase`, `InvariantCultureIgnoreCase`
-
-For `IgnoreCase | IgnoreKanaType`, argument `sensitivity: "accent"` is used.
-
-``` JS
-let hiraganaBig = `${String.fromCharCode(12353)} A` // %u3041 = ぁ
-let katakanaSmall = `${String.fromCharCode(12449)} a` // %u30A1 = ァ
-hiraganaBig.localeCompare(katakanaSmall, "en-US", { sensitivity: "accent" }) // 0; accent: a ≠ b, a ≠ á, a = A
-```
-
-Known exceptions:
-
-| **character 1** | **character 2** | **CompareOptions** | **hybrid globalization** | **icu** | **comments** |
-|:---------------:|:---------------:|--------------------|:------------------------:|:-------:|:-------------------------------------------------------:|
-| a | `\uFF41` a | IgnoreKanaType | 0 | -1 | applies to all wide-narrow chars |
-| `\u30DC` ボ | `\uFF8E` ホ | IgnoreCase | 1 | -1 | 1 is returned in icu when we additionally ignore width |
-| `\u30BF` タ | `\uFF80` タ | IgnoreCase | 0 | -1 | |
-
-
-For `IgnoreCase` alone, a comparison with default option: `sensitivity: "variant"` is used after string case unification.
-
-``` JS
-let hiraganaBig = `${String.fromCharCode(12353)} A` // %u3041 = ぁ
-let katakanaSmall = `${String.fromCharCode(12449)} a` // %u30A1 = ァ
-let unchangedLocale = "en-US"
-let unchangedStr1 = hiraganaBig.toLocaleLowerCase(unchangedLocale);
-let unchangedStr2 = katakanaSmall.toLocaleLowerCase(unchangedLocale);
-unchangedStr1.localeCompare(unchangedStr2, unchangedLocale) // -1;
-let changedLocale = "ja-JP"
-let changedStr1 = hiraganaBig.toLocaleLowerCase(changedLocale);
-let changedStr2 = katakanaSmall.toLocaleLowerCase(changedLocale);
-changedStr1.localeCompare(changedStr2, changedLocale) // 0;
-```
-
-From this reason, comparison with locale `ja-JP` `CompareOption` `IgnoreCase` and `StringComparison`: `CurrentCultureIgnoreCase` and `InvariantCultureIgnoreCase` behave like a combination `IgnoreCase | IgnoreKanaType` (see: previous point about `IgnoreKanaType`). For other locales the behavior is unchanged with the following known exceptions:
-
-| **character 1** | **character 2** | **CompareOptions** | **hybrid globalization** | **icu** |
-|:------------------------------------------------:|:----------------------------------------------------------:|-----------------------------------|:------------------------:|:-------:|
-| `\uFF9E` (HALFWIDTH KATAKANA VOICED SOUND MARK) | `\u3099` (COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK) | None / IgnoreCase / IgnoreSymbols | 1 | 0 |
-
-- `IgnoreNonSpace`
-
-`IgnoreNonSpace` cannot be used separately without `IgnoreKanaType`. Argument `sensitivity: "case"` is used for comparison and it ignores both types of characters. Option `IgnoreNonSpace` alone throws `PlatformNotSupportedException`.
-
-``` JS
-let hiraganaAccent = `${String.fromCharCode(12353)} á` // %u3041 = ぁ
-let katakanaNoAccent = `${String.fromCharCode(12449)} a` // %u30A1 = ァ
-hiraganaAccent.localeCompare(katakanaNoAccent, "en-US", { sensitivity: "case" }) // 0; case: a ≠ b, a = á, a ≠ A
-```
-
-- `IgnoreNonSpace | IgnoreCase`
-Combination of `IgnoreNonSpace` and `IgnoreCase` cannot be used without `IgnoreKanaType`. Argument `sensitivity: "base"` is used for comparison and it ignores three types of characters. Combination `IgnoreNonSpace | IgnoreCase` alone throws `PlatformNotSupportedException`.
-
-``` JS
-let hiraganaBigAccent = `${String.fromCharCode(12353)} A á` // %u3041 = ぁ
-let katakanaSmallNoAccent = `${String.fromCharCode(12449)} a a` // %u30A1 = ァ
-hiraganaBigAccent.localeCompare(katakanaSmallNoAccent, "en-US", { sensitivity: "base" }) // 0; base: a ≠ b, a = á, a = A
-```
-
-- `IgnoreSymbols`
-
-The subset of ignored symbols is limited to the symbols ignored by `string1.localeCompare(string2, locale, { ignorePunctuation: true })`. E.g. currency symbols, & are not ignored
-
-``` JS
-let hiraganaAccent = `${String.fromCharCode(12353)} á` // %u3041 = ぁ
-let katakanaNoAccent = `${String.fromCharCode(12449)} a` // %u30A1 = ァ
-hiraganaBig.localeCompare(katakanaSmall, "en-US", { sensitivity: "base" }) // 0; base: a ≠ b, a = á, a = A
-```
-
-- List of all `CompareOptions` combinations always throwing `PlatformNotSupportedException`:
-
-`IgnoreCase`,
-
-`IgnoreNonSpace`,
-
-`IgnoreNonSpace | IgnoreCase`,
-
-`IgnoreSymbols | IgnoreCase`,
-
-`IgnoreSymbols | IgnoreNonSpace`,
-
-`IgnoreSymbols | IgnoreNonSpace | IgnoreCase`,
-
-`IgnoreWidth`,
-
-`IgnoreWidth | IgnoreCase`,
-
-`IgnoreWidth | IgnoreNonSpace`,
-
-`IgnoreWidth | IgnoreNonSpace | IgnoreCase`,
-
-`IgnoreWidth | IgnoreSymbols`
-
-`IgnoreWidth | IgnoreSymbols | IgnoreCase`
-
-`IgnoreWidth | IgnoreSymbols | IgnoreNonSpace`
-
-`IgnoreWidth | IgnoreSymbols | IgnoreNonSpace | IgnoreCase`
-
-`IgnoreKanaType | IgnoreWidth`
-
-`IgnoreKanaType | IgnoreWidth | IgnoreCase`
-
-`IgnoreKanaType | IgnoreWidth | IgnoreNonSpace`
-
-`IgnoreKanaType | IgnoreWidth | IgnoreNonSpace | IgnoreCase`
-
-`IgnoreKanaType | IgnoreWidth | IgnoreSymbols`
-
-`IgnoreKanaType | IgnoreWidth | IgnoreSymbols | IgnoreCase`
-
-`IgnoreKanaType | IgnoreWidth | IgnoreSymbols | IgnoreNonSpace`
-
-`IgnoreKanaType | IgnoreWidth | IgnoreSymbols | IgnoreNonSpace | IgnoreCase`
-
-
-**String starts with / ends with**
-
-Affected public APIs:
-- CompareInfo.IsPrefix
-- CompareInfo.IsSuffix
-- String.StartsWith
-- String.EndsWith
-
-Dependencies:
-- [String.prototype.normalize()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize)
-- [String.prototype.localeCompare()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare)
-
-Web API does not expose locale-sensitive endsWith/startsWith function. As a workaround, both strings get normalized and weightless characters are removed. Resulting strings are cut to the same length and comparison is performed. This approach, beyond having the same compare option limitations as described under **String comparison**, has additional limitations connected with the workaround used. Because we are normalizing strings to be able to cut them, we cannot calculate the match length on the original strings. Methods that calculate this information throw PlatformNotSupported exception:
-
-- [CompareInfo.IsPrefix](https://learn.microsoft.com/dotnet/api/system.globalization.compareinfo.isprefix?view=#system-globalization-compareinfo-isprefix(system-readonlyspan((system-char))-system-readonlyspan((system-char))-system-globalization-compareoptions-system-int32@))
-- [CompareInfo.IsSuffix](https://learn.microsoft.com/dotnet/api/system.globalization.compareinfo.issuffix?view=system-globalization-compareinfo-issuffix(system-readonlyspan((system-char))-system-readonlyspan((system-char))-system-globalization-compareoptions-system-int32@))
-
-- `IgnoreSymbols`
-Only comparisons that do not skip character types are allowed. E.g. `IgnoreSymbols` skips symbol-chars in comparison/indexing. All `CompareOptions` combinations that include `IgnoreSymbols` throw `PlatformNotSupportedException`.
-
-**String indexing**
-
-Affected public APIs:
-- CompareInfo.IndexOf
-- CompareInfo.LastIndexOf
-- String.IndexOf
-- String.LastIndexOf
-
-Web API does not expose locale-sensitive indexing function. There is a discussion on adding it: https://github.com/tc39/ecma402/issues/506. In the current state, as a workaround, locale-sensitive string segmenter combined with locale-sensitive comparison is used. This approach, beyond having the same compare option limitations as described under **String comparison**, has additional limitations connected with the workaround used. Information about additional limitations:
-
-- Methods that calculate `matchLength` always return throw PlatformNotSupported exception:
-
-[CompareInfo.IndexOf](https://learn.microsoft.com/en-us/dotnet/api/system.globalization.compareinfo.indexof?view=system-globalization-compareinfo-indexof(system-readonlyspan((system-char))-system-readonlyspan((system-char))-system-globalization-compareoptions-system-int32@))
-
-[CompareInfo.LastIndexOf](https://learn.microsoft.com/en-us/dotnet/api/system.globalization.compareinfo.lastindexof?view=system-globalization-compareinfo-lastindexof(system-readonlyspan((system-char))-system-readonlyspan((system-char))-system-globalization-compareoptions-system-int32@))
-
-- String.Replace that uses `StringComparison` argument relies internally on IndexOf with `matchLength` argument. From this reason, it throws PlatformNotSupportedException:
-[String.Replace](https://learn.microsoft.com/en-us/dotnet/api/system.string.replace?view=system-string-replace(system-string-system-string-system-stringcomparison))
-
-- Support depends on [`Intl.segmenter's support`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter#browser_compatibility).
-
-- `IgnoreSymbols`
-
-Only comparisons that ignore types of characters but do not skip them are allowed. E.g. `IgnoreCase` ignores type (case) of characters but `IgnoreSymbols` skips symbol-chars in comparison/indexing. All `CompareOptions` combinations that include `IgnoreSymbols` throw `PlatformNotSupportedException`.
-
-- Some letters consist of more than one grapheme.
-
-Using locale-sensitive segmenter `Intl.Segmenter(locale, { granularity: "grapheme" })` does not guarantee that string will be segmented by letters but by graphemes. E.g. in `cs-CZ` and `sk-SK` "ch" is 1 letter, 2 graphemes. The following code with `HybridGlobalization` switched off returns -1 (not found) while with `HybridGlobalization` switched on, it returns 1.
-
-``` C#
-new CultureInfo("sk-SK").CompareInfo.IndexOf("ch", "h"); // -1 or 1
-```
-
-- Some graphemes consist of more than one character.
-E.g. `\r\n` that represents two characters in C#, is treated as one grapheme by the segmenter:
-
-``` JS
-const segmenter = new Intl.Segmenter(undefined, { granularity: "grapheme" });
-Array.from(segmenter.segment("\r\n")) // {segment: '\r\n', index: 0, input: '\r\n'}
-```
-
-Because we are comparing grapheme-by-grapheme, character `\r` or character `\n` will not be found in `\r\n` string when `HybridGlobalization` is switched on.
-
-- Some graphemes have multi-grapheme equivalents.
-E.g. in `de-DE` ß (%u00DF) is one letter and one grapheme and "ss" is one letter and is recognized as two graphemes. Web API's equivalent of `IgnoreNonSpace` treats them as the same letter when comparing. Similar case: dz (%u01F3) and dz.
-``` JS
-"ß".localeCompare("ss", "de-DE", { sensitivity: "case" }); // 0
-```
-
-Using `IgnoreNonSpace` for these two with `HybridGlobalization` off, also returns 0 (they are equal). However, the workaround used in `HybridGlobalization` will compare them grapheme-by-grapheme and will return -1.
-
-``` C#
-new CultureInfo("de-DE").CompareInfo.IndexOf("strasse", "stra\u00DFe", 0, CompareOptions.IgnoreNonSpace); // 0 or -1
-```
-
-**Calandars**
-
-Affected public APIs:
-- DateTimeFormatInfo.AbbreviatedDayNames
-- DateTimeFormatInfo.GetAbbreviatedDayName()
-- DateTimeFormatInfo.AbbreviatedMonthGenitiveNames
-- DateTimeFormatInfo.AbbreviatedMonthNames
-- DateTimeFormatInfo.GetAbbreviatedMonthName()
-- DateTimeFormatInfo.AMDesignator
-- DateTimeFormatInfo.CalendarWeekRule
-- DateTimeFormatInfo.DayNames
-- DateTimeFormatInfo.GetDayName
-- DateTimeFormatInfo.GetAbbreviatedEraName()
-- DateTimeFormatInfo.GetEraName()
-- DateTimeFormatInfo.FirstDayOfWeek
-- DateTimeFormatInfo.FullDateTimePattern
-- DateTimeFormatInfo.LongDatePattern
-- DateTimeFormatInfo.LongTimePattern
-- DateTimeFormatInfo.MonthDayPattern
-- DateTimeFormatInfo.MonthGenitiveNames
-- DateTimeFormatInfo.MonthNames
-- DateTimeFormatInfo.GetMonthName()
-- DateTimeFormatInfo.NativeCalendarName
-- DateTimeFormatInfo.PMDesignator
-- DateTimeFormatInfo.ShortDatePattern
-- DateTimeFormatInfo.ShortestDayNames
-- DateTimeFormatInfo.GetShortestDayName()
-- DateTimeFormatInfo.ShortTimePattern
-- DateTimeFormatInfo.YearMonthPattern
-
-
-The Hybrid responses may differ because they use Web API functions. To better ilustrate the mechanism we provide an example for each endpoint. All exceptions cannot be listed, for reference check the response of specific version of Web API on your host.
-| **API** | **Functions used** | **Example of difference for locale** | **non-Hybrid** | **Hybrid** |
-|:-----------------------------:|:----------------------------------------------------------------------------------------------------------------------------------:|:------------------------------------:|:------------------:|:-----------------:|
-| AbbreviatedDayNames | `Date.prototype.toLocaleDateString(locale, { weekday: "short" })` | en-CA | Sun. | Sun |
-| AbbreviatedMonthGenitiveNames | `Date.prototype.toLocaleDateString(locale, { month: "short", day: "numeric"})` | kn-IN | ಆಗ | ಆಗಸ್ಟ್ |
-| AbbreviatedMonthNames | `Date.prototype.toLocaleDateString(locale, { month: "short" })` | lt-LT | saus. | 01 |
-| AMDesignator | `Date.prototype.toLocaleTimeString(locale, { hourCycle: "h12"})`; `Date.prototype.toLocaleTimeString(locale, { hourCycle: "h24"})` | sr-Cyrl-RS | пре подне | AM |
-| CalendarWeekRule | `Intl.Locale.prototype.getWeekInfo().minimalDay` | none | - | - |
-| DayNames | `Date.prototype.toLocaleDateString(locale, { weekday: "long" })` | none | - | - |
-| GetAbbreviatedEraName() | `Date.prototype.toLocaleDateString(locale, { era: "narrow" })` | bn-IN | খৃষ্টাব্দ | খ্রিঃ |
-| GetEraName() | `Date.prototype.toLocaleDateString(locale, { era: "short" })` | vi-VI | sau CN | CN |
-| FirstDayOfWeek | `Intl.Locale.prototype.getWeekInfo().firstDay` | zn-CN | Sunday | Monday |
-| FullDateTimePattern | `LongDatePattern` and `LongTimePattern` | - | | |
-| LongDatePattern | `Intl.DateTimeFormat(locale, { weekday: "long", year: "numeric", month: "long", day: "numeric"}).format(date)` | en-BW | dddd, dd MMMM yyyy | dddd, d MMMM yyyy |
-| LongTimePattern | `Intl.DateTimeFormat(locale, { timeStyle: "medium" })` | zn-CN | tth:mm:ss | HH:mm:ss |
-| MonthDayPattern | `Date.prototype.toLocaleDateString(locale, { month: "long", day: "numeric"})` | en-PH | d MMMM | MMMM d |
-| MonthGenitiveNames | `Date.prototype.toLocaleDateString(locale, { month: "long", day: "numeric"})` | ca-AD | de gener | gener |
-| MonthNames | `Date.prototype.toLocaleDateString(locale, { month: "long" })` | el-GR | Ιανουαρίου | Ιανουάριος |
-| NativeCalendarName | `Intl.Locale.prototype.getCalendars()` | for all locales it has English names | Gregorian Calendar | gregory |
-| PMDesignator | `Date.prototype.toLocaleTimeString(locale, { hourCycle: "h12"})`; `Date.prototype.toLocaleTimeString(locale, { hourCycle: "h24"})` | mr-IN | म.उ. | PM |
-| ShortDatePattern | `Date.prototype.toLocaleDateString(locale, {dateStyle: "short"})` | en-CH | dd.MM.yyyy | dd/MM/yyyy |
-| ShortestDayNames | `Date.prototype.toLocaleDateString(locale, { weekday: "narrow" })` | none | - | - |
-| ShortTimePattern | `Intl.DateTimeFormat(locale, { timeStyle: "medium" })` | bg-BG | HH:mm | H:mm |
-| YearMonthPattern | `Date.prototype.toLocaleDateString(locale, { year: "numeric", month: "long" })` | ar-SA | MMMM yyyy | MMMM yyyy g |
-
### Apple platforms
For Apple platforms (iOS/tvOS/maccatalyst) we are using native apis instead of ICU data.
diff --git a/docs/design/mono/diagnostics-tracing.md b/docs/design/mono/diagnostics-tracing.md
index 898ea1a3a96ff4..6485a25d241c62 100644
--- a/docs/design/mono/diagnostics-tracing.md
+++ b/docs/design/mono/diagnostics-tracing.md
@@ -6,7 +6,7 @@ MonoVM includes support for EventPipe and DiagnosticServer components used to ge
## Scenarios
-.Net supports several different EventPipe scenarios using tools mainly from diagnostics repository. MonoVM include support for several of these scenarios, running tools like `dotnet-counters` and `dotnet-trace` to collect and analyze runtime performance data. Other things like requesting a core/gc dump or attaching profiler over EventPipe is currently not supported on MonoVM.
+.NET supports several different EventPipe scenarios using tools mainly from diagnostics repository. MonoVM include support for several of these scenarios, running tools like `dotnet-counters` and `dotnet-trace` to collect and analyze runtime performance data. Other things like requesting a core dump or attaching profiler over EventPipe is currently not supported on MonoVM.
Due to differences between runtimes many of the NativeRuntimeEvents won't apply to MonoVM. Only a selected amount of NativeRuntimeEvents will initially be added to MonoVM. Current supported NativeRuntimeEvents can be viewed in MonoVM include file, https://github.com/dotnet/runtime/blob/main/src/mono/mono/eventpipe/gen-eventing-event-inc.lst. Since primary focus is EventPipe and mobile platforms (iOS/Android), ETW and LTTng providers have currently not been integrated/enabled for NativeRuntimeEvents on MonoVM.
@@ -95,17 +95,13 @@ On the other hand, if it is desired to include all components, there are two opt
true
```
-## Install diagnostic client tooling
-```
-dotnet tool install -g dotnet-trace --add-source=https://aka.ms/dotnet-tools/index.json
-dotnet tool install -g dotnet-counters --add-source=https://aka.ms/dotnet-tools/index.json
-```
-
-`dotnet-dsrouter` is still installed from preview source:
+## Install diagnostic client tooling
-```
-dotnet tool install -g dotnet-dsrouter --add-source=https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json
+```sh
+$ dotnet tool install -g dotnet-trace --add-source=https://aka.ms/dotnet-tools/index.json
+$ dotnet tool install -g dotnet-counters --add-source=https://aka.ms/dotnet-tools/index.json
+$ dotnet tool install -g dotnet-dsrouter --add-source=https://aka.ms/dotnet-tools/index.json
```
If tools have already been installed, they can all be updated to latest version using `update` keyword instead of `install` keyword.
@@ -122,7 +118,54 @@ Prerequisites when running below diagnostic scenarios:
* If anything EventSource related is used, make sure EventSourceSupport is enabled when building application (or ILLinker can remove needed EventSource classes). If just running tracing, collecting native EventPipe events emitted by SampleProfiler, DotNetRuntime or MonoProfiler providers, EventSourceSupport can be enabled or disabled.
* Install needed diagnostic tooling on development machine.
-### Application running diagnostics and connecting over loopback interface
+### Application running diagnostics using default .NET 8 configuration
+
+Starting in .NET 8, enhancements to `dotnet-dsrouter` supporting most of below described scenarios, using a smaller subset of available configurations using loopback interface on emulators/simulators and physical devices attached over usb. `dotnet-dsrouter` outputs detailed information on how to launch runtime as well as connect to the instance using diagnostic tooling.
+
+Starting `dotnet-dsrouter` to trace an application running on iOS simulator could be done using the `ios-sim` profile:
+
+```sh
+$ dotnet-dsrouter ios-sim -i
+WARNING: dotnet-dsrouter is a development tool not intended for production environments.
+
+How to connect current dotnet-dsrouter pid=26600 with iOS simulator and diagnostics tooling.
+Start an application on iOS simulator with ONE of the following environment variables set:
+[Default Tracing]
+DOTNET_DiagnosticPorts=127.0.0.1:9000,nosuspend,listen
+[Startup Tracing]
+DOTNET_DiagnosticPorts=127.0.0.1:9000,suspend,listen
+Run diagnostic tool connecting application on iOS simulator through dotnet-dsrouter pid=26600:
+dotnet-trace collect -p 26600
+See https://learn.microsoft.com/en-us/dotnet/core/diagnostics/dotnet-dsrouter for additional details and examples.
+
+info: dotnet-dsrouter-26600[0]
+ Starting dotnet-dsrouter using pid=26600
+info: dotnet-dsrouter-26600[0]
+ Starting IPC server (dotnet-diagnostic-dsrouter-26600) <--> TCP client (127.0.0.1:9000) router.
+```
+
+Using `-i` outputs enough details on how to configure the `DOTNET_DiagnosticPorts` when launching the application depending on default or startup tracing needs as well as how to run diagnostic tooling against the specific `dotnet-dsrouter` instance.
+
+For example, running default tracing together with above `dotnet-dsrouter` instance, set `DOTNET_DiagnosticPorts=127.0.0.1:9000,nosuspend,listen` environment variable for the launched application running on iOS simulator and then run diagnostic tooling using pid of running `dotnet-dsrouter`:
+
+```sh
+$ dotnet-trace collect -p 26600
+```
+
+Changing the environment variable for launched application to `DOTNET_DiagnosticPorts=127.0.0.1:9000,suspend,listen` will enable startup tracing using above `dotnet-dsrouter` instance.
+
+.NET 8 version of `dotnet-dsrouter` supports the following profiles that could be used when running diagnostic tool against iOS/Android simulator/emulator/devices:
+
+ * `ios-sim`
+ * `ios`
+ * `android-emu`
+ * `android`
+
+ Running profiles with `-i` gives detailed info on how to launch application and diagnostic tooling together with `dotnet-dsrouter`.
+
+In case the default profiles described above are too limited, the following sections describes all low level configuration details and options needed to trace applications on iOS/Android using `dotnet-dsrouter`.
+
+#### Application running diagnostics using custom configuration on simulator/emulator
Starting up application using `DOTNET_DiagnosticPorts=127.0.0.1:9000,nosuspend` on iOS, or `DOTNET_DiagnosticPorts=10.0.2.2:9000,nosuspend` on Android, will connect to `dotnet-dsrouter` listening on loopback port 9000 (can be any available port) on local machine. Once runtime is connected, it is possible to connect diagnostic tools like `dotnet-counters`, `dotnet-trace`, towards `dotnet-dsrouter` local IPC interface. To include startup events in EventPipe sessions, change `nosuspend` to `suspend` and runtime startup and wait for diagnostic tooling to connect before resuming.
@@ -140,8 +183,6 @@ https://developer.android.com/studio/command-line/adb#forwardports
On IOS, `--forward-port` works in the scenario where DiagnosticServer runs in listening mode on device (connected over usb) using loopback interface.
-Latest enhancements to `dotnet-dsrouter` have opened opportunity to run most of below described scenarios, using a smaller subset of available configurations using loopback interface on emulators/simulators and physical devices attached over usb.
-
Runtime configuration:
`DIAGNOSTIC_PORTS=127.0.0.1:9000,suspend|nosuspend,listen`
@@ -152,178 +193,266 @@ Use `nosuspend` keyword if runtime do regular startup, not waiting for any diagn
When running towards Android emulator or device (connected over usb):
-```
-dotnet-dsrouter server-client -ipcs ~/myport -tcpc 127.0.0.1:9000 --forward-port Android
+```sh
+$ dotnet-dsrouter server-client -ipcs ~/myport -tcpc 127.0.0.1:9000 --forward-port Android
```
When running towards iOS simulator:
-```
-dotnet-dsrouter server-client -ipcs ~/myport -tcpc 127.0.0.1:9000
+```sh
+$ dotnet-dsrouter server-client -ipcs ~/myport -tcpc 127.0.0.1:9000
```
When running towards iOS device (connected over usb):
-```
-dotnet-dsrouter server-client -ipcs ~/myport -tcpc 127.0.0.1:9000 --forward-port iOS
+```sh
+$ dotnet-dsrouter server-client -ipcs ~/myport -tcpc 127.0.0.1:9000 --forward-port iOS
```
Run diagnostic tooling like this, regardless of `suspend|nosuspend`, `Android|iOS` or `simulator|emulator|device` scenarios are being used:
-```
-dotnet-trace collect --diagnostic-port ~/myport,connect
+```sh
+$ dotnet-trace collect --diagnostic-port ~/myport,connect
```
or
+```sh
+$ dotnet-counters monitor --diagnostic-port ~/myport,connect
```
-dotnet-counters monitor --diagnostic-port ~/myport,connect
-```
+
+Android and iOS SDK's have documented similar steps on how to setup profiling/tracing:
+
+https://github.com/xamarin/xamarin-android/blob/main/Documentation/guides/tracing.md
+
+https://github.com/xamarin/xamarin-macios/wiki/Profiling
#### Example using dotnet-counters using sample app on iOS simulator
+`dotnet-dsrouter` needs to run using a compatible configuration depending on scenario. Either launch a new instance for every run or have a background instance running over several sessions using same configuration.
+
+##### Default .NET 8 configuration:
+
Make sure the following is enabled in https://github.com/dotnet/runtime/blob/main/src/mono/sample/iOS/Makefile,
-```
+```Makefile
RUNTIME_COMPONENTS=diagnostics_tracing
-DIAGNOSTIC_PORTS=127.0.0.1:9000,nosuspend
+DIAGNOSTIC_PORTS=127.0.0.1:9000,nosuspend,listen
```
-`dotnet-dsrouter` needs to run using a compatible configuration depending on scenario. Either launch a new instance for every run or have a background instance running over several sessions using same configuration.
+```sh
+$ dotnet-dsrouter ios-sim &
+```
+```sh
+$ dotnet-counters monitor -p
```
-dotnet-dsrouter server-server -ipcs ~/myport -tcps 127.0.0.1:9000 &
+
+##### Custom configuration:
+
+Make sure the following is enabled in https://github.com/dotnet/runtime/blob/main/src/mono/sample/iOS/Makefile,
+
+```Makefile
+RUNTIME_COMPONENTS=diagnostics_tracing
+DIAGNOSTIC_PORTS=127.0.0.1:9000,nosuspend
```
+```sh
+$ dotnet-dsrouter server-server -ipcs ~/myport -tcps 127.0.0.1:9000 &
```
+
+```sh
cd src/mono/sample/iOS/
-make run-sim
+$ make run-sim
```
-```
-dotnet-counters monitor --diagnostic-port ~/myport,connect
+```sh
+$ dotnet-counters monitor --diagnostic-port ~/myport,connect
```
#### Example using dotnet-counters using sample app on Android emulator
+`dotnet-dsrouter` needs to run using a compatible configuration depending on scenario. Either launch a new instance for every run or have a background instance running over several sessions using same configuration.
+
+##### Default .NET 8 configuration:
+
Make sure the following is enabled in https://github.com/dotnet/runtime/blob/main/src/mono/sample/Android/Makefile,
-```
+```Makefile
RUNTIME_COMPONENTS=diagnostics_tracing
-DIAGNOSTIC_PORTS=10.0.2.2:9000,nosuspend
+DIAGNOSTIC_PORTS=10.0.2.2:9000,nosuspend,connect
```
-`dotnet-dsrouter` needs to run using a compatible configuration depending on scenario. Either launch a new instance for every run or have a background instance running over several sessions using same configuration.
+```sh
+$ dotnet-dsrouter android-emu &
+```
+
+```sh
+cd src/mono/sample/Android/
+$ make run
+```
+```sh
+$ dotnet-counters monitor -p
```
-dotnet-dsrouter server-server -ipcs ~/myport -tcps 10.0.2.2:9000 &
+
+##### Custom configuration:
+
+Make sure the following is enabled in https://github.com/dotnet/runtime/blob/main/src/mono/sample/Android/Makefile,
+
+```Makefile
+RUNTIME_COMPONENTS=diagnostics_tracing
+DIAGNOSTIC_PORTS=10.0.2.2:9000,nosuspend
```
+```sh
+$ dotnet-dsrouter server-server -ipcs ~/myport -tcps 10.0.2.2:9000 &
```
+
+```sh
cd src/mono/sample/Android/
-make run
+$ make run
```
-```
-dotnet-counters monitor --diagnostic-port ~/myport,connect
+```sh
+$ dotnet-counters monitor --diagnostic-port ~/myport,connect
```
Using `adb` port forwarding it is possible to use `127.0.0.1:9000` in above scenario and adding `--forward-port Android` to `dotnet-dsrouter` launch arguments. That will automatically run needed `adb` commands. NOTE, `dotnet-dsrouter` needs to find `adb` tool for this to work, see above for more details.
#### Example using dotnet-trace startup tracing using sample app on iOS simulator
+`dotnet-dsrouter` needs to run using a compatible configuration depending on scenario. Either launch a new instance for every run or have a background instance running over several sessions using same configuration.
+
+##### Default .NET 8 configuration:
+
Make sure the following is enabled in https://github.com/dotnet/runtime/blob/main/src/mono/sample/iOS/Makefile,
-```
+```Makefile
RUNTIME_COMPONENTS=diagnostics_tracing
-DIAGNOSTIC_PORTS=127.0.0.1:9000,suspend
+DIAGNOSTIC_PORTS=127.0.0.1:9000,suspend,listen
```
-`dotnet-dsrouter` needs to run using a compatible configuration depending on scenario. Either launch a new instance for every run or have a background instance running over several sessions using same configuration.
-
+```sh
+$ dotnet-dsrouter ios-sim &
```
-dotnet-dsrouter client-server -tcpc ~/myport -tcps 127.0.0.1:9000 &
+
+```sh
+$ dotnet-counters monitor -p
```
+##### Custom configuration:
+
+Make sure the following is enabled in https://github.com/dotnet/runtime/blob/main/src/mono/sample/iOS/Makefile,
+
+```Makefile
+RUNTIME_COMPONENTS=diagnostics_tracing
+DIAGNOSTIC_PORTS=127.0.0.1:9000,suspend
```
-dotnet-trace collect --diagnostic-port ~/myport
+
+```sh
+$ dotnet-dsrouter client-server -tcpc ~/myport -tcps 127.0.0.1:9000 &
```
+```sh
+$ dotnet-trace collect --diagnostic-port ~/myport
```
+
+```sh
cd src/mono/sample/iOS/
-make run-sim
+$ make run-sim
```
Since `dotnet-dsrouter` is capable to run several different modes, it is also possible to do startup tracing using server-server mode.
Make sure the following is enabled in https://github.com/dotnet/runtime/blob/main/src/mono/sample/iOS/Makefile,
-```
+```Makefile
RUNTIME_COMPONENTS=diagnostics_tracing
DIAGNOSTIC_PORTS=127.0.0.1:9000,suspend
```
-`dotnet-dsrouter` needs to run using a compatible configuration depending on scenario. Either launch a new instance for every run or have a background instance running over several sessions using same configuration.
-
-```
-dotnet-dsrouter server-server -ipcs ~/myport -tcps 127.0.0.1:9000 &
+```sh
+$ dotnet-dsrouter server-server -ipcs ~/myport -tcps 127.0.0.1:9000 &
```
-```
+```sh
cd src/mono/sample/iOS/
-make run-sim
+$ make run-sim
```
-```
-dotnet-trace collect --diagnostic-port ~/myport,connect
+```sh
+$ dotnet-trace collect --diagnostic-port ~/myport,connect
```
#### Example using dotnet-trace startup tracing using sample app on Android emulator
+`dotnet-dsrouter` needs to run using a compatible configuration depending on scenario. Either launch a new instance for every run or have a background instance running over several sessions using same configuration.
+
+##### Default .NET 8 configuration:
+
Make sure the following is enabled in https://github.com/dotnet/runtime/blob/main/src/mono/sample/Android/Makefile,
-```
+```Makefile
RUNTIME_COMPONENTS=diagnostics_tracing
-DIAGNOSTIC_PORTS=10.0.2.2:9000,suspend
+DIAGNOSTIC_PORTS=10.0.2.2:9000,suspend,connect
```
-`dotnet-dsrouter` needs to run using a compatible configuration depending on scenario. Either launch a new instance for every run or have a background instance running over several sessions using same configuration.
+```sh
+$ dotnet-dsrouter android-emu &
+```
+```sh
+cd src/mono/sample/Android/
+$ make run
```
-dotnet-dsrouter client-server -tcpc ~/myport -tcps 127.0.0.1:9000 &
+
+```sh
+$ dotnet-counters monitor -p
```
+##### Custom configuration:
+
+Make sure the following is enabled in https://github.com/dotnet/runtime/blob/main/src/mono/sample/Android/Makefile,
+
+```Makefile
+RUNTIME_COMPONENTS=diagnostics_tracing
+DIAGNOSTIC_PORTS=10.0.2.2:9000,suspend
```
-dotnet-trace collect --diagnostic-port ~/myport
+
+```sh
+$ dotnet-dsrouter client-server -tcpc ~/myport -tcps 127.0.0.1:9000 &
```
+```sh
+$ dotnet-trace collect --diagnostic-port ~/myport
```
+
+```sh
cd src/mono/sample/Android/
-make run
+$ make run
```
Since `dotnet-dsrouter` is capable to run several different modes, it is also possible to do startup tracing using server-server mode.
Make sure the following is enabled in https://github.com/dotnet/runtime/blob/main/src/mono/sample/Android/Makefile,
-```
+```Makefile
RUNTIME_COMPONENTS=diagnostics_tracing
DIAGNOSTIC_PORTS=10.0.2.2:9000,suspend
```
-`dotnet-dsrouter` needs to run using a compatible configuration depending on scenario. Either launch a new instance for every run or have a background instance running over several sessions using same configuration.
-
-```
-dotnet-dsrouter server-server -ipcs ~/myport -tcps 10.0.2.2:9000 &
+```sh
+$ dotnet-dsrouter server-server -ipcs ~/myport -tcps 10.0.2.2:9000 &
```
-```
+```sh
cd src/mono/sample/Android/
-make run
+$ make run
```
-```
-dotnet-trace collect --diagnostic-port ~/myport,connect
+```sh
+$ dotnet-trace collect --diagnostic-port ~/myport,connect
```
Using `adb` port forwarding it is possible to use `127.0.0.1:9000` in above scenario and adding `--forward-port Android` to `dotnet-dsrouter` launch arguments. That will automatically run needed `adb` commands. NOTE, `dotnet-dsrouter` needs to find `adb` tool for this to work, see above for more details.
@@ -338,81 +467,111 @@ Below scenarios uses loopback interface together with device connected to develo
#### Android
-Launch application using the following environment variable set, `DIAGNOSTIC_PORTS=127.0.0.1:9000,suspend`
-
`dotnet-dsrouter` needs to run using a compatible configuration depending on scenario. Either launch a new instance for every run or have a background instance running over several sessions using same configuration.
-```
-dotnet-dsrouter server-server -ipcs ~/myport -tcps 127.0.0.1:9000 --forward-port Android &
+##### Default .NET 8 configuration:
+
+Launch application using the following environment variable set, `DIAGNOSTIC_PORTS=127.0.0.1:9000,suspend,connect`
+
+```sh
+$ dotnet-dsrouter android &
```
Run application on device connected over usb.
+```sh
+$ dotnet-trace collect -p
+```
+
+##### Custom configuration:
+
+Launch application using the following environment variable set, `DIAGNOSTIC_PORTS=127.0.0.1:9000,suspend`
+
+```sh
+$ dotnet-dsrouter server-server -ipcs ~/myport -tcps 127.0.0.1:9000 --forward-port Android &
```
-dotnet-trace collect --diagnostic-port ~/myport,connect
+
+Run application on device connected over usb.
+
+```sh
+$ dotnet-trace collect --diagnostic-port ~/myport,connect
```
The same scenario could be run pushing the TCP/IP listener over to device. Following changes needs to be done to above configuration:
`DIAGNOSTIC_PORTS=127.0.0.1:9000,suspend,listen`
-```
-dotnet-dsrouter server-client -ipcs ~/myport -tcpc 127.0.0.1:9000 --forward-port Android &
+```sh
+$ dotnet-dsrouter server-client -ipcs ~/myport -tcpc 127.0.0.1:9000 --forward-port Android &
```
#### iOS
-Launch application using the following environment variable set, `DIAGNOSTIC_PORTS=*:9000,suspend,listen`
-
`dotnet-dsrouter` needs to run using a compatible configuration depending on scenario. Either launch a new instance for every run or have a background instance running over several sessions using same configuration.
-```
-dotnet-dsrouter server-client -ipcs ~/myport -tcpc 127.0.0.1:9000 --forward-port iOS &
+##### Default .NET 8 configuration:
+
+Launch application using the following environment variable set, `DIAGNOSTIC_PORTS=127.0.0.1:9000,suspend,listen`
+
+```sh
+$ dotnet-dsrouter ios &
```
Run application on device connected over usb.
+```sh
+$ dotnet-trace collect -p
+```
+
+##### Custom configuration:
+
+Launch application using the following environment variable set, `DIAGNOSTIC_PORTS=*:9000,suspend,listen`
+
+```sh
+$ dotnet-dsrouter server-client -ipcs ~/myport -tcpc 127.0.0.1:9000 --forward-port iOS &
```
-dotnet-trace collect --diagnostic-port ~/myport,connect
+
+Run application on device connected over usb.
+
+```sh
+$ dotnet-trace collect --diagnostic-port ~/myport,connect
```
NOTE, iOS only support use of loopback interface when running DiagnosticServer in listening mode on device and using `dotnet-dsrouter` in server-client (IPC Server, TCP/IP client) with port forwarding.
### Application running single file based EventPipe session
-If application supports controlled runtime shutdown, `mono_jit_cleanup` gets called before terminating process, it is possible to run a single file based EventPipe session using environment variables as described in https://learn.microsoft.com/dotnet/core/diagnostics/eventpipe#trace-using-environment-variables. In .net6 an additional variable has been added, `DOTNET_EventPipeOutputStreaming`, making sure data is periodically flushed into the output file.
+If application supports controlled runtime shutdown, `mono_jit_cleanup` gets called before terminating process, it is possible to run a single file based EventPipe session using environment variables as described in https://learn.microsoft.com/dotnet/core/diagnostics/eventpipe#trace-using-environment-variables. In .NET 6 an additional variable has been added, `DOTNET_EventPipeOutputStreaming`, making sure data is periodically flushed into the output file.
If application doesn't support controlled runtime shutdown, this mode won't work, since it requires rundown events, only emitted when closing session and flushing memory manager. If application doesn't call `mono_jit_cleanup` before terminating, generated nettrace file will lack rundown events needed to produce callstacks including symbols.
Running using single file based EventPipe session will produce a file in working directory. Use platform specific tooling to extract file once application has terminated. Since file based EventPipe session doesn't use diagnostic server, there is no need to use `DOTNET_DiagnosticPorts` or running `dotnet-dsrouter`.
-### Analyze JIT/Loader events during startup.
+### Analyze JIT/Loader events during startup
Increasing the default log level in `dotnet-trace` for `Microsoft-Windows-DotNETRuntime` provider will include additional events in nettrace file giving more details around JIT and loader activities, like all loaded assemblies, loaded types, loaded/JIT:ed methods as well as timing and size metrics, all valuable information when analyzing things like startup performance, size of loaded/JIT:ed methods, time it takes to JIT all, subset or individual methods etc. To instruct `dotnet-trace` to only collect `Microsoft-Windows-DotNETRuntime` events during startup, use one of that startup tracing scenarios as described above, but add the following parameters to `dotnet-trace`,
-```
---clreventlevel verbose --providers Microsoft-Windows-DotNETRuntime
-```
+`--clreventlevel verbose --providers Microsoft-Windows-DotNETRuntime`
`Prefview` have built in analyzers for JIT/Loader stats, so either load resulting nettrace file in `Perfview` or analyze file using custom `TraceEvent` parsers.
-### Trace MonoVM Profiler events during startup.
+### Trace MonoVM profiler events during startup
+
+Starting with .NET 8 the experimental profiler provider, `Microsoft-DotNETRuntimeMonoProfiler`, has been disabled by default. In order to enable it, the following needs to be added to MonoVM specific environment variable:
+
+`MONO_DIAGNOSTICS=--diagnostic-mono-profiler=enable`
-MonoVM comes with a EventPipe provider mapping most of low-level Mono profiler events into native EventPipe events thought `Microsoft-DotNETRuntimeMonoProfiler`. Mainly this provider exists to simplify transition from old MonoVM log profiler over to nettrace, but it also adds a couple of features available in MonoVM profiler as well as ability to take heap shots over EventPipe when running on MonoVM (current dotnet-gcdump is tied to events emitted by CoreCLR GC and currently not supported on MonoVM).
+MonoVM comes with a EventPipe provider mapping most of low-level Mono profiler events into native EventPipe events thought `Microsoft-DotNETRuntimeMonoProfiler`. Mainly this provider exists to simplify transition from old MonoVM log profiler over to nettrace, but it also adds a couple of features available in MonoVM profiler.
Mono profiler includes the concept of method tracing and have support for method enter/leave events (method execution timing). This can be used when running in JIT/Interpreter mode (for AOT it needs to be passed to MonoVM AOT compiler). Enable enter/leave can produce a large set of events so there might be a risk hitting buffer manager size limits, temporary dropping events. This can be mitigated by either increasing buffer manager memory limit or reduce the number of instrumented methods. Since enter/leave needs instrumentation it must be enabled when a method is JIT:ed.
Method tracing can be controlled using a keyword in the MonoProfiler provider, but if an EventPipe session is not running when a method gets JIT:ed, it won't be instrumented and will not fire any enter/leave events. 0x20000000 will start to capture enter/leave events and 0x40000000000 can be used to enable instrumentation including all methods JIT:ed during lifetime of EventPipe session. To make sure all needed methods gets instrumented, runtime should be configured using startup profiling (as described above) and `dotnet-trace` should be run using the following provider configuration,
-```
---providers Microsoft-DotNETRuntimeMonoProfiler:0x40020000000;4
-```
+`--providers Microsoft-DotNETRuntimeMonoProfiler:0x40020000000;4`
To fully control the instrumentation (not depend on running EventPipe session), there is a MonoVM specific environment variable that can be set:
-```
-MONO_DIAGNOSTICS=--diagnostic-mono-profiler-callspec=
-```
+`MONO_DIAGNOSTICS=--diagnostic-mono-profiler-callspec=`
That will enable enter/leave profiling for all JIT:ed methods matching callspec. Callspec uses MonoVM callspec format:
@@ -432,35 +591,33 @@ It is possible to combine include and exclude expressions using `,` as separator
Trace all methods, except methods belonging to `System.Int32` type.
-```
-MONO_DIAGNOSTICS=--diagnostic-mono-profiler-callspec=all,-T:System.Int32
-```
+`MONO_DIAGNOSTICS=--diagnostic-mono-profiler-callspec=all,-T:System.Int32`
Trace all methods in `Program` type.
-```
-MONO_DIAGNOSTICS=--diagnostic-mono-profiler-callspec=T:Program
-```
+`MONO_DIAGNOSTICS=--diagnostic-mono-profiler-callspec=T:Program`
If no EventPipe session is running using MonoProfiler provider with method tracing keyword, no events will be emitted, even if running methods have been instrumented using `MONO_DIAGNOSTICS`.
When instrumenting methods using `MONO_DIAGNOSTICS`, it is possible to run `dotnet-trace` using the following provider configuration,
-```
---providers Microsoft-DotNETRuntimeMonoProfiler:0x20000000:4
-```
+`--providers Microsoft-DotNETRuntimeMonoProfiler:0x20000000:4`
Since all methods matching callspec will be instrumented it is possible to capture enter/leave events only when needed at any time during application lifetime.
A way to effectively use this precise profiling is to first run with SampleProfiler provider, identifying hot paths worth additional investigation and then enable tracing using a matching callspec and trace execution of methods using MonoProfiler provider tracing keyword. It is of course possible to do enter/leave profiling during startup as well (using callspec or provider enabled instrumentation), just keep in mind that it can produce many events, especially in case when no callspec is in use.
-### Collect GC dumps on MonoVM.
+NOTE, EventPipe technology comes with an overhead emitting events that will have impact on enter/leave measurements. If more precise instrumentation is needed it is recommended to implement a Mono profiler provider handling the enter/leave callbacks directly.
+
+### Collect GC dumps on MonoVM .NET 8
+
+Starting with .NET 8 MonoVM support GC dumps functionality using tools like `dotnet-gcdump`. No need to use `Microsoft-DotNETRuntimeMonoProfiler` or custom tooling to analyze GC dumps. For more information capturing GC dumps on MonoVM, see https://learn.microsoft.com/en-us/dotnet/core/diagnostics/dotnet-gcdump.
+
+### Collect GC dumps on MonoVM pre .NET 8
MonoVM EventPipe provider `Microsoft-DotNETRuntimeMonoProfiler`, includes several GC related events that can be used to track allocations, roots and other GC events as well as generating GC heap dumps. Heap dumps can be requested on demand using `dotnet-trace` using the following provider configuration,
-```
---providers Microsoft-DotNETRuntimeMonoProfiler:0x8900001:4
-```
+`--providers Microsoft-DotNETRuntimeMonoProfiler:0x8900001:4`
This will trigger a heap dump including object references, object type info and GC events that can be used to detect when dump starts and completes (to know when to end EventPipe session). If `dotnet-trace` is used, there is no clear indication when full dump has been completed but looking at the stream size counter will indicate when no more data gets written into stream and session can be closed.
@@ -470,22 +627,16 @@ It is also possible to get details about roots registration/deregistration, hand
To track GC allocations with callstack, it needs to be enabled when starting up application using an environment variable:
-```
-MONO_DIAGNOSTICS=--diagnostic-mono-profiler=alloc
-```
+`MONO_DIAGNOSTICS=--diagnostic-mono-profiler=alloc`
NOTE, this affects runtime performance since it will change the underlying allocator. It however won't emit any events until an EventPipe session has been created with keywords enabling allocation tracking,
-```
---providers Microsoft-DotNETRuntimeMonoProfiler:0x200000:4
-```
+`--providers Microsoft-DotNETRuntimeMonoProfiler:0x200000:4`
It is also possible to setup one EventPipe session running over longer periods of time, getting all requested GC events, including multiple heap dumps. A different EventPipe session can be used to trigger heap dumps on demand, but that session
won't get any additional events, just trigger a heap dump.
-```
---providers Microsoft-DotNETRuntimeMonoProfiler:0x800000:4
-```
+`--providers Microsoft-DotNETRuntimeMonoProfiler:0x800000:4`
Combining different sessions including different GC information opens up ability to track all GC allocations during a specific time period (to reduce size of captured data), while taking heap dumps into separate sessions, make it possible to do full analysis of GC memory increase/decrease tied allocation callstacks for individual object instances.
@@ -507,7 +658,7 @@ Using the diagnostic client library gives full flexibility to use data in nettra
TraceEvent library, https://www.nuget.org/packages/Microsoft.Diagnostics.Tracing.TraceEvent/ can be used to implement custom nettrace parsers.
-https://github.com/lateralusX/diagnostics-nettrace-samples includes a couple of custom tools (startup tracing, instrumented method execution, GC heap dump analysis) analyzing nettrace files using TraceEvent library.
+https://github.com/lateralusX/diagnostics-nettrace-samples includes a couple of custom tools (startup tracing, instrumented method execution, pre .NET 8 MonoVM GC heap dump analysis) analyzing nettrace files using TraceEvent library.
## Developing EventPipe/DiagnosticServer on MonoVM
@@ -515,4 +666,4 @@ https://github.com/lateralusX/diagnostics-nettrace-samples includes a couple of
** TODO **: How to add a new NativeRuntimeEvent.
-** TODO **: How to add a new component API.
+** TODO **: How to add a new component API.
\ No newline at end of file
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index 70c0a792543b35..e588f7a1ef49a1 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -376,17 +376,17 @@
https://github.com/dotnet/runtime-assets
4daef9f8f673c1d0bbec273f2bcda1ab9074ef75
-
+
https://github.com/dotnet/roslyn
- 94fff7ad4f11977f903f435b0d97dcf0f2183710
+ 86d60f7a00b0274a806a40afde8801a89d27e6bc
-
+
https://github.com/dotnet/roslyn
- 94fff7ad4f11977f903f435b0d97dcf0f2183710
+ 86d60f7a00b0274a806a40afde8801a89d27e6bc
-
+
https://github.com/dotnet/roslyn
- 94fff7ad4f11977f903f435b0d97dcf0f2183710
+ 86d60f7a00b0274a806a40afde8801a89d27e6bc
https://github.com/dotnet/roslyn-analyzers
@@ -397,9 +397,9 @@
5435ba7b1037f21237adc1b3845f97e9fdbc075d
-
+
https://github.com/dotnet/roslyn
- 94fff7ad4f11977f903f435b0d97dcf0f2183710
+ 86d60f7a00b0274a806a40afde8801a89d27e6bc
diff --git a/eng/Versions.props b/eng/Versions.props
index b762a76e6910cd..788fd0df01aa64 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -43,9 +43,9 @@
Any tools that contribute to the design-time experience should use the MicrosoftCodeAnalysisVersion_LatestVS property above to ensure
they do not break the local dev experience.
-->
- 4.13.0-2.24570.4
- 4.13.0-2.24570.4
- 4.13.0-2.24570.4
+ 4.13.0-3.24611.10
+ 4.13.0-3.24611.10
+ 4.13.0-3.24611.10
-
- - HybridGlobalization
- $(HybridGlobalizationPath)
@@ -51,48 +46,48 @@
-
+
$(WorkItemDirectory)
cd $(BlazorMinDirectory) && $(PublishCommand) && $(Python) test.py sod --scenario-name "%(Identity)" $(ScenarioArgs)
-
+
$(WorkItemDirectory)
cd $(BlazorMinAOTDirectory) && $(PublishCommand) && $(Python) test.py sod --scenario-name "%(Identity)" $(ScenarioArgs)
00:30
-
+
$(WorkItemDirectory)
cd $(BlazorDirectory) && $(PublishCommand) && $(Python) test.py sod --scenario-name "%(Identity)" $(ScenarioArgs)
$(Python) post.py --readonly-dotnet
-
+
$(WorkItemDirectory)
cd $(BlazorAOTDirectory) && $(PublishCommand) && $(Python) test.py sod --scenario-name "%(Identity)" $(ScenarioArgs)
$(Python) post.py --readonly-dotnet
00:30
-
+
$(WorkItemDirectory)
cd $(BlazorPizzaDirectory) && $(PublishCommand) -f $(PerflabTargetFrameworks) && $(Python) test.py sod --scenario-name "%(Identity)" --dirs $(PizzaAppPubLocation) $(ScenarioArgs)
$(Python) post.py --readonly-dotnet
-
+
$(WorkItemDirectory)
cd $(BlazorPizzaAOTDirectory) && $(PublishCommand) -f $(PerflabTargetFrameworks) && $(Python) test.py sod --scenario-name "%(Identity)" --dirs $(PizzaAppPubLocation) $(ScenarioArgs)
$(Python) post.py --readonly-dotnet
1:00
-
+
$(WorkItemDirectory)
cd $(BlazorLocalizedDirectory) && $(PublishCommand) -f $(PerflabTargetFrameworks) && $(Python) test.py sod --scenario-name "%(Identity)" --dirs $(PizzaAppPubLocation) $(ScenarioArgs)
$(Python) post.py --readonly-dotnet
1:00
-
+
<_PublishArgsWithAOT>--msbuild "$(_MSBuildArgs);/p:RunAOTCompilation=true"
$(WorkItemDirectory)
cd $(BlazorLocalizedDirectory) && $(PublishCommand) $(_PublishArgsWithAOT) -f $(PerflabTargetFrameworks) && $(Python) test.py sod --scenario-name "%(Identity)" --dirs $(PizzaAppPubLocation) $(ScenarioArgs)
diff --git a/eng/testing/scenarios/BuildWasmAppsJobsList.txt b/eng/testing/scenarios/BuildWasmAppsJobsList.txt
index f94f6fbcaa6c1d..8df77ea901da48 100644
--- a/eng/testing/scenarios/BuildWasmAppsJobsList.txt
+++ b/eng/testing/scenarios/BuildWasmAppsJobsList.txt
@@ -3,24 +3,21 @@ Wasm.Build.NativeRebuild.Tests.NoopNativeRebuildTest
Wasm.Build.NativeRebuild.Tests.OptimizationFlagChangeTests
Wasm.Build.NativeRebuild.Tests.ReferenceNewAssemblyRebuildTest
Wasm.Build.NativeRebuild.Tests.SimpleSourceChangeRebuildTest
-Wasm.Build.Tests.TestAppScenarios.InterpPgoTests
+Wasm.Build.Tests.InterpPgoTests
Wasm.Build.Templates.Tests.NativeBuildTests
Wasm.Build.Tests.Blazor.AppsettingsTests
Wasm.Build.Tests.Blazor.BuildPublishTests
Wasm.Build.Tests.Blazor.SimpleRunTests
Wasm.Build.Tests.Blazor.CleanTests
Wasm.Build.Tests.Blazor.MiscTests
-Wasm.Build.Tests.Blazor.MiscTests2
-Wasm.Build.Tests.Blazor.MiscTests3
+Wasm.Build.Tests.Blazor.DllImportTests
Wasm.Build.Tests.Blazor.NativeTests
Wasm.Build.Tests.Blazor.NoopNativeRebuildTest
Wasm.Build.Tests.Blazor.WorkloadRequiredTests
-Wasm.Build.Tests.Blazor.IcuTests
-Wasm.Build.Tests.Blazor.IcuShardingTests
Wasm.Build.Tests.Blazor.SignalRClientTests
Wasm.Build.Tests.BuildPublishTests
Wasm.Build.Tests.ConfigSrcTests
-Wasm.Build.Tests.HybridGlobalizationTests
+Wasm.Build.Tests.DllImportTests
Wasm.Build.Tests.IcuShardingTests
Wasm.Build.Tests.IcuShardingTests2
Wasm.Build.Tests.IcuTests
@@ -33,13 +30,13 @@ Wasm.Build.Tests.NonWasmTemplateBuildTests
Wasm.Build.Tests.PInvokeTableGeneratorTests
Wasm.Build.Tests.RebuildTests
Wasm.Build.Tests.SatelliteAssembliesTests
-Wasm.Build.Tests.TestAppScenarios.AppSettingsTests
-Wasm.Build.Tests.TestAppScenarios.DownloadThenInitTests
-Wasm.Build.Tests.TestAppScenarios.LazyLoadingTests
-Wasm.Build.Tests.TestAppScenarios.LibraryInitializerTests
-Wasm.Build.Tests.TestAppScenarios.SatelliteLoadingTests
-Wasm.Build.Tests.TestAppScenarios.ModuleConfigTests
-Wasm.Build.Tests.TestAppScenarios.MemoryTests
+Wasm.Build.Tests.AppSettingsTests
+Wasm.Build.Tests.DownloadThenInitTests
+Wasm.Build.Tests.LazyLoadingTests
+Wasm.Build.Tests.LibraryInitializerTests
+Wasm.Build.Tests.SatelliteLoadingTests
+Wasm.Build.Tests.ModuleConfigTests
+Wasm.Build.Tests.MemoryTests
Wasm.Build.Tests.AspNetCore.SignalRClientTests
Wasm.Build.Tests.WasmBuildAppTest
Wasm.Build.Tests.WasmNativeDefaultsTests
diff --git a/eng/testing/tests.browser.targets b/eng/testing/tests.browser.targets
index 44c7bc6805fa80..e7029f44e21915 100644
--- a/eng/testing/tests.browser.targets
+++ b/eng/testing/tests.browser.targets
@@ -227,7 +227,6 @@
<_WasmPropertyNames Include="EmccLinkOptimizationFlag" />
<_WasmPropertyNames Include="WasmIncludeFullIcuData" />
<_WasmPropertyNames Include="WasmIcuDataFileName" />
- <_WasmPropertyNames Include="HybridGlobalization" />
diff --git a/eng/testing/tests.wasi.targets b/eng/testing/tests.wasi.targets
index 7f981dde513c7f..e29f86cbc2aa04 100644
--- a/eng/testing/tests.wasi.targets
+++ b/eng/testing/tests.wasi.targets
@@ -138,7 +138,6 @@
<_WasmPropertyNames Include="WasiClangLinkOptimizationFlag" />
<_WasmPropertyNames Include="WasmIncludeFullIcuData" />
<_WasmPropertyNames Include="WasmIcuDataFileName" />
- <_WasmPropertyNames Include="HybridGlobalization" />
diff --git a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj
index f4109a290f9206..70e02de9c08a69 100644
--- a/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj
+++ b/src/coreclr/System.Private.CoreLib/System.Private.CoreLib.csproj
@@ -231,7 +231,6 @@
-
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimePropertyInfo.cs b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimePropertyInfo.cs
index 2d542fb78ee101..51b1f84864b1a9 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimePropertyInfo.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/Reflection/RuntimePropertyInfo.cs
@@ -107,7 +107,7 @@ internal bool EqualsSig(RuntimePropertyInfo target)
Debug.Assert(this != target);
Debug.Assert(this.ReflectedType == target.ReflectedType);
- return Signature.CompareSig(this.Signature, target.Signature);
+ return Signature.AreEqual(this.Signature, target.Signature);
}
internal BindingFlags BindingFlags => m_bindingFlags;
#endregion
diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs
index 236078b88c5679..a1907fd90df765 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeHandles.cs
@@ -514,11 +514,45 @@ internal static IntroducedMethodEnumerator GetIntroducedMethods(RuntimeType type
[MethodImpl(MethodImplOptions.InternalCall)]
private static extern void GetNextIntroducedMethod(ref RuntimeMethodHandleInternal method);
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern bool GetFields(RuntimeType type, IntPtr* result, int* count);
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetFields")]
+ private static partial Interop.BOOL GetFields(MethodTable* pMT, Span data, ref int usedCount);
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern Type[]? GetInterfaces(RuntimeType type);
+ internal static bool GetFields(RuntimeType type, Span buffer, out int count)
+ {
+ Debug.Assert(!IsGenericVariable(type));
+
+ TypeHandle typeHandle = type.GetNativeTypeHandle();
+ if (typeHandle.IsTypeDesc)
+ {
+ count = 0;
+ return true;
+ }
+
+ int countLocal = buffer.Length;
+ bool success = GetFields(typeHandle.AsMethodTable(), buffer, ref countLocal) != Interop.BOOL.FALSE;
+ GC.KeepAlive(type);
+ count = countLocal;
+ return success;
+ }
+
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetInterfaces")]
+ private static unsafe partial void GetInterfaces(MethodTable* pMT, ObjectHandleOnStack result);
+
+ internal static Type[] GetInterfaces(RuntimeType type)
+ {
+ Debug.Assert(!IsGenericVariable(type));
+
+ TypeHandle typeHandle = type.GetNativeTypeHandle();
+ if (typeHandle.IsTypeDesc)
+ {
+ return [];
+ }
+
+ Type[] result = [];
+ GetInterfaces(typeHandle.AsMethodTable(), ObjectHandleOnStack.Create(ref result));
+ GC.KeepAlive(type);
+ return result;
+ }
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "RuntimeTypeHandle_GetConstraints")]
private static partial void GetConstraints(QCallTypeHandle handle, ObjectHandleOnStack types);
@@ -1859,10 +1893,11 @@ internal static int GetMDStreamVersion(RuntimeModule module)
public int MDStreamVersion => GetMDStreamVersion(GetRuntimeModule());
}
- internal sealed unsafe class Signature
+ internal sealed unsafe partial class Signature
{
#region FCalls
[MemberNotNull(nameof(m_arguments))]
+ [MemberNotNull(nameof(m_declaringType))]
[MemberNotNull(nameof(m_returnTypeORfieldType))]
[MethodImpl(MethodImplOptions.InternalCall)]
private extern void GetSignature(
@@ -1875,7 +1910,7 @@ private extern void GetSignature(
// Keep the layout in sync with SignatureNative in the VM
//
internal RuntimeType[] m_arguments;
- internal RuntimeType? m_declaringType;
+ internal RuntimeType m_declaringType;
internal RuntimeType m_returnTypeORfieldType;
internal object? m_keepalive;
internal void* m_sig;
@@ -1923,8 +1958,17 @@ public Signature(void* pCorSig, int cCorSig, RuntimeType declaringType)
internal RuntimeType ReturnType => m_returnTypeORfieldType;
internal RuntimeType FieldType => m_returnTypeORfieldType;
- [MethodImpl(MethodImplOptions.InternalCall)]
- internal static extern bool CompareSig(Signature sig1, Signature sig2);
+ [LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Signature_AreEqual")]
+ private static partial Interop.BOOL AreEqual(
+ void* sig1, int csig1, QCallTypeHandle type1,
+ void* sig2, int csig2, QCallTypeHandle type2);
+
+ internal static bool AreEqual(Signature sig1, Signature sig2)
+ {
+ return AreEqual(
+ sig1.m_sig, sig1.m_csig, new QCallTypeHandle(ref sig1.m_declaringType),
+ sig2.m_sig, sig2.m_csig, new QCallTypeHandle(ref sig2.m_declaringType)) != Interop.BOOL.FALSE;
+ }
internal Type[] GetCustomModifiers(int parameterIndex, bool required) =>
GetCustomModifiersAtOffset(GetParameterOffset(parameterIndex), required);
diff --git a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs
index b73f8263782e90..d1591d88036b28 100644
--- a/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs
+++ b/src/coreclr/System.Private.CoreLib/src/System/RuntimeType.CoreCLR.cs
@@ -826,30 +826,21 @@ private RuntimeFieldInfo[] PopulateFields(Filter filter)
#endregion
#region Populate Literal Fields on Interfaces
+ Type[] interfaces;
if (ReflectedType.IsGenericParameter)
{
- Type[] interfaces = ReflectedType.BaseType!.GetInterfaces();
-
- for (int i = 0; i < interfaces.Length; i++)
- {
- // Populate literal fields defined on any of the interfaces implemented by the declaring type
- PopulateLiteralFields(filter, (RuntimeType)interfaces[i], ref list);
- PopulateRtFields(filter, (RuntimeType)interfaces[i], ref list);
- }
+ interfaces = ReflectedType.BaseType!.GetInterfaces();
}
else
{
- Type[]? interfaces = RuntimeTypeHandle.GetInterfaces(ReflectedType);
+ interfaces = RuntimeTypeHandle.GetInterfaces(ReflectedType);
+ }
- if (interfaces != null)
- {
- for (int i = 0; i < interfaces.Length; i++)
- {
- // Populate literal fields defined on any of the interfaces implemented by the declaring type
- PopulateLiteralFields(filter, (RuntimeType)interfaces[i], ref list);
- PopulateRtFields(filter, (RuntimeType)interfaces[i], ref list);
- }
- }
+ foreach (Type iface in interfaces)
+ {
+ // Populate literal fields defined on any of the interfaces implemented by the declaring type
+ PopulateLiteralFields(filter, (RuntimeType)iface, ref list);
+ PopulateRtFields(filter, (RuntimeType)iface, ref list);
}
#endregion
@@ -858,25 +849,22 @@ private RuntimeFieldInfo[] PopulateFields(Filter filter)
private unsafe void PopulateRtFields(Filter filter, RuntimeType declaringType, ref ListBuilder list)
{
- IntPtr* pResult = stackalloc IntPtr[64];
- int count = 64;
-
- if (!RuntimeTypeHandle.GetFields(declaringType, pResult, &count))
+ Span result = stackalloc IntPtr[64];
+ int count;
+ while (!RuntimeTypeHandle.GetFields(declaringType, result, out count))
{
- fixed (IntPtr* pBigResult = new IntPtr[count])
- {
- RuntimeTypeHandle.GetFields(declaringType, pBigResult, &count);
- PopulateRtFields(filter, pBigResult, count, declaringType, ref list);
- }
+ Debug.Assert(count > result.Length);
+ result = new IntPtr[count];
}
- else if (count > 0)
+
+ if (count > 0)
{
- PopulateRtFields(filter, pResult, count, declaringType, ref list);
+ PopulateRtFields(filter, result.Slice(0, count), declaringType, ref list);
}
}
private unsafe void PopulateRtFields(Filter filter,
- IntPtr* ppFieldHandles, int count, RuntimeType declaringType, ref ListBuilder list)
+ ReadOnlySpan fieldHandles, RuntimeType declaringType, ref ListBuilder list)
{
Debug.Assert(declaringType != null);
Debug.Assert(ReflectedType != null);
@@ -884,9 +872,9 @@ private unsafe void PopulateRtFields(Filter filter,
bool needsStaticFieldForGeneric = declaringType.IsGenericType && !RuntimeTypeHandle.ContainsGenericVariables(declaringType);
bool isInherited = declaringType != ReflectedType;
- for (int i = 0; i < count; i++)
+ foreach (IntPtr handle in fieldHandles)
{
- RuntimeFieldHandleInternal runtimeFieldHandle = new RuntimeFieldHandleInternal(ppFieldHandles[i]);
+ RuntimeFieldHandleInternal runtimeFieldHandle = new RuntimeFieldHandleInternal(handle);
if (filter.RequiresStringComparison())
{
@@ -1017,23 +1005,19 @@ private RuntimeType[] PopulateInterfaces(Filter filter)
if (!RuntimeTypeHandle.IsGenericVariable(declaringType))
{
- Type[]? ifaces = RuntimeTypeHandle.GetInterfaces(declaringType);
-
- if (ifaces != null)
+ Type[] ifaces = RuntimeTypeHandle.GetInterfaces(declaringType);
+ foreach (Type iface in ifaces)
{
- for (int i = 0; i < ifaces.Length; i++)
- {
- RuntimeType interfaceType = (RuntimeType)ifaces[i];
-
- if (filter.RequiresStringComparison())
- {
- if (!filter.Match(RuntimeTypeHandle.GetUtf8Name(interfaceType)))
- continue;
- }
+ RuntimeType interfaceType = (RuntimeType)iface;
- Debug.Assert(interfaceType.IsInterface);
- list.Add(interfaceType);
+ if (filter.RequiresStringComparison())
+ {
+ if (!filter.Match(RuntimeTypeHandle.GetUtf8Name(interfaceType)))
+ continue;
}
+
+ Debug.Assert(interfaceType.IsInterface);
+ list.Add(interfaceType);
}
if (ReflectedType.IsSZArray)
diff --git a/src/coreclr/System.Private.CoreLib/src/System/Threading/ThreadPool.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Threading/ThreadPool.CoreCLR.cs
deleted file mode 100644
index e13fdeef311194..00000000000000
--- a/src/coreclr/System.Private.CoreLib/src/System/Threading/ThreadPool.CoreCLR.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-/*=============================================================================
-**
-**
-**
-** Purpose: Class for creating and managing a threadpool
-**
-**
-=============================================================================*/
-
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Runtime.ConstrainedExecution;
-using System.Runtime.InteropServices;
-using System.Runtime.Versioning;
-
-namespace System.Threading
-{
-
- public static partial class ThreadPool
- {
- internal static bool EnsureConfigInitialized()
- {
- return s_initialized;
- }
-
- private static readonly bool s_initialized = InitializeConfig();
-
- private static unsafe bool InitializeConfig()
- {
- int configVariableIndex = 1;
- while (true)
- {
- int nextConfigVariableIndex =
- GetNextConfigUInt32Value(
- configVariableIndex,
- out uint configValue,
- out bool isBoolean,
- out char* appContextConfigNameUnsafe);
- if (nextConfigVariableIndex < 0)
- {
- break;
- }
-
- Debug.Assert(nextConfigVariableIndex > configVariableIndex);
- configVariableIndex = nextConfigVariableIndex;
-
- Debug.Assert(appContextConfigNameUnsafe != null);
-
- var appContextConfigName = new string(appContextConfigNameUnsafe);
- if (isBoolean)
- {
- AppContext.SetSwitch(appContextConfigName, configValue != 0);
- }
- else
- {
- AppContext.SetData(appContextConfigName, configValue);
- }
- }
-
- return true;
- }
-
- [MethodImpl(MethodImplOptions.InternalCall)]
- private static extern unsafe int GetNextConfigUInt32Value(
- int configVariableIndex,
- out uint configValue,
- out bool isBoolean,
- out char* appContextConfigName);
-
- }
-}
diff --git a/src/coreclr/debug/daccess/request.cpp b/src/coreclr/debug/daccess/request.cpp
index 34ce7f2aa8827d..7a07a8c0f6c3c1 100644
--- a/src/coreclr/debug/daccess/request.cpp
+++ b/src/coreclr/debug/daccess/request.cpp
@@ -1049,6 +1049,11 @@ HRESULT ClrDataAccess::GetMethodDescData(
{
ILCodeVersion activeILCodeVersion = pCodeVersionManager->GetActiveILCodeVersion(pMD);
activeNativeCodeVersion = activeILCodeVersion.GetActiveNativeCodeVersion(pMD);
+ if (activeNativeCodeVersion.IsNull())
+ {
+ // This is caught below and S_OK is returned
+ DacError(E_ACCESSDENIED);
+ }
}
CopyNativeCodeVersionToReJitData(
activeNativeCodeVersion,
@@ -1571,12 +1576,18 @@ ClrDataAccess::GetObjectStringData(CLRDATA_ADDRESS obj, unsigned int count, _Ino
count = needed;
TADDR pszStr = TO_TADDR(obj)+offsetof(StringObject, m_FirstChar);
- hr = m_pTarget->ReadVirtual(pszStr, (PBYTE)stringData, count * sizeof(WCHAR), &needed);
+ ULONG32 bytesRead;
+ hr = m_pTarget->ReadVirtual(pszStr, (PBYTE)stringData, count * sizeof(WCHAR), &bytesRead);
+ needed = bytesRead / sizeof(WCHAR);
if (SUCCEEDED(hr))
- stringData[count - 1] = W('\0');
+ {
+ stringData[needed - 1] = W('\0');
+ }
else
+ {
stringData[0] = W('\0');
+ }
}
else
{
diff --git a/src/coreclr/debug/ee/arm64/walker.cpp b/src/coreclr/debug/ee/arm64/walker.cpp
index 12b9e3b121b54e..ebec232a9afb96 100644
--- a/src/coreclr/debug/ee/arm64/walker.cpp
+++ b/src/coreclr/debug/ee/arm64/walker.cpp
@@ -278,9 +278,9 @@ BOOL NativeWalker::DecodePCRelativeBranchInst(PT_CONTEXT context, const PRD_TYP
{
offset = (opcode & 0x03FFFFFF) << 2;
// Sign extension
- if ((offset & 0x4000000)) //Check for 26'st bit
+ if ((offset & 0x8000000)) //Check for (26 + 2)'st bit
{
- offset = offset | 0xFFFFFFFFF8000000;
+ offset = offset | 0xFFFFFFFFF0000000;
}
if ((opcode & 0x80000000) != 0) //BL
diff --git a/src/coreclr/debug/ee/controller.cpp b/src/coreclr/debug/ee/controller.cpp
index 47b6e0b5a81349..ca63a24170d127 100644
--- a/src/coreclr/debug/ee/controller.cpp
+++ b/src/coreclr/debug/ee/controller.cpp
@@ -5815,7 +5815,7 @@ static bool IsTailCall(const BYTE * ip, ControllerStackInfo* info, TailCallFunct
if (type == TailCallFunctionType::StoreTailCallArgs)
{
- return (pTargetMD->IsDynamicMethod() && pTargetMD->AsDynamicMethodDesc()->GetILStubType() == DynamicMethodDesc::StubTailCallStoreArgs);
+ return (pTargetMD && pTargetMD->IsDynamicMethod() && pTargetMD->AsDynamicMethodDesc()->GetILStubType() == DynamicMethodDesc::StubTailCallStoreArgs);
}
if (pTargetMD != pTailCallDispatcherMD)
@@ -7585,7 +7585,15 @@ bool DebuggerStepper::TriggerSingleStep(Thread *thread, const BYTE *ip)
if (!g_pEEInterface->IsManagedNativeCode(ip))
{
LOG((LF_CORDB,LL_INFO10000, "DS::TSS: not in managed code, Returning false (case 0)!\n"));
- DisableSingleStep();
+ // Sometimes we can get here with a callstack that is coming from an APC
+ // this will disable the single stepping and incorrectly resume an app that the user
+ // is stepping through.
+#ifdef FEATURE_THREAD_ACTIVATION
+ if ((thread->m_State & Thread::TS_DebugWillSync) == 0)
+#endif
+ {
+ DisableSingleStep();
+ }
return false;
}
diff --git a/src/coreclr/debug/runtimeinfo/datadescriptor.cpp b/src/coreclr/debug/runtimeinfo/datadescriptor.cpp
index a6443a730985e0..72a1ee18304578 100644
--- a/src/coreclr/debug/runtimeinfo/datadescriptor.cpp
+++ b/src/coreclr/debug/runtimeinfo/datadescriptor.cpp
@@ -13,6 +13,10 @@
#include "methodtable.h"
#include "threads.h"
+#ifdef HAVE_GCCOVER
+#include "gccover.h"
+#endif // HAVE_GCCOVER
+
// begin blob definition
extern "C"
diff --git a/src/coreclr/debug/runtimeinfo/datadescriptor.h b/src/coreclr/debug/runtimeinfo/datadescriptor.h
index 1fa37c6ba50d2e..e58d91bd6cab3a 100644
--- a/src/coreclr/debug/runtimeinfo/datadescriptor.h
+++ b/src/coreclr/debug/runtimeinfo/datadescriptor.h
@@ -331,6 +331,9 @@ CDAC_TYPE_FIELD(MethodDesc, /*uint16*/, Flags, cdac_data::Flags)
CDAC_TYPE_FIELD(MethodDesc, /*uint16*/, Flags3AndTokenRemainder, cdac_data::Flags3AndTokenRemainder)
CDAC_TYPE_FIELD(MethodDesc, /*uint8*/, EntryPointFlags, cdac_data::EntryPointFlags)
CDAC_TYPE_FIELD(MethodDesc, /*pointer*/, CodeData, cdac_data::CodeData)
+#ifdef HAVE_GCCOVER
+CDAC_TYPE_FIELD(MethodDesc, /*pointer*/, GCCoverageInfo, offsetof(MethodDesc, m_GcCover))
+#endif // HAVE_GCCOVER
CDAC_TYPE_END(MethodDesc)
CDAC_TYPE_BEGIN(MethodDescChunk)
@@ -342,6 +345,18 @@ CDAC_TYPE_FIELD(MethodDescChunk, /*uint8*/, Count, cdac_data::C
CDAC_TYPE_FIELD(MethodDescChunk, /*uint16*/, FlagsAndTokenRange, cdac_data::FlagsAndTokenRange)
CDAC_TYPE_END(MethodDescChunk)
+CDAC_TYPE_BEGIN(NonVtableSlot)
+CDAC_TYPE_SIZE(sizeof(MethodDesc::NonVtableSlot))
+CDAC_TYPE_END(NonVtableSlot)
+
+CDAC_TYPE_BEGIN(MethodImpl)
+CDAC_TYPE_SIZE(sizeof(MethodImpl))
+CDAC_TYPE_END(MethodImpl)
+
+CDAC_TYPE_BEGIN(NativeCodeSlot)
+CDAC_TYPE_SIZE(sizeof(MethodDesc::NativeCodeSlot))
+CDAC_TYPE_END(NativeCodeSlot)
+
CDAC_TYPE_BEGIN(InstantiatedMethodDesc)
CDAC_TYPE_SIZE(sizeof(InstantiatedMethodDesc))
CDAC_TYPE_FIELD(InstantiatedMethodDesc, /*pointer*/, PerInstInfo, cdac_data::PerInstInfo)
@@ -361,6 +376,28 @@ CDAC_TYPE_SIZE(sizeof(DynamicMethodDesc))
CDAC_TYPE_FIELD(DynamicMethodDesc, /*pointer*/, MethodName, cdac_data::MethodName)
CDAC_TYPE_END(DynamicMethodDesc)
+CDAC_TYPE_BEGIN(ArrayMethodDesc)
+CDAC_TYPE_SIZE(sizeof(ArrayMethodDesc))
+CDAC_TYPE_END(ArrayMethodDesc)
+
+CDAC_TYPE_BEGIN(FCallMethodDesc)
+CDAC_TYPE_SIZE(sizeof(FCallMethodDesc))
+CDAC_TYPE_END(FCallMethodDesc)
+
+CDAC_TYPE_BEGIN(PInvokeMethodDesc)
+CDAC_TYPE_SIZE(sizeof(NDirectMethodDesc))
+CDAC_TYPE_END(PInvokeMethodDesc)
+
+CDAC_TYPE_BEGIN(EEImplMethodDesc)
+CDAC_TYPE_SIZE(sizeof(EEImplMethodDesc))
+CDAC_TYPE_END(EEImplMethodDesc)
+
+#ifdef FEATURE_COMINTEROP
+CDAC_TYPE_BEGIN(CLRToCOMCallMethodDesc)
+CDAC_TYPE_SIZE(sizeof(CLRToCOMCallMethodDesc))
+CDAC_TYPE_END(CLRToCOMCallMethodDesc)
+#endif // FEATURE_COMINTEROP
+
CDAC_TYPE_BEGIN(CodePointer)
CDAC_TYPE_SIZE(sizeof(PCODE))
CDAC_TYPE_END(CodePointer)
@@ -510,6 +547,9 @@ CDAC_TYPE_FIELD(NativeCodeVersionNode, /*pointer*/, MethodDesc, cdac_data::NativeCode)
CDAC_TYPE_FIELD(NativeCodeVersionNode, /*uint32*/, Flags, cdac_data::Flags)
CDAC_TYPE_FIELD(NativeCodeVersionNode, /*nuint*/, ILVersionId, cdac_data::ILVersionId)
+#ifdef HAVE_GCCOVER
+CDAC_TYPE_FIELD(NativeCodeVersionNode, /*pointer*/, GCCoverageInfo, cdac_data::GCCoverageInfo)
+#endif // HAVE_GCCOVER
CDAC_TYPE_END(NativeCodeVersionNode)
CDAC_TYPE_BEGIN(ILCodeVersionNode)
@@ -523,6 +563,13 @@ CDAC_TYPE_BEGIN(ProfControlBlock)
CDAC_TYPE_FIELD(ProfControlBlock, /*uint64*/, GlobalEventMask, offsetof(ProfControlBlock, globalEventMask))
CDAC_TYPE_END(ProfControlBlock)
+#ifdef HAVE_GCCOVER
+CDAC_TYPE_BEGIN(GCCoverageInfo)
+CDAC_TYPE_INDETERMINATE(GCCoverageInfo)
+CDAC_TYPE_FIELD(GCCoverageInfo, /*pointer*/, SavedCode, offsetof(GCCoverageInfo, savedCode))
+CDAC_TYPE_END(GCCoverageInfo)
+#endif // HAVE_GCCOVER
+
CDAC_TYPES_END()
CDAC_GLOBALS_BEGIN()
diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp
index bf2276f8411f59..3b717a6e239157 100644
--- a/src/coreclr/gc/gc.cpp
+++ b/src/coreclr/gc/gc.cpp
@@ -39921,7 +39921,7 @@ void gc_heap::bgc_thread_function()
{
dprintf (6666, ("h%d no concurrent GC needed, exiting", heap_number));
-#ifdef STRESS_DYNAMIC_HEAP_COUNT
+#if defined(TRACE_GC) && defined(SIMPLE_DPRINTF) && defined(STRESS_DYNAMIC_HEAP_COUNT)
flush_gc_log (true);
GCToOSInterface::DebugBreak();
#endif
diff --git a/src/coreclr/inc/clr/fs.h b/src/coreclr/inc/clr/fs.h
deleted file mode 100644
index d7efac04cf5fb3..00000000000000
--- a/src/coreclr/inc/clr/fs.h
+++ /dev/null
@@ -1,13 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-//
-
-//
-// This header will include all headers relating to file system functionality.
-
-#ifndef _clr_fs_h_
-#define _clr_fs_h_
-
-#include "fs/path.h"
-
-#endif // _clr_fs_h_
diff --git a/src/coreclr/inc/clr/fs/path.h b/src/coreclr/inc/clr/fs/path.h
index efc21a5cdd4392..1f5454c9ac9252 100644
--- a/src/coreclr/inc/clr/fs/path.h
+++ b/src/coreclr/inc/clr/fs/path.h
@@ -10,10 +10,6 @@
#include "clrtypes.h"
-#include "strsafe.h"
-
-#include "clr/str.h"
-
namespace clr
{
namespace fs
diff --git a/src/coreclr/inc/clr/str.h b/src/coreclr/inc/clr/str.h
deleted file mode 100644
index d09a965fed6816..00000000000000
--- a/src/coreclr/inc/clr/str.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-//
-
-//
-// This header provides general standard string services.
-//
-
-#ifndef _clr_str_h_
-#define _clr_str_h_
-
-namespace clr
-{
- namespace str
- {
- //-----------------------------------------------------------------------------------------
- // Returns true if the provided string is a null pointer or the empty string.
- static inline bool
- IsNullOrEmpty(LPCWSTR wzStr)
- {
- return wzStr == nullptr || *wzStr == W('\0');
- }
- }
-}
-
-#endif // _clr_str_h_
-
diff --git a/src/coreclr/inc/clrconfigvalues.h b/src/coreclr/inc/clrconfigvalues.h
index d0a76bc85bcefe..61dcad88227714 100644
--- a/src/coreclr/inc/clrconfigvalues.h
+++ b/src/coreclr/inc/clrconfigvalues.h
@@ -516,36 +516,6 @@ RETAIL_CONFIG_DWORD_INFO(EXTERNAL_Thread_UseAllCpuGroups, W("Thread_UseAllCpuGro
RETAIL_CONFIG_DWORD_INFO(EXTERNAL_Thread_AssignCpuGroups, W("Thread_AssignCpuGroups"), 1, "Specifies whether to automatically distribute threads created by the CLR across CPU Groups. Effective only when Thread_UseAllCpuGroups and GCCpuGroup are enabled.")
RETAIL_CONFIG_DWORD_INFO_EX(EXTERNAL_ProcessorCount, W("PROCESSOR_COUNT"), 0, "Specifies the number of processors available for the process, which is returned by Environment.ProcessorCount", CLRConfig::LookupOptions::ParseIntegerAsBase10)
-///
-/// Threadpool
-///
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_ThreadPool_ForceMinWorkerThreads, W("ThreadPool_ForceMinWorkerThreads"), 0, "Overrides the MinThreads setting for the ThreadPool worker pool")
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_ThreadPool_ForceMaxWorkerThreads, W("ThreadPool_ForceMaxWorkerThreads"), 0, "Overrides the MaxThreads setting for the ThreadPool worker pool")
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_ThreadPool_DisableStarvationDetection, W("ThreadPool_DisableStarvationDetection"), 0, "Disables the ThreadPool feature that forces new threads to be added when workitems run for too long")
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_ThreadPool_DebugBreakOnWorkerStarvation, W("ThreadPool_DebugBreakOnWorkerStarvation"), 0, "Breaks into the debugger if the ThreadPool detects work queue starvation")
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_ThreadPool_EnableWorkerTracking, W("ThreadPool_EnableWorkerTracking"), 0, "Enables extra expensive tracking of how many workers threads are working simultaneously")
-#ifdef TARGET_ARM64
-// Spinning scheme is currently different on ARM64
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_ThreadPool_UnfairSemaphoreSpinLimit, W("ThreadPool_UnfairSemaphoreSpinLimit"), 0x32, "Maximum number of spins per processor a thread pool worker thread performs before waiting for work")
-#else // !TARGET_ARM64
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_ThreadPool_UnfairSemaphoreSpinLimit, W("ThreadPool_UnfairSemaphoreSpinLimit"), 0x46, "Maximum number of spins a thread pool worker thread performs before waiting for work")
-#endif // TARGET_ARM64
-
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_HillClimbing_Disable, W("HillClimbing_Disable"), 0, "Disables hill climbing for thread adjustments in the thread pool");
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_HillClimbing_WavePeriod, W("HillClimbing_WavePeriod"), 4, "");
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_HillClimbing_TargetSignalToNoiseRatio, W("HillClimbing_TargetSignalToNoiseRatio"), 300, "");
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_HillClimbing_ErrorSmoothingFactor, W("HillClimbing_ErrorSmoothingFactor"), 1, "");
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_HillClimbing_WaveMagnitudeMultiplier, W("HillClimbing_WaveMagnitudeMultiplier"), 100, "");
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_HillClimbing_MaxWaveMagnitude, W("HillClimbing_MaxWaveMagnitude"), 20, "");
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_HillClimbing_WaveHistorySize, W("HillClimbing_WaveHistorySize"), 8, "");
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_HillClimbing_Bias, W("HillClimbing_Bias"), 15, "The 'cost' of a thread. 0 means drive for increased throughput regardless of thread count; higher values bias more against higher thread counts.");
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_HillClimbing_MaxChangePerSecond, W("HillClimbing_MaxChangePerSecond"), 4, "");
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_HillClimbing_MaxChangePerSample, W("HillClimbing_MaxChangePerSample"), 20, "");
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_HillClimbing_MaxSampleErrorPercent, W("HillClimbing_MaxSampleErrorPercent"), 15, "");
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_HillClimbing_SampleIntervalLow, W("HillClimbing_SampleIntervalLow"), 10, "");
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_HillClimbing_SampleIntervalHigh, W("HillClimbing_SampleIntervalHigh"), 200, "");
-RETAIL_CONFIG_DWORD_INFO(INTERNAL_HillClimbing_GainExponent, W("HillClimbing_GainExponent"), 200, "The exponent to apply to the gain, times 100. 100 means to use linear gain, higher values will enhance large moves and damp small ones.");
-
///
/// Tiered Compilation
///
diff --git a/src/coreclr/interop/trackerobjectmanager.cpp b/src/coreclr/interop/trackerobjectmanager.cpp
index d4302054baedba..0df78164906dcc 100644
--- a/src/coreclr/interop/trackerobjectmanager.cpp
+++ b/src/coreclr/interop/trackerobjectmanager.cpp
@@ -84,7 +84,10 @@ namespace
STDMETHODIMP HostServices::ReleaseDisconnectedReferenceSources()
{
- return InteropLibImports::WaitForRuntimeFinalizerForExternal();
+ // We'd like to call InteropLibImports::WaitForRuntimeFinalizerForExternal() here, but this could
+ // lead to deadlock if the finalizer thread is trying to get back to this thread, because we are
+ // not pumping anymore. Disable this for now. See: https://github.com/dotnet/runtime/issues/109538.
+ return S_OK;
}
STDMETHODIMP HostServices::NotifyEndOfReferenceTrackingOnThread()
diff --git a/src/coreclr/jit/block.cpp b/src/coreclr/jit/block.cpp
index b630e18c9e7b97..eb4d5666fcf4e8 100644
--- a/src/coreclr/jit/block.cpp
+++ b/src/coreclr/jit/block.cpp
@@ -267,15 +267,21 @@ FlowEdge* Compiler::BlockPredsWithEH(BasicBlock* blk)
// 'blk'.
//
// Arguments:
-// blk - Block to get dominance predecessors for.
+// blk - Block to get dominance predecessors for.
//
// Returns:
-// List of edges.
+// List of edges.
//
// Remarks:
-// Differs from BlockPredsWithEH only in the treatment of handler blocks;
-// enclosed blocks are never dominance preds, while all predecessors of
-// blocks in the 'try' are (currently only the first try block expected).
+// Differs from BlockPredsWithEH only in the treatment of handler blocks;
+// enclosed blocks are never dominance preds, while all predecessors of
+// blocks in the 'try' are (currently only the first try block expected).
+//
+// There are additional complications due to spurious flow because of
+// two-pass EH. In the flow graph with EH edges we can see entries into the
+// try from filters outside the try, to blocks other than the "try-begin"
+// block. Hence we need to consider the full set of blocks in the try region
+// when considering the block dominance preds.
//
FlowEdge* Compiler::BlockDominancePreds(BasicBlock* blk)
{
@@ -284,14 +290,6 @@ FlowEdge* Compiler::BlockDominancePreds(BasicBlock* blk)
return blk->bbPreds;
}
- EHblkDsc* ehblk = ehGetBlockHndDsc(blk);
- if (!ehblk->HasFinallyOrFaultHandler() || (ehblk->ebdHndBeg != blk))
- {
- return ehblk->ebdTryBeg->bbPreds;
- }
-
- // Finally/fault handlers can be preceded by enclosing filters due to 2
- // pass EH, so add those and keep them cached.
BlockToFlowEdgeMap* domPreds = GetDominancePreds();
FlowEdge* res;
if (domPreds->Lookup(blk, &res))
@@ -299,29 +297,11 @@ FlowEdge* Compiler::BlockDominancePreds(BasicBlock* blk)
return res;
}
- res = ehblk->ebdTryBeg->bbPreds;
- if (ehblk->HasFinallyOrFaultHandler() && (ehblk->ebdHndBeg == blk))
+ EHblkDsc* ehblk = ehGetBlockHndDsc(blk);
+ res = BlockPredsWithEH(blk);
+ for (BasicBlock* predBlk : ehblk->ebdTryBeg->PredBlocks())
{
- // block is a finally or fault handler; all enclosing filters are predecessors
- unsigned enclosing = ehblk->ebdEnclosingTryIndex;
- while (enclosing != EHblkDsc::NO_ENCLOSING_INDEX)
- {
- EHblkDsc* enclosingDsc = ehGetDsc(enclosing);
- if (enclosingDsc->HasFilter())
- {
- for (BasicBlock* filterBlk = enclosingDsc->ebdFilter; filterBlk != enclosingDsc->ebdHndBeg;
- filterBlk = filterBlk->Next())
- {
- res = new (this, CMK_FlowEdge) FlowEdge(filterBlk, blk, res);
-
- assert(filterBlk->VisitEHEnclosedHandlerSecondPassSuccs(this, [blk](BasicBlock* succ) {
- return succ == blk ? BasicBlockVisit::Abort : BasicBlockVisit::Continue;
- }) == BasicBlockVisit::Abort);
- }
- }
-
- enclosing = enclosingDsc->ebdEnclosingTryIndex;
- }
+ res = new (this, CMK_FlowEdge) FlowEdge(predBlk, blk, res);
}
domPreds->Set(blk, res);
@@ -527,6 +507,7 @@ void BasicBlock::dspFlags() const
{BBF_HAS_IDX_LEN, "idxlen"},
{BBF_HAS_MD_IDX_LEN, "mdidxlen"},
{BBF_HAS_NEWOBJ, "newobj"},
+ {BBF_HAS_NEWARR, "newarr"},
{BBF_HAS_NULLCHECK, "nullcheck"},
{BBF_BACKWARD_JUMP, "bwd"},
{BBF_BACKWARD_JUMP_TARGET, "bwd-target"},
diff --git a/src/coreclr/jit/block.h b/src/coreclr/jit/block.h
index d0d09143b1eda3..03770815f0125a 100644
--- a/src/coreclr/jit/block.h
+++ b/src/coreclr/jit/block.h
@@ -461,12 +461,14 @@ enum BasicBlockFlags : uint64_t
BBF_CAN_ADD_PRED = MAKE_BBFLAG(38), // Ok to add pred edge to this block, even when "safe" edge creation disabled
BBF_HAS_VALUE_PROFILE = MAKE_BBFLAG(39), // Block has a node that needs a value probing
+ BBF_HAS_NEWARR = MAKE_BBFLAG(40), // BB contains 'new' of an array type.
+
// The following are sets of flags.
// Flags to update when two blocks are compacted
BBF_COMPACT_UPD = BBF_GC_SAFE_POINT | BBF_NEEDS_GCPOLL | BBF_HAS_JMP | BBF_HAS_IDX_LEN | BBF_HAS_MD_IDX_LEN | BBF_BACKWARD_JUMP | \
- BBF_HAS_NEWOBJ | BBF_HAS_NULLCHECK | BBF_HAS_MDARRAYREF | BBF_LOOP_HEAD,
+ BBF_HAS_NEWOBJ | BBF_HAS_NEWARR | BBF_HAS_NULLCHECK | BBF_HAS_MDARRAYREF | BBF_LOOP_HEAD,
// Flags a block should not have had before it is split.
@@ -484,7 +486,7 @@ enum BasicBlockFlags : uint64_t
// For example, the bottom block might or might not have BBF_HAS_NULLCHECK, but we assume it has BBF_HAS_NULLCHECK.
// TODO: Should BBF_RUN_RARELY be added to BBF_SPLIT_GAINED ?
- BBF_SPLIT_GAINED = BBF_DONT_REMOVE | BBF_HAS_JMP | BBF_BACKWARD_JUMP | BBF_HAS_IDX_LEN | BBF_HAS_MD_IDX_LEN | BBF_PROF_WEIGHT | \
+ BBF_SPLIT_GAINED = BBF_DONT_REMOVE | BBF_HAS_JMP | BBF_BACKWARD_JUMP | BBF_HAS_IDX_LEN | BBF_HAS_MD_IDX_LEN | BBF_PROF_WEIGHT | BBF_HAS_NEWARR | \
BBF_HAS_NEWOBJ | BBF_KEEP_BBJ_ALWAYS | BBF_CLONED_FINALLY_END | BBF_HAS_NULLCHECK | BBF_HAS_HISTOGRAM_PROFILE | BBF_HAS_VALUE_PROFILE | BBF_HAS_MDARRAYREF | BBF_NEEDS_GCPOLL,
// Flags that must be propagated to a new block if code is copied from a block to a new block. These are flags that
@@ -492,7 +494,7 @@ enum BasicBlockFlags : uint64_t
// have actually copied one of these type of tree nodes, but if we only copy a portion of the block's statements,
// we don't know (unless we actually pay close attention during the copy).
- BBF_COPY_PROPAGATE = BBF_HAS_NEWOBJ | BBF_HAS_NULLCHECK | BBF_HAS_IDX_LEN | BBF_HAS_MD_IDX_LEN | BBF_HAS_MDARRAYREF,
+ BBF_COPY_PROPAGATE = BBF_HAS_NEWOBJ | BBF_HAS_NEWARR | BBF_HAS_NULLCHECK | BBF_HAS_IDX_LEN | BBF_HAS_MD_IDX_LEN | BBF_HAS_MDARRAYREF,
};
FORCEINLINE
diff --git a/src/coreclr/jit/codegenlinear.cpp b/src/coreclr/jit/codegenlinear.cpp
index dcfbcdb9884630..1d6ac2301c45dd 100644
--- a/src/coreclr/jit/codegenlinear.cpp
+++ b/src/coreclr/jit/codegenlinear.cpp
@@ -156,10 +156,6 @@ void CodeGen::genCodeForBBlist()
genMarkLabelsForCodegen();
- assert(!compiler->fgFirstBBScratch ||
- compiler->fgFirstBB == compiler->fgFirstBBScratch); // compiler->fgFirstBBScratch
- // has to be first.
-
/* Initialize structures used in the block list iteration */
genInitialize();
@@ -367,9 +363,9 @@ void CodeGen::genCodeForBBlist()
siBeginBlock(block);
// BBF_INTERNAL blocks don't correspond to any single IL instruction.
- if (compiler->opts.compDbgInfo && block->HasFlag(BBF_INTERNAL) &&
- !compiler->fgBBisScratch(block)) // If the block is the distinguished first scratch block, then no need to
- // emit a NO_MAPPING entry, immediately after the prolog.
+ // Add a NoMapping entry unless this is right after the prolog where it
+ // is unnecessary.
+ if (compiler->opts.compDbgInfo && block->HasFlag(BBF_INTERNAL) && !block->IsFirst())
{
genIPmappingAdd(IPmappingDscKind::NoMapping, DebugInfo(), true);
}
@@ -388,17 +384,17 @@ void CodeGen::genCodeForBBlist()
#ifdef SWIFT_SUPPORT
// Reassemble Swift struct parameters on the local stack frame in the
- // scratch BB right after the prolog. There can be arbitrary amounts of
+ // init BB right after the prolog. There can be arbitrary amounts of
// codegen related to doing this, so it cannot be done in the prolog.
- if (compiler->fgBBisScratch(block) && compiler->lvaHasAnySwiftStackParamToReassemble())
+ if (block->IsFirst() && compiler->lvaHasAnySwiftStackParamToReassemble())
{
genHomeSwiftStructParameters(/* handleStack */ true);
}
#endif
- // Emit poisoning into scratch BB that comes right after prolog.
+ // Emit poisoning into the init BB that comes right after prolog.
// We cannot emit this code in the prolog as it might make the prolog too large.
- if (compiler->compShouldPoisonFrame() && compiler->fgBBisScratch(block))
+ if (compiler->compShouldPoisonFrame() && block->IsFirst())
{
genPoisonFrame(newLiveRegSet);
}
diff --git a/src/coreclr/jit/compiler.cpp b/src/coreclr/jit/compiler.cpp
index 16f5b55ca27289..e2bae6d02fd67f 100644
--- a/src/coreclr/jit/compiler.cpp
+++ b/src/coreclr/jit/compiler.cpp
@@ -3743,20 +3743,6 @@ void Compiler::compInitDebuggingInfo()
compInitScopeLists();
}
- if (opts.compDbgCode && (info.compVarScopesCount > 0))
- {
- /* Create a new empty basic block. fgExtendDbgLifetimes() may add
- initialization of variables which are in scope right from the
- start of the (real) first BB (and therefore artificially marked
- as alive) into this block.
- */
-
- fgEnsureFirstBBisScratch();
-
- fgNewStmtAtEnd(fgFirstBB, gtNewNothingNode());
-
- JITDUMP("Debuggable code - Add new %s to perform initialization of variables\n", fgFirstBB->dspToString());
- }
/*-------------------------------------------------------------------------
*
* Read the stmt-offsets table and the line-number table
@@ -4053,9 +4039,12 @@ void Compiler::compSetOptimizationLevel()
{
codeGen->SetAlignLoops(JitConfig.JitAlignLoops() == 1);
}
- }
- fgCanRelocateEHRegions = true;
+#ifdef DEBUG
+ const char* tieringName = compGetTieringName(true);
+ JitMetadata::report(this, JitMetadata::TieringName, tieringName, strlen(tieringName));
+#endif
+ }
}
#if defined(TARGET_ARMARCH) || defined(TARGET_RISCV64)
@@ -4523,6 +4512,9 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
activePhaseChecks |= PhaseChecks::CHECK_PROFILE;
DoPhase(this, PHASE_INCPROFILE, &Compiler::fgIncorporateProfileData);
+ activePhaseChecks |= PhaseChecks::CHECK_FG_INIT_BLOCK;
+ DoPhase(this, PHASE_CANONICALIZE_ENTRY, &Compiler::fgCanonicalizeFirstBB);
+
// If we are doing OSR, update flow to initially reach the appropriate IL offset.
//
if (opts.IsOSR())
@@ -4691,10 +4683,6 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
if (opts.OptimizationEnabled())
{
- // Canonicalize entry to have unique entry BB to put IR in for the upcoming phases
- //
- DoPhase(this, PHASE_CANONICALIZE_ENTRY, &Compiler::fgCanonicalizeFirstBB);
-
// Build post-order and remove dead blocks
//
DoPhase(this, PHASE_DFS_BLOCKS2, &Compiler::fgDfsBlocksAndRemove);
@@ -4789,10 +4777,6 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
return fgHeadTailMerge(false);
});
- // Canonicalize entry to give a unique dominator tree root
- //
- DoPhase(this, PHASE_CANONICALIZE_ENTRY, &Compiler::fgCanonicalizeFirstBB);
-
// Compute DFS tree and remove all unreachable blocks.
//
DoPhase(this, PHASE_DFS_BLOCKS3, &Compiler::fgDfsBlocksAndRemove);
@@ -5024,12 +5008,6 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
assert(opts.optRepeat);
- // We may have optimized away the canonical entry BB that SSA
- // depends on above, so if we are going for another iteration then
- // make sure we still have a canonical entry.
- //
- DoPhase(this, PHASE_CANONICALIZE_ENTRY, &Compiler::fgCanonicalizeFirstBB);
-
ResetOptAnnotations();
RecomputeFlowGraphAnnotations();
@@ -7152,13 +7130,6 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr,
opts.disAsm = false;
}
-#ifdef DEBUG
- {
- const char* tieringName = compGetTieringName(true);
- JitMetadata::report(this, JitMetadata::TieringName, tieringName, strlen(tieringName));
- }
-#endif
-
#if COUNT_BASIC_BLOCKS
bbCntTable.record(fgBBcount);
diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h
index 75381c2b22171f..f18684f5296308 100644
--- a/src/coreclr/jit/compiler.h
+++ b/src/coreclr/jit/compiler.h
@@ -1542,6 +1542,7 @@ enum class PhaseChecks : unsigned int
CHECK_LIKELIHOODS = 1 << 5, // profile data likelihood integrity
CHECK_PROFILE = 1 << 6, // profile data full integrity
CHECK_LINKED_LOCALS = 1 << 7, // check linked list of locals
+ CHECK_FG_INIT_BLOCK = 1 << 8, // flow graph has an init block
};
inline constexpr PhaseChecks operator ~(PhaseChecks a)
@@ -2219,9 +2220,6 @@ class FlowGraphNaturalLoop
template
BasicBlockVisit VisitLoopBlocks(TFunc func);
- template
- BasicBlockVisit VisitLoopBlocksLexical(TFunc func);
-
template
BasicBlockVisit VisitRegularExitBlocks(TFunc func);
@@ -3747,7 +3745,7 @@ class Compiler
//-------------------------------------------------------------------------
- GenTree* gtFoldExpr(GenTree* tree);
+ GenTree* gtFoldExpr(GenTree* tree, bool* folded = nullptr);
GenTree* gtFoldExprConst(GenTree* tree);
GenTree* gtFoldIndirConst(GenTreeIndir* indir);
GenTree* gtFoldExprSpecial(GenTree* tree);
@@ -5200,8 +5198,6 @@ class Compiler
BasicBlock* fgEntryBB = nullptr; // For OSR, the original method's entry point
BasicBlock* fgOSREntryBB = nullptr; // For OSR, the logical entry point (~ patchpoint)
BasicBlock* fgFirstFuncletBB = nullptr; // First block of outlined funclets (to allow block insertion before the funclets)
- BasicBlock* fgFirstBBScratch = nullptr; // Block inserted for initialization stuff. Is nullptr if no such block has been
- // created.
BasicBlockList* fgReturnBlocks = nullptr; // list of BBJ_RETURN blocks
unsigned fgEdgeCount = 0; // # of control flow edges between the BBs
unsigned fgBBcount = 0; // # of BBs in the method (in the linked list that starts with fgFirstBB)
@@ -5249,10 +5245,6 @@ class Compiler
return getAllocator(cmk).allocate(fgBBNumMax + 1);
}
- bool fgEnsureFirstBBisScratch();
- bool fgFirstBBisScratch();
- bool fgBBisScratch(BasicBlock* block);
-
void fgExtendEHRegionBefore(BasicBlock* block);
void fgExtendEHRegionAfter(BasicBlock* block);
@@ -5335,7 +5327,6 @@ class Compiler
// - Rationalization links all nodes into linear form which is kept until
// the end of compilation. The first and last nodes are stored in the block.
NodeThreading fgNodeThreading = NodeThreading::None;
- bool fgCanRelocateEHRegions; // true if we are allowed to relocate the EH regions
weight_t fgCalledCount = BB_ZERO_WEIGHT; // count of the number of times this method was called
// This is derived from the profile data
// or is BB_UNITY_WEIGHT when we don't have profile data
@@ -5443,6 +5434,7 @@ class Compiler
};
PhaseStatus fgMorphBlocks();
+ BasicBlock* fgGetFirstILBlock();
void fgMorphBlock(BasicBlock* block, MorphUnreachableInfo* unreachableInfo = nullptr);
void fgMorphStmts(BasicBlock* block);
@@ -6162,6 +6154,7 @@ class Compiler
bool fgCheckRemoveStmt(BasicBlock* block, Statement* stmt);
PhaseStatus fgCanonicalizeFirstBB();
+ void fgCreateNewInitBB();
void fgSetEHRegionForNewPreheaderOrExit(BasicBlock* preheader);
@@ -6183,6 +6176,8 @@ class Compiler
bool fgCanCompactBlock(BasicBlock* block);
+ bool fgCanCompactInitBlock();
+
void fgCompactBlock(BasicBlock* block);
BasicBlock* fgConnectFallThrough(BasicBlock* bSrc, BasicBlock* bDst);
@@ -6359,6 +6354,7 @@ class Compiler
void fgDebugCheckBBNumIncreasing();
void fgDebugCheckBBlist(bool checkBBNum = false, bool checkBBRefs = true);
void fgDebugCheckBlockLinks();
+ void fgDebugCheckInitBB();
void fgDebugCheckLinks(bool morphTrees = false);
void fgDebugCheckStmtsList(BasicBlock* block, bool morphTrees);
void fgDebugCheckNodeLinks(BasicBlock* block, Statement* stmt);
@@ -6545,6 +6541,7 @@ class Compiler
}
void fgRemoveProfileData(const char* reason);
+ void fgRepairProfileCondToUncond(BasicBlock* block, FlowEdge* retainedEdge, FlowEdge* removedEdge, int* metric = nullptr);
//-------- Insert a statement at the start or end of a basic block --------
diff --git a/src/coreclr/jit/compiler.hpp b/src/coreclr/jit/compiler.hpp
index 4355eda65cf307..38fa10167c48a9 100644
--- a/src/coreclr/jit/compiler.hpp
+++ b/src/coreclr/jit/compiler.hpp
@@ -5127,41 +5127,6 @@ BasicBlockVisit FlowGraphNaturalLoop::VisitLoopBlocks(TFunc func)
return VisitLoopBlocksReversePostOrder(func);
}
-//------------------------------------------------------------------------------
-// FlowGraphNaturalLoop::VisitLoopBlocksLexical: Visit the loop's blocks in
-// lexical order.
-//
-// Type parameters:
-// TFunc - Callback functor type
-//
-// Arguments:
-// func - Callback functor that takes a BasicBlock* and returns a
-// BasicBlockVisit.
-//
-// Returns:
-// BasicBlockVisit that indicated whether the visit was aborted by the
-// callback or whether all blocks were visited.
-//
-template
-BasicBlockVisit FlowGraphNaturalLoop::VisitLoopBlocksLexical(TFunc func)
-{
- BasicBlock* const top = GetLexicallyTopMostBlock();
- BasicBlock* const bottom = GetLexicallyBottomMostBlock();
-
- for (BasicBlock* const block : m_dfsTree->GetCompiler()->Blocks(top, bottom))
- {
- if (ContainsBlock(block))
- {
- if (func(block) == BasicBlockVisit::Abort)
- {
- return BasicBlockVisit::Abort;
- }
- }
- }
-
- return BasicBlockVisit::Continue;
-}
-
//------------------------------------------------------------------------------
// FlowGraphNaturalLoop::VisitRegularExitBlocks: Visit non-handler blocks that
// are outside the loop but that may have regular predecessors inside the loop.
diff --git a/src/coreclr/jit/decomposelongs.cpp b/src/coreclr/jit/decomposelongs.cpp
index 84802400feeb0a..9280f459f978b9 100644
--- a/src/coreclr/jit/decomposelongs.cpp
+++ b/src/coreclr/jit/decomposelongs.cpp
@@ -1707,6 +1707,11 @@ GenTree* DecomposeLongs::DecomposeHWIntrinsic(LIR::Use& use)
return DecomposeHWIntrinsicGetElement(use, hwintrinsicTree);
}
+ case NI_EVEX_MoveMask:
+ {
+ return DecomposeHWIntrinsicMoveMask(use, hwintrinsicTree);
+ }
+
default:
{
noway_assert(!"unexpected GT_HWINTRINSIC node in long decomposition");
@@ -1830,6 +1835,106 @@ GenTree* DecomposeLongs::DecomposeHWIntrinsicGetElement(LIR::Use& use, GenTreeHW
return FinalizeDecomposition(use, loResult, hiResult, hiResult);
}
+//------------------------------------------------------------------------
+// DecomposeHWIntrinsicMoveMask: Decompose GT_HWINTRINSIC -- NI_EVEX_MoveMask
+//
+// Decompose a MoveMask(x) node on Vector512<*>. For:
+//
+// GT_HWINTRINSIC{MoveMask}[*](simd_var)
+//
+// create:
+//
+// tmp_simd_var = simd_var
+// tmp_simd_lo = GT_HWINTRINSIC{GetLower}(tmp_simd_var)
+// lo_result = GT_HWINTRINSIC{MoveMask}(tmp_simd_lo)
+// tmp_simd_hi = GT_HWINTRINSIC{GetUpper}(tmp_simd_var)
+// hi_result = GT_HWINTRINSIC{MoveMask}(tmp_simd_hi)
+// return: GT_LONG(lo_result, hi_result)
+//
+// Noting that for all types except byte/sbyte, hi_result will be exclusively
+// zero and so we can actually optimize this a bit more directly
+//
+// Arguments:
+// use - the LIR::Use object for the def that needs to be decomposed.
+// node - the hwintrinsic node to decompose
+//
+// Return Value:
+// The next node to process.
+//
+GenTree* DecomposeLongs::DecomposeHWIntrinsicMoveMask(LIR::Use& use, GenTreeHWIntrinsic* node)
+{
+ assert(node == use.Def());
+ assert(varTypeIsLong(node));
+ assert(node->GetHWIntrinsicId() == NI_EVEX_MoveMask);
+
+ GenTree* op1 = node->Op(1);
+ CorInfoType simdBaseJitType = node->GetSimdBaseJitType();
+ var_types simdBaseType = node->GetSimdBaseType();
+ unsigned simdSize = node->GetSimdSize();
+
+ assert(varTypeIsArithmetic(simdBaseType));
+ assert(op1->TypeGet() == TYP_MASK);
+ assert(simdSize == 64);
+
+ GenTree* loResult = nullptr;
+ GenTree* hiResult = nullptr;
+
+ if (varTypeIsByte(simdBaseType))
+ {
+ // Create:
+ // simdTmpVar = op1
+
+ GenTree* simdTmpVar = RepresentOpAsLocalVar(op1, node, &node->Op(1));
+ unsigned simdTmpVarNum = simdTmpVar->AsLclVarCommon()->GetLclNum();
+ JITDUMP("[DecomposeHWIntrinsicMoveMask]: Saving op1 tree to a temp var:\n");
+ DISPTREERANGE(Range(), simdTmpVar);
+ Range().Remove(simdTmpVar);
+
+ Range().InsertBefore(node, simdTmpVar);
+
+ // Create:
+ // loResult = GT_HWINTRINSIC{MoveMask}(simdTmpVar)
+
+ loResult = m_compiler->gtNewSimdHWIntrinsicNode(TYP_INT, simdTmpVar, NI_EVEX_MoveMask, simdBaseJitType, 32);
+ Range().InsertBefore(node, loResult);
+
+ simdTmpVar = m_compiler->gtNewLclLNode(simdTmpVarNum, simdTmpVar->TypeGet());
+ Range().InsertBefore(node, simdTmpVar);
+
+ // Create:
+ // simdTmpVar = GT_HWINTRINSIC{ShiftRightMask}(simdTmpVar, 32)
+ // hiResult = GT_HWINTRINSIC{MoveMask}(simdTmpVar)
+
+ GenTree* shiftIcon = m_compiler->gtNewIconNode(32, TYP_INT);
+ Range().InsertBefore(node, shiftIcon);
+
+ simdTmpVar = m_compiler->gtNewSimdHWIntrinsicNode(TYP_MASK, simdTmpVar, shiftIcon, NI_EVEX_ShiftRightMask,
+ simdBaseJitType, 64);
+ Range().InsertBefore(node, simdTmpVar);
+
+ hiResult = m_compiler->gtNewSimdHWIntrinsicNode(TYP_INT, simdTmpVar, NI_EVEX_MoveMask, simdBaseJitType, 32);
+ Range().InsertBefore(node, hiResult);
+ }
+ else
+ {
+ // Create:
+ // loResult = GT_HWINTRINSIC{MoveMask}(op1)
+
+ loResult = m_compiler->gtNewSimdHWIntrinsicNode(TYP_INT, op1, NI_EVEX_MoveMask, simdBaseJitType, simdSize);
+ Range().InsertBefore(node, loResult);
+
+ // Create:
+ // hiResult = GT_ICON(0)
+
+ hiResult = m_compiler->gtNewZeroConNode(TYP_INT);
+ Range().InsertBefore(node, hiResult);
+ }
+
+ // Done with the original tree; remove it.
+ Range().Remove(node);
+
+ return FinalizeDecomposition(use, loResult, hiResult, hiResult);
+}
#endif // FEATURE_HW_INTRINSICS
//------------------------------------------------------------------------
diff --git a/src/coreclr/jit/decomposelongs.h b/src/coreclr/jit/decomposelongs.h
index 744061091e42be..02681322a552e9 100644
--- a/src/coreclr/jit/decomposelongs.h
+++ b/src/coreclr/jit/decomposelongs.h
@@ -64,6 +64,7 @@ class DecomposeLongs
#ifdef FEATURE_HW_INTRINSICS
GenTree* DecomposeHWIntrinsic(LIR::Use& use);
GenTree* DecomposeHWIntrinsicGetElement(LIR::Use& use, GenTreeHWIntrinsic* node);
+ GenTree* DecomposeHWIntrinsicMoveMask(LIR::Use& use, GenTreeHWIntrinsic* node);
#endif // FEATURE_HW_INTRINSICS
GenTree* OptimizeCastFromDecomposedLong(GenTreeCast* cast, GenTree* nextNode);
diff --git a/src/coreclr/jit/fgbasic.cpp b/src/coreclr/jit/fgbasic.cpp
index 30a3a83581a3bb..320ad81906c310 100644
--- a/src/coreclr/jit/fgbasic.cpp
+++ b/src/coreclr/jit/fgbasic.cpp
@@ -8,167 +8,102 @@
// Flowgraph Construction and Maintenance
-//------------------------------------------------------------------------
-// fgEnsureFirstBBisScratch: Ensure that fgFirstBB is a scratch BasicBlock
+//------------------------------------------------------------------------------
+// fgCanonicalizeFirstBB: Canonicalize the method entry to be dominate all
+// blocks in the BB and to be executed exactly once.
//
// Returns:
-// True, if a new basic block was allocated.
-//
-// Notes:
-// This should be called before adding on-entry initialization code to
-// the method, to ensure that fgFirstBB is not part of a loop.
-//
-// Does nothing, if fgFirstBB is already a scratch BB. After calling this,
-// fgFirstBB may already contain code. Callers have to be careful
-// that they do not mess up the order of things added to this block and
-// inadvertently change semantics.
-//
-// We maintain the invariant that a scratch BB ends with BBJ_ALWAYS,
-// so that when adding independent bits of initialization,
-// callers can generally append to the fgFirstBB block without worrying
-// about what code is there already.
+// Suitable phase status.
//
-// Can be called at any time, and can be called multiple times.
-//
-bool Compiler::fgEnsureFirstBBisScratch()
+PhaseStatus Compiler::fgCanonicalizeFirstBB()
{
- // Have we already allocated a scratch block?
- if (fgFirstBBisScratch())
+ if (fgFirstBB->hasTryIndex())
{
- return false;
+ JITDUMP("Canonicalizing entry because it currently is the beginning of a try region\n");
+ }
+ else if (fgFirstBB->bbPreds != nullptr)
+ {
+ JITDUMP("Canonicalizing entry because it currently has predecessors\n");
+ }
+ else if (opts.compDbgCode && !fgFirstBB->HasFlag(BBF_INTERNAL))
+ {
+ // For debug ensure the first BB is internal so as to not conflate user
+ // code with JIT added code.
+ JITDUMP("Canonicalizing entry because it currently is a user BB and we are generating debug code\n");
+ }
+ else
+ {
+ return PhaseStatus::MODIFIED_NOTHING;
}
- assert(fgFirstBBScratch == nullptr);
-
- BasicBlock* block;
+ fgCreateNewInitBB();
+ return PhaseStatus::MODIFIED_EVERYTHING;
+}
- if (fgFirstBB != nullptr)
- {
- // The first block has an implicit ref count which we must
- // remove. Note the ref count could be greater than one, if
- // the first block is not scratch and is targeted by a
- // branch.
- assert(fgFirstBB->bbRefs >= 1);
- fgFirstBB->bbRefs--;
+//------------------------------------------------------------------------------
+// fgCreateNewInitBB:
+// Create a new init BB at the beginning of the function.
+//
+void Compiler::fgCreateNewInitBB()
+{
+ // The first block has an implicit ref count which we must remove. Note the
+ // ref count could be greater than one, if the first block is targeted by a
+ // branch.
+ assert(fgFirstBB->bbRefs >= 1);
+ fgFirstBB->bbRefs--;
- block = BasicBlock::New(this);
+ BasicBlock* block = BasicBlock::New(this);
- // If we have profile data determine the weight of the scratch BB
+ // If we have profile data determine the weight of the initBB BB
+ //
+ if (fgFirstBB->hasProfileWeight())
+ {
+ // If current entry has preds, sum up those weights
//
- if (fgFirstBB->hasProfileWeight())
+ weight_t nonEntryWeight = 0;
+ for (FlowEdge* const edge : fgFirstBB->PredEdges())
{
- // If current entry has preds, sum up those weights
- //
- weight_t nonEntryWeight = 0;
- for (FlowEdge* const edge : fgFirstBB->PredEdges())
- {
- nonEntryWeight += edge->getLikelyWeight();
- }
+ nonEntryWeight += edge->getLikelyWeight();
+ }
- // entry weight is weight not from any pred
+ // entry weight is weight not from any pred
+ //
+ weight_t const entryWeight = fgFirstBB->bbWeight - nonEntryWeight;
+ if (entryWeight <= 0)
+ {
+ // If the result is clearly nonsensical, just inherit
//
- weight_t const entryWeight = fgFirstBB->bbWeight - nonEntryWeight;
- if (entryWeight <= 0)
- {
- // If the result is clearly nonsensical, just inherit
- //
- JITDUMP(
- "\fgEnsureFirstBBisScratch: Profile data could not be locally repaired. Data %s inconsistent.\n",
+ JITDUMP("\fgCanonicalizeFirstBB: Profile data could not be locally repaired. Data %s inconsistent.\n",
fgPgoConsistent ? "is now" : "was already");
- if (fgPgoConsistent)
- {
- Metrics.ProfileInconsistentScratchBB++;
- fgPgoConsistent = false;
- }
-
- block->inheritWeight(fgFirstBB);
- }
- else
+ if (fgPgoConsistent)
{
- block->setBBProfileWeight(entryWeight);
+ Metrics.ProfileInconsistentScratchBB++;
+ fgPgoConsistent = false;
}
- }
- // The new scratch bb will fall through to the old first bb
- FlowEdge* const edge = fgAddRefPred(fgFirstBB, block);
- block->SetKindAndTargetEdge(BBJ_ALWAYS, edge);
- fgInsertBBbefore(fgFirstBB, block);
- }
- else
- {
- noway_assert(fgLastBB == nullptr);
- block = BasicBlock::New(this, BBJ_ALWAYS);
- fgFirstBB = block;
- fgLastBB = block;
+ block->inheritWeight(fgFirstBB);
+ }
+ else
+ {
+ block->setBBProfileWeight(entryWeight);
+ }
}
- noway_assert(fgLastBB != nullptr);
+ // The new scratch bb will fall through to the old first bb
+ FlowEdge* const edge = fgAddRefPred(fgFirstBB, block);
+ block->SetKindAndTargetEdge(BBJ_ALWAYS, edge);
+ fgInsertBBbefore(fgFirstBB, block);
// Set the expected flags
- block->SetFlags(BBF_INTERNAL | BBF_IMPORTED);
+ block->SetFlags(BBF_INTERNAL);
// This new first BB has an implicit ref, and no others.
//
- // But if we call this early, before fgLinkBasicBlocks,
- // defer and let it handle adding the implicit ref.
- //
- block->bbRefs = fgPredsComputed ? 1 : 0;
-
- fgFirstBBScratch = fgFirstBB;
-
-#ifdef DEBUG
- if (verbose)
- {
- printf("New scratch " FMT_BB "\n", block->bbNum);
- }
-#endif
-
- return true;
-}
-
-//------------------------------------------------------------------------
-// fgFirstBBisScratch: Check if fgFirstBB is a scratch block
-//
-// Returns:
-// true if fgFirstBB is a scratch block.
-//
-bool Compiler::fgFirstBBisScratch()
-{
- if (fgFirstBBScratch != nullptr)
- {
- assert(fgFirstBBScratch == fgFirstBB);
- assert(fgFirstBBScratch->HasFlag(BBF_INTERNAL));
- if (fgPredsComputed)
- {
- assert(fgFirstBBScratch->countOfInEdges() == 1);
- }
-
- // Normally, the first scratch block is a fall-through block. However, if the block after it was an empty
- // BBJ_ALWAYS block, it might get removed, and the code that removes it will make the first scratch block
- // a BBJ_ALWAYS block.
- assert(fgFirstBBScratch->KindIs(BBJ_ALWAYS));
-
- return true;
- }
- else
- {
- return false;
- }
-}
+ assert(fgPredsComputed);
+ block->bbRefs = 1;
-//------------------------------------------------------------------------
-// fgBBisScratch: Check if a given block is a scratch block.
-//
-// Arguments:
-// block - block in question
-//
-// Returns:
-// true if this block is the first block and is a scratch block.
-//
-bool Compiler::fgBBisScratch(BasicBlock* block)
-{
- return fgFirstBBisScratch() && (block == fgFirstBB);
+ JITDUMP("New init " FMT_BB "\n", block->bbNum);
}
/*
@@ -4071,8 +4006,9 @@ void Compiler::fgFixEntryFlowForOSR()
// Now branch from method start to the OSR entry.
//
- fgEnsureFirstBBisScratch();
- assert(fgFirstBB->KindIs(BBJ_ALWAYS) && fgFirstBB->JumpsToNext());
+ fgCreateNewInitBB();
+ assert(fgFirstBB->KindIs(BBJ_ALWAYS));
+
fgRedirectTargetEdge(fgFirstBB, fgOSREntryBB);
// We don't know the right weight for this block, since
@@ -4952,22 +4888,9 @@ void Compiler::fgUnlinkBlock(BasicBlock* block)
{
assert(block == fgFirstBB);
assert(block != fgLastBB);
- assert((fgFirstBBScratch == nullptr) || (fgFirstBBScratch == fgFirstBB));
fgFirstBB = block->Next();
fgFirstBB->SetPrevToNull();
-
- if (fgFirstBBScratch != nullptr)
- {
-#ifdef DEBUG
- // We had created an initial scratch BB, but now we're deleting it.
- if (verbose)
- {
- printf("Unlinking scratch " FMT_BB "\n", block->bbNum);
- }
-#endif // DEBUG
- fgFirstBBScratch = nullptr;
- }
}
else if (block->IsLast())
{
@@ -5126,15 +5049,6 @@ BasicBlock* Compiler::fgRemoveBlock(BasicBlock* block, bool unreachable)
BasicBlock* succBlock = block->GetTarget();
- bool skipUnmarkLoop = false;
-
- if (succBlock->isLoopHead() && bPrev && (succBlock->bbNum <= bPrev->bbNum))
- {
- // It looks like `block` is the source of a back edge of a loop, and once we remove `block` the
- // loop will still exist because we'll move the edge to `bPrev`. So, don't unscale the loop blocks.
- skipUnmarkLoop = true;
- }
-
// Update fgFirstFuncletBB if necessary
if (block == fgFirstFuncletBB)
{
@@ -5925,7 +5839,7 @@ BasicBlock* Compiler::fgNewBBFromTreeAfter(
*/
void Compiler::fgInsertBBbefore(BasicBlock* insertBeforeBlk, BasicBlock* newBlk)
{
- if (fgFirstBB == insertBeforeBlk)
+ if (insertBeforeBlk == fgFirstBB)
{
newBlk->SetNext(fgFirstBB);
@@ -5937,8 +5851,7 @@ void Compiler::fgInsertBBbefore(BasicBlock* insertBeforeBlk, BasicBlock* newBlk)
fgInsertBBafter(insertBeforeBlk->Prev(), newBlk);
}
- /* Update fgFirstFuncletBB if insertBeforeBlk is the first block of the funclet region. */
- if (fgFirstFuncletBB == insertBeforeBlk)
+ if (insertBeforeBlk == fgFirstFuncletBB)
{
fgFirstFuncletBB = newBlk;
}
diff --git a/src/coreclr/jit/fgdiagnostic.cpp b/src/coreclr/jit/fgdiagnostic.cpp
index 0abf553f2f0c60..9003430bb0bcc0 100644
--- a/src/coreclr/jit/fgdiagnostic.cpp
+++ b/src/coreclr/jit/fgdiagnostic.cpp
@@ -959,6 +959,10 @@ bool Compiler::fgDumpFlowGraph(Phases phase, PhasePosition pos)
{
fprintf(fgxFile, "\n callsNew=\"true\"");
}
+ if (block->HasFlag(BBF_HAS_NEWARR))
+ {
+ fprintf(fgxFile, "\n callsNewArr=\"true\"");
+ }
if (block->HasFlag(BBF_LOOP_HEAD))
{
fprintf(fgxFile, "\n loopHead=\"true\"");
@@ -2905,7 +2909,6 @@ void Compiler::fgDebugCheckBBlist(bool checkBBNum /* = false */, bool checkBBRef
}
fgDebugCheckBlockLinks();
- fgFirstBBisScratch();
if (fgBBcount > 10000 && expensiveDebugCheckLevel < 1)
{
@@ -3217,6 +3220,17 @@ void Compiler::fgDebugCheckBBlist(bool checkBBNum /* = false */, bool checkBBRef
}
}
+//------------------------------------------------------------------------
+// fgDebugCheckInitBB: Check that the first BB is a valid init BB.
+//
+void Compiler::fgDebugCheckInitBB()
+{
+ assert(fgFirstBB != nullptr);
+ assert(!fgFirstBB->hasTryIndex());
+ assert(fgFirstBB->bbPreds == nullptr);
+ assert(!opts.compDbgCode || fgFirstBB->HasFlag(BBF_INTERNAL));
+}
+
//------------------------------------------------------------------------
// fgDebugCheckTypes: Validate node types used in the given tree
//
@@ -4712,7 +4726,9 @@ void Compiler::fgDebugCheckFlowGraphAnnotations()
{
if (m_dfsTree == nullptr)
{
- assert((m_loops == nullptr) && (m_domTree == nullptr) && (m_reachabilitySets == nullptr));
+ assert(m_loops == nullptr);
+ assert((m_domTree == nullptr) && (m_domFrontiers == nullptr));
+ assert(m_reachabilitySets == nullptr);
return;
}
diff --git a/src/coreclr/jit/fginline.cpp b/src/coreclr/jit/fginline.cpp
index d7abf54dfc3946..ee75f8b13cd774 100644
--- a/src/coreclr/jit/fginline.cpp
+++ b/src/coreclr/jit/fginline.cpp
@@ -644,98 +644,28 @@ class SubstitutePlaceholdersAndDevirtualizeWalker : public GenTreeVisitorgtUpdateNodeSideEffects(tree);
assert((tree->gtFlags & GTF_SIDE_EFFECT) == 0);
tree->gtBashToNOP();
- m_madeChanges = true;
- FlowEdge* removedEdge = nullptr;
+ m_madeChanges = true;
+ FlowEdge* removedEdge = nullptr;
+ FlowEdge* retainedEdge = nullptr;
if (condTree->IsIntegralConst(0))
{
- removedEdge = block->GetTrueEdge();
- m_compiler->fgRemoveRefPred(removedEdge);
- block->SetKindAndTargetEdge(BBJ_ALWAYS, block->GetFalseEdge());
+ removedEdge = block->GetTrueEdge();
+ retainedEdge = block->GetFalseEdge();
}
else
{
- removedEdge = block->GetFalseEdge();
- m_compiler->fgRemoveRefPred(removedEdge);
- block->SetKindAndTargetEdge(BBJ_ALWAYS, block->GetTrueEdge());
+ removedEdge = block->GetFalseEdge();
+ retainedEdge = block->GetTrueEdge();
}
- // Update profile; make it consistent if possible
- //
- if (block->hasProfileWeight())
- {
- bool repairWasComplete = true;
- bool missingProfileData = false;
- weight_t const weight = removedEdge->getLikelyWeight();
-
- if (weight > 0)
- {
- // Target block weight will increase.
- //
- BasicBlock* const target = block->GetTarget();
-
- // We may have a profiled inlinee in an unprofiled method
- //
- if (target->hasProfileWeight())
- {
- target->setBBProfileWeight(target->bbWeight + weight);
- missingProfileData = true;
- }
-
- // Alternate weight will decrease
- //
- BasicBlock* const alternate = removedEdge->getDestinationBlock();
-
- if (alternate->hasProfileWeight())
- {
- weight_t const alternateNewWeight = alternate->bbWeight - weight;
-
- // If profile weights are consistent, expect at worst a slight underflow.
- //
- if (m_compiler->fgPgoConsistent && (alternateNewWeight < 0))
- {
- assert(m_compiler->fgProfileWeightsEqual(alternateNewWeight, 0));
- }
- alternate->setBBProfileWeight(max(0.0, alternateNewWeight));
- }
- else
- {
- missingProfileData = true;
- }
-
- // This will affect profile transitively, so in general
- // the profile will become inconsistent.
- //
- repairWasComplete = false;
+ m_compiler->fgRemoveRefPred(removedEdge);
+ block->SetKindAndTargetEdge(BBJ_ALWAYS, retainedEdge);
- // But we can check for the special case where the
- // block's postdominator is target's target (simple
- // if/then/else/join).
- //
- if (!missingProfileData && target->KindIs(BBJ_ALWAYS))
- {
- repairWasComplete =
- alternate->KindIs(BBJ_ALWAYS) && alternate->TargetIs(target->GetTarget());
- }
- }
-
- if (missingProfileData)
- {
- JITDUMP("Profile data could not be locally repaired. Data was missing.\n");
- }
-
- if (!repairWasComplete)
- {
- JITDUMP("Profile data could not be locally repaired. Data %s inconsistent.\n",
- m_compiler->fgPgoConsistent ? "is now" : "was already");
-
- if (m_compiler->fgPgoConsistent)
- {
- m_compiler->Metrics.ProfileInconsistentInlinerBranchFold++;
- m_compiler->fgPgoConsistent = false;
- }
- }
- }
+ // Update profile, make it consistent if possible.
+ //
+ m_compiler->fgRepairProfileCondToUncond(block, retainedEdge, removedEdge,
+ &m_compiler->Metrics.ProfileInconsistentInlinerBranchFold);
}
}
else
diff --git a/src/coreclr/jit/fgopt.cpp b/src/coreclr/jit/fgopt.cpp
index 9d80caeb5db3d5..834a53be776a61 100644
--- a/src/coreclr/jit/fgopt.cpp
+++ b/src/coreclr/jit/fgopt.cpp
@@ -823,9 +823,9 @@ bool Compiler::fgCanCompactBlock(BasicBlock* block)
return false;
}
- // Don't compact the first block if it was specially created as a scratch block.
+ // Ensure we leave a valid init BB around.
//
- if (fgBBisScratch(block))
+ if ((block == fgFirstBB) && !fgCanCompactInitBlock())
{
return false;
}
@@ -851,6 +851,40 @@ bool Compiler::fgCanCompactBlock(BasicBlock* block)
return true;
}
+//-------------------------------------------------------------
+// fgCanCompactInitBlock: Check if the first BB (the init BB) can be compacted
+// into its target.
+//
+// Returns:
+// true if compaction is allowed
+//
+bool Compiler::fgCanCompactInitBlock()
+{
+ assert(fgFirstBB->KindIs(BBJ_ALWAYS));
+ BasicBlock* target = fgFirstBB->GetTarget();
+ if (target->hasTryIndex())
+ {
+ // Inside a try region
+ return false;
+ }
+
+ assert(target->bbPreds != nullptr);
+ if (target->bbPreds->getNextPredEdge() != nullptr)
+ {
+ // Multiple preds
+ return false;
+ }
+
+ if (opts.compDbgCode && !target->HasFlag(BBF_INTERNAL))
+ {
+ // Init BB must be internal for debug code to avoid conflating
+ // JIT-inserted code with user code.
+ return false;
+ }
+
+ return true;
+}
+
//-------------------------------------------------------------
// fgCompactBlock: Compact BBJ_ALWAYS block and its target into one.
//
@@ -1389,7 +1423,7 @@ bool Compiler::fgOptimizeEmptyBlock(BasicBlock* block)
if (bPrev == nullptr)
{
assert(block == fgFirstBB);
- if (!block->JumpsToNext())
+ if (!block->JumpsToNext() || !fgCanCompactInitBlock())
{
break;
}
@@ -1401,8 +1435,9 @@ bool Compiler::fgOptimizeEmptyBlock(BasicBlock* block)
break;
}
- // Don't remove fgEntryBB
- if (block == fgEntryBB)
+ // Don't remove the init BB if it does not leave a proper init BB
+ // in place
+ if ((block == fgFirstBB) && !fgCanCompactInitBlock())
{
break;
}
@@ -2161,11 +2196,6 @@ bool Compiler::fgOptimizeUncondBranchToSimpleCond(BasicBlock* block, BasicBlock*
return false;
}
- if (fgBBisScratch(block))
- {
- return false;
- }
-
unsigned lclNum = BAD_VAR_NUM;
// First check if the successor tests a local and then branches on the result
@@ -2525,12 +2555,6 @@ bool Compiler::fgOptimizeBranch(BasicBlock* bJump)
return false;
}
- // Don't hoist a conditional branch into the scratch block; we'd prefer it stay BBJ_ALWAYS.
- if (fgBBisScratch(bJump))
- {
- return false;
- }
-
BasicBlock* bDest = bJump->GetTarget();
if (!bDest->KindIs(BBJ_COND))
@@ -6481,9 +6505,9 @@ PhaseStatus Compiler::fgHeadTailMerge(bool early)
Statement* const stmt = info.m_stmt;
BasicBlock* const predBlock = info.m_block;
- // Never pick the scratch block as the victim as that would
+ // Never pick the init block as the victim as that would
// cause us to add a predecessor to it, which is invalid.
- if (fgBBisScratch(predBlock))
+ if (predBlock == fgFirstBB)
{
continue;
}
diff --git a/src/coreclr/jit/fgprofile.cpp b/src/coreclr/jit/fgprofile.cpp
index 4bbcb6ea9b7aa4..0b8f4378c48270 100644
--- a/src/coreclr/jit/fgprofile.cpp
+++ b/src/coreclr/jit/fgprofile.cpp
@@ -4474,7 +4474,7 @@ bool Compiler::fgComputeCalledCount(weight_t returnWeight)
// If we allocated a scratch block as the first BB then we need
// to set its profile-derived weight to be fgCalledCount
- if (fgFirstBBisScratch())
+ if (fgFirstBB->HasFlag(BBF_INTERNAL))
{
fgFirstBB->setBBProfileWeight(fgCalledCount);
madeChanges = true;
@@ -5063,3 +5063,115 @@ bool Compiler::fgDebugCheckOutgoingProfileData(BasicBlock* block, ProfileChecks
}
#endif // DEBUG
+
+//------------------------------------------------------------------------
+// fgRepairProfileCondToUncond: attempt to repair profile after modifying
+// a conditinal branch to an unconditional branch.
+//
+// Arguments:
+// block - block that was just altered
+// retainedEdge - flow edge that remains
+// removedEdge - flow edge that was removed
+// metric - [in/out, optional] metric to update if profile becomes inconsistent
+//
+void Compiler::fgRepairProfileCondToUncond(BasicBlock* block,
+ FlowEdge* retainedEdge,
+ FlowEdge* removedEdge,
+ int* metric /* = nullptr */)
+{
+ assert(block->KindIs(BBJ_ALWAYS));
+ assert(block->GetTargetEdge() == retainedEdge);
+
+ // If block does not have profile data, there's nothing to do.
+ //
+ if (!block->hasProfileWeight())
+ {
+ return;
+ }
+
+ // If the removed edge was not carrying away any profile, there's nothing to do.
+ //
+ weight_t const weight = removedEdge->getLikelyWeight();
+
+ if (weight == 0.0)
+ {
+ return;
+ }
+
+ // If the branch was degenerate, there is nothing to do
+ //
+ if (retainedEdge == removedEdge)
+ {
+ return;
+ }
+
+ // This flow graph change will affect profile transitively, so in general
+ // the profile will become inconsistent.
+ //
+ bool repairWasComplete = false;
+ bool missingProfileData = false;
+
+ // Target block weight will increase.
+ //
+ BasicBlock* const target = block->GetTarget();
+
+ if (target->hasProfileWeight())
+ {
+ target->setBBProfileWeight(target->bbWeight + weight);
+ }
+ else
+ {
+ missingProfileData = true;
+ }
+
+ // Alternate weight will decrease
+ //
+ BasicBlock* const alternate = removedEdge->getDestinationBlock();
+
+ if (alternate->hasProfileWeight())
+ {
+ weight_t const alternateNewWeight = alternate->bbWeight - weight;
+
+ // If profile weights are consistent, expect at worst a slight underflow.
+ //
+ if (fgPgoConsistent && (alternateNewWeight < 0.0))
+ {
+ assert(fgProfileWeightsEqual(alternateNewWeight, 0.0));
+ }
+ alternate->setBBProfileWeight(max(0.0, alternateNewWeight));
+ }
+ else
+ {
+ missingProfileData = true;
+ }
+
+ // Check for the special case where the block's postdominator
+ // is target's target (simple if/then/else/join).
+ //
+ // TODO: try a bit harder to find a postdominator, if it's "nearby"
+ //
+ if (!missingProfileData && target->KindIs(BBJ_ALWAYS))
+ {
+ repairWasComplete = alternate->KindIs(BBJ_ALWAYS) && (alternate->GetTarget() == target->GetTarget());
+ }
+
+ if (missingProfileData)
+ {
+ JITDUMP("Profile data could not be locally repaired. Data was missing.\n");
+ }
+
+ if (!repairWasComplete)
+ {
+ JITDUMP("Profile data could not be locally repaired. Data %s inconsistent.\n",
+ fgPgoConsistent ? "is now" : "was already");
+
+ if (fgPgoConsistent)
+ {
+ if (metric != nullptr)
+ {
+ *metric++;
+ }
+ fgPgoConsistent = false;
+ }
+ }
+}
diff --git a/src/coreclr/jit/flowgraph.cpp b/src/coreclr/jit/flowgraph.cpp
index 91d62de8316b75..127b76e63e8486 100644
--- a/src/coreclr/jit/flowgraph.cpp
+++ b/src/coreclr/jit/flowgraph.cpp
@@ -1388,14 +1388,9 @@ void Compiler::fgAddSyncMethodEnterExit()
NYI("No support for synchronized methods");
#endif // !FEATURE_EH
- // Create a scratch first BB where we can put the new variable initialization.
- // Don't put the scratch BB in the protected region.
-
- fgEnsureFirstBBisScratch();
-
// Create a block for the start of the try region, where the monitor enter call
// will go.
- BasicBlock* const tryBegBB = fgSplitBlockAtEnd(fgFirstBB);
+ BasicBlock* const tryBegBB = fgSplitBlockAtBeginning(fgFirstBB);
BasicBlock* const tryLastBB = fgLastBB;
// Create a block for the fault.
@@ -1517,7 +1512,7 @@ void Compiler::fgAddSyncMethodEnterExit()
GenTree* zero = gtNewZeroConNode(typeMonAcquired);
GenTree* initNode = gtNewStoreLclVarNode(lvaMonAcquired, zero);
- fgNewStmtAtEnd(fgFirstBB, initNode);
+ fgNewStmtAtBeg(fgFirstBB, initNode);
#ifdef DEBUG
if (verbose)
@@ -1543,7 +1538,7 @@ void Compiler::fgAddSyncMethodEnterExit()
GenTree* thisNode = gtNewLclVarNode(info.compThisArg);
GenTree* initNode = gtNewStoreLclVarNode(lvaCopyThis, thisNode);
- fgNewStmtAtEnd(tryBegBB, initNode);
+ fgNewStmtAtBeg(tryBegBB, initNode);
}
// For OSR, we do not need the enter tree as the monitor is acquired by the original method.
@@ -1603,38 +1598,45 @@ GenTree* Compiler::fgCreateMonitorTree(unsigned lvaMonAcquired, unsigned lvaThis
}
#endif
- if (block->KindIs(BBJ_RETURN) && block->lastStmt()->GetRootNode()->OperIs(GT_RETURN))
+ if (enter)
{
- GenTreeUnOp* retNode = block->lastStmt()->GetRootNode()->AsUnOp();
- GenTree* retExpr = retNode->gtOp1;
-
- if (retExpr != nullptr)
+ fgNewStmtAtBeg(block, tree);
+ }
+ else
+ {
+ if (block->KindIs(BBJ_RETURN) && block->lastStmt()->GetRootNode()->OperIs(GT_RETURN))
{
- // have to insert this immediately before the GT_RETURN so we transform:
- // ret(...) ->
- // ret(comma(comma(tmp=...,call mon_exit), tmp))
- //
- TempInfo tempInfo = fgMakeTemp(retExpr);
- GenTree* lclVar = tempInfo.load;
+ GenTreeUnOp* retNode = block->lastStmt()->GetRootNode()->AsUnOp();
+ GenTree* retExpr = retNode->gtOp1;
+
+ if (retExpr != nullptr)
+ {
+ // have to insert this immediately before the GT_RETURN so we transform:
+ // ret(...) ->
+ // ret(comma(comma(tmp=...,call mon_exit), tmp))
+ //
+ TempInfo tempInfo = fgMakeTemp(retExpr);
+ GenTree* lclVar = tempInfo.load;
- // TODO-1stClassStructs: delete this NO_CSE propagation. Requires handling multi-regs in copy prop.
- lclVar->gtFlags |= (retExpr->gtFlags & GTF_DONT_CSE);
+ // TODO-1stClassStructs: delete this NO_CSE propagation. Requires handling multi-regs in copy prop.
+ lclVar->gtFlags |= (retExpr->gtFlags & GTF_DONT_CSE);
- retExpr = gtNewOperNode(GT_COMMA, lclVar->TypeGet(), tree, lclVar);
- retExpr = gtNewOperNode(GT_COMMA, lclVar->TypeGet(), tempInfo.store, retExpr);
- retNode->gtOp1 = retExpr;
- retNode->AddAllEffectsFlags(retExpr);
+ retExpr = gtNewOperNode(GT_COMMA, lclVar->TypeGet(), tree, lclVar);
+ retExpr = gtNewOperNode(GT_COMMA, lclVar->TypeGet(), tempInfo.store, retExpr);
+ retNode->gtOp1 = retExpr;
+ retNode->AddAllEffectsFlags(retExpr);
+ }
+ else
+ {
+ // Insert this immediately before the GT_RETURN
+ fgNewStmtNearEnd(block, tree);
+ }
}
else
{
- // Insert this immediately before the GT_RETURN
- fgNewStmtNearEnd(block, tree);
+ fgNewStmtAtEnd(block, tree);
}
}
- else
- {
- fgNewStmtAtEnd(block, tree);
- }
return tree;
}
@@ -1727,8 +1729,6 @@ void Compiler::fgAddReversePInvokeEnterExit()
tree = gtNewHelperCallNode(CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER, TYP_VOID, pInvokeFrameVar);
}
- fgEnsureFirstBBisScratch();
-
fgNewStmtAtBeg(fgFirstBB, tree);
#ifdef DEBUG
@@ -2307,15 +2307,6 @@ PhaseStatus Compiler::fgAddInternal()
// type with a runtime lookup
madeChanges |= fgCreateFiltersForGenericExceptions();
- // The backend requires a scratch BB into which it can safely insert a P/Invoke method prolog if one is
- // required. Similarly, we need a scratch BB for poisoning and when we have Swift parameters to reassemble.
- // Create it here.
- if (compMethodRequiresPInvokeFrame() || compShouldPoisonFrame() || lvaHasAnySwiftStackParamToReassemble())
- {
- madeChanges |= fgEnsureFirstBBisScratch();
- fgFirstBB->SetFlags(BBF_DONT_REMOVE);
- }
-
/*
VSW441487
@@ -2351,8 +2342,7 @@ PhaseStatus Compiler::fgAddInternal()
// Now assign the original input "this" to the temp.
GenTree* store = gtNewStoreLclVarNode(lvaArg0Var, gtNewLclVarNode(info.compThisArg));
- fgEnsureFirstBBisScratch();
- fgNewStmtAtEnd(fgFirstBB, store);
+ fgNewStmtAtBeg(fgFirstBB, store);
JITDUMP("\nCopy \"this\" to lvaArg0Var in first basic block %s\n", fgFirstBB->dspToString());
DISPTREE(store);
@@ -2481,8 +2471,7 @@ PhaseStatus Compiler::fgAddInternal()
// Stick the conditional call at the start of the method
- fgEnsureFirstBBisScratch();
- fgNewStmtAtEnd(fgFirstBB, gtNewQmarkNode(TYP_VOID, guardCheckCond, callback->AsColon()));
+ fgNewStmtAtBeg(fgFirstBB, gtNewQmarkNode(TYP_VOID, guardCheckCond, callback->AsColon()));
madeChanges = true;
}
@@ -2509,10 +2498,7 @@ PhaseStatus Compiler::fgAddInternal()
tree = gtNewHelperCallNode(CORINFO_HELP_MON_ENTER, TYP_VOID, tree);
- /* Create a new basic block and stick the call in it */
-
- fgEnsureFirstBBisScratch();
- fgNewStmtAtEnd(fgFirstBB, tree);
+ fgNewStmtAtBeg(fgFirstBB, tree);
#ifdef DEBUG
if (verbose)
@@ -6001,9 +5987,7 @@ void FlowGraphNaturalLoop::Duplicate(BasicBlock** insertAfter, BlockToBlockMap*
Compiler* comp = m_dfsTree->GetCompiler();
- BasicBlock* bottom = GetLexicallyBottomMostBlock();
-
- VisitLoopBlocksLexical([=](BasicBlock* blk) {
+ VisitLoopBlocks([=](BasicBlock* blk) {
// Initialize newBlk as BBJ_ALWAYS without jump target, and fix up jump target later
// with BasicBlock::CopyTarget().
BasicBlock* newBlk = comp->fgNewBBafter(BBJ_ALWAYS, *insertAfter, /*extendRegion*/ true);
@@ -6213,7 +6197,7 @@ void FlowGraphNaturalLoop::DuplicateWithEH(BasicBlock** insertAfter, BlockToBloc
BitVecTraits traits(comp->compBasicBlockID, comp);
BitVec visited(BitVecOps::MakeEmpty(&traits));
- VisitLoopBlocksLexical([=, &traits, &visited, &clonedTry, &ehIndexShift](BasicBlock* blk) {
+ VisitLoopBlocks([=, &traits, &visited, &clonedTry, &ehIndexShift](BasicBlock* blk) {
// Try cloning may have already handled this block
//
if (BitVecOps::IsMember(&traits, visited, blk->bbID))
diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp
index 2a3762aa3898c5..c31d6ac1b2c552 100644
--- a/src/coreclr/jit/gentree.cpp
+++ b/src/coreclr/jit/gentree.cpp
@@ -13572,10 +13572,13 @@ void Compiler::gtDispLIRNode(GenTree* node, const char* prefixMsg /* = nullptr *
* and call the methods to perform the folding
*/
-GenTree* Compiler::gtFoldExpr(GenTree* tree)
+GenTree* Compiler::gtFoldExpr(GenTree* tree, bool* folded)
{
unsigned kind = tree->OperKind();
+ if (folded != nullptr)
+ *folded = false;
+
/* We must have a simple operation to fold */
// If we're in CSE, it's not safe to perform tree
@@ -13595,13 +13598,19 @@ GenTree* Compiler::gtFoldExpr(GenTree* tree)
{
if (tree->OperIsConditional())
{
- return gtFoldExprConditional(tree);
+ GenTree* newTree = gtFoldExprConditional(tree);
+ if (folded != nullptr)
+ *folded = newTree != tree;
+ return newTree;
}
#if defined(FEATURE_HW_INTRINSICS)
if (tree->OperIsHWIntrinsic())
{
- return gtFoldExprHWIntrinsic(tree->AsHWIntrinsic());
+ GenTree* newTree = gtFoldExprHWIntrinsic(tree->AsHWIntrinsic());
+ if (folded != nullptr)
+ *folded = newTree != tree;
+ return newTree;
}
#endif // FEATURE_HW_INTRINSICS
@@ -13629,6 +13638,7 @@ GenTree* Compiler::gtFoldExpr(GenTree* tree)
{
if (op1->OperIsConst())
{
+ // constants folding results in a new tree that may be folded again, don't mark it as folded
return gtFoldExprConst(tree);
}
}
@@ -13640,7 +13650,8 @@ GenTree* Compiler::gtFoldExpr(GenTree* tree)
// one of their arguments is an address.
if (op1->OperIsConst() && op2->OperIsConst() && !tree->OperIsAtomicOp())
{
- /* both nodes are constants - fold the expression */
+ // both nodes are constants - fold the expression
+ // constants folding results in a new tree that may be folded again, don't mark it as folded
return gtFoldExprConst(tree);
}
else if (op1->OperIsConst() || op2->OperIsConst())
@@ -13655,13 +13666,19 @@ GenTree* Compiler::gtFoldExpr(GenTree* tree)
return tree;
}
- return gtFoldExprSpecial(tree);
+ GenTree* newTree = gtFoldExprSpecial(tree);
+ if (folded != nullptr)
+ *folded = newTree != tree;
+ return newTree;
}
else if (tree->OperIsCompare())
{
/* comparisons of two local variables can sometimes be folded */
- return gtFoldExprCompare(tree);
+ GenTree* newTree = gtFoldExprCompare(tree);
+ if (folded != nullptr)
+ *folded = newTree != tree;
+ return newTree;
}
}
@@ -27624,8 +27641,7 @@ void GenTreeHWIntrinsic::SetHWIntrinsicId(NamedIntrinsic intrinsicId)
{
return (op1->TypeGet() == op2->TypeGet()) && (op1->GetHWIntrinsicId() == op2->GetHWIntrinsicId()) &&
(op1->GetSimdBaseType() == op2->GetSimdBaseType()) && (op1->GetSimdSize() == op2->GetSimdSize()) &&
- (op1->GetAuxiliaryType() == op2->GetAuxiliaryType()) && (op1->GetRegByIndex(1) == op2->GetRegByIndex(1)) &&
- OperandsAreEqual(op1, op2);
+ (op1->GetAuxiliaryType() == op2->GetAuxiliaryType()) && OperandsAreEqual(op1, op2);
}
void GenTreeHWIntrinsic::Initialize(NamedIntrinsic intrinsicId)
diff --git a/src/coreclr/jit/gschecks.cpp b/src/coreclr/jit/gschecks.cpp
index ed2d7538a39787..558c30f6b35769 100644
--- a/src/coreclr/jit/gschecks.cpp
+++ b/src/coreclr/jit/gschecks.cpp
@@ -525,25 +525,68 @@ void Compiler::gsParamsToShadows()
call->gtArgs.PushBack(this, NewCallArg::Primitive(dst));
call->gtArgs.PushBack(this, NewCallArg::Primitive(src));
- fgEnsureFirstBBisScratch();
compCurBB = fgFirstBB; // Needed by some morphing
if (opts.IsReversePInvoke())
{
- JITDUMP(
- "Inserting special copy helper call at the end of the first block after Reverse P/Invoke transition\n");
+ // If we are in a reverse P/Invoke, then we need to insert
+ // the call at the end of the first block as we need to do the GC transition
+ // before we can call the helper.
+ //
+ // TODO-Cleanup: These gymnastics indicate that we are
+ // inserting reverse pinvoke transitions way too early in the
+ // JIT.
-#ifdef DEBUG
- // assert that we don't have any uses of the local variable in the first block
- // before we insert the shadow copy statement.
+ struct HasReversePInvokeEnterVisitor : GenTreeVisitor
+ {
+ enum
+ {
+ DoPreOrder = true,
+ };
+
+ HasReversePInvokeEnterVisitor(Compiler* comp)
+ : GenTreeVisitor(comp)
+ {
+ }
+
+ fgWalkResult PreOrderVisit(GenTree** use, GenTree* user)
+ {
+ if (((*use)->gtFlags & GTF_CALL) == 0)
+ {
+ return fgWalkResult::WALK_SKIP_SUBTREES;
+ }
+
+ if ((*use)->IsHelperCall(m_compiler, CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER) ||
+ (*use)->IsHelperCall(m_compiler, CORINFO_HELP_JIT_REVERSE_PINVOKE_ENTER_TRACK_TRANSITIONS))
+ {
+ return fgWalkResult::WALK_ABORT;
+ }
+
+ return fgWalkResult::WALK_CONTINUE;
+ }
+ };
+
+ HasReversePInvokeEnterVisitor checker(this);
+
+ Statement* reversePInvokeStmt = nullptr;
for (Statement* const stmt : fgFirstBB->Statements())
{
+ // assert that we don't have any uses of the local variable
+ // at the point before we insert the shadow copy statement.
assert(!gtHasRef(stmt->GetRootNode(), lclNum));
+
+ if (checker.WalkTree(stmt->GetRootNodePointer(), nullptr) == fgWalkResult::WALK_ABORT)
+ {
+ reversePInvokeStmt = stmt;
+ break;
+ }
}
-#endif
- // If we are in a reverse P/Invoke, then we need to insert
- // the call at the end of the first block as we need to do the GC transition
- // before we can call the helper.
- (void)fgNewStmtAtEnd(fgFirstBB, fgMorphTree(call));
+
+ noway_assert(reversePInvokeStmt != nullptr);
+
+ JITDUMP("Inserting special copy helper call after Reverse P/Invoke transition " FMT_STMT "\n",
+ reversePInvokeStmt->GetID());
+
+ (void)fgInsertStmtAfter(fgFirstBB, reversePInvokeStmt, gtNewStmt(fgMorphTree(call)));
}
else
{
@@ -559,9 +602,8 @@ void Compiler::gsParamsToShadows()
GenTree* store = gtNewStoreLclVarNode(shadowVarNum, src);
- fgEnsureFirstBBisScratch();
compCurBB = fgFirstBB; // Needed by some morphing
- (void)fgNewStmtAtBeg(fgFirstBB, fgMorphTree(store));
+ fgNewStmtAtBeg(fgFirstBB, fgMorphTree(store));
}
}
compCurBB = nullptr;
diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp
index d4651444bf5e7b..7ba8c6615f3617 100644
--- a/src/coreclr/jit/hwintrinsicxarch.cpp
+++ b/src/coreclr/jit/hwintrinsicxarch.cpp
@@ -2511,14 +2511,13 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
break;
}
+ case NI_Vector128_ExtractMostSignificantBits:
+ case NI_Vector256_ExtractMostSignificantBits:
case NI_Vector512_ExtractMostSignificantBits:
{
-#if defined(TARGET_X86)
- // TODO-XARCH-CQ: It may be beneficial to decompose this operation
- break;
-#endif // TARGET_X86
+ assert(sig->numArgs == 1);
- if (IsBaselineVector512IsaSupportedOpportunistically())
+ if ((simdSize == 64) || (varTypeIsShort(simdBaseType) && canUseEvexEncoding()))
{
op1 = impSIMDPopStack();
@@ -2527,14 +2526,8 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic,
op1 = gtNewSimdCvtVectorToMaskNode(TYP_MASK, op1, simdBaseJitType, simdSize);
}
retNode = gtNewSimdHWIntrinsicNode(retType, op1, NI_EVEX_MoveMask, simdBaseJitType, simdSize);
+ break;
}
- break;
- }
-
- case NI_Vector128_ExtractMostSignificantBits:
- case NI_Vector256_ExtractMostSignificantBits:
- {
- assert(sig->numArgs == 1);
if ((simdSize != 32) || varTypeIsFloating(simdBaseType) ||
compOpportunisticallyDependsOn(InstructionSet_AVX2))
diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp
index 564d3560109859..576e8be6f367ce 100644
--- a/src/coreclr/jit/importer.cpp
+++ b/src/coreclr/jit/importer.cpp
@@ -7613,64 +7613,8 @@ void Compiler::impImportBlockCode(BasicBlock* block)
fgRemoveRefPred(removedEdge);
block->SetKindAndTargetEdge(BBJ_ALWAYS, retainedEdge);
Metrics.ImporterBranchFold++;
-
- // If we removed an edge carrying profile, try to do a local repair.
- //
- if (block->hasProfileWeight())
- {
- bool repairWasComplete = true;
- weight_t const weight = removedEdge->getLikelyWeight();
-
- if (weight > 0)
- {
- // Target block weight will increase.
- //
- BasicBlock* const target = block->GetTarget();
- assert(target->hasProfileWeight());
- target->setBBProfileWeight(target->bbWeight + weight);
-
- // Alternate weight will decrease
- //
- BasicBlock* const alternate = removedEdge->getDestinationBlock();
- assert(alternate->hasProfileWeight());
- weight_t const alternateNewWeight = alternate->bbWeight - weight;
-
- // If profile weights are consistent, expect at worst a slight underflow.
- //
- if (fgPgoConsistent && (alternateNewWeight < 0))
- {
- assert(fgProfileWeightsEqual(alternateNewWeight, 0));
- }
- alternate->setBBProfileWeight(max(0.0, alternateNewWeight));
-
- // This will affect profile transitively, so in general
- // the profile will become inconsistent.
- //
- repairWasComplete = false;
-
- // But we can check for the special case where the
- // block's postdominator is target's target (simple
- // if/then/else/join).
- //
- if (target->KindIs(BBJ_ALWAYS))
- {
- repairWasComplete = alternate->KindIs(BBJ_ALWAYS) &&
- (alternate->GetTarget() == target->GetTarget());
- }
- }
-
- if (!repairWasComplete)
- {
- JITDUMP("Profile data could not be locally repaired. Data %s inconsistent.\n",
- fgPgoConsistent ? "is now" : "was already");
-
- if (fgPgoConsistent)
- {
- Metrics.ProfileInconsistentImporterBranchFold++;
- fgPgoConsistent = false;
- }
- }
- }
+ fgRepairProfileCondToUncond(block, retainedEdge, removedEdge,
+ &Metrics.ProfileInconsistentImporterBranchFold);
}
if (!op1->OperIs(GT_CNS_INT))
@@ -9735,10 +9679,32 @@ void Compiler::impImportBlockCode(BasicBlock* block)
// Remember that this function contains 'new' of an SD array.
optMethodFlags |= OMF_HAS_NEWARRAY;
+ block->SetFlags(BBF_HAS_NEWARR);
+
+ if (opts.OptimizationEnabled())
+ {
+ // We assign the newly allocated object (by a GT_CALL to newarr node)
+ // to a temp. Note that the pattern "temp = allocArr" is required
+ // by ObjectAllocator phase to be able to determine newarr nodes
+ // without exhaustive walk over all expressions.
+ lclNum = lvaGrabTemp(true DEBUGARG("NewArr temp"));
- /* Push the result of the call on the stack */
+ impStoreToTemp(lclNum, op1, CHECK_SPILL_ALL);
- impPushOnStack(op1, tiRetVal);
+ assert(lvaTable[lclNum].lvSingleDef == 0);
+ lvaTable[lclNum].lvSingleDef = 1;
+ JITDUMP("Marked V%02u as a single def local\n", lclNum);
+ lvaSetClass(lclNum, resolvedToken.hClass, true /* is Exact */);
+
+ /* Push the result of the call on the stack */
+
+ impPushOnStack(gtNewLclvNode(lclNum, TYP_REF), tiRetVal);
+ }
+ else
+ {
+ /* Push the result of the call on the stack */
+ impPushOnStack(op1, tiRetVal);
+ }
callTyp = TYP_REF;
}
diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp
index 033ea50dc20e26..37ba933a75a97a 100644
--- a/src/coreclr/jit/importercalls.cpp
+++ b/src/coreclr/jit/importercalls.cpp
@@ -1274,7 +1274,7 @@ var_types Compiler::impImportCall(OPCODE opcode,
{
// For normal jitting we may branch back to the firstBB; this
// should already be imported.
- loopHead = fgFirstBB;
+ loopHead = fgGetFirstILBlock();
}
JITDUMP("\nTail recursive call [%06u] in the method. Mark " FMT_BB " to " FMT_BB
@@ -2606,12 +2606,33 @@ GenTree* Compiler::impInitializeArrayIntrinsic(CORINFO_SIG_INFO* sig)
}
//
- // We start by looking at the last statement, making sure it's a store, and
- // that the target of the store is the array passed to InitializeArray.
+ // We start by looking at the last statement, making sure it's a store.
//
GenTree* arrayLocalStore = impLastStmt->GetRootNode();
- if (!arrayLocalStore->OperIs(GT_STORE_LCL_VAR) || !arrayLocalNode->OperIs(GT_LCL_VAR) ||
- (arrayLocalStore->AsLclVar()->GetLclNum() != arrayLocalNode->AsLclVar()->GetLclNum()))
+ if (arrayLocalStore->OperIs(GT_STORE_LCL_VAR) && arrayLocalNode->OperIs(GT_LCL_VAR))
+ {
+ // Make sure the target of the store is the array passed to InitializeArray.
+ if (arrayLocalStore->AsLclVar()->GetLclNum() != arrayLocalNode->AsLclVar()->GetLclNum())
+ {
+ if (opts.OptimizationDisabled())
+ {
+ return nullptr;
+ }
+
+ // The array can be spilled to a temp for stack allocation.
+ // Try getting the actual store node from the previous statement.
+ if (arrayLocalStore->AsLclVar()->Data()->OperIs(GT_LCL_VAR) && impLastStmt->GetPrevStmt() != nullptr)
+ {
+ arrayLocalStore = impLastStmt->GetPrevStmt()->GetRootNode();
+ if (!arrayLocalStore->OperIs(GT_STORE_LCL_VAR) ||
+ arrayLocalStore->AsLclVar()->GetLclNum() != arrayLocalNode->AsLclVar()->GetLclNum())
+ {
+ return nullptr;
+ }
+ }
+ }
+ }
+ else
{
return nullptr;
}
diff --git a/src/coreclr/jit/indirectcalltransformer.cpp b/src/coreclr/jit/indirectcalltransformer.cpp
index 9fbac3b55a46ee..f2149f62546b87 100644
--- a/src/coreclr/jit/indirectcalltransformer.cpp
+++ b/src/coreclr/jit/indirectcalltransformer.cpp
@@ -754,8 +754,21 @@ class IndirectCallTransformer
//
void SpillArgToTempBeforeGuard(CallArg* arg)
{
- unsigned tmpNum = compiler->lvaGrabTemp(true DEBUGARG("guarded devirt arg temp"));
- GenTree* store = compiler->gtNewTempStore(tmpNum, arg->GetNode());
+ unsigned tmpNum = compiler->lvaGrabTemp(true DEBUGARG("guarded devirt arg temp"));
+ GenTree* const argNode = arg->GetNode();
+ GenTree* store = compiler->gtNewTempStore(tmpNum, argNode);
+
+ if (argNode->TypeIs(TYP_REF))
+ {
+ bool isExact = false;
+ bool isNonNull = false;
+ CORINFO_CLASS_HANDLE cls = compiler->gtGetClassHandle(argNode, &isExact, &isNonNull);
+ if (cls != NO_CLASS_HANDLE)
+ {
+ compiler->lvaSetClass(tmpNum, cls, isExact);
+ }
+ }
+
Statement* storeStmt = compiler->fgNewStmtFromTree(store, stmt->GetDebugInfo());
compiler->fgInsertStmtAtEnd(checkBlock, storeStmt);
diff --git a/src/coreclr/jit/jiteh.cpp b/src/coreclr/jit/jiteh.cpp
index 8327f14f633239..703c615fcd6339 100644
--- a/src/coreclr/jit/jiteh.cpp
+++ b/src/coreclr/jit/jiteh.cpp
@@ -4397,75 +4397,37 @@ bool Compiler::fgRelocateEHRegions()
printf("*************** In fgRelocateEHRegions()\n");
#endif
- if (fgCanRelocateEHRegions)
- {
- unsigned XTnum;
- EHblkDsc* HBtab;
+ unsigned XTnum;
+ EHblkDsc* HBtab;
- for (XTnum = 0, HBtab = compHndBBtab; XTnum < compHndBBtabCount; XTnum++, HBtab++)
+ for (XTnum = 0, HBtab = compHndBBtab; XTnum < compHndBBtabCount; XTnum++, HBtab++)
+ {
+ // Nested EH regions cannot be moved.
+ // Also we don't want to relocate an EH region that has a filter
+ if ((HBtab->ebdHandlerNestingLevel == 0) && !HBtab->HasFilter())
{
- // Nested EH regions cannot be moved.
- // Also we don't want to relocate an EH region that has a filter
- if ((HBtab->ebdHandlerNestingLevel == 0) && !HBtab->HasFilter())
- {
- bool movedTry = false;
+ bool movedTry = false;
#if DEBUG
- bool movedHnd = false;
+ bool movedHnd = false;
#endif // DEBUG
- // Only try to move the outermost try region
- if (HBtab->ebdEnclosingTryIndex == EHblkDsc::NO_ENCLOSING_INDEX)
- {
- // Move the entire try region if it can be moved
- if (HBtab->ebdTryBeg->isRunRarely())
- {
- BasicBlock* bTryLastBB = fgRelocateEHRange(XTnum, FG_RELOCATE_TRY);
- if (bTryLastBB != NULL)
- {
- result = true;
- movedTry = true;
- }
- }
-#if DEBUG
- if (verbose && movedTry)
- {
- printf("\nAfter relocating an EH try region");
- fgDispBasicBlocks();
- fgDispHandlerTab();
-
- // Make sure that the predecessor lists are accurate
- if (expensiveDebugCheckLevel >= 2)
- {
- fgDebugCheckBBlist();
- }
- }
-#endif // DEBUG
- }
-
- // Currently it is not good to move the rarely run handler regions to the end of the method
- // because fgDetermineFirstColdBlock() must put the start of any handler region in the hot
- // section.
-
-#if 0
- // Now try to move the entire handler region if it can be moved.
- // Don't try to move a finally handler unless we already moved the try region.
- if (HBtab->ebdHndBeg->isRunRarely() &&
- !HBtab->ebdHndBeg->hasTryIndex() &&
- (movedTry || !HBtab->HasFinallyHandler()))
+ // Only try to move the outermost try region
+ if (HBtab->ebdEnclosingTryIndex == EHblkDsc::NO_ENCLOSING_INDEX)
+ {
+ // Move the entire try region if it can be moved
+ if (HBtab->ebdTryBeg->isRunRarely())
{
- BasicBlock* bHndLastBB = fgRelocateEHRange(XTnum, FG_RELOCATE_HANDLER);
- if (bHndLastBB != NULL)
+ BasicBlock* bTryLastBB = fgRelocateEHRange(XTnum, FG_RELOCATE_TRY);
+ if (bTryLastBB != NULL)
{
result = true;
- movedHnd = true;
+ movedTry = true;
}
}
-#endif // 0
-
#if DEBUG
- if (verbose && movedHnd)
+ if (verbose && movedTry)
{
- printf("\nAfter relocating an EH handler region");
+ printf("\nAfter relocating an EH try region");
fgDispBasicBlocks();
fgDispHandlerTab();
@@ -4477,6 +4439,41 @@ bool Compiler::fgRelocateEHRegions()
}
#endif // DEBUG
}
+
+ // Currently it is not good to move the rarely run handler regions to the end of the method
+ // because fgDetermineFirstColdBlock() must put the start of any handler region in the hot
+ // section.
+
+#if 0
+ // Now try to move the entire handler region if it can be moved.
+ // Don't try to move a finally handler unless we already moved the try region.
+ if (HBtab->ebdHndBeg->isRunRarely() &&
+ !HBtab->ebdHndBeg->hasTryIndex() &&
+ (movedTry || !HBtab->HasFinallyHandler()))
+ {
+ BasicBlock* bHndLastBB = fgRelocateEHRange(XTnum, FG_RELOCATE_HANDLER);
+ if (bHndLastBB != NULL)
+ {
+ result = true;
+ movedHnd = true;
+ }
+ }
+#endif // 0
+
+#if DEBUG
+ if (verbose && movedHnd)
+ {
+ printf("\nAfter relocating an EH handler region");
+ fgDispBasicBlocks();
+ fgDispHandlerTab();
+
+ // Make sure that the predecessor lists are accurate
+ if (expensiveDebugCheckLevel >= 2)
+ {
+ fgDebugCheckBBlist();
+ }
+ }
+#endif // DEBUG
}
}
diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp
index 53e43858ace0a9..63a03c60975853 100644
--- a/src/coreclr/jit/lower.cpp
+++ b/src/coreclr/jit/lower.cpp
@@ -5856,9 +5856,6 @@ void Lowering::InsertPInvokeMethodProlog()
JITDUMP("======= Inserting PInvoke method prolog\n");
- // The first BB must be a scratch BB in order for us to be able to safely insert the P/Invoke prolog.
- assert(comp->fgFirstBBisScratch());
-
LIR::Range& firstBlockRange = LIR::AsRange(comp->fgFirstBB);
const CORINFO_EE_INFO* pInfo = comp->eeGetEEInfo();
diff --git a/src/coreclr/jit/lsrabuild.cpp b/src/coreclr/jit/lsrabuild.cpp
index 5748a143d29c9d..56bba3469eb27b 100644
--- a/src/coreclr/jit/lsrabuild.cpp
+++ b/src/coreclr/jit/lsrabuild.cpp
@@ -2526,7 +2526,6 @@ void LinearScan::buildIntervals()
// handling clobbers REG_SCRATCH, so kill it here.
if ((block == compiler->fgFirstBB) && compiler->lvaHasAnySwiftStackParamToReassemble())
{
- assert(compiler->fgFirstBBisScratch());
addKillForRegs(genRegMask(REG_SCRATCH), currentLoc + 1);
currentLoc += 2;
}
@@ -2536,7 +2535,6 @@ void LinearScan::buildIntervals()
// into the scratch register, so it will be killed here.
if (compiler->compShouldPoisonFrame() && (block == compiler->fgFirstBB))
{
- assert(compiler->fgFirstBBisScratch());
regMaskTP killed;
#if defined(TARGET_XARCH)
// Poisoning uses EAX for small vars and rep stosd that kills edi, ecx and eax for large vars.
diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp
index c0b7a6417b2980..eceb31f590a52c 100644
--- a/src/coreclr/jit/morph.cpp
+++ b/src/coreclr/jit/morph.cpp
@@ -51,7 +51,6 @@ PhaseStatus Compiler::fgMorphInit()
impTokenLookupContextHandle /* context */) &
CORINFO_INITCLASS_USE_HELPER)
{
- fgEnsureFirstBBisScratch();
fgNewStmtAtBeg(fgFirstBB, fgInitThisClass());
madeChanges = true;
}
@@ -67,8 +66,7 @@ PhaseStatus Compiler::fgMorphInit()
GenTree* op = gtNewLclvNode(i, TYP_REF);
op = gtNewHelperCallNode(CORINFO_HELP_CHECK_OBJ, TYP_VOID, op);
- fgEnsureFirstBBisScratch();
- fgNewStmtAtEnd(fgFirstBB, op);
+ fgNewStmtAtBeg(fgFirstBB, op);
madeChanges = true;
if (verbose)
{
@@ -6744,24 +6742,19 @@ void Compiler::fgMorphRecursiveFastTailCallIntoLoop(BasicBlock* block, GenTreeCa
if (opts.IsOSR())
{
// Todo: this may not look like a viable loop header.
- // Might need the moral equivalent of a scratch BB.
+ // Might need the moral equivalent of an init BB.
FlowEdge* const newEdge = fgAddRefPred(fgEntryBB, block);
block->SetKindAndTargetEdge(BBJ_ALWAYS, newEdge);
}
else
{
- // We should have ensured the first BB was scratch
- // in morph init...
- //
assert(doesMethodHaveRecursiveTailcall());
- assert(fgFirstBBisScratch());
- // Loop detection needs to see a pred out of the loop,
- // so mark the scratch block BBF_DONT_REMOVE to prevent empty
- // block removal on it.
- //
- fgFirstBB->SetFlags(BBF_DONT_REMOVE);
- FlowEdge* const newEdge = fgAddRefPred(fgFirstBB->Next(), block);
+ // TODO-Cleanup: We should really be expanding tailcalls into loops
+ // much earlier than this, at a place where we do not need to have
+ // hacky workarounds to figure out what the actual IL entry block is.
+ BasicBlock* firstILBB = fgGetFirstILBlock();
+ FlowEdge* const newEdge = fgAddRefPred(firstILBB, block);
block->SetKindAndTargetEdge(BBJ_ALWAYS, newEdge);
}
@@ -8305,10 +8298,17 @@ GenTree* Compiler::fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac, bool* optA
}
// Try to fold it, maybe we get lucky,
- tree = gtFoldExpr(tree);
+ bool folded;
+ tree = gtFoldExpr(tree, &folded);
if (oldTree != tree)
{
+ if (folded)
+ {
+ INDEBUG(tree->gtDebugFlags |= GTF_DEBUG_NODE_MORPHED);
+ return tree;
+ }
+
/* if gtFoldExpr returned op1 or op2 then we are done */
if ((tree == op1) || (tree == op2) || (tree == qmarkOp1) || (tree == qmarkOp2))
{
@@ -13510,14 +13510,6 @@ PhaseStatus Compiler::fgMorphBlocks()
lvSetMinOptsDoNotEnreg();
}
- // Ensure the first BB is scratch if we might need it as a pred for
- // the recursive tail call to loop optimization.
- //
- if (doesMethodHaveRecursiveTailcall())
- {
- fgEnsureFirstBBisScratch();
- }
-
// Morph all blocks.
//
if (!optLocalAssertionProp)
@@ -13544,17 +13536,16 @@ PhaseStatus Compiler::fgMorphBlocks()
MorphUnreachableInfo unreachableInfo(this);
// Allow edge creation to genReturnBB (target of return merging)
- // and the scratch block successor (target for tail call to loop).
+ // and the first IL BB (target for tail call to loop).
// This will also disallow dataflow into these blocks.
//
if (genReturnBB != nullptr)
{
genReturnBB->SetFlags(BBF_CAN_ADD_PRED);
}
- if (fgFirstBBisScratch())
- {
- fgFirstBB->Next()->SetFlags(BBF_CAN_ADD_PRED);
- }
+ // TODO-Cleanup: Remove this by transforming tailcalls to loops earlier.
+ BasicBlock* firstILBB = opts.IsOSR() ? fgEntryBB : fgGetFirstILBlock();
+ firstILBB->SetFlags(BBF_CAN_ADD_PRED);
// Remember this so we can sanity check that no new blocks will get created.
//
@@ -13579,10 +13570,7 @@ PhaseStatus Compiler::fgMorphBlocks()
{
genReturnBB->RemoveFlags(BBF_CAN_ADD_PRED);
}
- if (fgFirstBBisScratch())
- {
- fgFirstBB->Next()->RemoveFlags(BBF_CAN_ADD_PRED);
- }
+ firstILBB->RemoveFlags(BBF_CAN_ADD_PRED);
}
// Under OSR, we no longer need to specially protect the original method entry
@@ -13630,9 +13618,35 @@ PhaseStatus Compiler::fgMorphBlocks()
Metrics.MorphLocals = lvaCount;
}
+ // We may have converted a tailcall into a loop, in which case the first BB
+ // may no longer be canonical.
+ fgCanonicalizeFirstBB();
+
return PhaseStatus::MODIFIED_EVERYTHING;
}
+//------------------------------------------------------------------------
+// fgGetFirstILBB: Obtain the first basic block that was created due to IL.
+//
+// Returns:
+// The basic block, skipping the init BB.
+//
+// Remarks:
+// TODO-Cleanup: Refactor users to be able to remove this function.
+//
+BasicBlock* Compiler::fgGetFirstILBlock()
+{
+ BasicBlock* firstILBB = fgFirstBB;
+ while (firstILBB->HasFlag(BBF_INTERNAL))
+ {
+ assert(firstILBB->KindIs(BBJ_ALWAYS));
+ firstILBB = firstILBB->GetTarget();
+ assert((firstILBB != nullptr) && (firstILBB != fgFirstBB));
+ }
+
+ return firstILBB;
+}
+
//------------------------------------------------------------------------
// gtRemoveTreesAfterNoReturnCall:
// Given a statement that may contain a no-return call, try to find it and
diff --git a/src/coreclr/jit/objectalloc.cpp b/src/coreclr/jit/objectalloc.cpp
index e8c85d7ca48bcc..29fa2bce242768 100644
--- a/src/coreclr/jit/objectalloc.cpp
+++ b/src/coreclr/jit/objectalloc.cpp
@@ -669,14 +669,7 @@ unsigned int ObjectAllocator::MorphAllocObjNodeIntoStackAlloc(
BasicBlock* removedBlock = removedEdge->getDestinationBlock();
comp->fgRemoveRefPred(removedEdge);
predBlock->SetKindAndTargetEdge(BBJ_ALWAYS, keptEdge);
-
- if (predBlock->hasProfileWeight())
- {
- block->setBBProfileWeight(predBlock->bbWeight);
- JITDUMP("Profile weight into " FMT_BB " needs to be propagated to successors. Profile %s inconsistent.\n",
- block->bbNum, comp->fgPgoConsistent ? "is now" : "was already");
- comp->fgPgoConsistent = false;
- }
+ comp->fgRepairProfileCondToUncond(predBlock, keptEdge, removedEdge);
// Just lop off the JTRUE, the rest can clean up later
// (eg may have side effects)
diff --git a/src/coreclr/jit/optimizemaskconversions.cpp b/src/coreclr/jit/optimizemaskconversions.cpp
index 7ab61c698d7e0a..1685581b0523db 100644
--- a/src/coreclr/jit/optimizemaskconversions.cpp
+++ b/src/coreclr/jit/optimizemaskconversions.cpp
@@ -227,13 +227,22 @@ class MaskConversionsCheckVisitor final : public GenTreeVisitorInvalidateWeight();
return fgWalkResult::WALK_CONTINUE;
}
+
+ // Cannot convert any locals that r promoted struct fields
+ if (varDsc->lvIsStructField)
+ {
+ JITDUMP("is struct field. ");
+ weight->InvalidateWeight();
+ return fgWalkResult::WALK_CONTINUE;
+ }
+
// TODO: Converting to a mask loses data - as each field is only a single bit.
// For parameters, OSR locals, and locals which are used as vectors, then they
// cannot be stored as a mask as data will be lost.
// For all of these, conversions could be done by creating a new store of type mask.
// Then uses as mask could be converted to type mask and pointed to use the new
// definition. The weighting would need updating to take this into account.
- else if (isLocalUse && !hasConversion)
+ if (isLocalUse && !hasConversion)
{
JITDUMP("is used as vector. ");
weight->InvalidateWeight();
diff --git a/src/coreclr/jit/optimizer.cpp b/src/coreclr/jit/optimizer.cpp
index c2eae010428a01..35e58d539eea8b 100644
--- a/src/coreclr/jit/optimizer.cpp
+++ b/src/coreclr/jit/optimizer.cpp
@@ -5137,33 +5137,6 @@ void Compiler::fgSetEHRegionForNewPreheaderOrExit(BasicBlock* block)
}
}
-//------------------------------------------------------------------------------
-// fgCanonicalizeFirstBB: Canonicalize the method entry for loop and dominator
-// purposes.
-//
-// Returns:
-// Suitable phase status.
-//
-PhaseStatus Compiler::fgCanonicalizeFirstBB()
-{
- if (fgFirstBB->hasTryIndex())
- {
- JITDUMP("Canonicalizing entry because it currently is the beginning of a try region\n");
- }
- else if (fgFirstBB->bbPreds != nullptr)
- {
- JITDUMP("Canonicalizing entry because it currently has predecessors\n");
- }
- else
- {
- return PhaseStatus::MODIFIED_NOTHING;
- }
-
- assert(!fgFirstBBisScratch());
- fgEnsureFirstBBisScratch();
- return PhaseStatus::MODIFIED_EVERYTHING;
-}
-
LoopSideEffects::LoopSideEffects()
: VarInOut(VarSetOps::UninitVal())
, VarUseDef(VarSetOps::UninitVal())
diff --git a/src/coreclr/jit/patchpoint.cpp b/src/coreclr/jit/patchpoint.cpp
index 71622ecfc3d759..ab695c0a5c3bb1 100644
--- a/src/coreclr/jit/patchpoint.cpp
+++ b/src/coreclr/jit/patchpoint.cpp
@@ -47,12 +47,6 @@ class PatchpointTransformer
// Number of patchpoints transformed.
int Run()
{
- // If the first block is a patchpoint, insert a scratch block.
- if (compiler->fgFirstBB->HasFlag(BBF_PATCHPOINT))
- {
- compiler->fgEnsureFirstBBisScratch();
- }
-
int count = 0;
for (BasicBlock* const block : compiler->Blocks(compiler->fgFirstBB->Next()))
{
@@ -196,8 +190,6 @@ class PatchpointTransformer
// ppCounter =
void TransformEntry(BasicBlock* block)
{
- assert(!block->HasFlag(BBF_PATCHPOINT));
-
int initialCounterValue = JitConfig.TC_OnStackReplacement_InitialCounter();
if (initialCounterValue < 0)
@@ -208,7 +200,7 @@ class PatchpointTransformer
GenTree* initialCounterNode = compiler->gtNewIconNode(initialCounterValue, TYP_INT);
GenTree* ppCounterStore = compiler->gtNewStoreLclVarNode(ppCounterLclNum, initialCounterNode);
- compiler->fgNewStmtNearEnd(block, ppCounterStore);
+ compiler->fgNewStmtAtBeg(block, ppCounterStore);
}
//------------------------------------------------------------------------
diff --git a/src/coreclr/jit/phase.cpp b/src/coreclr/jit/phase.cpp
index 9723c123137ea2..0a6299fc1fdeb5 100644
--- a/src/coreclr/jit/phase.cpp
+++ b/src/coreclr/jit/phase.cpp
@@ -164,6 +164,11 @@ void Phase::PostPhase(PhaseStatus status)
comp->fgDebugCheckBBlist();
}
+ if (hasFlag(checks, PhaseChecks::CHECK_FG_INIT_BLOCK))
+ {
+ comp->fgDebugCheckInitBB();
+ }
+
if (hasFlag(checks, PhaseChecks::CHECK_IR))
{
comp->fgDebugCheckLinks();
diff --git a/src/coreclr/nativeaot/Bootstrap/base/CMakeLists.txt b/src/coreclr/nativeaot/Bootstrap/base/CMakeLists.txt
index 22c194d7fafb74..a1c605ab778e2c 100644
--- a/src/coreclr/nativeaot/Bootstrap/base/CMakeLists.txt
+++ b/src/coreclr/nativeaot/Bootstrap/base/CMakeLists.txt
@@ -9,11 +9,7 @@ set_target_properties(bootstrapper PROPERTIES OUTPUT_NAME bootstrapper)
install_bootstrapper_object(bootstrapper aotsdk)
-if (CLR_CMAKE_TARGET_WIN32)
- add_library(bootstrapper.GuardCF OBJECT ${SOURCES})
- install_bootstrapper_object(bootstrapper.GuardCF aotsdk)
- set_target_properties(bootstrapper.GuardCF PROPERTIES CLR_CONTROL_FLOW_GUARD ON)
-else()
+if (CLR_CMAKE_HOST_UNIX)
add_library(stdc++compat STATIC ../stdcppshim.cpp)
install_static_library(stdc++compat aotsdk nativeaot)
endif()
diff --git a/src/coreclr/nativeaot/Bootstrap/dll/CMakeLists.txt b/src/coreclr/nativeaot/Bootstrap/dll/CMakeLists.txt
index 263518e4b006f3..e2c7d1d23f8e88 100644
--- a/src/coreclr/nativeaot/Bootstrap/dll/CMakeLists.txt
+++ b/src/coreclr/nativeaot/Bootstrap/dll/CMakeLists.txt
@@ -9,9 +9,3 @@ set(SOURCES
add_library(bootstrapperdll STATIC ${SOURCES})
install_bootstrapper_object(bootstrapperdll aotsdk)
-
-if (CLR_CMAKE_TARGET_WIN32)
- add_library(bootstrapperdll.GuardCF STATIC ${SOURCES})
- install_bootstrapper_object(bootstrapperdll.GuardCF aotsdk)
- set_target_properties(bootstrapperdll.GuardCF PROPERTIES CLR_CONTROL_FLOW_GUARD ON)
-endif()
diff --git a/src/coreclr/nativeaot/Bootstrap/dllmain/CMakeLists.txt b/src/coreclr/nativeaot/Bootstrap/dllmain/CMakeLists.txt
index 0dc7299781ea84..2a49ed0a437962 100644
--- a/src/coreclr/nativeaot/Bootstrap/dllmain/CMakeLists.txt
+++ b/src/coreclr/nativeaot/Bootstrap/dllmain/CMakeLists.txt
@@ -7,7 +7,3 @@ set(SOURCES
add_library(dllmain STATIC ${SOURCES})
install_bootstrapper_object(dllmain aotsdk)
-
-add_library(dllmain.GuardCF STATIC ${SOURCES})
-install_bootstrapper_object(dllmain.GuardCF aotsdk)
-set_target_properties(dllmain.GuardCF PROPERTIES CLR_CONTROL_FLOW_GUARD ON)
diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
index af68ed744c9d21..970b1debbf46e1 100644
--- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
+++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets
@@ -284,7 +284,7 @@ The .NET Foundation licenses this file to you under the MIT license.
-
+
diff --git a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets
index 67a2686336514b..23edaa60121447 100644
--- a/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets
+++ b/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Windows.targets
@@ -18,14 +18,12 @@ The .NET Foundation licenses this file to you under the MIT license.
lib
.obj
.lib
- .GuardCF.obj
- .GuardCF.lib
Runtime.WorkstationGC
- Runtime.ServerGC
+ Runtime.ServerGC
bootstrapper
bootstrapperdll
Runtime.VxsortEnabled
- Runtime.VxsortDisabled
+ Runtime.VxsortDisabled
standalonegc-disabled
standalonegc-enabled
wmainCRTStartup
diff --git a/src/coreclr/nativeaot/CMakeLists.txt b/src/coreclr/nativeaot/CMakeLists.txt
index 20deb87a60bb14..71e9567b91e54b 100644
--- a/src/coreclr/nativeaot/CMakeLists.txt
+++ b/src/coreclr/nativeaot/CMakeLists.txt
@@ -5,7 +5,6 @@ endif (WIN32)
if(MSVC)
set_property(DIRECTORY PROPERTY CLR_EH_OPTION /EHa-s-) # Native AOT runtime does not use C++ exception handling
- set_property(DIRECTORY PROPERTY CLR_CONTROL_FLOW_GUARD OFF)
# The code generated by the Native AOT compiler doesn't work with Link Time Code Generation
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION OFF)
diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/Unsafe.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/Unsafe.cs
index 89eedc1638a723..7f95b9bd401fca 100644
--- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/Unsafe.cs
+++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/CompilerServices/Unsafe.cs
@@ -16,6 +16,21 @@ namespace System.Runtime.CompilerServices
///
public static unsafe class Unsafe
{
+ ///
+ /// Determines the byte offset from origin to target from the given references.
+ ///
+ [Intrinsic]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static IntPtr ByteOffset(ref readonly T origin, ref readonly T target)
+ {
+ throw new PlatformNotSupportedException();
+
+ // ldarg .1
+ // ldarg .0
+ // sub
+ // ret
+ }
+
///
/// Returns a pointer to the given by-ref parameter.
///
diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs
index b7a1863d3727db..ae2b81bfa418d7 100644
--- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs
+++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/RuntimeExports.cs
@@ -73,7 +73,6 @@ public static unsafe object RhNewArray(MethodTable* pEEType, int length)
}
}
- [RuntimeExport("RhBox")]
public static unsafe object RhBox(MethodTable* pEEType, ref byte data)
{
// A null can be passed for boxing of a null ref.
@@ -207,7 +206,6 @@ public static unsafe void RhUnboxAny(object? o, ref byte data, MethodTable* pUnb
//
// Unbox helpers with RyuJIT conventions
//
- [RuntimeExport("RhUnbox2")]
public static unsafe ref byte RhUnbox2(MethodTable* pUnboxToEEType, object obj)
{
if ((obj == null) || !UnboxAnyTypeCompare(obj.GetMethodTable(), pUnboxToEEType))
@@ -218,7 +216,6 @@ public static unsafe ref byte RhUnbox2(MethodTable* pUnboxToEEType, object obj)
return ref obj.GetRawData();
}
- [RuntimeExport("RhUnboxNullable")]
public static unsafe void RhUnboxNullable(ref byte data, MethodTable* pUnboxToEEType, object obj)
{
if (obj != null && obj.GetMethodTable() != pUnboxToEEType->NullableType)
@@ -228,7 +225,6 @@ public static unsafe void RhUnboxNullable(ref byte data, MethodTable* pUnboxToEE
RhUnbox(obj, ref data, pUnboxToEEType);
}
- [RuntimeExport("RhUnboxTypeTest")]
public static unsafe void RhUnboxTypeTest(MethodTable* pType, MethodTable* pBoxType)
{
Debug.Assert(pType->IsValueType);
diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs
index 20427987539c39..8425f31f16cc15 100644
--- a/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs
+++ b/src/coreclr/nativeaot/Runtime.Base/src/System/Runtime/TypeCast.cs
@@ -63,7 +63,6 @@ internal enum AssignmentVariation
// IsInstanceOf test used for unusual cases (naked type parameters, variant generic types)
// Unlike the IsInstanceOfInterface and IsInstanceOfClass functions,
// this test must deal with all kinds of type tests
- [RuntimeExport("RhTypeCast_IsInstanceOfAny")]
public static unsafe object? IsInstanceOfAny(MethodTable* pTargetType, object? obj)
{
if (obj != null)
@@ -94,7 +93,6 @@ internal enum AssignmentVariation
return IsInstanceOfAny_NoCacheLookup(pTargetType, obj);
}
- [RuntimeExport("RhTypeCast_IsInstanceOfInterface")]
public static unsafe object? IsInstanceOfInterface(MethodTable* pTargetType, object? obj)
{
Debug.Assert(pTargetType->IsInterface);
@@ -184,7 +182,6 @@ internal enum AssignmentVariation
return obj;
}
- [RuntimeExport("RhTypeCast_IsInstanceOfClass")]
public static unsafe object? IsInstanceOfClass(MethodTable* pTargetType, object? obj)
{
Debug.Assert(!pTargetType->IsParameterizedType, "IsInstanceOfClass called with parameterized MethodTable");
@@ -248,7 +245,6 @@ internal enum AssignmentVariation
return obj;
}
- [RuntimeExport("RhTypeCast_IsInstanceOfException")]
public static unsafe bool IsInstanceOfException(MethodTable* pTargetType, object? obj)
{
// Based on IsInstanceOfClass
@@ -279,7 +275,6 @@ public static unsafe bool IsInstanceOfException(MethodTable* pTargetType, object
// ChkCast test used for unusual cases (naked type parameters, variant generic types)
// Unlike the ChkCastInterface and ChkCastClass functions,
// this test must deal with all kinds of type tests
- [RuntimeExport("RhTypeCast_CheckCastAny")]
public static unsafe object CheckCastAny(MethodTable* pTargetType, object obj)
{
CastResult result;
@@ -307,7 +302,6 @@ public static unsafe object CheckCastAny(MethodTable* pTargetType, object obj)
return objRet;
}
- [RuntimeExport("RhTypeCast_CheckCastInterface")]
public static unsafe object CheckCastInterface(MethodTable* pTargetType, object obj)
{
Debug.Assert(pTargetType->IsInterface);
@@ -393,7 +387,6 @@ private static unsafe object CheckCastInterface_Helper(MethodTable* pTargetType,
return ThrowInvalidCastException(pTargetType);
}
- [RuntimeExport("RhTypeCast_CheckCastClass")]
public static unsafe object CheckCastClass(MethodTable* pTargetType, object obj)
{
Debug.Assert(!pTargetType->IsParameterizedType, "CheckCastClass called with parameterized MethodTable");
@@ -411,7 +404,6 @@ public static unsafe object CheckCastClass(MethodTable* pTargetType, object obj)
// Optimized helper for classes. Assumes that the trivial cases
// has been taken care of by the inlined check
- [RuntimeExport("RhTypeCast_CheckCastClassSpecial")]
private static unsafe object CheckCastClassSpecial(MethodTable* pTargetType, object obj)
{
Debug.Assert(!pTargetType->IsParameterizedType, "CheckCastClassSpecial called with parameterized MethodTable");
@@ -761,8 +753,6 @@ private static unsafe void ThrowArrayMismatchException(object?[] array)
//
// Array stelem/ldelema helpers with RyuJIT conventions
//
-
- [RuntimeExport("RhpLdelemaRef")]
public static unsafe ref object? LdelemaRef(object?[] array, nint index, MethodTable* elementType)
{
Debug.Assert(array is null || array.GetMethodTable()->IsArray, "first argument must be an array");
@@ -794,7 +784,6 @@ private static unsafe void ThrowArrayMismatchException(object?[] array)
return ref element;
}
- [RuntimeExport("RhpStelemRef")]
public static unsafe void StelemRef(object?[] array, nint index, object? obj)
{
// This is supported only on arrays
diff --git a/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt
index f717c2786e0a2f..11618fd78edc0a 100644
--- a/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt
+++ b/src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt
@@ -51,24 +51,6 @@ endif (CLR_CMAKE_TARGET_ARCH_AMD64)
target_compile_definitions(Runtime.ServerGC PRIVATE -DFEATURE_SVR_GC)
if (CLR_CMAKE_TARGET_WIN32)
- add_library(standalonegc-disabled.GuardCF STATIC ${STANDALONEGC_DISABLED_SOURCES})
- set_target_properties(standalonegc-disabled.GuardCF PROPERTIES CLR_CONTROL_FLOW_GUARD ON)
- add_dependencies(standalonegc-disabled.GuardCF aot_eventing_headers)
- add_dependencies(standalonegc-disabled.GuardCF aot_etw_headers)
- add_library(standalonegc-enabled.GuardCF STATIC ${STANDALONEGC_ENABLED_SOURCES})
- set_target_properties(standalonegc-enabled.GuardCF PROPERTIES CLR_CONTROL_FLOW_GUARD ON)
- add_dependencies(standalonegc-enabled.GuardCF aot_eventing_headers)
- add_dependencies(standalonegc-enabled.GuardCF aot_etw_headers)
- add_library(Runtime.ServerGC.GuardCF STATIC ${COMMON_RUNTIME_SOURCES} ${FULL_RUNTIME_SOURCES} ${RUNTIME_SOURCES_ARCH_ASM} ${SERVER_GC_SOURCES} ${RUNTIME_ARCH_ASM_OBJECTS})
- target_compile_definitions(Runtime.ServerGC.GuardCF PRIVATE -DFEATURE_SVR_GC)
- set_target_properties(Runtime.ServerGC.GuardCF PROPERTIES CLR_CONTROL_FLOW_GUARD ON)
- target_link_libraries(Runtime.ServerGC.GuardCF PRIVATE aotminipal)
-
- if (CLR_CMAKE_TARGET_ARCH_AMD64)
- add_library(Runtime.VxsortEnabled.GuardCF STATIC ${VXSORT_SOURCES})
- set_target_properties(Runtime.VxsortEnabled.GuardCF PROPERTIES CLR_CONTROL_FLOW_GUARD ON)
- endif (CLR_CMAKE_TARGET_ARCH_AMD64)
-
set_target_properties(aotminipal PROPERTIES
COMPILE_PDB_NAME "aotminipal"
COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/$")
@@ -115,25 +97,13 @@ add_custom_target(
add_dependencies(Runtime.WorkstationGC RuntimeAsmHelpers)
add_dependencies(Runtime.ServerGC RuntimeAsmHelpers)
-if (CLR_CMAKE_TARGET_WIN32)
- add_dependencies(Runtime.ServerGC.GuardCF RuntimeAsmHelpers)
-endif (CLR_CMAKE_TARGET_WIN32)
install_static_library(Runtime.WorkstationGC aotsdk nativeaot)
install_static_library(Runtime.ServerGC aotsdk nativeaot)
install_static_library(standalonegc-disabled aotsdk nativeaot)
install_static_library(standalonegc-enabled aotsdk nativeaot)
install_static_library(aotminipal aotsdk nativeaot)
-if (CLR_CMAKE_TARGET_WIN32)
- install_static_library(Runtime.ServerGC.GuardCF aotsdk nativeaot)
- add_dependencies(Runtime.ServerGC.GuardCF aot_eventing_headers)
- install_static_library(standalonegc-disabled.GuardCF aotsdk nativeaot)
- install_static_library(standalonegc-enabled.GuardCF aotsdk nativeaot)
-endif (CLR_CMAKE_TARGET_WIN32)
if (CLR_CMAKE_TARGET_ARCH_AMD64)
install_static_library(Runtime.VxsortEnabled aotsdk nativeaot)
install_static_library(Runtime.VxsortDisabled aotsdk nativeaot)
- if (CLR_CMAKE_TARGET_WIN32)
- install_static_library(Runtime.VxsortEnabled.GuardCF aotsdk nativeaot)
- endif (CLR_CMAKE_TARGET_WIN32)
endif (CLR_CMAKE_TARGET_ARCH_AMD64)
diff --git a/src/coreclr/nativeaot/Runtime/eventpipe/CMakeLists.txt b/src/coreclr/nativeaot/Runtime/eventpipe/CMakeLists.txt
index 333180b43eb2d8..739738e6743465 100644
--- a/src/coreclr/nativeaot/Runtime/eventpipe/CMakeLists.txt
+++ b/src/coreclr/nativeaot/Runtime/eventpipe/CMakeLists.txt
@@ -168,26 +168,11 @@ set_target_properties(eventpipe-shared-objects PROPERTIES
COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/$"
)
if (CLR_CMAKE_TARGET_WIN32)
- add_library(eventpipe-shared-objects.GuardCF OBJECT)
- target_link_libraries(eventpipe-shared-objects.GuardCF PRIVATE dn-diagnosticserver dn-eventpipe dn-diagnosticserver-pal)
-
target_compile_options(eventpipe-shared-objects PRIVATE
"/FI${RUNTIME_DIR}/eventpipe/NativeaotEventPipeSupport.h")
- target_compile_options(eventpipe-shared-objects.GuardCF PRIVATE
- "/FI${RUNTIME_DIR}/eventpipe/NativeaotEventPipeSupport.h")
-
- # Build EventPipe and DiagnosticServer as unity-builds for better inlining.
- set_target_properties(eventpipe-shared-objects.GuardCF PROPERTIES
- UNITY_BUILD ON
- UNITY_BUILD_BATCH_SIZE 0
- CLR_CONTROL_FLOW_GUARD ON
- COMPILE_PDB_NAME "eventpipe-shared-objects.GuardCF"
- COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/$")
-
# Install the compile PDB for the eventpipe unity builds.
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/$/eventpipe-shared-objects.pdb" DESTINATION aotsdk COMPONENT nativeaot)
- install(FILES "${CMAKE_CURRENT_BINARY_DIR}/$/eventpipe-shared-objects.GuardCF.pdb" DESTINATION aotsdk COMPONENT nativeaot)
# For the container library, we need to produce a compile PDB and install it
set_target_properties(dn-containers-no-lto PROPERTIES
COMPILE_PDB_NAME "dn-containers"
@@ -222,20 +207,5 @@ endif()
add_library(eventpipe-disabled STATIC ${AOT_EVENTPIPE_DISABLED_SOURCES})
add_dependencies(eventpipe-disabled aot_eventing_headers)
-if (CLR_CMAKE_TARGET_WIN32)
- add_library(eventpipe-enabled.GuardCF STATIC ${EVENTPIPE_SOURCES})
- target_link_libraries(eventpipe-enabled.GuardCF PRIVATE eventpipe-shared-objects.GuardCF dn-containers-no-lto)
- add_dependencies(eventpipe-enabled.GuardCF aot_eventing_headers)
- add_dependencies(eventpipe-enabled.GuardCF aot_etw_headers)
- add_library(eventpipe-disabled.GuardCF STATIC ${AOT_EVENTPIPE_DISABLED_SOURCES})
- add_dependencies(eventpipe-disabled.GuardCF aot_eventing_headers)
- set_target_properties(eventpipe-enabled.GuardCF PROPERTIES CLR_CONTROL_FLOW_GUARD ON)
- set_target_properties(eventpipe-disabled.GuardCF PROPERTIES CLR_CONTROL_FLOW_GUARD ON)
-endif (CLR_CMAKE_TARGET_WIN32)
-
install_static_library(eventpipe-enabled aotsdk nativeaot)
install_static_library(eventpipe-disabled aotsdk nativeaot)
-if (CLR_CMAKE_TARGET_WIN32)
- install_static_library(eventpipe-enabled.GuardCF aotsdk nativeaot)
- install_static_library(eventpipe-disabled.GuardCF aotsdk nativeaot)
-endif (CLR_CMAKE_TARGET_WIN32)
diff --git a/src/coreclr/nativeaot/Runtime/threadstore.cpp b/src/coreclr/nativeaot/Runtime/threadstore.cpp
index c2b42491a387d9..c03907e4eed665 100644
--- a/src/coreclr/nativeaot/Runtime/threadstore.cpp
+++ b/src/coreclr/nativeaot/Runtime/threadstore.cpp
@@ -162,7 +162,7 @@ void ThreadStore::DetachCurrentThread()
}
// Unregister from OS notifications
- // This can return false if detach notification is spurious and does not belong to this thread.
+ // This can return false if a thread did not register for OS notification.
if (!PalDetachThread(pDetachingThread))
{
return;
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs
index 363a544f8c74d0..6fb23a261f3337 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/Internal/Runtime/Augments/RuntimeAugments.cs
@@ -216,7 +216,7 @@ public static unsafe void StoreValueTypeField(IntPtr address, object fieldValue,
public static unsafe object LoadValueTypeField(IntPtr address, RuntimeTypeHandle fieldType)
{
- return RuntimeImports.RhBox(fieldType.ToMethodTable(), ref *(byte*)address);
+ return RuntimeExports.RhBox(fieldType.ToMethodTable(), ref *(byte*)address);
}
public static unsafe object LoadPointerTypeField(IntPtr address, RuntimeTypeHandle fieldType)
@@ -236,7 +236,7 @@ public static unsafe void StoreValueTypeField(object obj, int fieldOffset, objec
public static unsafe object LoadValueTypeField(object obj, int fieldOffset, RuntimeTypeHandle fieldType)
{
ref byte address = ref Unsafe.AddByteOffset(ref obj.GetRawData(), new IntPtr(fieldOffset - ObjectHeaderSize));
- return RuntimeImports.RhBox(fieldType.ToMethodTable(), ref address);
+ return RuntimeExports.RhBox(fieldType.ToMethodTable(), ref address);
}
public static unsafe object LoadPointerTypeField(object obj, int fieldOffset, RuntimeTypeHandle fieldType)
@@ -244,7 +244,7 @@ public static unsafe object LoadPointerTypeField(object obj, int fieldOffset, Ru
ref byte address = ref Unsafe.AddByteOffset(ref obj.GetRawData(), new IntPtr(fieldOffset - ObjectHeaderSize));
if (fieldType.ToMethodTable()->IsFunctionPointer)
- return RuntimeImports.RhBox(MethodTable.Of(), ref address);
+ return RuntimeExports.RhBox(MethodTable.Of(), ref address);
return ReflectionPointer.Box((void*)Unsafe.As(ref address), Type.GetTypeFromHandle(fieldType));
}
@@ -285,7 +285,7 @@ public static object LoadValueTypeFieldValueFromValueType(TypedReference typedRe
Debug.Assert(TypedReference.TargetTypeToken(typedReference).ToMethodTable()->IsValueType);
Debug.Assert(fieldTypeHandle.ToMethodTable()->IsValueType);
- return RuntimeImports.RhBox(fieldTypeHandle.ToMethodTable(), ref Unsafe.Add(ref typedReference.Value, fieldOffset));
+ return RuntimeExports.RhBox(fieldTypeHandle.ToMethodTable(), ref Unsafe.Add(ref typedReference.Value, fieldOffset));
}
[CLSCompliant(false)]
@@ -391,7 +391,7 @@ public static bool IsInterface(RuntimeTypeHandle type)
public static unsafe object Box(RuntimeTypeHandle type, IntPtr address)
{
- return RuntimeImports.RhBox(type.ToMethodTable(), ref *(byte*)address);
+ return RuntimeExports.RhBox(type.ToMethodTable(), ref *(byte*)address);
}
//==============================================================================================
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs
index dc30aaecd1f06f..09439509355e88 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Array.NativeAot.cs
@@ -330,7 +330,7 @@ private static unsafe void CopyImplGcRefArray(Array sourceArray, int sourceIndex
for (int i = 0; i < length; i++)
{
object? value = Unsafe.Add(ref refSourceArray, sourceIndex - i);
- if (mustCastCheckEachElement && value != null && RuntimeImports.IsInstanceOf(destinationElementEEType, value) == null)
+ if (mustCastCheckEachElement && value != null && TypeCast.IsInstanceOfAny(destinationElementEEType, value) == null)
throw new InvalidCastException(SR.InvalidCast_DownCastArrayElement);
Unsafe.Add(ref refDestinationArray, destinationIndex - i) = value;
}
@@ -340,7 +340,7 @@ private static unsafe void CopyImplGcRefArray(Array sourceArray, int sourceIndex
for (int i = 0; i < length; i++)
{
object? value = Unsafe.Add(ref refSourceArray, sourceIndex + i);
- if (mustCastCheckEachElement && value != null && RuntimeImports.IsInstanceOf(destinationElementEEType, value) == null)
+ if (mustCastCheckEachElement && value != null && TypeCast.IsInstanceOfAny(destinationElementEEType, value) == null)
throw new InvalidCastException(SR.InvalidCast_DownCastArrayElement);
Unsafe.Add(ref refDestinationArray, destinationIndex + i) = value;
}
@@ -370,7 +370,7 @@ private static unsafe void CopyImplValueTypeArrayToReferenceArray(Array sourceAr
ref object refDestinationArray = ref Unsafe.As(ref MemoryMarshal.GetArrayDataReference(destinationArray));
for (int i = 0; i < length; i++)
{
- object boxedValue = RuntimeImports.RhBox(sourceElementEEType, ref *pElement);
+ object boxedValue = RuntimeExports.RhBox(sourceElementEEType, ref *pElement);
Unsafe.Add(ref refDestinationArray, destinationIndex + i) = boxedValue;
pElement += sourceElementSize;
}
@@ -457,7 +457,7 @@ private static unsafe void CopyImplValueTypeArrayWithInnerGcRefs(Array sourceArr
pDestinationElement -= cbElementSize;
}
- object boxedValue = RuntimeImports.RhBox(sourceElementEEType, ref *pSourceElement);
+ object boxedValue = RuntimeExports.RhBox(sourceElementEEType, ref *pSourceElement);
if (boxedElements != null)
boxedElements[i] = boxedValue;
else
@@ -768,7 +768,7 @@ internal unsafe nint GetFlattenedIndex(ReadOnlySpan indices)
MethodTable* pElementEEType = ElementMethodTable;
if (pElementEEType->IsValueType)
{
- return RuntimeImports.RhBox(pElementEEType, ref element);
+ return RuntimeExports.RhBox(pElementEEType, ref element);
}
else
{
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/InvokeUtils.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/InvokeUtils.cs
index b6fc499829d173..61a2d5367c7cb3 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/InvokeUtils.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/InvokeUtils.cs
@@ -133,7 +133,7 @@ private static Exception ConvertOrWidenPrimitivesEnumsAndPointersIfPossible(obje
if (dstElementType == srcElementType)
{
// Rebox the value if the EETypeElementTypes match
- dstObject = RuntimeImports.RhBox(dstEEType, ref srcObject.GetRawData());
+ dstObject = RuntimeExports.RhBox(dstEEType, ref srcObject.GetRawData());
}
else
{
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/DynamicInvokeInfo.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/DynamicInvokeInfo.cs
index 45bc2f9e19978a..d7837bdc649e18 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/DynamicInvokeInfo.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Reflection/DynamicInvokeInfo.cs
@@ -783,7 +783,7 @@ private unsafe void CopyBackToArray(ref object? src, object?[] dest)
}
else
{
- obj = RuntimeImports.RhBox(
+ obj = RuntimeExports.RhBox(
(transform & Transform.FunctionPointer) != 0 ? MethodTable.Of() : argumentInfo.Type,
ref obj.GetRawData());
}
@@ -818,7 +818,7 @@ private unsafe void CopyBackToSpan(Span src, Span dest)
}
else
{
- obj = RuntimeImports.RhBox(
+ obj = RuntimeExports.RhBox(
(transform & Transform.FunctionPointer) != 0 ? MethodTable.Of() : argumentInfo.Type,
ref obj.GetRawData());
}
@@ -849,7 +849,7 @@ private unsafe object ReturnTransform(ref byte byref, bool wrapInTargetInvocatio
else if ((_returnTransform & Transform.FunctionPointer) != 0)
{
Debug.Assert(Type.GetTypeFromMethodTable(_returnType).IsFunctionPointer);
- obj = RuntimeImports.RhBox(MethodTable.Of(), ref byref);
+ obj = RuntimeExports.RhBox(MethodTable.Of(), ref byref);
}
else if ((_returnTransform & Transform.Reference) != 0)
{
@@ -859,7 +859,7 @@ private unsafe object ReturnTransform(ref byte byref, bool wrapInTargetInvocatio
else
{
Debug.Assert((_returnTransform & (Transform.ByRef | Transform.Nullable)) != 0);
- obj = RuntimeImports.RhBox(_returnType, ref byref);
+ obj = RuntimeExports.RhBox(_returnType, ref byref);
}
return obj;
}
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs
index 8488a99f12a26f..b30bfd88ef0822 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.NativeAot.cs
@@ -380,7 +380,7 @@ public static unsafe object GetUninitializedObject(
if (mt->IsByRefLike)
throw new NotSupportedException(SR.NotSupported_ByRefLike);
- return RuntimeImports.RhBox(mt, ref target);
+ return RuntimeExports.RhBox(mt, ref target);
}
///
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs
index cc33e85d73917c..b4d70b66c2a937 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.NativeAot.cs
@@ -1418,15 +1418,10 @@ internal static unsafe int IReferenceTrackerHost_DisconnectUnusedReferenceSource
[UnmanagedCallersOnly]
internal static unsafe int IReferenceTrackerHost_ReleaseDisconnectedReferenceSources(IntPtr pThis)
{
- try
- {
- GC.WaitForPendingFinalizers();
- return HResults.S_OK;
- }
- catch (Exception e)
- {
- return Marshal.GetHRForException(e);
- }
+ // We'd like to call GC.WaitForPendingFinalizers() here, but this could lead to deadlock
+ // if the finalizer thread is trying to get back to this thread, because we are not pumping
+ // anymore. Disable this for now. See: https://github.com/dotnet/runtime/issues/109538.
+ return HResults.S_OK;
}
[UnmanagedCallersOnly]
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs
index 15587b47467210..454c5a1e0c4be0 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/RuntimeImports.cs
@@ -379,10 +379,6 @@ internal static IntPtr RhHandleAllocDependent(object primary, object secondary)
[RuntimeImport(RuntimeLibrary, "RhTypeCast_CheckArrayStore")]
internal static extern void RhCheckArrayStore(object array, object? obj);
- [MethodImpl(MethodImplOptions.InternalCall)]
- [RuntimeImport(RuntimeLibrary, "RhTypeCast_IsInstanceOfAny")]
- internal static extern unsafe object IsInstanceOf(MethodTable* pTargetType, object obj);
-
//
// calls to runtime for allocation
// These calls are needed in types which cannot use "new" to allocate and need to do it manually
@@ -405,10 +401,6 @@ internal static IntPtr RhHandleAllocDependent(object primary, object secondary)
[RuntimeImport(RuntimeLibrary, "RhNewString")]
internal static extern unsafe string RhNewString(MethodTable* pEEType, int length);
- [MethodImpl(MethodImplOptions.InternalCall)]
- [RuntimeImport(RuntimeLibrary, "RhBox")]
- internal static extern unsafe object RhBox(MethodTable* pEEType, ref byte data);
-
[MethodImpl(MethodImplOptions.InternalCall)]
[RuntimeImport(RuntimeLibrary, "RhUnbox")]
internal static extern unsafe void RhUnbox(object? obj, ref byte data, MethodTable* pUnboxToEEType);
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs
index 1ccb983b64bc32..1854e6ddeb210d 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeType.cs
@@ -630,7 +630,7 @@ public override bool IsInstanceOfType([NotNullWhen(true)] object? o)
return false;
if (pEEType->IsNullable)
pEEType = pEEType->NullableType;
- return RuntimeImports.IsInstanceOf(pEEType, o) != null;
+ return TypeCast.IsInstanceOfAny(pEEType, o) != null;
}
//
diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/ValueType.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/ValueType.cs
index 968e97c425cf81..c19988c9bd6782 100644
--- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/ValueType.cs
+++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/ValueType.cs
@@ -146,7 +146,7 @@ private unsafe void RegularGetValueTypeHashCode(ref HashCode hashCode, ref byte
// of __GetFieldHelper, decodes the unboxing stub pointed to by the slot to the real target
// (we already have that part), and calls the entrypoint that expects a byref `this`, and use the
// data to decide between calling fast or regular hashcode helper.
- var fieldValue = (ValueType)RuntimeImports.RhBox(fieldType, ref fieldData);
+ var fieldValue = (ValueType)RuntimeExports.RhBox(fieldType, ref fieldData);
if (fieldValue != null)
{
hashCode.Add(fieldValue);
diff --git a/src/coreclr/nativeaot/Test.CoreLib/src/System/Buffer.cs b/src/coreclr/nativeaot/Test.CoreLib/src/System/Buffer.cs
new file mode 100644
index 00000000000000..9549be1ae49c7b
--- /dev/null
+++ b/src/coreclr/nativeaot/Test.CoreLib/src/System/Buffer.cs
@@ -0,0 +1,15 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Runtime;
+using System.Runtime.CompilerServices;
+
+namespace System
+{
+ public static partial class Buffer
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static void BulkMoveWithWriteBarrier(ref byte destination, ref byte source, nuint byteCount) =>
+ RuntimeImports.RhBulkMoveWithWriteBarrier(ref destination, ref source, byteCount);
+ }
+}
diff --git a/src/coreclr/nativeaot/Test.CoreLib/src/System/SpanHelpers.cs b/src/coreclr/nativeaot/Test.CoreLib/src/System/SpanHelpers.cs
new file mode 100644
index 00000000000000..77c20f716a4d6f
--- /dev/null
+++ b/src/coreclr/nativeaot/Test.CoreLib/src/System/SpanHelpers.cs
@@ -0,0 +1,34 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Runtime.CompilerServices;
+
+namespace System
+{
+ internal static partial class SpanHelpers
+ {
+ [Intrinsic]
+ public static unsafe void ClearWithoutReferences(ref byte dest, nuint len)
+ {
+ Fill(ref dest, 0, len);
+ }
+
+ [Intrinsic]
+ internal static unsafe void Memmove(ref byte dest, ref byte src, nuint len)
+ {
+ if ((nuint)(nint)Unsafe.ByteOffset(ref src, ref dest) >= len)
+ for (nuint i = 0; i < len; i++)
+ Unsafe.Add(ref dest, (nint)i) = Unsafe.Add(ref src, (nint)i);
+ else
+ for (nuint i = len; i > 0; i--)
+ Unsafe.Add(ref dest, (nint)(i - 1)) = Unsafe.Add(ref src, (nint)(i - 1));
+ }
+
+
+ internal static void Fill(ref byte dest, byte value, nuint len)
+ {
+ for (nuint i = 0; i < len; i++)
+ Unsafe.Add(ref dest, (nint)i) = value;
+ }
+ }
+}
diff --git a/src/coreclr/nativeaot/Test.CoreLib/src/Test.CoreLib.csproj b/src/coreclr/nativeaot/Test.CoreLib/src/Test.CoreLib.csproj
index 9d606a6b757115..b838c2ed7c14b7 100644
--- a/src/coreclr/nativeaot/Test.CoreLib/src/Test.CoreLib.csproj
+++ b/src/coreclr/nativeaot/Test.CoreLib/src/Test.CoreLib.csproj
@@ -232,6 +232,8 @@
+
+
diff --git a/src/coreclr/pal/src/include/pal/misc.h b/src/coreclr/pal/src/include/pal/misc.h
deleted file mode 100644
index ffa6448ed7d308..00000000000000
--- a/src/coreclr/pal/src/include/pal/misc.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-/*++
-
-
-
-Module Name:
-
- include/pal/misc.h
-
-Abstract:
- Header file for the initialization and clean up functions
- for the misc Win32 functions
-
-
-
---*/
-
-#ifndef __MISC_H_
-#define __MISC_H_
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif // __cplusplus
-
-/*++
-Function :
- MsgBoxInitialize
-
- Initialize the critical sections.
-
-Return value:
- TRUE if initialize succeeded
- FALSE otherwise
-
---*/
-BOOL MsgBoxInitialize( void );
-
-/*++
-Function :
- MsgBoxCleanup
-
- Deletes the critical sections.
-
---*/
-void MsgBoxCleanup( void );
-
-#ifdef __cplusplus
-}
-#endif // __cplusplus
-
-#endif /* __MISC_H_ */
diff --git a/src/coreclr/pal/src/init/pal.cpp b/src/coreclr/pal/src/init/pal.cpp
index a6bd6f01f1dff0..8dcf3a1aee4830 100644
--- a/src/coreclr/pal/src/init/pal.cpp
+++ b/src/coreclr/pal/src/init/pal.cpp
@@ -30,7 +30,6 @@ SET_DEFAULT_DEBUG_CHANNEL(PAL); // some headers have code with asserts, so do th
#include "../thread/procprivate.hpp"
#include "pal/module.h"
#include "pal/virtual.h"
-#include "pal/misc.h"
#include "pal/environ.h"
#include "pal/utils.h"
#include "pal/debug.h"
diff --git a/src/coreclr/pal/src/misc/fmtmessage.cpp b/src/coreclr/pal/src/misc/fmtmessage.cpp
index 0598914b06cb51..cfedd815da3cae 100644
--- a/src/coreclr/pal/src/misc/fmtmessage.cpp
+++ b/src/coreclr/pal/src/misc/fmtmessage.cpp
@@ -23,7 +23,6 @@ Revision History:
#include "pal/dbgmsg.h"
#include "pal/critsect.h"
#include "pal/module.h"
-#include "pal/misc.h"
#include "errorstrings.h"
diff --git a/src/coreclr/pal/src/misc/perftrace.cpp b/src/coreclr/pal/src/misc/perftrace.cpp
index 691c9048cb5729..2f5072a8da2375 100644
--- a/src/coreclr/pal/src/misc/perftrace.cpp
+++ b/src/coreclr/pal/src/misc/perftrace.cpp
@@ -27,7 +27,6 @@ Module Name:
#include "pal/perftrace.h"
#include "pal/dbgmsg.h"
#include "pal/cruntime.h"
-#include "pal/misc.h"
/* Standard headers */
#include
diff --git a/src/coreclr/pal/src/misc/time.cpp b/src/coreclr/pal/src/misc/time.cpp
index 7d78ae930c3979..2774cb7f125b75 100644
--- a/src/coreclr/pal/src/misc/time.cpp
+++ b/src/coreclr/pal/src/misc/time.cpp
@@ -19,7 +19,6 @@ Module Name:
#include "pal/palinternal.h"
#include "pal/dbgmsg.h"
-#include "pal/misc.h"
#include
#include
diff --git a/src/coreclr/scripts/superpmi.py b/src/coreclr/scripts/superpmi.py
index 33c27755a95409..53cf7f2d21c2aa 100644
--- a/src/coreclr/scripts/superpmi.py
+++ b/src/coreclr/scripts/superpmi.py
@@ -1954,7 +1954,7 @@ def aggregate_diff_metrics(details_file):
# Project out these fields for the saved diffs, to use for further
# processing. Saving everything into memory is costly on memory when there
# are a large number of diffs.
- diffs_fields = ["Context", "Context size", "Base ActualCodeBytes", "Diff ActualCodeBytes", "Base PerfScore", "Diff PerfScore"]
+ diffs_fields = ["Context", "Method full name", "Context size", "Base ActualCodeBytes", "Diff ActualCodeBytes", "Base PerfScore", "Diff PerfScore"]
diffs = []
for row in read_csv(details_file):
@@ -2725,12 +2725,40 @@ def diff_pct(r):
display_subset("Smallest {} zero sized diffs:", smallest_zero_size_contexts)
- by_diff_size_pct_examples = [diff for diff in by_diff_size_pct if abs(int(diff['Diff ActualCodeBytes']) - int(diff['Base ActualCodeBytes'])) < 50]
- if len(by_diff_size_pct_examples) == 0:
- by_diff_size_pct_examples = by_diff_size_pct
+ # Prefer to show small diffs over large percentage wise diffs; sort by this additionally.
+ # sorted is stable, so for multiple small diffs this will keep them in order of percentage wise improvement/regression.
+ def is_small_diff(row):
+ if abs(int(row['Diff ActualCodeBytes']) - int(row['Base ActualCodeBytes'])) < 50:
+ return 0
+
+ return 1
+
+ by_small_then_improvement = sorted(by_diff_size_pct, key=is_small_diff)
+ by_small_then_regression = sorted(reversed(by_diff_size_pct), key=is_small_diff)
+
+ def pick_examples(diffs, picked_contexts):
+ seen = set()
+ def try_add_seen(row):
+ len_before = len(seen)
+ seen.add(row["Method full name"])
+ return len_before < len(seen)
+
+ result = []
+ for row in diffs:
+ if row["Context"] in picked_contexts or not try_add_seen(row):
+ continue
+
+ result.append(row)
+ if len(result) >= 3:
+ break
+
+ return result
+
+ example_improvements = pick_examples(by_small_then_improvement, set())
+
+ example_improvement_contexts = set(row["Context"] for row in example_improvements)
+ example_regressions = pick_examples(by_small_then_regression, example_improvement_contexts)
- example_improvements = by_diff_size_pct_examples[:3]
- example_regressions = by_diff_size_pct_examples[3:][-3:]
contexts = smallest_contexts + top_improvements + top_regressions + top_improvements_pct + top_regressions_pct + smallest_zero_size_contexts + example_improvements + example_regressions
examples = example_improvements + example_regressions
diff --git a/src/coreclr/tools/Common/TypeSystem/IL/HelperExtensions.cs b/src/coreclr/tools/Common/TypeSystem/IL/HelperExtensions.cs
index 4ccaff2d6dd9f0..a02c9bbf9da982 100644
--- a/src/coreclr/tools/Common/TypeSystem/IL/HelperExtensions.cs
+++ b/src/coreclr/tools/Common/TypeSystem/IL/HelperExtensions.cs
@@ -33,6 +33,12 @@ public static MethodDesc GetHelperEntryPoint(this TypeSystemContext context, str
return helperMethod;
}
+ public static MethodDesc GetCoreLibEntryPoint(this TypeSystemContext context, string namespaceName, string typeName, string methodName, MethodSignature signature)
+ {
+ MetadataType owningType = context.SystemModule.GetKnownType(namespaceName, typeName);
+ return owningType.GetKnownMethod(methodName, signature);
+ }
+
public static MethodDesc GetOptionalHelperEntryPoint(this TypeSystemContext context, string typeName, string methodName)
{
MetadataType helperType = context.GetOptionalHelperType(typeName);
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs
index d1fc6c593eef81..4d9328f1a34eef 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ILScanner.cs
@@ -137,6 +137,19 @@ private void CompileSingleMethod(ScannedMethodNode methodCodeNodeNeedingCode)
ILScanResults IILScanner.Scan()
{
+ _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.BulkWriteBarrier), "Not tracked by scanner");
+ _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.MemCpy), "Not tracked by scanner");
+ _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.MemSet), "Not tracked by scanner");
+ _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.MemZero), "Not tracked by scanner");
+ _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.CheckCastAny), "Not tracked by scanner");
+ _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.CheckCastInterface), "Not tracked by scanner");
+ _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.CheckCastClass), "Not tracked by scanner");
+ _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.CheckCastClassSpecial), "Not tracked by scanner");
+ _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.CheckInstanceAny), "Not tracked by scanner");
+ _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.CheckInstanceInterface), "Not tracked by scanner");
+ _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.CheckInstanceClass), "Not tracked by scanner");
+ _dependencyGraph.AddRoot(GetHelperEntrypoint(ReadyToRunHelper.IsInstanceOfException), "Not tracked by scanner");
+
_dependencyGraph.ComputeMarkedNodes();
_nodeFactory.SetMarkingComplete();
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs
index 8861535467c8ca..1d78df875c125b 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/JitHelper.cs
@@ -73,7 +73,7 @@ public static void GetEntryPoint(TypeSystemContext context, ReadyToRunHelper id,
mangledName = context.Target.Architecture == TargetArchitecture.ARM64 ? "RhpCheckedAssignRefArm64" : "RhpCheckedAssignRef";
break;
case ReadyToRunHelper.BulkWriteBarrier:
- mangledName = "RhBuffer_BulkMoveWithWriteBarrier";
+ methodDesc = context.GetCoreLibEntryPoint("System", "Buffer", "BulkMoveWithWriteBarrier", null);
break;
case ReadyToRunHelper.ByRefWriteBarrier:
mangledName = context.Target.Architecture == TargetArchitecture.ARM64 ? "RhpByRefAssignRefArm64" : "RhpByRefAssignRef";
@@ -116,16 +116,16 @@ public static void GetEntryPoint(TypeSystemContext context, ReadyToRunHelper id,
break;
case ReadyToRunHelper.Box:
case ReadyToRunHelper.Box_Nullable:
- mangledName = "RhBox";
+ methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "RuntimeExports", "RhBox", null);
break;
case ReadyToRunHelper.Unbox:
- mangledName = "RhUnbox2";
+ methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "RuntimeExports", "RhUnbox2", null);
break;
case ReadyToRunHelper.Unbox_Nullable:
- mangledName = "RhUnboxNullable";
+ methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "RuntimeExports", "RhUnboxNullable", null);
break;
case ReadyToRunHelper.Unbox_TypeTest:
- mangledName = "RhUnboxTypeTest";
+ methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "RuntimeExports", "RhUnboxTypeTest", null);
break;
case ReadyToRunHelper.NewMultiDimArr:
@@ -143,20 +143,20 @@ public static void GetEntryPoint(TypeSystemContext context, ReadyToRunHelper id,
break;
case ReadyToRunHelper.Stelem_Ref:
- mangledName = "RhpStelemRef";
+ methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "TypeCast", "StelemRef", null);
break;
case ReadyToRunHelper.Ldelema_Ref:
- mangledName = "RhpLdelemaRef";
+ methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "TypeCast", "LdelemaRef", null);
break;
case ReadyToRunHelper.MemCpy:
- mangledName = "RhSpanHelpers_MemCopy";
+ methodDesc = context.GetCoreLibEntryPoint("System", "SpanHelpers", "Memmove", null);
break;
case ReadyToRunHelper.MemSet:
- mangledName = "RhSpanHelpers_MemSet";
+ methodDesc = context.GetCoreLibEntryPoint("System", "SpanHelpers", "Fill", null);
break;
case ReadyToRunHelper.MemZero:
- mangledName = "RhSpanHelpers_MemZero";
+ methodDesc = context.GetCoreLibEntryPoint("System", "SpanHelpers", "ClearWithoutReferences", null);
break;
case ReadyToRunHelper.NativeMemSet:
mangledName = "memset";
@@ -284,29 +284,29 @@ public static void GetEntryPoint(TypeSystemContext context, ReadyToRunHelper id,
break;
case ReadyToRunHelper.CheckCastAny:
- mangledName = "RhTypeCast_CheckCastAny";
+ methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "TypeCast", "CheckCastAny", null);
break;
case ReadyToRunHelper.CheckCastInterface:
- mangledName = "RhTypeCast_CheckCastInterface";
+ methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "TypeCast", "CheckCastInterface", null);
break;
case ReadyToRunHelper.CheckCastClass:
- mangledName = "RhTypeCast_CheckCastClass";
+ methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "TypeCast", "CheckCastClass", null);
break;
case ReadyToRunHelper.CheckCastClassSpecial:
- mangledName = "RhTypeCast_CheckCastClassSpecial";
+ methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "TypeCast", "CheckCastClassSpecial", null);
break;
case ReadyToRunHelper.CheckInstanceAny:
- mangledName = "RhTypeCast_IsInstanceOfAny";
+ methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "TypeCast", "IsInstanceOfAny", null);
break;
case ReadyToRunHelper.CheckInstanceInterface:
- mangledName = "RhTypeCast_IsInstanceOfInterface";
+ methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "TypeCast", "IsInstanceOfInterface", null);
break;
case ReadyToRunHelper.CheckInstanceClass:
- mangledName = "RhTypeCast_IsInstanceOfClass";
+ methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "TypeCast", "IsInstanceOfClass", null);
break;
case ReadyToRunHelper.IsInstanceOfException:
- mangledName = "RhTypeCast_IsInstanceOfException";
+ methodDesc = context.GetCoreLibEntryPoint("System.Runtime", "TypeCast", "IsInstanceOfException", null);
break;
case ReadyToRunHelper.MonitorEnter:
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ReachabilityInstrumentationFilter.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ReachabilityInstrumentationFilter.cs
index 9afe7e724fcc81..2fb613d9521dff 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ReachabilityInstrumentationFilter.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ReachabilityInstrumentationFilter.cs
@@ -44,7 +44,7 @@ public ReachabilityInstrumentationFilter(string profileDataFileName, ILProvider
int numTokens = reader.ReadInt32();
bool[] tokenStates = new bool[numTokens];
- if (reader.Read(MemoryMarshal.Cast(tokenStates)) != numTokens)
+ if (reader.Read(MemoryMarshal.Cast(tokenStates.AsSpan())) != numTokens)
throw new IOException("Unexpected end of file");
_reachabilityInfo.Add(new Guid(guidBytes), tokenStates);
diff --git a/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs b/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs
index 611d11e02edd1a..00a0d56d48150f 100644
--- a/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Compiler/IL/ILImporter.Scanner.cs
@@ -897,6 +897,7 @@ private void ImportUnbox(int token, ILOpcode opCode)
if (opCode == ILOpcode.unbox)
{
helper = ReadyToRunHelper.Unbox;
+ _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.Unbox_TypeTest), "Unbox");
}
else
{
@@ -1237,11 +1238,16 @@ private void ImportLoadElement(TypeDesc elementType)
private void ImportStoreElement(int token)
{
- _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.RngChkFail), "stelem");
+ ImportStoreElement((TypeDesc)_methodIL.GetObject(token));
}
private void ImportStoreElement(TypeDesc elementType)
{
+ if (elementType == null || elementType.IsGCPointer)
+ {
+ _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.Stelem_Ref), "stelem");
+ }
+
_dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.RngChkFail), "stelem");
}
@@ -1254,6 +1260,8 @@ private void ImportAddressOfElement(int token)
_dependencies.Add(GetGenericLookupHelper(ReadyToRunHelperId.TypeHandle, elementType), "ldelema");
else
_dependencies.Add(_factory.NecessaryTypeSymbol(elementType), "ldelema");
+
+ _dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.Ldelema_Ref), "ldelema");
}
_dependencies.Add(GetHelperEntrypoint(ReadyToRunHelper.RngChkFail), "ldelema");
diff --git a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCases/TestSuites.cs b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCases/TestSuites.cs
index a3493db1786a8d..87d8fc21ce8798 100644
--- a/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCases/TestSuites.cs
+++ b/src/coreclr/tools/aot/ILCompiler.Trimming.Tests/TestCases/TestSuites.cs
@@ -71,9 +71,6 @@ public void Reflection (string t)
{
switch (t)
{
- case "ObjectGetType":
- // Skip for now
- break;
case "ObjectGetTypeLibraryMode":
case "TypeHierarchyLibraryModeSuppressions":
// No Library mode
diff --git a/src/coreclr/tools/superpmi/superpmi/superpmi.cpp b/src/coreclr/tools/superpmi/superpmi/superpmi.cpp
index 9513fedfa63d4b..e26f13a7f49d27 100644
--- a/src/coreclr/tools/superpmi/superpmi/superpmi.cpp
+++ b/src/coreclr/tools/superpmi/superpmi/superpmi.cpp
@@ -157,12 +157,12 @@ static void PrintDiffsCsvRow(
bool hasDiff)
{
fw.Printf("%d,%u,", context, contextSize);
- fw.PrintQuotedCsvField(baseRes.CompileResults->MethodFullName == nullptr ? "" : baseRes.CompileResults->MethodFullName);
+ fw.PrintQuotedCsvField(diffRes.CompileResults->MethodFullName == nullptr ? "" : diffRes.CompileResults->MethodFullName);
fw.Printf(
",%s,%s,%s,%s,%s,%lld,%lld",
- baseRes.CompileResults->TieringName == nullptr ? "" : baseRes.CompileResults->TieringName,
+ diffRes.CompileResults->TieringName == nullptr ? "" : diffRes.CompileResults->TieringName,
ResultToString(baseRes.Result), ResultToString(diffRes.Result),
- baseRes.IsMinOpts ? "True" : "False",
+ diffRes.IsMinOpts ? "True" : "False",
hasDiff ? "True" : "False",
baseRes.NumExecutedInstructions, diffRes.NumExecutedInstructions);
diff --git a/src/coreclr/vm/CMakeLists.txt b/src/coreclr/vm/CMakeLists.txt
index 3033d205882218..7254075b562de4 100644
--- a/src/coreclr/vm/CMakeLists.txt
+++ b/src/coreclr/vm/CMakeLists.txt
@@ -302,7 +302,6 @@ set(VM_SOURCES_WKS
comdynamic.cpp
commodule.cpp
comsynchronizable.cpp
- comthreadpool.cpp
comutilnative.cpp
comwaithandle.cpp
coreassemblyspec.cpp
@@ -402,7 +401,6 @@ set(VM_HEADERS_WKS
comdynamic.h
commodule.h
comsynchronizable.h
- comthreadpool.h
comutilnative.h
comwaithandle.h
customattribute.h
diff --git a/src/coreclr/vm/callhelpers.cpp b/src/coreclr/vm/callhelpers.cpp
index 3906d396c87f54..d926ff9d8d62c7 100644
--- a/src/coreclr/vm/callhelpers.cpp
+++ b/src/coreclr/vm/callhelpers.cpp
@@ -11,10 +11,6 @@
// To include declaration of "AppDomainTransitionExceptionFilter"
#include "excep.h"
-
-// To include declaration of "SignatureNative"
-#include "runtimehandles.h"
-
#include "invokeutil.h"
#include "argdestination.h"
diff --git a/src/coreclr/vm/ceemain.cpp b/src/coreclr/vm/ceemain.cpp
index 3e38d60a538fee..eba08c952b21dc 100644
--- a/src/coreclr/vm/ceemain.cpp
+++ b/src/coreclr/vm/ceemain.cpp
@@ -151,7 +151,6 @@
#include "../dlls/mscorrc/resource.h"
#include "util.hpp"
#include "shimload.h"
-#include "comthreadpool.h"
#include "posterror.h"
#include "virtualcallstub.h"
#include "strongnameinternal.h"
@@ -1702,6 +1701,125 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
#endif // !defined(CORECLR_EMBEDDED)
+static void RuntimeThreadShutdown(void* thread)
+{
+ Thread* pThread = (Thread*)thread;
+ _ASSERTE(pThread == GetThreadNULLOk());
+
+ if (pThread)
+ {
+#ifdef FEATURE_COMINTEROP
+ // reset the CoInitialize state
+ // so we don't call CoUninitialize during thread detach
+ pThread->ResetCoInitialized();
+#endif // FEATURE_COMINTEROP
+ // For case where thread calls ExitThread directly, we need to reset the
+ // frame pointer. Otherwise stackwalk would AV. We need to do it in cooperative mode.
+ // We need to set m_GCOnTransitionsOK so this thread won't trigger GC when toggle GC mode
+ if (pThread->m_pFrame != FRAME_TOP)
+ {
+#ifdef _DEBUG
+ pThread->m_GCOnTransitionsOK = FALSE;
+#endif
+ GCX_COOP_NO_DTOR();
+ pThread->m_pFrame = FRAME_TOP;
+ GCX_COOP_NO_DTOR_END();
+ }
+
+ pThread->DetachThread(TRUE);
+ }
+ else
+ {
+ // Since we don't actually cleanup the TLS data along this path, verify that it is already cleaned up
+ AssertThreadStaticDataFreed();
+ }
+
+ ThreadDetaching();
+}
+
+#ifdef TARGET_WINDOWS
+
+// Index for the fiber local storage of the attached thread pointer
+static uint32_t g_flsIndex = FLS_OUT_OF_INDEXES;
+
+// This is called when each *fiber* is destroyed. When the home fiber of a thread is destroyed,
+// it means that the thread itself is destroyed.
+// Since we receive that notification outside of the Loader Lock, it allows us to safely acquire
+// the ThreadStore lock in the RuntimeThreadShutdown.
+static void __stdcall FiberDetachCallback(void* lpFlsData)
+{
+ ASSERT(g_flsIndex != FLS_OUT_OF_INDEXES);
+ ASSERT(lpFlsData == FlsGetValue(g_flsIndex));
+
+ if (lpFlsData != NULL)
+ {
+ // The current fiber is the home fiber of a thread, so the thread is shutting down
+ RuntimeThreadShutdown(lpFlsData);
+ }
+}
+
+void InitFlsSlot()
+{
+ // We use fiber detach callbacks to run our thread shutdown code because the fiber detach
+ // callback is made without the OS loader lock
+ g_flsIndex = FlsAlloc(FiberDetachCallback);
+ if (g_flsIndex == FLS_OUT_OF_INDEXES)
+ {
+ COMPlusThrowWin32();
+ }
+}
+
+// Register the thread with OS to be notified when thread is about to be destroyed
+// It fails fast if a different thread was already registered with the current fiber.
+// Parameters:
+// thread - thread to attach
+static void OsAttachThread(void* thread)
+{
+ void* threadFromCurrentFiber = FlsGetValue(g_flsIndex);
+
+ if (threadFromCurrentFiber != NULL)
+ {
+ _ASSERTE_ALL_BUILDS(!"Multiple threads encountered from a single fiber");
+ }
+
+ // Associate the current fiber with the current thread. This makes the current fiber the thread's "home"
+ // fiber. This fiber is the only fiber allowed to execute managed code on this thread. When this fiber
+ // is destroyed, we consider the thread to be destroyed.
+ FlsSetValue(g_flsIndex, thread);
+}
+
+// Detach thread from OS notifications.
+// It fails fast if some other thread value was attached to the current fiber.
+// Parameters:
+// thread - thread to detach
+// Return:
+// true if the thread was detached, false if there was no attached thread
+void OsDetachThread(void* thread)
+{
+ ASSERT(g_flsIndex != FLS_OUT_OF_INDEXES);
+ void* threadFromCurrentFiber = FlsGetValue(g_flsIndex);
+
+ if (threadFromCurrentFiber == NULL)
+ {
+ // we've seen this thread, but not this fiber. It must be a "foreign" fiber that was
+ // borrowing this thread.
+ return;
+ }
+
+ if (threadFromCurrentFiber != thread)
+ {
+ _ASSERTE_ALL_BUILDS(!"Detaching a thread from the wrong fiber");
+ }
+
+ FlsSetValue(g_flsIndex, NULL);
+}
+
+void EnsureTlsDestructionMonitor()
+{
+ OsAttachThread(GetThread());
+}
+
+#else
struct TlsDestructionMonitor
{
bool m_activated = false;
@@ -1715,36 +1833,7 @@ struct TlsDestructionMonitor
{
if (m_activated)
{
- Thread* thread = GetThreadNULLOk();
- if (thread)
- {
-#ifdef FEATURE_COMINTEROP
- // reset the CoInitialize state
- // so we don't call CoUninitialize during thread detach
- thread->ResetCoInitialized();
-#endif // FEATURE_COMINTEROP
- // For case where thread calls ExitThread directly, we need to reset the
- // frame pointer. Otherwise stackwalk would AV. We need to do it in cooperative mode.
- // We need to set m_GCOnTransitionsOK so this thread won't trigger GC when toggle GC mode
- if (thread->m_pFrame != FRAME_TOP)
- {
-#ifdef _DEBUG
- thread->m_GCOnTransitionsOK = FALSE;
-#endif
- GCX_COOP_NO_DTOR();
- thread->m_pFrame = FRAME_TOP;
- GCX_COOP_NO_DTOR_END();
- }
-
- thread->DetachThread(TRUE);
- }
- else
- {
- // Since we don't actually cleanup the TLS data along this path, verify that it is already cleaned up
- AssertThreadStaticDataFreed();
- }
-
- ThreadDetaching();
+ RuntimeThreadShutdown(GetThreadNULLOk());
}
}
};
@@ -1758,6 +1847,8 @@ void EnsureTlsDestructionMonitor()
tls_destructionMonitor.Activate();
}
+#endif
+
#ifdef DEBUGGING_SUPPORTED
//
// InitializeDebugger initialized the Runtime-side COM+ Debugging Services
diff --git a/src/coreclr/vm/ceemain.h b/src/coreclr/vm/ceemain.h
index 1404a5a04237ff..120082d30572ca 100644
--- a/src/coreclr/vm/ceemain.h
+++ b/src/coreclr/vm/ceemain.h
@@ -46,6 +46,10 @@ void ForceEEShutdown(ShutdownCompleteAction sca = SCA_ExitProcessWhenShutdownCom
void ThreadDetaching();
void EnsureTlsDestructionMonitor();
+#ifdef TARGET_WINDOWS
+void InitFlsSlot();
+void OsDetachThread(void* thread);
+#endif
void SetLatchedExitCode (INT32 code);
INT32 GetLatchedExitCode (void);
diff --git a/src/coreclr/vm/codeversion.h b/src/coreclr/vm/codeversion.h
index 442a2846543757..b9dc76b90e3066 100644
--- a/src/coreclr/vm/codeversion.h
+++ b/src/coreclr/vm/codeversion.h
@@ -330,6 +330,9 @@ struct cdac_data
static constexpr size_t NativeCode = offsetof(NativeCodeVersionNode, m_pNativeCode);
static constexpr size_t Flags = offsetof(NativeCodeVersionNode, m_flags);
static constexpr size_t ILVersionId = offsetof(NativeCodeVersionNode, m_parentId);
+#ifdef HAVE_GCCOVER
+ static constexpr size_t GCCoverageInfo = offsetof(NativeCodeVersionNode, m_gcCover);
+#endif // HAVE_GCCOVER
};
class NativeCodeVersionCollection
diff --git a/src/coreclr/vm/comthreadpool.cpp b/src/coreclr/vm/comthreadpool.cpp
deleted file mode 100644
index daa8d48d3a3078..00000000000000
--- a/src/coreclr/vm/comthreadpool.cpp
+++ /dev/null
@@ -1,70 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-#include "common.h"
-
-#include "comthreadpool.h"
-#include "eeconfig.h"
-
-/*****************************************************************************************************/
-// Enumerates some runtime config variables that are used by CoreLib for initialization. The config variable index should start
-// at 0 to begin enumeration. If a config variable at or after the specified config variable index is configured, returns the
-// next config variable index to pass in on the next call to continue enumeration.
-FCIMPL4(INT32, ThreadPoolNative::GetNextConfigUInt32Value,
- INT32 configVariableIndex,
- UINT32 *configValueRef,
- BOOL *isBooleanRef,
- LPCWSTR *appContextConfigNameRef)
-{
- FCALL_CONTRACT;
- _ASSERTE(configVariableIndex >= 0);
- _ASSERTE(configValueRef != NULL);
- _ASSERTE(isBooleanRef != NULL);
- _ASSERTE(appContextConfigNameRef != NULL);
-
- auto TryGetConfig =
- [=](const CLRConfig::ConfigDWORDInfo &configInfo, bool isBoolean, const WCHAR *appContextConfigName) -> bool
- {
- bool wasNotConfigured = true;
- *configValueRef = CLRConfig::GetConfigValue(configInfo, &wasNotConfigured);
- if (wasNotConfigured)
- {
- return false;
- }
-
- *isBooleanRef = isBoolean;
- *appContextConfigNameRef = appContextConfigName;
- return true;
- };
-
- switch (configVariableIndex)
- {
- case 1: if (TryGetConfig(CLRConfig::INTERNAL_ThreadPool_ForceMinWorkerThreads, false, W("System.Threading.ThreadPool.MinThreads"))) { return 2; } FALLTHROUGH;
- case 2: if (TryGetConfig(CLRConfig::INTERNAL_ThreadPool_ForceMaxWorkerThreads, false, W("System.Threading.ThreadPool.MaxThreads"))) { return 3; } FALLTHROUGH;
- case 3: if (TryGetConfig(CLRConfig::INTERNAL_ThreadPool_DisableStarvationDetection, true, W("System.Threading.ThreadPool.DisableStarvationDetection"))) { return 4; } FALLTHROUGH;
- case 4: if (TryGetConfig(CLRConfig::INTERNAL_ThreadPool_DebugBreakOnWorkerStarvation, true, W("System.Threading.ThreadPool.DebugBreakOnWorkerStarvation"))) { return 5; } FALLTHROUGH;
- case 5: if (TryGetConfig(CLRConfig::INTERNAL_ThreadPool_UnfairSemaphoreSpinLimit, false, W("System.Threading.ThreadPool.UnfairSemaphoreSpinLimit"))) { return 6; } FALLTHROUGH;
-
- case 6: if (TryGetConfig(CLRConfig::INTERNAL_HillClimbing_Disable, true, W("System.Threading.ThreadPool.HillClimbing.Disable"))) { return 7; } FALLTHROUGH;
- case 7: if (TryGetConfig(CLRConfig::INTERNAL_HillClimbing_WavePeriod, false, W("System.Threading.ThreadPool.HillClimbing.WavePeriod"))) { return 8; } FALLTHROUGH;
- case 8: if (TryGetConfig(CLRConfig::INTERNAL_HillClimbing_TargetSignalToNoiseRatio, false, W("System.Threading.ThreadPool.HillClimbing.TargetSignalToNoiseRatio"))) { return 9; } FALLTHROUGH;
- case 9: if (TryGetConfig(CLRConfig::INTERNAL_HillClimbing_ErrorSmoothingFactor, false, W("System.Threading.ThreadPool.HillClimbing.ErrorSmoothingFactor"))) { return 10; } FALLTHROUGH;
- case 10: if (TryGetConfig(CLRConfig::INTERNAL_HillClimbing_WaveMagnitudeMultiplier, false, W("System.Threading.ThreadPool.HillClimbing.WaveMagnitudeMultiplier"))) { return 11; } FALLTHROUGH;
- case 11: if (TryGetConfig(CLRConfig::INTERNAL_HillClimbing_MaxWaveMagnitude, false, W("System.Threading.ThreadPool.HillClimbing.MaxWaveMagnitude"))) { return 12; } FALLTHROUGH;
- case 12: if (TryGetConfig(CLRConfig::INTERNAL_HillClimbing_WaveHistorySize, false, W("System.Threading.ThreadPool.HillClimbing.WaveHistorySize"))) { return 13; } FALLTHROUGH;
- case 13: if (TryGetConfig(CLRConfig::INTERNAL_HillClimbing_Bias, false, W("System.Threading.ThreadPool.HillClimbing.Bias"))) { return 14; } FALLTHROUGH;
- case 14: if (TryGetConfig(CLRConfig::INTERNAL_HillClimbing_MaxChangePerSecond, false, W("System.Threading.ThreadPool.HillClimbing.MaxChangePerSecond"))) { return 15; } FALLTHROUGH;
- case 15: if (TryGetConfig(CLRConfig::INTERNAL_HillClimbing_MaxChangePerSample, false, W("System.Threading.ThreadPool.HillClimbing.MaxChangePerSample"))) { return 16; } FALLTHROUGH;
- case 16: if (TryGetConfig(CLRConfig::INTERNAL_HillClimbing_MaxSampleErrorPercent, false, W("System.Threading.ThreadPool.HillClimbing.MaxSampleErrorPercent"))) { return 17; } FALLTHROUGH;
- case 17: if (TryGetConfig(CLRConfig::INTERNAL_HillClimbing_SampleIntervalLow, false, W("System.Threading.ThreadPool.HillClimbing.SampleIntervalLow"))) { return 18; } FALLTHROUGH;
- case 18: if (TryGetConfig(CLRConfig::INTERNAL_HillClimbing_SampleIntervalHigh, false, W("System.Threading.ThreadPool.HillClimbing.SampleIntervalHigh"))) { return 19; } FALLTHROUGH;
- case 19: if (TryGetConfig(CLRConfig::INTERNAL_HillClimbing_GainExponent, false, W("System.Threading.ThreadPool.HillClimbing.GainExponent"))) { return 20; } FALLTHROUGH;
-
- default:
- *configValueRef = 0;
- *isBooleanRef = false;
- *appContextConfigNameRef = NULL;
- return -1;
- }
-}
-FCIMPLEND
diff --git a/src/coreclr/vm/comthreadpool.h b/src/coreclr/vm/comthreadpool.h
deleted file mode 100644
index e3ad28c01c0c17..00000000000000
--- a/src/coreclr/vm/comthreadpool.h
+++ /dev/null
@@ -1,17 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-#ifndef _COMTHREADPOOL_H
-#define _COMTHREADPOOL_H
-
-class ThreadPoolNative
-{
-public:
- static FCDECL4(INT32, GetNextConfigUInt32Value,
- INT32 configVariableIndex,
- UINT32 *configValueRef,
- BOOL *isBooleanRef,
- LPCWSTR *appContextConfigNameRef);
-};
-
-#endif
diff --git a/src/coreclr/vm/corelib.cpp b/src/coreclr/vm/corelib.cpp
index 4c3f7438a559ab..beb66a2086a226 100644
--- a/src/coreclr/vm/corelib.cpp
+++ b/src/coreclr/vm/corelib.cpp
@@ -31,7 +31,6 @@
#include "comdatetime.h"
#include "debugdebugger.h"
#include "assemblynative.hpp"
-#include "comthreadpool.h"
#include "comwaithandle.h"
#include "proftoeeinterfaceimpl.h"
diff --git a/src/coreclr/vm/ecalllist.h b/src/coreclr/vm/ecalllist.h
index a934364e77591c..7535c717c3955b 100644
--- a/src/coreclr/vm/ecalllist.h
+++ b/src/coreclr/vm/ecalllist.h
@@ -91,8 +91,6 @@ FCFuncStart(gCOMTypeHandleFuncs)
FCFuncElement("GetArrayRank", RuntimeTypeHandle::GetArrayRank)
FCFuncElement("GetToken", RuntimeTypeHandle::GetToken)
FCFuncElement("GetUtf8NameInternal", RuntimeTypeHandle::GetUtf8Name)
- FCFuncElement("GetFields", RuntimeTypeHandle::GetFields)
- FCFuncElement("GetInterfaces", RuntimeTypeHandle::GetInterfaces)
FCFuncElement("GetAttributes", RuntimeTypeHandle::GetAttributes)
FCFuncElement("GetNumVirtuals", RuntimeTypeHandle::GetNumVirtuals)
FCFuncElement("CanCastTo", RuntimeTypeHandle::CanCastTo)
@@ -135,7 +133,6 @@ FCFuncEnd()
FCFuncStart(gSignatureNative)
FCFuncElement("GetSignature", SignatureNative::GetSignature)
- FCFuncElement("CompareSig", SignatureNative::CompareSig)
FCFuncElement("GetParameterOffsetInternal", SignatureNative::GetParameterOffsetInternal)
FCFuncElement("GetTypeParameterOffset", SignatureNative::GetTypeParameterOffset)
FCFuncElement("GetCustomModifiersAtOffset", SignatureNative::GetCustomModifiersAtOffset)
@@ -251,10 +248,6 @@ FCFuncStart(gThreadFuncs)
FCFuncElement("get_OptimalMaxSpinWaitsPerSpinIteration", ThreadNative::GetOptimalMaxSpinWaitsPerSpinIteration)
FCFuncEnd()
-FCFuncStart(gThreadPoolFuncs)
- FCFuncElement("GetNextConfigUInt32Value", ThreadPoolNative::GetNextConfigUInt32Value)
-FCFuncEnd()
-
FCFuncStart(gCastHelpers)
FCFuncElement("WriteBarrier", ::WriteBarrier_Helper)
FCFuncEnd()
@@ -417,7 +410,6 @@ FCClassElement("Signature", "System", gSignatureNative)
FCClassElement("String", "System", gStringFuncs)
FCClassElement("StubHelpers", "System.StubHelpers", gStubHelperFuncs)
FCClassElement("Thread", "System.Threading", gThreadFuncs)
-FCClassElement("ThreadPool", "System.Threading", gThreadPoolFuncs)
#undef FCFuncElement
#undef FCFuncElementSig
diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp
index c4e390130cc348..44d03a2ffd3c16 100644
--- a/src/coreclr/vm/method.hpp
+++ b/src/coreclr/vm/method.hpp
@@ -1853,10 +1853,8 @@ class MethodDesc
//
// Optional MethodDesc slots appear after the end of base MethodDesc in this order:
//
-
- // class MethodImpl; // Present if HasMethodImplSlot() is true
-
typedef PCODE NonVtableSlot; // Present if HasNonVtableSlot() is true
+ // class MethodImpl; // Present if HasMethodImplSlot() is true
typedef PCODE NativeCodeSlot; // Present if HasNativeCodeSlot() is true
// Stub Dispatch code
diff --git a/src/coreclr/vm/precode.cpp b/src/coreclr/vm/precode.cpp
index 74111c297fc25f..e793425d2bec50 100644
--- a/src/coreclr/vm/precode.cpp
+++ b/src/coreclr/vm/precode.cpp
@@ -150,23 +150,6 @@ MethodDesc* Precode::GetMethodDesc(BOOL fSpeculative /*= FALSE*/)
return (PTR_MethodDesc)pMD;
}
-BOOL Precode::IsCorrectMethodDesc(MethodDesc * pMD)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
- MethodDesc * pMDfromPrecode = GetMethodDesc(TRUE);
-
- if (pMDfromPrecode == pMD)
- return TRUE;
-
- return FALSE;
-}
-
BOOL Precode::IsPointingToPrestub(PCODE target)
{
CONTRACTL
diff --git a/src/coreclr/vm/precode.h b/src/coreclr/vm/precode.h
index aca583676a20fe..894a708e195f6b 100644
--- a/src/coreclr/vm/precode.h
+++ b/src/coreclr/vm/precode.h
@@ -531,7 +531,6 @@ class Precode {
PTR_PCODE GetTargetSlot();
MethodDesc * GetMethodDesc(BOOL fSpeculative = FALSE);
- BOOL IsCorrectMethodDesc(MethodDesc * pMD);
static Precode* Allocate(PrecodeType t, MethodDesc* pMD,
LoaderAllocator *pLoaderAllocator, AllocMemTracker *pamTracker);
diff --git a/src/coreclr/vm/profilingenumerators.cpp b/src/coreclr/vm/profilingenumerators.cpp
index f214be043f0bf8..50883da5ea8822 100644
--- a/src/coreclr/vm/profilingenumerators.cpp
+++ b/src/coreclr/vm/profilingenumerators.cpp
@@ -552,9 +552,11 @@ HRESULT ProfilerThreadEnum::Init()
}
CONTRACTL_END;
+ // If EnumThreads is called from a profiler callback where the runtime is already suspended,
+ // don't recursively acquire/release the ThreadStore Lock.
// If a profiler has requested that the runtime suspend to do stack snapshots, it
// will be holding the ThreadStore lock already
- ThreadStoreLockHolder tsLock(!g_profControlBlock.fProfilerRequestedRuntimeSuspend);
+ ThreadStoreLockHolder tsLock(!ThreadStore::HoldingThreadStore() && !g_profControlBlock.fProfilerRequestedRuntimeSuspend);
Thread * pThread = NULL;
diff --git a/src/coreclr/vm/proftoeeinterfaceimpl.cpp b/src/coreclr/vm/proftoeeinterfaceimpl.cpp
index 1d3530c615d1e5..bdf2648af9d7fa 100644
--- a/src/coreclr/vm/proftoeeinterfaceimpl.cpp
+++ b/src/coreclr/vm/proftoeeinterfaceimpl.cpp
@@ -6835,8 +6835,8 @@ HRESULT ProfToEEInterfaceImpl::SuspendRuntime()
return CORPROF_E_SUSPENSION_IN_PROGRESS;
}
- g_profControlBlock.fProfilerRequestedRuntimeSuspend = TRUE;
ThreadSuspend::SuspendEE(ThreadSuspend::SUSPEND_REASON::SUSPEND_FOR_PROFILER);
+ g_profControlBlock.fProfilerRequestedRuntimeSuspend = TRUE;
return S_OK;
}
@@ -6874,8 +6874,8 @@ HRESULT ProfToEEInterfaceImpl::ResumeRuntime()
return CORPROF_E_UNSUPPORTED_CALL_SEQUENCE;
}
- ThreadSuspend::RestartEE(FALSE /* bFinishedGC */, TRUE /* SuspendSucceeded */);
g_profControlBlock.fProfilerRequestedRuntimeSuspend = FALSE;
+ ThreadSuspend::RestartEE(FALSE /* bFinishedGC */, TRUE /* SuspendSucceeded */);
return S_OK;
}
@@ -7667,8 +7667,8 @@ HRESULT ProfToEEInterfaceImpl::EnumerateGCHeapObjects(ObjectCallback callback, v
// SuspendEE() may race with other threads by design and this thread may block
// arbitrarily long inside SuspendEE() for other threads to complete their own
// suspensions.
- g_profControlBlock.fProfilerRequestedRuntimeSuspend = TRUE;
ThreadSuspend::SuspendEE(ThreadSuspend::SUSPEND_REASON::SUSPEND_FOR_PROFILER);
+ g_profControlBlock.fProfilerRequestedRuntimeSuspend = TRUE;
ownEESuspension = TRUE;
}
@@ -7700,8 +7700,8 @@ HRESULT ProfToEEInterfaceImpl::EnumerateGCHeapObjects(ObjectCallback callback, v
if (ownEESuspension)
{
- ThreadSuspend::RestartEE(FALSE /* bFinishedGC */, TRUE /* SuspendSucceeded */);
g_profControlBlock.fProfilerRequestedRuntimeSuspend = FALSE;
+ ThreadSuspend::RestartEE(FALSE /* bFinishedGC */, TRUE /* SuspendSucceeded */);
}
return hr;
diff --git a/src/coreclr/vm/qcallentrypoints.cpp b/src/coreclr/vm/qcallentrypoints.cpp
index 56c67fc1e3282c..a359ecde8aa68b 100644
--- a/src/coreclr/vm/qcallentrypoints.cpp
+++ b/src/coreclr/vm/qcallentrypoints.cpp
@@ -26,7 +26,6 @@
#include "comdatetime.h"
#include "debugdebugger.h"
#include "assemblynative.hpp"
-#include "comthreadpool.h"
#include "comwaithandle.h"
#include "proftoeeinterfaceimpl.h"
@@ -125,12 +124,14 @@ static const Entry s_QCall[] =
DllImportEntry(RuntimeTypeHandle_GetModuleSlow)
DllImportEntry(RuntimeTypeHandle_GetNumVirtualsAndStaticVirtuals)
DllImportEntry(RuntimeTypeHandle_GetMethodAt)
+ DllImportEntry(RuntimeTypeHandle_GetFields)
DllImportEntry(RuntimeTypeHandle_VerifyInterfaceIsImplemented)
DllImportEntry(RuntimeTypeHandle_GetInterfaceMethodImplementation)
DllImportEntry(RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable)
DllImportEntry(RuntimeTypeHandle_GetDeclaringTypeHandle)
DllImportEntry(RuntimeTypeHandle_IsVisible)
DllImportEntry(RuntimeTypeHandle_ConstructName)
+ DllImportEntry(RuntimeTypeHandle_GetInterfaces)
DllImportEntry(RuntimeTypeHandle_GetInstantiation)
DllImportEntry(RuntimeTypeHandle_Instantiate)
DllImportEntry(RuntimeTypeHandle_GetGenericTypeDefinition)
@@ -186,6 +187,7 @@ static const Entry s_QCall[] =
DllImportEntry(ModuleHandle_GetPEKind)
DllImportEntry(ModuleHandle_GetDynamicMethod)
DllImportEntry(AssemblyHandle_GetManifestModuleSlow)
+ DllImportEntry(Signature_AreEqual)
DllImportEntry(TypeBuilder_DefineGenericParam)
DllImportEntry(TypeBuilder_DefineType)
DllImportEntry(TypeBuilder_SetParentType)
diff --git a/src/coreclr/vm/runtimehandles.cpp b/src/coreclr/vm/runtimehandles.cpp
index 932c69fa34eb5a..42f1772e37d8c7 100644
--- a/src/coreclr/vm/runtimehandles.cpp
+++ b/src/coreclr/vm/runtimehandles.cpp
@@ -455,55 +455,39 @@ extern "C" MethodDesc* QCALLTYPE RuntimeTypeHandle_GetMethodAt(MethodTable* pMT,
return pRetMethod;
}
-FCIMPL3(FC_BOOL_RET, RuntimeTypeHandle::GetFields, ReflectClassBaseObject *pTypeUNSAFE, INT32 **result, INT32 *pCount) {
- CONTRACTL {
- FCALL_CHECK;
- }
- CONTRACTL_END;
-
- REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
- if (refType == NULL)
- FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
-
- TypeHandle typeHandle = refType->GetType();
-
- if (!pCount || !result)
- FCThrow(kArgumentNullException);
+extern "C" BOOL QCALLTYPE RuntimeTypeHandle_GetFields(MethodTable* pMT, intptr_t* result, INT32* pCount)
+{
+ QCALL_CONTRACT;
- if (typeHandle.IsGenericVariable())
- FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
+ _ASSERTE(pMT != NULL);
+ _ASSERTE(result != NULL);
+ _ASSERTE(pCount != NULL);
- if (typeHandle.IsTypeDesc() || typeHandle.IsArray()) {
- *pCount = 0;
- FC_RETURN_BOOL(TRUE);
- }
+ BOOL retVal = FALSE;
- MethodTable *pMT= typeHandle.GetMethodTable();
- if (!pMT)
- FCThrowRes(kArgumentException, W("Arg_InvalidHandle"));
+ BEGIN_QCALL;
- BOOL retVal = FALSE;
- HELPER_METHOD_FRAME_BEGIN_RET_1(refType);
- // Check this approximation - we may be losing exact type information
EncApproxFieldDescIterator fdIterator(pMT, ApproxFieldDescIterator::ALL_FIELDS, TRUE);
INT32 count = (INT32)fdIterator.Count();
if (count > *pCount)
{
*pCount = count;
+ retVal = FALSE;
}
else
{
- for(INT32 i = 0; i < count; i ++)
- result[i] = (INT32*)fdIterator.Next();
+ for(INT32 i = 0; i < count; ++i)
+ result[i] = (intptr_t)fdIterator.Next();
*pCount = count;
retVal = TRUE;
}
- HELPER_METHOD_FRAME_END();
- FC_RETURN_BOOL(retVal);
+
+ END_QCALL;
+
+ return retVal;
}
-FCIMPLEND
extern "C" void QCALLTYPE RuntimeMethodHandle_ConstructInstantiation(MethodDesc * pMethod, DWORD format, QCall::StringHandleOnStack retString)
{
@@ -531,7 +515,50 @@ extern "C" void QCALLTYPE RuntimeTypeHandle_ConstructName(QCall::TypeHandle pTyp
END_QCALL;
}
-PTRARRAYREF CopyRuntimeTypeHandles(TypeHandle * prgTH, INT32 numTypeHandles, BinderClassID arrayElemType)
+extern "C" void QCALLTYPE RuntimeTypeHandle_GetInterfaces(MethodTable* pMT, QCall::ObjectHandleOnStack result)
+{
+ QCALL_CONTRACT;
+
+ _ASSERTE(pMT != NULL);
+
+ BEGIN_QCALL;
+
+ INT32 ifaceCount = pMT->GetNumInterfaces();
+ // Allocate the array
+ if (ifaceCount > 0)
+ {
+ GCX_COOP();
+
+ struct
+ {
+ PTRARRAYREF Types;
+ } gc;
+ gc.Types = NULL;
+ GCPROTECT_BEGIN(gc);
+ TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(g_pRuntimeTypeClass), ELEMENT_TYPE_SZARRAY);
+ gc.Types = (PTRARRAYREF)AllocateSzArray(arrayHandle, ifaceCount);
+
+ UINT i = 0;
+
+ // Populate type array
+ MethodTable::InterfaceMapIterator it = pMT->IterateInterfaceMap();
+ while (it.Next())
+ {
+ _ASSERTE(i < (UINT)ifaceCount);
+ OBJECTREF refInterface = it.GetInterface(pMT)->GetManagedClassObject();
+ gc.Types->SetAt(i, refInterface);
+ _ASSERTE(gc.Types->GetAt(i) != NULL);
+ i++;
+ }
+
+ result.Set(gc.Types);
+ GCPROTECT_END();
+ }
+
+ END_QCALL;
+}
+
+static PTRARRAYREF CopyRuntimeTypeHandles(TypeHandle * prgTH, INT32 numTypeHandles, BinderClassID arrayElemType)
{
CONTRACTL {
THROWS;
@@ -595,61 +622,6 @@ extern "C" void QCALLTYPE RuntimeTypeHandle_GetConstraints(QCall::TypeHandle pTy
return;
}
-FCIMPL1(PtrArray*, RuntimeTypeHandle::GetInterfaces, ReflectClassBaseObject *pTypeUNSAFE) {
- CONTRACTL {
- FCALL_CHECK;
- }
- CONTRACTL_END;
-
- REFLECTCLASSBASEREF refType = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(pTypeUNSAFE);
-
- if (refType == NULL)
- FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
-
- TypeHandle typeHandle = refType->GetType();
-
- if (typeHandle.IsGenericVariable())
- FCThrowRes(kArgumentNullException, W("Arg_InvalidHandle"));
-
- INT32 ifaceCount = 0;
-
- PTRARRAYREF refRetVal = NULL;
- HELPER_METHOD_FRAME_BEGIN_RET_2(refRetVal, refType);
- {
- if (typeHandle.IsTypeDesc())
- {
- ifaceCount = 0;
- }
- else
- {
- ifaceCount = typeHandle.GetMethodTable()->GetNumInterfaces();
- }
-
- // Allocate the array
- if (ifaceCount > 0)
- {
- TypeHandle arrayHandle = ClassLoader::LoadArrayTypeThrowing(TypeHandle(g_pRuntimeTypeClass), ELEMENT_TYPE_SZARRAY);
- refRetVal = (PTRARRAYREF)AllocateSzArray(arrayHandle, ifaceCount);
-
- // populate type array
- UINT i = 0;
-
- MethodTable::InterfaceMapIterator it = typeHandle.GetMethodTable()->IterateInterfaceMap();
- while (it.Next())
- {
- OBJECTREF refInterface = it.GetInterface(typeHandle.GetMethodTable())->GetManagedClassObject();
- refRetVal->SetAt(i, refInterface);
- _ASSERTE(refRetVal->GetAt(i) != NULL);
- i++;
- }
- }
- }
- HELPER_METHOD_FRAME_END();
-
- return (PtrArray*)OBJECTREFToObject(refRetVal);
-}
-FCIMPLEND
-
FCIMPL1(INT32, RuntimeTypeHandle::GetAttributes, ReflectClassBaseObject *pTypeUNSAFE) {
CONTRACTL {
FCALL_CHECK;
@@ -1856,32 +1828,25 @@ FCIMPL6(void, SignatureNative::GetSignature,
}
FCIMPLEND
-FCIMPL2(FC_BOOL_RET, SignatureNative::CompareSig, SignatureNative* pLhsUNSAFE, SignatureNative* pRhsUNSAFE)
+extern "C" BOOL QCALLTYPE Signature_AreEqual(
+ PCCOR_SIGNATURE sig1, INT32 cSig1, QCall::TypeHandle handle1,
+ PCCOR_SIGNATURE sig2, INT32 cSig2, QCall::TypeHandle handle2)
{
- FCALL_CONTRACT;
+ QCALL_CONTRACT;
- INT32 ret = 0;
+ BOOL ret = FALSE;
- struct
- {
- SIGNATURENATIVEREF pLhs;
- SIGNATURENATIVEREF pRhs;
- } gc;
+ BEGIN_QCALL;
- gc.pLhs = (SIGNATURENATIVEREF)pLhsUNSAFE;
- gc.pRhs = (SIGNATURENATIVEREF)pRhsUNSAFE;
+ ret = MetaSig::CompareMethodSigs(
+ sig1, cSig1, handle1.AsTypeHandle().GetModule(), NULL,
+ sig2, cSig2, handle2.AsTypeHandle().GetModule(), NULL,
+ FALSE);
- HELPER_METHOD_FRAME_BEGIN_RET_PROTECT(gc);
- {
- ret = MetaSig::CompareMethodSigs(
- gc.pLhs->GetCorSig(), gc.pLhs->GetCorSigSize(), gc.pLhs->GetModule(), NULL,
- gc.pRhs->GetCorSig(), gc.pRhs->GetCorSigSize(), gc.pRhs->GetModule(), NULL,
- FALSE);
- }
- HELPER_METHOD_FRAME_END();
- FC_RETURN_BOOL(ret);
+ END_QCALL;
+
+ return ret;
}
-FCIMPLEND
extern "C" void QCALLTYPE RuntimeMethodHandle_GetMethodInstantiation(MethodDesc * pMethod, QCall::ObjectHandleOnStack retTypes, BOOL fAsRuntimeTypeArray)
{
diff --git a/src/coreclr/vm/runtimehandles.h b/src/coreclr/vm/runtimehandles.h
index 30683f5c2a8e70..5dd2f5ff5676e9 100644
--- a/src/coreclr/vm/runtimehandles.h
+++ b/src/coreclr/vm/runtimehandles.h
@@ -137,11 +137,8 @@ class RuntimeTypeHandle
static FCDECL2(FC_BOOL_RET, CompareCanonicalHandles, PTR_ReflectClassBaseObject pLeft, PTR_ReflectClassBaseObject pRight);
- static FCDECL1(PtrArray*, GetInterfaces, ReflectClassBaseObject *pType);
-
static FCDECL1(EnregisteredTypeHandle, GetElementTypeHandle, EnregisteredTypeHandle th);
static FCDECL1(INT32, GetNumVirtuals, ReflectClassBaseObject *pType);
- static FCDECL3(FC_BOOL_RET, GetFields, ReflectClassBaseObject *pType, INT32 **result, INT32 *pCount);
static FCDECL1(MethodDesc *, GetFirstIntroducedMethod, ReflectClassBaseObject* pType);
static FCDECL1(void, GetNextIntroducedMethod, MethodDesc **ppMethod);
@@ -180,6 +177,7 @@ extern "C" void QCALLTYPE RuntimeTypeHandle_MakeArray(QCall::TypeHandle pTypeHan
extern "C" BOOL QCALLTYPE RuntimeTypeHandle_IsCollectible(QCall::TypeHandle pTypeHandle);
extern "C" void QCALLTYPE RuntimeTypeHandle_PrepareMemberInfoCache(QCall::TypeHandle pMemberInfoCache);
extern "C" void QCALLTYPE RuntimeTypeHandle_ConstructName(QCall::TypeHandle pTypeHandle, DWORD format, QCall::StringHandleOnStack retString);
+extern "C" void QCALLTYPE RuntimeTypeHandle_GetInterfaces(MethodTable* pMT, QCall::ObjectHandleOnStack result);
extern "C" BOOL QCALLTYPE RuntimeTypeHandle_IsVisible(QCall::TypeHandle pTypeHandle);
extern "C" void QCALLTYPE RuntimeTypeHandle_GetInstantiation(QCall::TypeHandle pTypeHandle, QCall::ObjectHandleOnStack retType, BOOL fAsRuntimeTypeArray);
extern "C" void QCALLTYPE RuntimeTypeHandle_Instantiate(QCall::TypeHandle pTypeHandle, TypeHandle * pInstArray, INT32 cInstArray, QCall::ObjectHandleOnStack retType);
@@ -190,6 +188,7 @@ extern "C" void QCALLTYPE RuntimeTypeHandle_GetAssemblySlow(QCall::ObjectHandleO
extern "C" void QCALLTYPE RuntimeTypeHandle_GetModuleSlow(QCall::ObjectHandleOnStack type, QCall::ObjectHandleOnStack module);
extern "C" INT32 QCALLTYPE RuntimeTypeHandle_GetNumVirtualsAndStaticVirtuals(QCall::TypeHandle pTypeHandle);
extern "C" MethodDesc* QCALLTYPE RuntimeTypeHandle_GetMethodAt(MethodTable* pMT, INT32 slot);
+extern "C" BOOL QCALLTYPE RuntimeTypeHandle_GetFields(MethodTable* pMT, intptr_t* result, INT32* pCount);
extern "C" void QCALLTYPE RuntimeTypeHandle_VerifyInterfaceIsImplemented(QCall::TypeHandle pTypeHandle, QCall::TypeHandle pIFaceHandle);
extern "C" MethodDesc* QCALLTYPE RuntimeTypeHandle_GetInterfaceMethodImplementation(QCall::TypeHandle pTypeHandle, QCall::TypeHandle pOwner, MethodDesc * pMD);
extern "C" EnregisteredTypeHandle QCALLTYPE RuntimeTypeHandle_GetDeclaringTypeHandleForGenericVariable(EnregisteredTypeHandle pTypeHandle);
@@ -328,8 +327,6 @@ class SignatureNative : public Object
FieldDesc *pFieldDesc, ReflectMethodObject *pMethodUNSAFE,
ReflectClassBaseObject *pDeclaringType);
- static FCDECL2(FC_BOOL_RET, CompareSig, SignatureNative* pLhs, SignatureNative* pRhs);
-
static FCDECL3(INT32, GetParameterOffsetInternal, PCCOR_SIGNATURE sig, DWORD csig, INT32 parameterIndex);
static FCDECL3(INT32, GetTypeParameterOffset, SignatureNative* pSig, INT32 offset, INT32 index);
@@ -509,6 +506,10 @@ class SignatureNative : public Object
MethodDesc* m_pMethod;
};
+extern "C" BOOL QCALLTYPE Signature_AreEqual(
+ PCCOR_SIGNATURE sig1, INT32 cSig1, QCall::TypeHandle handle1,
+ PCCOR_SIGNATURE sig2, INT32 cSig2, QCall::TypeHandle handle2);
+
class ReflectionPointer : public Object
{
public:
diff --git a/src/coreclr/vm/siginfo.cpp b/src/coreclr/vm/siginfo.cpp
index d1154722b340c5..e7717aba1ce75a 100644
--- a/src/coreclr/vm/siginfo.cpp
+++ b/src/coreclr/vm/siginfo.cpp
@@ -16,7 +16,6 @@
#include "gcheaputilities.h"
#include "field.h"
#include "eeconfig.h"
-#include "runtimehandles.h" // for SignatureNative
#include "winwrap.h"
#include
#include "sigbuilder.h"
diff --git a/src/coreclr/vm/syncblk.cpp b/src/coreclr/vm/syncblk.cpp
index 868fffca0c0552..3fb9089bf31c54 100644
--- a/src/coreclr/vm/syncblk.cpp
+++ b/src/coreclr/vm/syncblk.cpp
@@ -1816,7 +1816,9 @@ BOOL ObjHeader::GetThreadOwningMonitorLock(DWORD *pThreadId, DWORD *pAcquisition
_ASSERTE(psb->GetMonitor() != NULL);
Thread* pThread = psb->GetMonitor()->GetHoldingThread();
- if(pThread == NULL)
+ // If the lock is orphaned during sync block creation, pThread would be assigned -1.
+ // Otherwise pThread would point to the owning thread if there was one or NULL if there wasn't.
+ if (pThread == NULL || pThread == (Thread*) -1)
{
*pThreadId = 0;
*pAcquisitionCount = 0;
@@ -1824,7 +1826,12 @@ BOOL ObjHeader::GetThreadOwningMonitorLock(DWORD *pThreadId, DWORD *pAcquisition
}
else
{
- *pThreadId = pThread->GetThreadId();
+ // However, the lock might get orphaned after the sync block is created.
+ // Therefore accessing pThread is not safe and pThread->GetThreadId() shouldn't be used.
+ // The thread id can be obtained from the monitor, which would be the id of the thread that owned the lock.
+ // Notice this id now could have been reused for a different thread,
+ // but this way we avoid crashing the process and orphaned locks shouldn't be expected to work correctly anyway.
+ *pThreadId = psb->GetMonitor()->GetHoldingThreadId();
*pAcquisitionCount = psb->GetMonitor()->GetRecursionLevel();
return TRUE;
}
@@ -2190,20 +2197,23 @@ SyncBlock *ObjHeader::GetSyncBlock()
_ASSERTE(lockThreadId != 0);
Thread *pThread = g_pThinLockThreadIdDispenser->IdToThreadWithValidation(lockThreadId);
+ DWORD threadId = 0;
SIZE_T osThreadId;
if (pThread == NULL)
{
// The lock is orphaned.
pThread = (Thread*) -1;
+ threadId = -1;
osThreadId = (SIZE_T)-1;
}
else
{
+ threadId = pThread->GetThreadId();
osThreadId = pThread->GetOSThreadId64();
}
- syncBlock->InitState(recursionLevel + 1, pThread, osThreadId);
+ syncBlock->InitState(recursionLevel + 1, pThread, threadId, osThreadId);
}
}
else if ((bits & BIT_SBLK_IS_HASHCODE) != 0)
@@ -2367,6 +2377,7 @@ void AwareLock::Enter()
{
// We get here if we successfully acquired the mutex.
m_HoldingThread = pCurThread;
+ m_HoldingThreadId = pCurThread->GetThreadId();
m_HoldingOSThreadId = pCurThread->GetOSThreadId64();
m_Recursion = 1;
@@ -2430,6 +2441,7 @@ BOOL AwareLock::TryEnter(INT32 timeOut)
{
// We get here if we successfully acquired the mutex.
m_HoldingThread = pCurThread;
+ m_HoldingThreadId = pCurThread->GetThreadId();
m_HoldingOSThreadId = pCurThread->GetOSThreadId64();
m_Recursion = 1;
@@ -2709,6 +2721,7 @@ BOOL AwareLock::EnterEpilogHelper(Thread* pCurThread, INT32 timeOut)
}
m_HoldingThread = pCurThread;
+ m_HoldingThreadId = pCurThread->GetThreadId();
m_HoldingOSThreadId = pCurThread->GetOSThreadId64();
m_Recursion = 1;
diff --git a/src/coreclr/vm/syncblk.h b/src/coreclr/vm/syncblk.h
index 7cdf92cdda8786..aa76cd3056b887 100644
--- a/src/coreclr/vm/syncblk.h
+++ b/src/coreclr/vm/syncblk.h
@@ -436,6 +436,7 @@ class AwareLock
ULONG m_Recursion;
PTR_Thread m_HoldingThread;
+ DWORD m_HoldingThreadId;
SIZE_T m_HoldingOSThreadId;
LONG m_TransientPrecious;
@@ -459,6 +460,7 @@ class AwareLock
// PreFAST has trouble with initializing a NULL PTR_Thread.
m_HoldingThread(NULL),
#endif // DACCESS_COMPILE
+ m_HoldingThreadId(0),
m_HoldingOSThreadId(0),
m_TransientPrecious(0),
m_dwSyncIndex(indx),
@@ -523,19 +525,26 @@ class AwareLock
return m_HoldingThread;
}
+ DWORD GetHoldingThreadId() const
+ {
+ LIMITED_METHOD_CONTRACT;
+ return m_HoldingThreadId;
+ }
+
private:
void ResetWaiterStarvationStartTime();
void RecordWaiterStarvationStartTime();
bool ShouldStopPreemptingWaiters() const;
private: // friend access is required for this unsafe function
- void InitializeToLockedWithNoWaiters(ULONG recursionLevel, PTR_Thread holdingThread, SIZE_T holdingOSThreadId)
+ void InitializeToLockedWithNoWaiters(ULONG recursionLevel, PTR_Thread holdingThread, DWORD holdingThreadId, SIZE_T holdingOSThreadId)
{
WRAPPER_NO_CONTRACT;
m_lockState.InitializeToLockedWithNoWaiters();
m_Recursion = recursionLevel;
m_HoldingThread = holdingThread;
+ m_HoldingThreadId = holdingThreadId;
m_HoldingOSThreadId = holdingOSThreadId;
}
@@ -1270,10 +1279,10 @@ class SyncBlock
// This should ONLY be called when initializing a SyncBlock (i.e. ONLY from
// ObjHeader::GetSyncBlock()), otherwise we'll have a race condition.
//
- void InitState(ULONG recursionLevel, PTR_Thread holdingThread, SIZE_T holdingOSThreadId)
+ void InitState(ULONG recursionLevel, PTR_Thread holdingThread, DWORD holdingThreadId, SIZE_T holdingOSThreadId)
{
WRAPPER_NO_CONTRACT;
- m_Monitor.InitializeToLockedWithNoWaiters(recursionLevel, holdingThread, holdingOSThreadId);
+ m_Monitor.InitializeToLockedWithNoWaiters(recursionLevel, holdingThread, holdingThreadId, holdingOSThreadId);
}
#if defined(ENABLE_CONTRACTS_IMPL)
diff --git a/src/coreclr/vm/syncblk.inl b/src/coreclr/vm/syncblk.inl
index 97b479168f1462..4cad064c8149de 100644
--- a/src/coreclr/vm/syncblk.inl
+++ b/src/coreclr/vm/syncblk.inl
@@ -479,6 +479,7 @@ FORCEINLINE bool AwareLock::TryEnterHelper(Thread* pCurThread)
if (m_lockState.InterlockedTryLock())
{
m_HoldingThread = pCurThread;
+ m_HoldingThreadId = pCurThread->GetThreadId();
m_HoldingOSThreadId = pCurThread->GetOSThreadId64();
m_Recursion = 1;
return true;
@@ -525,6 +526,7 @@ FORCEINLINE AwareLock::EnterHelperResult AwareLock::TryEnterBeforeSpinLoopHelper
// Lock was acquired and the spinner was not registered
m_HoldingThread = pCurThread;
+ m_HoldingThreadId = pCurThread->GetThreadId();
m_HoldingOSThreadId = pCurThread->GetOSThreadId64();
m_Recursion = 1;
return EnterHelperResult_Entered;
@@ -557,6 +559,7 @@ FORCEINLINE AwareLock::EnterHelperResult AwareLock::TryEnterInsideSpinLoopHelper
// Lock was acquired and spinner was unregistered
m_HoldingThread = pCurThread;
+ m_HoldingThreadId = pCurThread->GetThreadId();
m_HoldingOSThreadId = pCurThread->GetOSThreadId64();
m_Recursion = 1;
return EnterHelperResult_Entered;
@@ -580,6 +583,7 @@ FORCEINLINE bool AwareLock::TryEnterAfterSpinLoopHelper(Thread *pCurThread)
// Spinner was unregistered and the lock was acquired
m_HoldingThread = pCurThread;
+ m_HoldingThreadId = pCurThread->GetThreadId();
m_HoldingOSThreadId = pCurThread->GetOSThreadId64();
m_Recursion = 1;
return true;
@@ -699,6 +703,7 @@ FORCEINLINE AwareLock::LeaveHelperAction AwareLock::LeaveHelper(Thread* pCurThre
if (--m_Recursion == 0)
{
m_HoldingThread = NULL;
+ m_HoldingThreadId = 0;
m_HoldingOSThreadId = 0;
// Clear lock bit and determine whether we must signal a waiter to wake
diff --git a/src/coreclr/vm/threads.cpp b/src/coreclr/vm/threads.cpp
index e89b6c7d94c1d0..7ffb9f4746d94a 100644
--- a/src/coreclr/vm/threads.cpp
+++ b/src/coreclr/vm/threads.cpp
@@ -353,6 +353,7 @@ void SetThread(Thread* t)
{
LIMITED_METHOD_CONTRACT
+ Thread* origThread = gCurrentThreadInfo.m_pThread;
gCurrentThreadInfo.m_pThread = t;
if (t != NULL)
{
@@ -360,6 +361,14 @@ void SetThread(Thread* t)
EnsureTlsDestructionMonitor();
t->InitRuntimeThreadLocals();
}
+#ifdef TARGET_WINDOWS
+ else if (origThread != NULL)
+ {
+ // Unregister from OS notifications
+ // This can return false if a thread did not register for OS notification.
+ OsDetachThread(origThread);
+ }
+#endif
// Clear or set the app domain to the one domain based on if the thread is being nulled out or set
gCurrentThreadInfo.m_pAppDomain = t == NULL ? NULL : AppDomain::GetCurrentDomain();
@@ -1039,6 +1048,10 @@ void InitThreadManager()
}
CONTRACTL_END;
+#ifdef TARGET_WINDOWS
+ InitFlsSlot();
+#endif
+
// All patched helpers should fit into one page.
// If you hit this assert on retail build, there is most likely problem with BBT script.
_ASSERTE_ALL_BUILDS((BYTE*)JIT_PatchedCodeLast - (BYTE*)JIT_PatchedCodeStart > (ptrdiff_t)0);
diff --git a/src/coreclr/vm/threadsuspend.cpp b/src/coreclr/vm/threadsuspend.cpp
index 6bc046e2b40bd4..505ceb174684f3 100644
--- a/src/coreclr/vm/threadsuspend.cpp
+++ b/src/coreclr/vm/threadsuspend.cpp
@@ -5732,8 +5732,9 @@ BOOL CheckActivationSafePoint(SIZE_T ip)
Thread *pThread = GetThreadNULLOk();
// The criteria for safe activation is to be running managed code.
- // Also we are not interested in handling interruption if we are already in preemptive mode.
- BOOL isActivationSafePoint = pThread != NULL &&
+ // Also we are not interested in handling interruption if we are already in preemptive mode nor if we are single stepping
+ BOOL isActivationSafePoint = pThread != NULL &&
+ (pThread->m_StateNC & Thread::TSNC_DebuggerIsStepping) == 0 &&
pThread->PreemptiveGCDisabled() &&
ExecutionManager::IsManagedCode(ip);
@@ -5918,7 +5919,12 @@ bool Thread::InjectActivation(ActivationReason reason)
{
return true;
}
-
+ // Avoid APC calls when the thread is in single step state to avoid any
+ // wrong resume because it's running a native code.
+ if ((m_StateNC & Thread::TSNC_DebuggerIsStepping) != 0)
+ {
+ return false;
+ }
#ifdef FEATURE_SPECIAL_USER_MODE_APC
_ASSERTE(UseSpecialUserModeApc());
diff --git a/src/coreclr/vm/util.cpp b/src/coreclr/vm/util.cpp
index c279c50bf2b981..331a430436e25b 100644
--- a/src/coreclr/vm/util.cpp
+++ b/src/coreclr/vm/util.cpp
@@ -1889,62 +1889,6 @@ int __cdecl stricmpUTF8(const char* szStr1, const char* szStr2)
}
#ifndef DACCESS_COMPILE
-//
-//
-// COMCharacter and Helper functions
-//
-//
-
-#ifndef TARGET_UNIX
-/*============================GetCharacterInfoHelper============================
-**Determines character type info (digit, whitespace, etc) for the given char.
-**Args: c is the character on which to operate.
-** CharInfoType is one of CT_CTYPE1, CT_CTYPE2, CT_CTYPE3 and specifies the type
-** of information being requested.
-**Returns: The bitmask returned by GetStringTypeEx. The caller needs to know
-** how to interpret this.
-**Exceptions: ArgumentException if GetStringTypeEx fails.
-==============================================================================*/
-INT32 GetCharacterInfoHelper(WCHAR c, INT32 CharInfoType)
-{
- WRAPPER_NO_CONTRACT;
-
- unsigned short result=0;
- if (!GetStringTypeEx(LOCALE_USER_DEFAULT, CharInfoType, &(c), 1, &result)) {
- _ASSERTE(!"This should not happen, verify the arguments passed to GetStringTypeEx()");
- }
- return(INT32)result;
-}
-#endif // !TARGET_UNIX
-
-/*==============================nativeIsWhiteSpace==============================
-**The locally available version of IsWhiteSpace. Designed to be called by other
-**native methods. The work is mostly done by GetCharacterInfoHelper
-**Args: c -- the character to check.
-**Returns: true if c is whitespace, false otherwise.
-**Exceptions: Only those thrown by GetCharacterInfoHelper.
-==============================================================================*/
-BOOL COMCharacter::nativeIsWhiteSpace(WCHAR c)
-{
- WRAPPER_NO_CONTRACT;
-
-#ifndef TARGET_UNIX
- if (c <= (WCHAR) 0x7F) // common case
- {
- BOOL result = (c == ' ') || (c == '\r') || (c == '\n') || (c == '\t') || (c == '\f') || (c == (WCHAR) 0x0B);
-
- ASSERT(result == ((GetCharacterInfoHelper(c, CT_CTYPE1) & C1_SPACE)!=0));
-
- return result;
- }
-
- // GetCharacterInfoHelper costs around 160 instructions
- return((GetCharacterInfoHelper(c, CT_CTYPE1) & C1_SPACE)!=0);
-#else // !TARGET_UNIX
- return iswspace(c);
-#endif // !TARGET_UNIX
-}
-
BOOL RuntimeFileNotFound(HRESULT hr)
{
LIMITED_METHOD_CONTRACT;
diff --git a/src/coreclr/vm/util.hpp b/src/coreclr/vm/util.hpp
index a025e86e0768b0..e50c42153b4139 100644
--- a/src/coreclr/vm/util.hpp
+++ b/src/coreclr/vm/util.hpp
@@ -18,13 +18,6 @@
#include "posterror.h"
#include
-// Hot cache lines need to be aligned to cache line size to improve performance
-#if defined(TARGET_ARM64)
-#define MAX_CACHE_LINE_SIZE 128
-#else
-#define MAX_CACHE_LINE_SIZE 64
-#endif
-
#ifndef DACCESS_COMPILE
#if defined(TARGET_WINDOWS) && defined(TARGET_ARM64)
// Flag to check if atomics feature is available on
@@ -800,17 +793,6 @@ BOOL DbgIsExecutable(LPVOID lpMem, SIZE_T length);
int GetRandomInt(int maxVal);
-//
-//
-// COMCHARACTER
-//
-//
-class COMCharacter {
-public:
- //These are here for support from native code. They are never called from our managed classes.
- static BOOL nativeIsWhiteSpace(WCHAR c);
-};
-
// ======================================================================================
// Simple, reusable 100ns timer for normalizing ticks. For use in Q/FCalls to avoid discrepency with
// tick frequency between native and managed.
diff --git a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props
index 0c00174fe0d063..3a884bd23a05aa 100644
--- a/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props
+++ b/src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props
@@ -150,29 +150,18 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/libraries/Common/tests/StreamConformanceTests/System/IO/StreamConformanceTests.cs b/src/libraries/Common/tests/StreamConformanceTests/System/IO/StreamConformanceTests.cs
index 61fb0f51936e27..e9ff147bbe5f03 100644
--- a/src/libraries/Common/tests/StreamConformanceTests/System/IO/StreamConformanceTests.cs
+++ b/src/libraries/Common/tests/StreamConformanceTests/System/IO/StreamConformanceTests.cs
@@ -1915,7 +1915,7 @@ public virtual async Task ReadWrite_MessagesSmallerThanReadBuffer_Success(ReadWr
}
Assert.Equal(writerBytes.Length, n);
- AssertExtensions.SequenceEqual(writerBytes, readerBytes.AsSpan(0, writerBytes.Length));
+ AssertExtensions.SequenceEqual(writerBytes.AsSpan(), readerBytes.AsSpan(0, writerBytes.Length));
await writes;
}
@@ -3069,7 +3069,7 @@ public virtual async Task ZeroByteRead_PerformsZeroByteReadOnUnderlyingStreamWhe
if (FlushGuaranteesAllDataWritten)
{
- AssertExtensions.SequenceEqual(data, buffer.AsSpan(0, bytesRead));
+ AssertExtensions.SequenceEqual(data.AsSpan(), buffer.AsSpan(0, bytesRead));
}
}
}
diff --git a/src/libraries/Common/tests/System/Reflection/InvokeInterpretedTests.cs b/src/libraries/Common/tests/System/Reflection/InvokeInterpretedTests.cs
index 6370e83d41c8f6..03a876131f4787 100644
--- a/src/libraries/Common/tests/System/Reflection/InvokeInterpretedTests.cs
+++ b/src/libraries/Common/tests/System/Reflection/InvokeInterpretedTests.cs
@@ -16,7 +16,6 @@ public static void VerifyInvokeIsUsingInterpreter_Method()
Exception exInner = ex.InnerException;
Assert.Contains("Here", exInner.ToString());
- Assert.Contains("InterpretedInvoke_Method", exInner.ToString());
Assert.DoesNotContain("InvokeStub_TestClassThatThrows", exInner.ToString());
}
@@ -29,7 +28,6 @@ public static void VerifyInvokeIsUsingInterpreter_Constructor()
Exception exInner = ex.InnerException;
Assert.Contains("Here", exInner.ToString());
- Assert.Contains("InterpretedInvoke_Constructor", exInner.ToString());
Assert.DoesNotContain("InvokeStub_TestClassThatThrows", exInner.ToString());
}
diff --git a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs
index 23d63a5ab0e70e..a37457fda62a54 100644
--- a/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs
+++ b/src/libraries/Common/tests/TestUtilities/System/PlatformDetection.cs
@@ -389,9 +389,7 @@ public static string GetDistroVersionString()
public static bool IsInvariantGlobalization => m_isInvariant.Value;
public static bool IsHybridGlobalization => m_isHybrid.Value;
- public static bool IsHybridGlobalizationOnBrowser => m_isHybrid.Value && IsBrowser;
public static bool IsHybridGlobalizationOnApplePlatform => m_isHybrid.Value && (IsMacCatalyst || IsiOS || IstvOS);
- public static bool IsNotHybridGlobalizationOnBrowser => !IsHybridGlobalizationOnBrowser;
public static bool IsNotInvariantGlobalization => !IsInvariantGlobalization;
public static bool IsNotHybridGlobalization => !IsHybridGlobalization;
public static bool IsNotHybridGlobalizationOnApplePlatform => !IsHybridGlobalizationOnApplePlatform;
@@ -401,8 +399,6 @@ public static string GetDistroVersionString()
// HG on apple platforms implies ICU
public static bool IsIcuGlobalization => !IsInvariantGlobalization && (IsHybridGlobalizationOnApplePlatform || ICUVersion > new Version(0, 0, 0, 0));
-
- public static bool IsIcuGlobalizationAndNotHybridOnBrowser => IsIcuGlobalization && IsNotHybridGlobalizationOnBrowser;
public static bool IsNlsGlobalization => IsNotInvariantGlobalization && !IsIcuGlobalization && !IsHybridGlobalization;
public static bool IsSubstAvailable
diff --git a/src/libraries/Common/tests/Tests/System/StringTests.cs b/src/libraries/Common/tests/Tests/System/StringTests.cs
index 0d904ecb7ef774..caa4383c3ce001 100644
--- a/src/libraries/Common/tests/Tests/System/StringTests.cs
+++ b/src/libraries/Common/tests/Tests/System/StringTests.cs
@@ -1034,7 +1034,7 @@ public static void CompareToNoMatch_StringComparison()
var secondSpan = new ReadOnlySpan(second);
Assert.True(0 > firstSpan.CompareTo(secondSpan, StringComparison.Ordinal));
- // On Apple platforms, string comparison is handled by native Apple functions, which apply normalization techniques
+ // On Apple platforms, string comparison is handled by native Apple functions, which apply normalization techniques
// like `precomposedStringWithCanonicalMapping`. This can lead to differences in behavior compared to other platforms.
if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
@@ -1315,7 +1315,7 @@ public static void ContainsNoMatch_StringComparison()
Assert.False(firstSpan.Contains(secondSpan, StringComparison.OrdinalIgnoreCase));
- // On Apple platforms, string comparison is handled by native Apple functions, which apply normalization techniques
+ // On Apple platforms, string comparison is handled by native Apple functions, which apply normalization techniques
// like `precomposedStringWithCanonicalMapping`. This can lead to differences in behavior compared to other platforms.
if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
@@ -3227,8 +3227,7 @@ which ignore the contraction collation weights (defined as 'tertiary' rules)
Assert.Equal(PlatformDetection.IsNlsGlobalization ? 0 : -1, source.IndexOf(target));
Assert.Equal(PlatformDetection.IsNlsGlobalization ? 0 : -1, source.IndexOf(target, StringComparison.CurrentCulture));
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser)
- Assert.Equal(0, source.IndexOf(target, StringComparison.CurrentCultureIgnoreCase));
+ Assert.Equal(0, source.IndexOf(target, StringComparison.CurrentCultureIgnoreCase));
Assert.Equal(-1, source.IndexOf(target, StringComparison.Ordinal));
Assert.Equal(-1, source.IndexOf(target, StringComparison.OrdinalIgnoreCase));
@@ -3236,8 +3235,7 @@ which ignore the contraction collation weights (defined as 'tertiary' rules)
Assert.Equal(PlatformDetection.IsNlsGlobalization ? 0 : -1, span.IndexOf(target.AsSpan(), StringComparison.CurrentCulture));
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser)
- Assert.Equal(0, span.IndexOf(target.AsSpan(), StringComparison.CurrentCultureIgnoreCase));
+ Assert.Equal(0, span.IndexOf(target.AsSpan(), StringComparison.CurrentCultureIgnoreCase));
Assert.Equal(-1, span.IndexOf(target.AsSpan(), StringComparison.Ordinal));
Assert.Equal(-1, span.IndexOf(target.AsSpan(), StringComparison.OrdinalIgnoreCase));
}
@@ -5425,7 +5423,6 @@ private static IEnumerable ToLower_Culture_TestData()
[ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95338", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnApplePlatform))]
- [ActiveIssue("https://github.com/dotnet/runtime/issues/95503", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
public static void Test_ToLower_Culture()
{
foreach (object[] testdata in ToLower_Culture_TestData())
@@ -5943,7 +5940,6 @@ public static IEnumerable ToUpper_Culture_TestData()
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95338", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnApplePlatform))]
[MemberData(nameof(ToUpper_Culture_TestData))]
- [ActiveIssue("https://github.com/dotnet/runtime/issues/95503", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
public static void Test_ToUpper_Culture(string actual, string expected, CultureInfo culture)
{
Assert.Equal(expected, actual.ToUpper(culture));
diff --git a/src/libraries/Microsoft.VisualBasic.Core/tests/LateBindingTests.cs b/src/libraries/Microsoft.VisualBasic.Core/tests/LateBindingTests.cs
index a95f101731dfc0..a04e4b0b29333e 100644
--- a/src/libraries/Microsoft.VisualBasic.Core/tests/LateBindingTests.cs
+++ b/src/libraries/Microsoft.VisualBasic.Core/tests/LateBindingTests.cs
@@ -9,7 +9,7 @@ namespace Microsoft.VisualBasic.CompilerServices.Tests
{
public class LateBindingTests
{
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[MemberData(nameof(LateCall_TestData))]
public void LateCall(object obj, Type objType, string name, object[] args, string[] paramNames, bool[] copyBack, Func getResult, object expected)
{
@@ -17,14 +17,14 @@ public void LateCall(object obj, Type objType, string name, object[] args, strin
Assert.Equal(expected, getResult(obj));
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[MemberData(nameof(LateGet_TestData))]
public void LateGet(object obj, Type objType, string name, object[] args, string[] paramNames, bool[] copyBack, object expected)
{
Assert.Equal(expected, LateBinding.LateGet(obj, objType, name, args, paramNames, copyBack));
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[MemberData(nameof(LateSet_TestData))]
public void LateSet(object obj, Type objType, string name, object[] args, string[] paramNames, Func getResult, object expected)
{
@@ -74,14 +74,14 @@ public void LateIndexSet(object obj, object[] args, string[] paramNames, Func(() => LateBinding.LateIndexSet(obj, args, paramNames));
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[MemberData(nameof(LateIndexSetComplex_TestData))]
public void LateIndexSetComplex(object obj, object[] args, string[] paramNames, bool missing, bool valueType)
{
diff --git a/src/libraries/Microsoft.VisualBasic.Core/tests/LikeOperatorTests.cs b/src/libraries/Microsoft.VisualBasic.Core/tests/LikeOperatorTests.cs
index 892fbc5c31b5e1..1452be5b7fb333 100644
--- a/src/libraries/Microsoft.VisualBasic.Core/tests/LikeOperatorTests.cs
+++ b/src/libraries/Microsoft.VisualBasic.Core/tests/LikeOperatorTests.cs
@@ -9,7 +9,7 @@ namespace Microsoft.VisualBasic.CompilerServices.Tests
{
public class LikeOperatorTests
{
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[MemberData(nameof(LikeObject_TestData))]
[MemberData(nameof(LikeString_TestData))]
public void LikeObject(object source, object pattern, object expectedBinaryCompare, object expectedTextCompare)
@@ -18,7 +18,7 @@ public void LikeObject(object source, object pattern, object expectedBinaryCompa
Assert.Equal(expectedTextCompare, LikeOperator.LikeObject(source, pattern, CompareMethod.Text));
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[MemberData(nameof(LikeString_TestData))]
public void LikeString(string source, string pattern, bool expectedBinaryCompare, bool expectedTextCompare)
{
diff --git a/src/libraries/Microsoft.VisualBasic.Core/tests/ObjectTypeTests.cs b/src/libraries/Microsoft.VisualBasic.Core/tests/ObjectTypeTests.cs
index d520d69d6cb6f6..f1e4b8ac6935f1 100644
--- a/src/libraries/Microsoft.VisualBasic.Core/tests/ObjectTypeTests.cs
+++ b/src/libraries/Microsoft.VisualBasic.Core/tests/ObjectTypeTests.cs
@@ -287,7 +287,7 @@ public static IEnumerable GetObjectValuePrimitive_TestData()
// Add more...
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[MemberData(nameof(LikeObj_TestData))]
public void LikeObj(object left, object right, object expectedBinaryCompare, object expectedTextCompare)
{
@@ -323,7 +323,7 @@ public static IEnumerable LikeObj_NullReference_TestData()
yield return new object[] { null, "*" };
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[MemberData(nameof(ObjTst_TestData))]
public void ObjTst(object x, object y, bool textCompare, object expected)
{
diff --git a/src/libraries/Microsoft.VisualBasic.Core/tests/OperatorsTests.Comparison.cs b/src/libraries/Microsoft.VisualBasic.Core/tests/OperatorsTests.Comparison.cs
index 9e300ec063a232..f90fd7d819824c 100644
--- a/src/libraries/Microsoft.VisualBasic.Core/tests/OperatorsTests.Comparison.cs
+++ b/src/libraries/Microsoft.VisualBasic.Core/tests/OperatorsTests.Comparison.cs
@@ -1107,7 +1107,7 @@ public static IEnumerable Compare_InvalidObjects_TestData()
yield return new object[] { new object(), new char[] { '8' } };
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[MemberData(nameof(Compare_Primitives_TestData))]
public void CompareObjectEqual_Invoke_ReturnsExpected(object left, object right, bool greater, bool equal, bool less)
{
@@ -1171,7 +1171,7 @@ public class CompareObjectEqual
public static string op_Equality(OperatorsTests left, CompareObjectEqual right) => "tcejbomotsuc";
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[MemberData(nameof(Compare_Primitives_TestData))]
public void CompareObjectGreater_Invoke_ReturnsExpected(object left, object right, bool greater, bool equal, bool less)
{
@@ -1235,7 +1235,7 @@ public class CompareObjectGreater
public static string op_GreaterThan(OperatorsTests left, CompareObjectGreater right) => "tcejbomotsuc";
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[MemberData(nameof(Compare_Primitives_TestData))]
public void CompareObjectGreaterEqual_Invoke_ReturnsExpected(object left, object right, bool greater, bool equal, bool less)
{
@@ -1298,7 +1298,7 @@ public class CompareObjectGreaterEqual
public static string op_GreaterThanOrEqual(OperatorsTests left, CompareObjectGreaterEqual right) => "tcejbomotsuc";
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[MemberData(nameof(Compare_Primitives_TestData))]
public void CompareObjectLess_Invoke_ReturnsExpected(object left, object right, bool greater, bool equal, bool less)
{
@@ -1362,7 +1362,7 @@ public class CompareObjectLess
public static string op_LessThan(OperatorsTests left, CompareObjectLess right) => "tcejbomotsuc";
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[MemberData(nameof(Compare_Primitives_TestData))]
public void CompareObjectLessEqual_Invoke_ReturnsExpected(object left, object right, bool greater, bool equal, bool less)
{
@@ -1425,7 +1425,7 @@ public class CompareObjectLessEqual
public static string op_LessThanOrEqual(OperatorsTests left, CompareObjectLessEqual right) => "tcejbomotsuc";
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[MemberData(nameof(Compare_Primitives_TestData))]
public void CompareObjectNotEqual_Invoke_ReturnsExpected(object left, object right, bool greater, bool equal, bool less)
{
@@ -1490,7 +1490,7 @@ public class CompareObjectNotEqual
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[MemberData(nameof(Compare_Primitives_TestData))]
public void ConditionalCompareObjectEqual_Invoke_ReturnsExpected(object left, object right, bool greater, bool equal, bool less)
{
@@ -1554,7 +1554,7 @@ public class ConditionalCompareObjectEqual
public static bool op_Equality(OperatorsTests left, ConditionalCompareObjectEqual right) => true;
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[MemberData(nameof(Compare_Primitives_TestData))]
public void ConditionalCompareObjectGreater_Invoke_ReturnsExpected(object left, object right, bool greater, bool equal, bool less)
{
@@ -1618,7 +1618,7 @@ public class ConditionalCompareObjectGreater
public static bool op_GreaterThan(OperatorsTests left, ConditionalCompareObjectGreater right) => true;
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[MemberData(nameof(Compare_Primitives_TestData))]
public void ConditionalCompareObjectGreaterEqual_Invoke_ReturnsExpected(object left, object right, bool greater, bool equal, bool less)
{
@@ -1681,7 +1681,7 @@ public class ConditionalCompareObjectGreaterEqual
public static bool op_GreaterThanOrEqual(OperatorsTests left, ConditionalCompareObjectGreaterEqual right) => true;
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[MemberData(nameof(Compare_Primitives_TestData))]
public void ConditionalCompareObjectLess_Invoke_ReturnsExpected(object left, object right, bool greater, bool equal, bool less)
{
@@ -1745,7 +1745,7 @@ public class ConditionalCompareObjectLess
public static bool op_LessThan(OperatorsTests left, ConditionalCompareObjectLess right) => true;
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[MemberData(nameof(Compare_Primitives_TestData))]
public void ConditionalCompareObjectLessEqual_Invoke_ReturnsExpected(object left, object right, bool greater, bool equal, bool less)
{
@@ -1808,7 +1808,7 @@ public class ConditionalCompareObjectLessEqual
public static bool op_LessThanOrEqual(OperatorsTests left, ConditionalCompareObjectLessEqual right) => true;
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[MemberData(nameof(Compare_Primitives_TestData))]
public void ConditionalCompareObjectNotEqual_Invoke_ReturnsExpected(object left, object right, bool greater, bool equal, bool less)
{
diff --git a/src/libraries/Microsoft.VisualBasic.Core/tests/StringTypeTests.cs b/src/libraries/Microsoft.VisualBasic.Core/tests/StringTypeTests.cs
index 76d390ea840e61..8d4d2842766d7f 100644
--- a/src/libraries/Microsoft.VisualBasic.Core/tests/StringTypeTests.cs
+++ b/src/libraries/Microsoft.VisualBasic.Core/tests/StringTypeTests.cs
@@ -363,7 +363,7 @@ public void MidStmtStr_ArgumentException(string str, int start, int length, stri
Assert.Throws(() => StringType.MidStmtStr(ref str, start, length, insert));
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[MemberData(nameof(StrCmp_TestData))]
public void StrCmp(string left, string right, int expectedBinaryCompare, int expectedTextCompare)
{
@@ -388,7 +388,7 @@ public static IEnumerable StrCmp_TestData()
yield return new object[] { "abc", "ABC", 32, 0 };
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[InlineData(null, null, true, true)]
[InlineData("", null, true, true)]
[InlineData("", "*", true, true)]
diff --git a/src/libraries/Microsoft.VisualBasic.Core/tests/StringsTests.cs b/src/libraries/Microsoft.VisualBasic.Core/tests/StringsTests.cs
index 037412ed582757..27967fa777fe10 100644
--- a/src/libraries/Microsoft.VisualBasic.Core/tests/StringsTests.cs
+++ b/src/libraries/Microsoft.VisualBasic.Core/tests/StringsTests.cs
@@ -431,7 +431,7 @@ public void InStr_BinaryCompare(string string1, string string2, int expected)
Assert.Equal(expected, Strings.InStr(1, string1, string2, CompareMethod.Binary));
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[InlineData("A", "a", 1)]
[InlineData("Aa", "a", 1)]
public void InStr_TextCompare(string string1, string string2, int expected)
@@ -479,7 +479,7 @@ public void InStrRev_BinaryCompare(string stringCheck, string stringMatch, int s
Assert.Equal(expected, Strings.InStrRev(stringCheck, stringMatch, start, CompareMethod.Binary));
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[InlineData("A", "a", 1, 1)]
[InlineData("aA", "a", 2, 2)]
public void InStrRev_TextCompare(string stringCheck, string stringMatch, int start, int expected)
@@ -779,7 +779,7 @@ public void Trim_Valid(string str, string expected)
Assert.Equal(expected, Strings.Trim(str));
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[InlineData("", "", null, 1, -1, CompareMethod.Text, null)]
[InlineData("", null, "", 1, -1, CompareMethod.Text, null)]
[InlineData("", "", "", 1, -1, CompareMethod.Text, null)]
@@ -815,7 +815,7 @@ public void Space(int number, string expected)
Assert.Equal(expected, Strings.Space(number));
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[InlineData(null, null, -1, CompareMethod.Text, new string[] { "" })]
[InlineData(null, "", -1, CompareMethod.Text, new string[] { "" })]
[InlineData("", null, -1, CompareMethod.Text, new string[] { "" })]
@@ -833,14 +833,14 @@ public void Split(string expression, string delimiter, int limit, CompareMethod
Assert.Equal(expected, Strings.Split(expression, delimiter, limit, compare));
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[InlineData("A, B, C", ", ", 0, CompareMethod.Text)]
public void Split_IndexOutOfRangeException(string expression, string delimiter, int limit, CompareMethod compare)
{
Assert.Throws< IndexOutOfRangeException>(() => Strings.Split(expression, delimiter, limit, compare));
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[InlineData("a", "a", 0, 0)]
[InlineData("a", "b", -1, -1)]
[InlineData("b", "a", 1, 1)]
diff --git a/src/libraries/System.Collections.NonGeneric/tests/CaseInsensitiveHashCodeProviderTests.cs b/src/libraries/System.Collections.NonGeneric/tests/CaseInsensitiveHashCodeProviderTests.cs
index b0f4cc6c9ee3b9..ee5087139eb0eb 100644
--- a/src/libraries/System.Collections.NonGeneric/tests/CaseInsensitiveHashCodeProviderTests.cs
+++ b/src/libraries/System.Collections.NonGeneric/tests/CaseInsensitiveHashCodeProviderTests.cs
@@ -97,7 +97,6 @@ public void Ctor_CultureInfo_ChangeCurrentCulture_GetHashCodeCompare(object a, o
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/37069", TestPlatforms.Android | TestPlatforms.LinuxBionic)]
[ActiveIssue("https://github.com/dotnet/runtime/issues/95338", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnApplePlatform))]
- [ActiveIssue("https://github.com/dotnet/runtime/issues/95503", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
public void Ctor_CultureInfo_GetHashCodeCompare_TurkishI()
{
var cultureNames = Helpers.TestCultureNames;
diff --git a/src/libraries/System.Data.Common/tests/System.Data.DataSetExtensions.Tests/Mono/DataRowComparerTest.cs b/src/libraries/System.Data.Common/tests/System.Data.DataSetExtensions.Tests/Mono/DataRowComparerTest.cs
index 0e8fb95a74e6df..6d4ddbe9b3f58d 100644
--- a/src/libraries/System.Data.Common/tests/System.Data.DataSetExtensions.Tests/Mono/DataRowComparerTest.cs
+++ b/src/libraries/System.Data.Common/tests/System.Data.DataSetExtensions.Tests/Mono/DataRowComparerTest.cs
@@ -216,7 +216,7 @@ public void Equals_Rows_Deleted()
}
}
- [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Fact]
public void GetHashCodeWithVersions()
{
DataSet ds = new DataSet();
diff --git a/src/libraries/System.Data.Common/tests/System.Data.DataSetExtensions.Tests/Mono/DataTableExtensionsTest.cs b/src/libraries/System.Data.Common/tests/System.Data.DataSetExtensions.Tests/Mono/DataTableExtensionsTest.cs
index 7f6d7bb12c0f29..479807057113e7 100644
--- a/src/libraries/System.Data.Common/tests/System.Data.DataSetExtensions.Tests/Mono/DataTableExtensionsTest.cs
+++ b/src/libraries/System.Data.Common/tests/System.Data.DataSetExtensions.Tests/Mono/DataTableExtensionsTest.cs
@@ -75,7 +75,7 @@ public void CopyToDataTableTableArgNoRows()
dt.AsEnumerable().CopyToDataTable(dst, LoadOption.PreserveChanges);
}
- [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Fact]
public void AsEnumerable()
{
DataSet ds = new DataSet();
diff --git a/src/libraries/System.Data.Common/tests/System.Data.DataSetExtensions.Tests/Mono/EnumerableRowCollectionTest.cs b/src/libraries/System.Data.Common/tests/System.Data.DataSetExtensions.Tests/Mono/EnumerableRowCollectionTest.cs
index ba292235291e37..a1f0dd6ec13ff8 100644
--- a/src/libraries/System.Data.Common/tests/System.Data.DataSetExtensions.Tests/Mono/EnumerableRowCollectionTest.cs
+++ b/src/libraries/System.Data.Common/tests/System.Data.DataSetExtensions.Tests/Mono/EnumerableRowCollectionTest.cs
@@ -41,7 +41,7 @@ public class EnumerableRowCollectionTest
{
private string _testDataSet = "Mono/testdataset1.xml";
- [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Fact]
public void QueryWhere()
{
var ds = new DataSet();
@@ -68,7 +68,7 @@ where line.Field("Score") > 80
}
}
- [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Fact]
public void QueryWhereSelect ()
{
var ds = new DataSet ();
@@ -89,7 +89,7 @@ where line.Field ("Score") > 80
}
}
- [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Fact]
public void QueryWhereSelectOrderBy ()
{
var ds = new DataSet ();
@@ -119,7 +119,7 @@ orderby line.Field ("ID")
}
}
- [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Fact]
public void QueryWhereSelectOrderByDescending ()
{
var ds = new DataSet ();
@@ -149,7 +149,7 @@ orderby line.Field ("ID") descending
}
}
- [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Fact]
public void ThenBy ()
{
var ds = new DataSet ();
@@ -179,7 +179,7 @@ orderby line.Field ("Gender"), line.Field ("ID")
}
}
- [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Fact]
public void ThenByDescending ()
{
var ds = new DataSet ();
diff --git a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArraySinglePrimitiveRecord.cs b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArraySinglePrimitiveRecord.cs
index a28359d9bb13dc..ef2195a342a04d 100644
--- a/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArraySinglePrimitiveRecord.cs
+++ b/src/libraries/System.Formats.Nrbf/src/System/Formats/Nrbf/ArraySinglePrimitiveRecord.cs
@@ -161,7 +161,7 @@ internal static IReadOnlyList DecodePrimitiveTypes(BinaryReader reader, int c
{
if (typeof(T) == typeof(short) || typeof(T) == typeof(ushort))
{
- Span span = MemoryMarshal.Cast(result);
+ Span span = MemoryMarshal.Cast(result.AsSpan());
#if NET
BinaryPrimitives.ReverseEndianness(span, span);
#else
@@ -173,7 +173,7 @@ internal static IReadOnlyList DecodePrimitiveTypes(BinaryReader reader, int c
}
else if (typeof(T) == typeof(int) || typeof(T) == typeof(uint) || typeof(T) == typeof(float))
{
- Span span = MemoryMarshal.Cast(result);
+ Span span = MemoryMarshal.Cast(result.AsSpan());
#if NET
BinaryPrimitives.ReverseEndianness(span, span);
#else
@@ -185,7 +185,7 @@ internal static IReadOnlyList DecodePrimitiveTypes(BinaryReader reader, int c
}
else if (typeof(T) == typeof(long) || typeof(T) == typeof(ulong) || typeof(T) == typeof(double))
{
- Span span = MemoryMarshal.Cast(result);
+ Span span = MemoryMarshal.Cast(result.AsSpan());
#if NET
BinaryPrimitives.ReverseEndianness(span, span);
#else
@@ -201,7 +201,7 @@ internal static IReadOnlyList DecodePrimitiveTypes(BinaryReader reader, int c
{
// See DontCastBytesToBooleans test to see what could go wrong.
bool[] booleans = (bool[])(object)result;
- Span resultAsBytes = MemoryMarshal.AsBytes(result);
+ Span resultAsBytes = MemoryMarshal.AsBytes(result.AsSpan());
for (int i = 0; i < booleans.Length; i++)
{
// We don't use the bool array to get the value, as an optimizing compiler or JIT could elide this.
diff --git a/src/libraries/System.Formats.Nrbf/tests/ArraySinglePrimitiveRecordTests.cs b/src/libraries/System.Formats.Nrbf/tests/ArraySinglePrimitiveRecordTests.cs
index 7ef801808e4e95..9f714c9dddac15 100644
--- a/src/libraries/System.Formats.Nrbf/tests/ArraySinglePrimitiveRecordTests.cs
+++ b/src/libraries/System.Formats.Nrbf/tests/ArraySinglePrimitiveRecordTests.cs
@@ -20,7 +20,7 @@ public NonSeekableStream(byte[] buffer) : base(buffer) { }
public static IEnumerable GetCanReadArrayOfAnySizeArgs()
{
- foreach (int size in new[] { 1, 127, 128, 512_001, 512_001 })
+ foreach (int size in new[] { 1, 127, 128, 20_001 })
{
yield return new object[] { size, true };
yield return new object[] { size, false };
diff --git a/src/libraries/System.Linq/tests/RangeTests.cs b/src/libraries/System.Linq/tests/RangeTests.cs
index 2e331cfee7ecd7..26ec544f327af7 100644
--- a/src/libraries/System.Linq/tests/RangeTests.cs
+++ b/src/libraries/System.Linq/tests/RangeTests.cs
@@ -270,7 +270,7 @@ static void Validate(IEnumerable e, int[] expected)
list.CopyTo(actual, 1);
Assert.Equal(0, actual[0]);
Assert.Equal(0, actual[^1]);
- AssertExtensions.SequenceEqual(expected, actual.AsSpan(1, expected.Length));
+ AssertExtensions.SequenceEqual(expected.AsSpan(), actual.AsSpan(1, expected.Length));
}
}
}
diff --git a/src/libraries/System.Linq/tests/RepeatTests.cs b/src/libraries/System.Linq/tests/RepeatTests.cs
index df8eebda35691e..9ee0d7f68fb146 100644
--- a/src/libraries/System.Linq/tests/RepeatTests.cs
+++ b/src/libraries/System.Linq/tests/RepeatTests.cs
@@ -282,7 +282,7 @@ static void Validate(IEnumerable e, int[] expected)
list.CopyTo(actual, 1);
Assert.Equal(0, actual[0]);
Assert.Equal(0, actual[^1]);
- AssertExtensions.SequenceEqual(expected, actual.AsSpan(1, expected.Length));
+ AssertExtensions.SequenceEqual(expected.AsSpan(), actual.AsSpan(1, expected.Length));
}
}
}
diff --git a/src/libraries/System.Memory/tests/Base64Url/Base64UrlUnicodeAPIsUnitTests.cs b/src/libraries/System.Memory/tests/Base64Url/Base64UrlUnicodeAPIsUnitTests.cs
index 09326bef170ea8..a455075bb9c7ed 100644
--- a/src/libraries/System.Memory/tests/Base64Url/Base64UrlUnicodeAPIsUnitTests.cs
+++ b/src/libraries/System.Memory/tests/Base64Url/Base64UrlUnicodeAPIsUnitTests.cs
@@ -438,7 +438,7 @@ public static void Base64_AllMethodsRoundtripConsistently()
Span decodedBytes = new byte[original.Length];
int decoded = Base64Url.DecodeFromChars(encodedArray, decodedBytes);
Assert.Equal(original.Length, decoded);
- AssertExtensions.SequenceEqual(original, decodedBytes);
+ AssertExtensions.SequenceEqual(original.AsSpan(), decodedBytes);
byte[] actualBytes = new byte[original.Length];
Assert.True(Base64Url.TryDecodeFromChars(encodedSpan, actualBytes, out int bytesWritten));
diff --git a/src/libraries/System.Memory/tests/Span/SearchValues.cs b/src/libraries/System.Memory/tests/Span/SearchValues.cs
index 00e9c71e3dfb75..51c8688bfae2b9 100644
--- a/src/libraries/System.Memory/tests/Span/SearchValues.cs
+++ b/src/libraries/System.Memory/tests/Span/SearchValues.cs
@@ -465,7 +465,7 @@ static SearchValuesTestHelper()
s_randomLatin1Chars[i] = (char)rng.Next(0, 256);
}
- rng.NextBytes(MemoryMarshal.Cast(s_randomChars));
+ rng.NextBytes(MemoryMarshal.Cast(s_randomChars.AsSpan()));
s_randomAsciiBytes = Encoding.ASCII.GetBytes(s_randomAsciiChars);
diff --git a/src/libraries/System.Memory/tests/Span/StringSearchValues.cs b/src/libraries/System.Memory/tests/Span/StringSearchValues.cs
index c0b80b5ab06776..f702b0bdcad99d 100644
--- a/src/libraries/System.Memory/tests/Span/StringSearchValues.cs
+++ b/src/libraries/System.Memory/tests/Span/StringSearchValues.cs
@@ -620,7 +620,7 @@ public StringSearchValuesTestHelper(IndexOfAnySearchDelegate expected, SearchVal
}));
}
- rng.NextBytes(MemoryMarshal.Cast(_randomChars));
+ rng.NextBytes(MemoryMarshal.Cast(_randomChars.AsSpan()));
}
public void StressRandomInputs(TimeSpan duration)
diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Metrics/HttpMetricsEnrichmentContext.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Metrics/HttpMetricsEnrichmentContext.cs
index 89a5d1fd1bfacd..34f274d98aa73d 100644
--- a/src/libraries/System.Net.Http/src/System/Net/Http/Metrics/HttpMetricsEnrichmentContext.cs
+++ b/src/libraries/System.Net.Http/src/System/Net/Http/Metrics/HttpMetricsEnrichmentContext.cs
@@ -1,12 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Metrics;
-using System.Runtime.InteropServices;
-using System.Threading;
namespace System.Net.Http.Metrics
{
@@ -19,22 +16,18 @@ namespace System.Net.Http.Metrics
/// information exposed on the instance.
///
/// > [!IMPORTANT]
- /// > The intance must not be used from outside of the enrichment callbacks.
+ /// > The instance must not be used from outside of the enrichment callbacks.
///
public sealed class HttpMetricsEnrichmentContext
{
- private static readonly HttpRequestOptionsKey s_optionsKeyForContext = new(nameof(HttpMetricsEnrichmentContext));
- private static readonly ConcurrentQueue s_pool = new();
- private static int s_poolItemCount;
- private const int PoolCapacity = 1024;
+ private static readonly HttpRequestOptionsKey>> s_optionsKeyForCallbacks = new(nameof(HttpMetricsEnrichmentContext));
- private readonly List> _callbacks = new();
private HttpRequestMessage? _request;
private HttpResponseMessage? _response;
private Exception? _exception;
- private List> _tags = new(capacity: 16);
+ private TagList _tags;
- internal HttpMetricsEnrichmentContext() { } // Hide the default parameterless constructor.
+ private HttpMetricsEnrichmentContext() { } // Hide the default parameterless constructor.
///
/// Gets the that has been sent.
@@ -68,7 +61,7 @@ public sealed class HttpMetricsEnrichmentContext
///
/// This method must not be used from outside of the enrichment callbacks.
///
- public void AddCustomTag(string name, object? value) => _tags.Add(new KeyValuePair(name, value));
+ public void AddCustomTag(string name, object? value) => _tags.Add(name, value);
///
/// Adds a callback to register custom tags for request metrics `http-client-request-duration` and `http-client-failed-requests`.
@@ -77,85 +70,55 @@ public sealed class HttpMetricsEnrichmentContext
/// The callback responsible to add custom tags via .
public static void AddCallback(HttpRequestMessage request, Action callback)
{
+ ArgumentNullException.ThrowIfNull(request);
+ ArgumentNullException.ThrowIfNull(callback);
+
HttpRequestOptions options = request.Options;
- // We associate an HttpMetricsEnrichmentContext with the request on the first call to AddCallback(),
- // and store the callbacks in the context. This allows us to cache all the enrichment objects together.
- if (!options.TryGetValue(s_optionsKeyForContext, out HttpMetricsEnrichmentContext? context))
+ if (options.TryGetValue(s_optionsKeyForCallbacks, out List>? callbacks))
+ {
+ callbacks.Add(callback);
+ }
+ else
{
- if (s_pool.TryDequeue(out context))
- {
- Debug.Assert(context._callbacks.Count == 0);
- Interlocked.Decrement(ref s_poolItemCount);
- }
- else
- {
- context = new HttpMetricsEnrichmentContext();
- }
-
- options.Set(s_optionsKeyForContext, context);
+ options.Set(s_optionsKeyForCallbacks, [callback]);
}
- context._callbacks.Add(callback);
}
- internal static HttpMetricsEnrichmentContext? GetEnrichmentContextForRequest(HttpRequestMessage request)
+ internal static List>? GetEnrichmentCallbacksForRequest(HttpRequestMessage request)
{
- if (request._options is null)
+ if (request._options is HttpRequestOptions options &&
+ options.Remove(s_optionsKeyForCallbacks.Key, out object? callbacks))
{
- return null;
+ return (List>)callbacks!;
}
- request._options.TryGetValue(s_optionsKeyForContext, out HttpMetricsEnrichmentContext? context);
- return context;
+
+ return null;
}
- internal void RecordDurationWithEnrichment(HttpRequestMessage request,
+ internal static void RecordDurationWithEnrichment(
+ List> callbacks,
+ HttpRequestMessage request,
HttpResponseMessage? response,
Exception? exception,
TimeSpan durationTime,
in TagList commonTags,
Histogram requestDuration)
{
- _request = request;
- _response = response;
- _exception = exception;
-
- Debug.Assert(_tags.Count == 0);
-
- // Adding the enrichment tags to the TagList would likely exceed its' on-stack capacity, leading to an allocation.
- // To avoid this, we add all the tags to a List which is cached together with HttpMetricsEnrichmentContext.
- // Use a for loop to iterate over the TagList, since TagList.GetEnumerator() allocates, see
- // https://github.com/dotnet/runtime/issues/87022.
- for (int i = 0; i < commonTags.Count; i++)
+ var context = new HttpMetricsEnrichmentContext
{
- _tags.Add(commonTags[i]);
- }
+ _request = request,
+ _response = response,
+ _exception = exception,
+ _tags = commonTags,
+ };
- try
+ foreach (Action callback in callbacks)
{
- foreach (Action callback in _callbacks)
- {
- callback(this);
- }
-
- requestDuration.Record(durationTime.TotalSeconds, CollectionsMarshal.AsSpan(_tags));
- }
- finally
- {
- _request = null;
- _response = null;
- _exception = null;
- _callbacks.Clear();
- _tags.Clear();
-
- if (Interlocked.Increment(ref s_poolItemCount) <= PoolCapacity)
- {
- s_pool.Enqueue(this);
- }
- else
- {
- Interlocked.Decrement(ref s_poolItemCount);
- }
+ callback(context);
}
+
+ requestDuration.Record(durationTime.TotalSeconds, context._tags);
}
}
}
diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/Metrics/MetricsHandler.cs b/src/libraries/System.Net.Http/src/System/Net/Http/Metrics/MetricsHandler.cs
index 7a381483099d4d..79a544816ccb09 100644
--- a/src/libraries/System.Net.Http/src/System/Net/Http/Metrics/MetricsHandler.cs
+++ b/src/libraries/System.Net.Http/src/System/Net/Http/Metrics/MetricsHandler.cs
@@ -121,14 +121,14 @@ private void RequestStop(HttpRequestMessage request, HttpResponseMessage? respon
TimeSpan durationTime = Stopwatch.GetElapsedTime(startTimestamp, Stopwatch.GetTimestamp());
- HttpMetricsEnrichmentContext? enrichmentContext = HttpMetricsEnrichmentContext.GetEnrichmentContextForRequest(request);
- if (enrichmentContext is null)
+ List>? callbacks = HttpMetricsEnrichmentContext.GetEnrichmentCallbacksForRequest(request);
+ if (callbacks is null)
{
_requestsDuration.Record(durationTime.TotalSeconds, tags);
}
else
{
- enrichmentContext.RecordDurationWithEnrichment(request, response, exception, durationTime, tags, _requestsDuration);
+ HttpMetricsEnrichmentContext.RecordDurationWithEnrichment(callbacks, request, response, exception, durationTime, tags, _requestsDuration);
}
}
diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/MetricsTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/MetricsTest.cs
index 6a8d156cdfc41a..9d4afdd97788ab 100644
--- a/src/libraries/System.Net.Http/tests/FunctionalTests/MetricsTest.cs
+++ b/src/libraries/System.Net.Http/tests/FunctionalTests/MetricsTest.cs
@@ -467,6 +467,49 @@ public Task RequestDuration_CustomTags_Recorded()
VerifyRequestDuration(m, uri, UseVersion, 200);
Assert.Equal("/test", m.Tags.ToArray().Single(t => t.Key == "route").Value);
+ }, async server =>
+ {
+ await server.HandleRequestAsync();
+ });
+ }
+
+ [Fact]
+ public Task RequestDuration_MultipleCallbacksPerRequest_AllCalledInOrder()
+ {
+ return LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
+ {
+ using HttpMessageInvoker client = CreateHttpMessageInvoker();
+ using InstrumentRecorder recorder = SetupInstrumentRecorder(InstrumentNames.RequestDuration);
+ using HttpRequestMessage request = new(HttpMethod.Get, uri) { Version = UseVersion };
+
+ int lastCallback = -1;
+
+ HttpMetricsEnrichmentContext.AddCallback(request, ctx =>
+ {
+ Assert.Equal(-1, lastCallback);
+ lastCallback = 1;
+ ctx.AddCustomTag("custom1", "foo");
+ });
+ HttpMetricsEnrichmentContext.AddCallback(request, ctx =>
+ {
+ Assert.Equal(1, lastCallback);
+ lastCallback = 2;
+ ctx.AddCustomTag("custom2", "bar");
+ });
+ HttpMetricsEnrichmentContext.AddCallback(request, ctx =>
+ {
+ Assert.Equal(2, lastCallback);
+ ctx.AddCustomTag("custom3", "baz");
+ });
+
+ using HttpResponseMessage response = await SendAsync(client, request);
+
+ Measurement m = Assert.Single(recorder.GetMeasurements());
+ VerifyRequestDuration(m, uri, UseVersion, 200);
+ Assert.Equal("foo", Assert.Single(m.Tags.ToArray(), t => t.Key == "custom1").Value);
+ Assert.Equal("bar", Assert.Single(m.Tags.ToArray(), t => t.Key == "custom2").Value);
+ Assert.Equal("baz", Assert.Single(m.Tags.ToArray(), t => t.Key == "custom3").Value);
+
}, async server =>
{
await server.AcceptConnectionSendResponseAndCloseAsync();
@@ -1075,6 +1118,96 @@ public class HttpMetricsTest_Http11_Async_HttpMessageInvoker : HttpMetricsTest_H
public HttpMetricsTest_Http11_Async_HttpMessageInvoker(ITestOutputHelper output) : base(output)
{
}
+
+ [Fact]
+ public async Task RequestDuration_RequestReused_EnrichmentCallbacksAreCleared()
+ {
+ await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
+ {
+ using HttpMessageInvoker client = CreateHttpMessageInvoker();
+ using InstrumentRecorder recorder = SetupInstrumentRecorder(InstrumentNames.RequestDuration);
+
+ using HttpRequestMessage request = new(HttpMethod.Get, uri);
+
+ int firstCallbackCalls = 0;
+
+ HttpMetricsEnrichmentContext.AddCallback(request, ctx =>
+ {
+ firstCallbackCalls++;
+ ctx.AddCustomTag("key1", "foo");
+ });
+
+ (await SendAsync(client, request)).Dispose();
+ Assert.Equal(1, firstCallbackCalls);
+
+ Measurement m = Assert.Single(recorder.GetMeasurements());
+ Assert.Equal("key1", Assert.Single(m.Tags.ToArray(), t => t.Value as string == "foo").Key);
+
+ HttpMetricsEnrichmentContext.AddCallback(request, static ctx =>
+ {
+ ctx.AddCustomTag("key2", "foo");
+ });
+
+ (await SendAsync(client, request)).Dispose();
+ Assert.Equal(1, firstCallbackCalls);
+
+ Assert.Equal(2, recorder.GetMeasurements().Count);
+ m = recorder.GetMeasurements()[1];
+ Assert.Equal("key2", Assert.Single(m.Tags.ToArray(), t => t.Value as string == "foo").Key);
+ }, async server =>
+ {
+ await server.HandleRequestAsync();
+ await server.HandleRequestAsync();
+ });
+ }
+
+ [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsThreadingSupported))]
+ public async Task RequestDuration_ConcurrentRequestsSeeDifferentContexts()
+ {
+ await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
+ {
+ using HttpMessageInvoker client = CreateHttpMessageInvoker();
+ using var _ = SetupInstrumentRecorder(InstrumentNames.RequestDuration);
+
+ using HttpRequestMessage request1 = new(HttpMethod.Get, uri);
+ using HttpRequestMessage request2 = new(HttpMethod.Get, uri);
+
+ HttpMetricsEnrichmentContext.AddCallback(request1, _ => { });
+ (await client.SendAsync(request1, CancellationToken.None)).Dispose();
+
+ HttpMetricsEnrichmentContext context1 = null;
+ HttpMetricsEnrichmentContext context2 = null;
+ CountdownEvent countdownEvent = new(2);
+
+ HttpMetricsEnrichmentContext.AddCallback(request1, ctx =>
+ {
+ context1 = ctx;
+ countdownEvent.Signal();
+ Assert.True(countdownEvent.Wait(TestHelper.PassingTestTimeout));
+ });
+ HttpMetricsEnrichmentContext.AddCallback(request2, ctx =>
+ {
+ context2 = ctx;
+ countdownEvent.Signal();
+ Assert.True(countdownEvent.Wait(TestHelper.PassingTestTimeout));
+ });
+
+ Task task1 = Task.Run(() => client.SendAsync(request1, CancellationToken.None));
+ Task task2 = Task.Run(() => client.SendAsync(request2, CancellationToken.None));
+
+ (await task1).Dispose();
+ (await task2).Dispose();
+
+ Assert.NotSame(context1, context2);
+ }, async server =>
+ {
+ await server.HandleRequestAsync();
+
+ await Task.WhenAll(
+ server.HandleRequestAsync(),
+ server.HandleRequestAsync());
+ }, options: new GenericLoopbackOptions { ListenBacklog = 2 });
+ }
}
[ConditionalClass(typeof(PlatformDetection), nameof(PlatformDetection.IsNotMobile))]
diff --git a/src/libraries/System.Net.NetworkInformation/tests/FunctionalTests/IPGlobalPropertiesTest.cs b/src/libraries/System.Net.NetworkInformation/tests/FunctionalTests/IPGlobalPropertiesTest.cs
index ea8fe35b96efe8..011bb87b92b92c 100644
--- a/src/libraries/System.Net.NetworkInformation/tests/FunctionalTests/IPGlobalPropertiesTest.cs
+++ b/src/libraries/System.Net.NetworkInformation/tests/FunctionalTests/IPGlobalPropertiesTest.cs
@@ -212,7 +212,10 @@ public async Task GetUnicastAddresses_NotEmpty()
public void IPGlobalProperties_DomainName_ReturnsEmptyStringWhenNotSet()
{
IPGlobalProperties gp = IPGlobalProperties.GetIPGlobalProperties();
- Assert.Equal(string.Empty, gp.DomainName);
+
+ // [ActiveIssue("https://github.com/dotnet/runtime/issues/109280")]
+ string expectedDomainName = PlatformDetection.IsAndroid ? "localdomain" : string.Empty;
+ Assert.Equal(expectedDomainName, gp.DomainName);
}
}
}
diff --git a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketAsyncEventArgsTest.cs b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketAsyncEventArgsTest.cs
index 9909192150ed0b..73c4ee74d18e21 100644
--- a/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketAsyncEventArgsTest.cs
+++ b/src/libraries/System.Net.Sockets/tests/FunctionalTests/SocketAsyncEventArgsTest.cs
@@ -728,7 +728,7 @@ public void AcceptAsync_WithReceiveBuffer_Success()
Assert.Equal(acceptBufferDataSize, acceptArgs.BytesTransferred);
- AssertExtensions.SequenceEqual(sendBuffer, acceptArgs.Buffer.AsSpan(0, acceptArgs.BytesTransferred));
+ AssertExtensions.SequenceEqual(sendBuffer.AsSpan(), acceptArgs.Buffer.AsSpan(0, acceptArgs.BytesTransferred));
}
}
diff --git a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs
index eec1e295e3c77b..1274b20b8cf9eb 100644
--- a/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs
+++ b/src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/netcore/TensorExtensions.cs
@@ -3521,7 +3521,17 @@ public static T StdDev(in ReadOnlyTensorSpan x)
TensorPrimitives.Abs(output, output);
TensorPrimitives.Pow((ReadOnlySpan)output, T.CreateChecked(2), output);
T sum = TensorPrimitives.Sum((ReadOnlySpan)output);
- return T.CreateChecked(sum / T.CreateChecked(x._shape._memoryLength));
+ T variance = sum / T.CreateChecked(x._shape._memoryLength);
+
+ if (typeof(T) == typeof(float))
+ {
+ return T.CreateChecked(MathF.Sqrt(float.CreateChecked(variance)));
+ }
+ if (typeof(T) == typeof(double))
+ {
+ return T.CreateChecked(Math.Sqrt(double.CreateChecked(variance)));
+ }
+ return T.Pow(variance, T.CreateChecked(0.5));
}
#endregion
diff --git a/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs b/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs
index 96e2e9ede1313b..a418230aff14a0 100644
--- a/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs
+++ b/src/libraries/System.Numerics.Tensors/tests/TensorTests.cs
@@ -1113,7 +1113,7 @@ public static float StdDev(float[] values)
{
sum += MathF.Pow(values[i] - mean, 2);
}
- return sum / values.Length;
+ return MathF.Sqrt(sum / values.Length);
}
[Fact]
diff --git a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx
index e7dadba40a5395..3e91b3ecb8340f 100644
--- a/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx
+++ b/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx
@@ -1,17 +1,17 @@
-
@@ -1315,6 +1315,9 @@
Invalid or unsupported normalization form.
+
+ `NormalizationForm.FormKC` and `NormalizationForm.FormKD` are not supported in browser environments or WebAssembly.
+
An undefined NumberStyles value is being used.
diff --git a/src/libraries/System.Private.CoreLib/src/System/AggregateException.cs b/src/libraries/System.Private.CoreLib/src/System/AggregateException.cs
index 66cc252717d7d4..7621b1fdda9732 100644
--- a/src/libraries/System.Private.CoreLib/src/System/AggregateException.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/AggregateException.cs
@@ -213,13 +213,16 @@ public override void GetObjectData(SerializationInfo info, StreamingContext cont
}
///
- /// Returns the that is the root cause of this exception.
+ /// Returns the that is the root cause of this exception.
///
+ ///
+ /// This will either be the root exception, or the first
+ /// that contains either multiple inner exceptions or no inner exceptions at all.
+ ///
public override Exception GetBaseException()
{
- // Returns the first inner AggregateException that contains more or less than one inner exception
-
- // Recursively traverse the inner exceptions as long as the inner exception of type AggregateException and has only one inner exception
+ // Recursively traverse the inner exceptions as long as the inner exception is of type
+ // AggregateException and has exactly one inner exception
Exception? back = this;
AggregateException? backAsAggregate = this;
while (backAsAggregate != null && backAsAggregate.InnerExceptions.Count == 1)
diff --git a/src/libraries/System.Private.CoreLib/src/System/AppContextConfigHelper.cs b/src/libraries/System.Private.CoreLib/src/System/AppContextConfigHelper.cs
index cfb4629187dcb5..87119ca280fe8b 100644
--- a/src/libraries/System.Private.CoreLib/src/System/AppContextConfigHelper.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/AppContextConfigHelper.cs
@@ -28,6 +28,25 @@ internal static bool GetBooleanConfig(string switchName, string envVariable, boo
return GetBooleanConfig(switchName, defaultValue);
}
+ internal static bool GetBooleanComPlusOrDotNetConfig(string configName, string envVariable, bool defaultValue)
+ {
+ string? str = Environment.GetEnvironmentVariable("DOTNET_" + envVariable)
+ ?? Environment.GetEnvironmentVariable("COMPlus_" + envVariable);
+
+ if (str != null && str.StartsWith("0x", StringComparison.Ordinal))
+ {
+ str = str.Substring(2);
+ }
+
+ if (str != null
+ && uint.TryParse(str, NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo, out uint resultUnsigned))
+ {
+ return resultUnsigned != 0;
+ }
+
+ return GetBooleanConfig(configName, defaultValue);
+ }
+
internal static int GetInt32Config(string configName, int defaultValue, bool allowNegative = true)
{
try
@@ -112,6 +131,29 @@ internal static int GetInt32Config(string configName, string envVariable, int de
return GetInt32Config(configName, defaultValue, allowNegative);
}
+ internal static int GetInt32ComPlusOrDotNetConfig(string configName, string envVariable, int defaultValue, bool allowNegative)
+ {
+ string? str = Environment.GetEnvironmentVariable("DOTNET_" + envVariable)
+ ?? Environment.GetEnvironmentVariable("COMPlus_" + envVariable);
+
+ if (str != null && str.StartsWith("0x", StringComparison.Ordinal))
+ {
+ str = str.Substring(2);
+ }
+
+ if (str != null
+ && uint.TryParse(str, NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo, out uint resultUnsigned))
+ {
+ int result = (int)resultUnsigned;
+ if (allowNegative || result >= 0)
+ {
+ return result;
+ }
+ }
+
+ return GetInt32Config(configName, defaultValue, allowNegative);
+ }
+
internal static short GetInt16Config(string configName, short defaultValue, bool allowNegative = true)
{
try
@@ -198,5 +240,28 @@ internal static short GetInt16Config(string configName, string envVariable, shor
return GetInt16Config(configName, defaultValue, allowNegative);
}
+
+ internal static short GetInt16ComPlusOrDotNetConfig(string configName, string envVariable, short defaultValue, bool allowNegative)
+ {
+ string? str = Environment.GetEnvironmentVariable("DOTNET_" + envVariable)
+ ?? Environment.GetEnvironmentVariable("COMPlus_" + envVariable);
+
+ if (str != null && str.StartsWith("0x", StringComparison.Ordinal))
+ {
+ str = str.Substring(2);
+ }
+
+ if (str != null
+ && ushort.TryParse(str, NumberStyles.HexNumber, NumberFormatInfo.InvariantInfo, out ushort resultUnsigned))
+ {
+ short result = (short)resultUnsigned;
+ if (allowNegative || result >= 0)
+ {
+ return result;
+ }
+ }
+
+ return GetInt16Config(configName, defaultValue, allowNegative);
+ }
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Buffer.cs b/src/libraries/System.Private.CoreLib/src/System/Buffer.cs
index 2a1e2a02999509..30ee85041633d6 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Buffer.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Buffer.cs
@@ -175,9 +175,6 @@ ref Unsafe.As(ref source),
private const uint BulkMoveWithWriteBarrierChunk = 0x4000;
#endif
-#if NATIVEAOT
- [System.Runtime.RuntimeExport("RhBuffer_BulkMoveWithWriteBarrier")]
-#endif
internal static void BulkMoveWithWriteBarrier(ref byte destination, ref byte source, nuint byteCount)
{
if (byteCount <= BulkMoveWithWriteBarrierChunk)
diff --git a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs
index 119f06ac9fecf5..2cc980619cf953 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/List.cs
@@ -1184,8 +1184,6 @@ public bool TrueForAll(Predicate match)
public struct Enumerator : IEnumerator, IEnumerator
{
- internal static IEnumerator? s_emptyEnumerator;
-
private readonly List _list;
private int _index;
private readonly int _version;
diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.Icu.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.Icu.cs
index 6ef9df95aa79d4..cffa2705c380f6 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.Icu.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.Icu.cs
@@ -10,31 +10,33 @@ namespace System.Globalization
{
internal static partial class Normalization
{
- private static unsafe bool IcuIsNormalized(string strInput, NormalizationForm normalizationForm)
+ private static unsafe bool IcuIsNormalized(ReadOnlySpan source, NormalizationForm normalizationForm)
{
Debug.Assert(!GlobalizationMode.Invariant);
Debug.Assert(!GlobalizationMode.UseNls);
+ Debug.Assert(!source.IsEmpty);
+ Debug.Assert(normalizationForm is NormalizationForm.FormC or NormalizationForm.FormD or NormalizationForm.FormKC or NormalizationForm.FormKD);
- ValidateArguments(strInput, normalizationForm);
+ ValidateArguments(source, normalizationForm, nameof(source));
int ret;
- fixed (char* pInput = strInput)
+ fixed (char* pInput = source)
{
#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
if (GlobalizationMode.Hybrid)
{
- ret = Interop.Globalization.IsNormalizedNative(normalizationForm, pInput, strInput.Length);
+ ret = Interop.Globalization.IsNormalizedNative(normalizationForm, pInput, source.Length);
}
else
#endif
{
- ret = Interop.Globalization.IsNormalized(normalizationForm, pInput, strInput.Length);
+ ret = Interop.Globalization.IsNormalized(normalizationForm, pInput, source.Length);
}
}
if (ret == -1)
{
- throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex, nameof(strInput));
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex, nameof(source));
}
return ret == 1;
@@ -44,6 +46,7 @@ private static unsafe string IcuNormalize(string strInput, NormalizationForm nor
{
Debug.Assert(!GlobalizationMode.Invariant);
Debug.Assert(!GlobalizationMode.UseNls);
+ Debug.Assert(normalizationForm == NormalizationForm.FormC || normalizationForm == NormalizationForm.FormD || normalizationForm == NormalizationForm.FormKC || normalizationForm == NormalizationForm.FormKD);
ValidateArguments(strInput, normalizationForm);
@@ -114,25 +117,95 @@ private static unsafe string IcuNormalize(string strInput, NormalizationForm nor
}
}
- private static void ValidateArguments(string strInput, NormalizationForm normalizationForm)
+ private static unsafe bool IcuTryNormalize(ReadOnlySpan source, Span destination, out int charsWritten, NormalizationForm normalizationForm = NormalizationForm.FormC)
{
- Debug.Assert(strInput != null);
+ Debug.Assert(!GlobalizationMode.Invariant);
+ Debug.Assert(!GlobalizationMode.UseNls);
+ Debug.Assert(!source.IsEmpty);
+ Debug.Assert(normalizationForm == NormalizationForm.FormC || normalizationForm == NormalizationForm.FormD || normalizationForm == NormalizationForm.FormKC || normalizationForm == NormalizationForm.FormKD);
- if ((OperatingSystem.IsBrowser() || OperatingSystem.IsWasi())&& (normalizationForm == NormalizationForm.FormKC || normalizationForm == NormalizationForm.FormKD))
+ if (destination.IsEmpty)
{
- // Browser's ICU doesn't contain data needed for FormKC and FormKD
- throw new PlatformNotSupportedException();
+ charsWritten = 0;
+ return false;
+ }
+
+ ValidateArguments(source, normalizationForm, nameof(source));
+
+ int realLen;
+ fixed (char* pInput = source)
+ fixed (char* pDest = destination)
+ {
+#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
+ if (GlobalizationMode.Hybrid)
+ {
+ realLen = Interop.Globalization.NormalizeStringNative(normalizationForm, pInput, source.Length, pDest, destination.Length);
+ }
+ else
+#endif
+ {
+ realLen = Interop.Globalization.NormalizeString(normalizationForm, pInput, source.Length, pDest, destination.Length);
+ }
}
- if (normalizationForm != NormalizationForm.FormC && normalizationForm != NormalizationForm.FormD &&
- normalizationForm != NormalizationForm.FormKC && normalizationForm != NormalizationForm.FormKD)
+ if (realLen < 0)
{
- throw new ArgumentException(SR.Argument_InvalidNormalizationForm, nameof(normalizationForm));
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex, nameof(source));
+ }
+
+ if (realLen <= destination.Length)
+ {
+ charsWritten = realLen;
+ return true;
+ }
+
+ charsWritten = 0;
+ return false;
+ }
+
+ private static unsafe int IcuGetNormalizedLength(ReadOnlySpan source, NormalizationForm normalizationForm)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+ Debug.Assert(!GlobalizationMode.UseNls);
+ Debug.Assert(!source.IsEmpty);
+ Debug.Assert(normalizationForm == NormalizationForm.FormC || normalizationForm == NormalizationForm.FormD || normalizationForm == NormalizationForm.FormKC || normalizationForm == NormalizationForm.FormKD);
+
+ ValidateArguments(source, normalizationForm, nameof(source));
+
+ int realLen;
+ fixed (char* pInput = source)
+ {
+#if TARGET_MACCATALYST || TARGET_IOS || TARGET_TVOS
+ if (GlobalizationMode.Hybrid)
+ {
+ realLen = Interop.Globalization.NormalizeStringNative(normalizationForm, pInput, source.Length, null, 0);
+ }
+ else
+#endif
+ {
+ realLen = Interop.Globalization.NormalizeString(normalizationForm, pInput, source.Length, null, 0);
+ }
+ }
+
+ if (realLen < 0)
+ {
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex, nameof(source));
+ }
+
+ return realLen;
+ }
+
+ private static void ValidateArguments(ReadOnlySpan strInput, NormalizationForm normalizationForm, string paramName = "strInput")
+ {
+ if ((OperatingSystem.IsBrowser() || OperatingSystem.IsWasi()) && (normalizationForm == NormalizationForm.FormKC || normalizationForm == NormalizationForm.FormKD))
+ {
+ // Browser's ICU doesn't contain data needed for FormKC and FormKD
+ throw new PlatformNotSupportedException(SR.Argument_UnsupportedNormalizationFormInBrowser);
}
if (HasInvalidUnicodeSequence(strInput))
{
- throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex, nameof(strInput));
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex, paramName);
}
}
@@ -143,18 +216,22 @@ private static void ValidateArguments(string strInput, NormalizationForm normali
/// We walk the string ourselves looking for these bad sequences so we can continue to throw
/// ArgumentException in these cases.
///
- private static bool HasInvalidUnicodeSequence(string s)
+ private static bool HasInvalidUnicodeSequence(ReadOnlySpan s)
{
- for (int i = 0; i < s.Length; i++)
+ const char Noncharacter = '\uFFFE';
+
+ int i = s.IndexOfAnyInRange(CharUnicodeInfo.HIGH_SURROGATE_START, Noncharacter);
+
+ for (; (uint)i < (uint)s.Length; i++)
{
char c = s[i];
- if (c < '\ud800')
+ if (c < CharUnicodeInfo.HIGH_SURROGATE_START)
{
continue;
}
- if (c == '\uFFFE')
+ if (c == Noncharacter)
{
return true;
}
@@ -167,17 +244,14 @@ private static bool HasInvalidUnicodeSequence(string s)
if (char.IsHighSurrogate(c))
{
- if (i + 1 >= s.Length || !char.IsLowSurrogate(s[i + 1]))
+ if ((uint)(i + 1) >= (uint)s.Length || !char.IsLowSurrogate(s[i + 1]))
{
// A high surrogate at the end of the string or a high surrogate
// not followed by a low surrogate
return true;
}
- else
- {
- i++; // consume the low surrogate.
- continue;
- }
+
+ i++; // consume the low surrogate.
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.Nls.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.Nls.cs
index 3abea572529896..2e63cd5daa5b81 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.Nls.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.Nls.cs
@@ -3,6 +3,7 @@
using System.Buffers;
using System.Diagnostics;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
@@ -10,45 +11,23 @@ namespace System.Globalization
{
internal static partial class Normalization
{
- private static unsafe bool NlsIsNormalized(string strInput, NormalizationForm normalizationForm)
+ private static unsafe bool NlsIsNormalized(ReadOnlySpan source, NormalizationForm normalizationForm)
{
Debug.Assert(!GlobalizationMode.Invariant);
Debug.Assert(GlobalizationMode.UseNls);
- Debug.Assert(strInput != null);
+ Debug.Assert(!source.IsEmpty);
+ Debug.Assert(normalizationForm == NormalizationForm.FormC || normalizationForm == NormalizationForm.FormD || normalizationForm == NormalizationForm.FormKC || normalizationForm == NormalizationForm.FormKD);
- // The only way to know if IsNormalizedString failed is through checking the Win32 last error
- // IsNormalizedString pinvoke has SetLastError attribute property which will set the last error
- // to 0 (ERROR_SUCCESS) before executing the calls.
Interop.BOOL result;
- fixed (char* pInput = strInput)
+ fixed (char* pInput = source)
{
- result = Interop.Normaliz.IsNormalizedString(normalizationForm, pInput, strInput.Length);
+ result = Interop.Normaliz.IsNormalizedString(normalizationForm, pInput, source.Length);
}
- int lastError = Marshal.GetLastPInvokeError();
- switch (lastError)
- {
- case Interop.Errors.ERROR_SUCCESS:
- break;
-
- case Interop.Errors.ERROR_INVALID_PARAMETER:
- case Interop.Errors.ERROR_NO_UNICODE_TRANSLATION:
- if (normalizationForm != NormalizationForm.FormC &&
- normalizationForm != NormalizationForm.FormD &&
- normalizationForm != NormalizationForm.FormKC &&
- normalizationForm != NormalizationForm.FormKD)
- {
- throw new ArgumentException(SR.Argument_InvalidNormalizationForm, nameof(normalizationForm));
- }
-
- throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex, nameof(strInput));
-
- case Interop.Errors.ERROR_NOT_ENOUGH_MEMORY:
- throw new OutOfMemoryException();
-
- default:
- throw new InvalidOperationException(SR.Format(SR.UnknownError_Num, lastError));
- }
+ // The only way to know if IsNormalizedString failed is through checking the Win32 last error
+ // IsNormalizedString pinvoke has SetLastError attribute property which will set the last error
+ // to 0 (ERROR_SUCCESS) before executing the calls.
+ CheckLastErrorAndThrowIfFailed(nameof(source));
return result != Interop.BOOL.FALSE;
}
@@ -58,6 +37,7 @@ private static unsafe string NlsNormalize(string strInput, NormalizationForm nor
Debug.Assert(!GlobalizationMode.Invariant);
Debug.Assert(GlobalizationMode.UseNls);
Debug.Assert(strInput != null);
+ Debug.Assert(normalizationForm == NormalizationForm.FormC || normalizationForm == NormalizationForm.FormD || normalizationForm == NormalizationForm.FormKC || normalizationForm == NormalizationForm.FormKD);
if (strInput.Length == 0)
{
@@ -111,14 +91,6 @@ private static unsafe string NlsNormalize(string strInput, NormalizationForm nor
case Interop.Errors.ERROR_INVALID_PARAMETER:
case Interop.Errors.ERROR_NO_UNICODE_TRANSLATION:
- if (normalizationForm != NormalizationForm.FormC &&
- normalizationForm != NormalizationForm.FormD &&
- normalizationForm != NormalizationForm.FormKC &&
- normalizationForm != NormalizationForm.FormKD)
- {
- throw new ArgumentException(SR.Argument_InvalidNormalizationForm, nameof(normalizationForm));
- }
-
// Illegal code point or order found. Ie: FFFE or D800 D800, etc.
throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex, nameof(strInput));
@@ -139,5 +111,113 @@ private static unsafe string NlsNormalize(string strInput, NormalizationForm nor
}
}
}
+
+ private static unsafe bool NlsTryNormalize(ReadOnlySpan source, Span destination, out int charsWritten, NormalizationForm normalizationForm = NormalizationForm.FormC)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+ Debug.Assert(GlobalizationMode.UseNls);
+ Debug.Assert(!source.IsEmpty);
+ Debug.Assert(normalizationForm == NormalizationForm.FormC || normalizationForm == NormalizationForm.FormD || normalizationForm == NormalizationForm.FormKC || normalizationForm == NormalizationForm.FormKD);
+
+ if (destination.IsEmpty)
+ {
+ charsWritten = 0;
+ return false;
+ }
+
+ // we depend on Win32 last error when calling NormalizeString
+ // NormalizeString pinvoke has SetLastError attribute property which will set the last error
+ // to 0 (ERROR_SUCCESS) before executing the calls.
+
+ int realLength;
+ fixed (char* pInput = source)
+ fixed (char* pDest = destination)
+ {
+ realLength = Interop.Normaliz.NormalizeString(normalizationForm, pInput, source.Length, pDest, destination.Length);
+ }
+
+ int lastError = Marshal.GetLastPInvokeError();
+ switch (lastError)
+ {
+ case Interop.Errors.ERROR_SUCCESS:
+ charsWritten = realLength;
+ return true;
+
+ // Do appropriate stuff for the individual errors:
+ case Interop.Errors.ERROR_INSUFFICIENT_BUFFER:
+ charsWritten = 0;
+ return false;
+
+ case Interop.Errors.ERROR_INVALID_PARAMETER:
+ case Interop.Errors.ERROR_NO_UNICODE_TRANSLATION:
+ // Illegal code point or order found. Ie: FFFE or D800 D800, etc.
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex, nameof(source));
+
+ case Interop.Errors.ERROR_NOT_ENOUGH_MEMORY:
+ throw new OutOfMemoryException();
+
+ default:
+ // We shouldn't get here...
+ throw new InvalidOperationException(SR.Format(SR.UnknownError_Num, lastError));
+ }
+ }
+
+ private static unsafe int NlsGetNormalizedLength(ReadOnlySpan source, NormalizationForm normalizationForm)
+ {
+ Debug.Assert(!GlobalizationMode.Invariant);
+ Debug.Assert(GlobalizationMode.UseNls);
+ Debug.Assert(!source.IsEmpty);
+ Debug.Assert(normalizationForm == NormalizationForm.FormC || normalizationForm == NormalizationForm.FormD || normalizationForm == NormalizationForm.FormKC || normalizationForm == NormalizationForm.FormKD);
+
+ // we depend on Win32 last error when calling NormalizeString
+ // NormalizeString pinvoke has SetLastError attribute property which will set the last error
+ // to 0 (ERROR_SUCCESS) before executing the calls.
+
+ int realLength;
+ fixed (char* pInput = source)
+ {
+ realLength = Interop.Normaliz.NormalizeString(normalizationForm, pInput, source.Length, null, 0);
+ }
+
+ int lastError = Marshal.GetLastPInvokeError();
+ switch (lastError)
+ {
+ case Interop.Errors.ERROR_SUCCESS:
+ return realLength;
+
+ case Interop.Errors.ERROR_INVALID_PARAMETER:
+ case Interop.Errors.ERROR_NO_UNICODE_TRANSLATION:
+ // Illegal code point or order found. Ie: FFFE or D800 D800, etc.
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex, nameof(source));
+
+ case Interop.Errors.ERROR_NOT_ENOUGH_MEMORY:
+ throw new OutOfMemoryException();
+
+ default:
+ // We shouldn't get here...
+ throw new InvalidOperationException(SR.Format(SR.UnknownError_Num, lastError));
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static void CheckLastErrorAndThrowIfFailed(string inputName)
+ {
+ int lastError = Marshal.GetLastPInvokeError();
+ switch (lastError)
+ {
+ case Interop.Errors.ERROR_SUCCESS:
+ break;
+
+ case Interop.Errors.ERROR_INVALID_PARAMETER:
+ case Interop.Errors.ERROR_NO_UNICODE_TRANSLATION:
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex, inputName);
+
+ case Interop.Errors.ERROR_NOT_ENOUGH_MEMORY:
+ throw new OutOfMemoryException();
+
+ default:
+ throw new InvalidOperationException(SR.Format(SR.UnknownError_Num, lastError));
+ }
+ }
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.cs b/src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.cs
index d120302a8aa8e7..2488ab7824be71 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Globalization/Normalization.cs
@@ -1,33 +1,37 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using System.Diagnostics;
+using System.Runtime.CompilerServices;
using System.Text;
namespace System.Globalization
{
internal static partial class Normalization
{
- internal static bool IsNormalized(string strInput, NormalizationForm normalizationForm)
+ internal static bool IsNormalized(ReadOnlySpan source, NormalizationForm normalizationForm = NormalizationForm.FormC)
{
- if (GlobalizationMode.Invariant)
+ CheckNormalizationForm(normalizationForm);
+
+ // In Invariant mode we assume all characters are normalized because we don't support any linguistic operations on strings.
+ // If it's ASCII && one of the 4 main forms, then it's already normalized.
+ if (GlobalizationMode.Invariant || Ascii.IsValid(source))
{
- // In Invariant mode we assume all characters are normalized.
- // This is because we don't support any linguistic operation on the strings
return true;
}
return GlobalizationMode.UseNls ?
- NlsIsNormalized(strInput, normalizationForm) :
- IcuIsNormalized(strInput, normalizationForm);
+ NlsIsNormalized(source, normalizationForm) :
+ IcuIsNormalized(source, normalizationForm);
}
internal static string Normalize(string strInput, NormalizationForm normalizationForm)
{
- if (GlobalizationMode.Invariant)
+ CheckNormalizationForm(normalizationForm);
+
+ // In Invariant mode we assume all characters are normalized because we don't support any linguistic operations on strings.
+ // If it's ASCII && one of the 4 main forms, then it's already normalized.
+ if (GlobalizationMode.Invariant || Ascii.IsValid(strInput))
{
- // In Invariant mode we assume all characters are normalized.
- // This is because we don't support any linguistic operation on the strings
return strInput;
}
@@ -35,5 +39,56 @@ internal static string Normalize(string strInput, NormalizationForm normalizatio
NlsNormalize(strInput, normalizationForm) :
IcuNormalize(strInput, normalizationForm);
}
+
+ internal static bool TryNormalize(ReadOnlySpan source, Span destination, out int charsWritten, NormalizationForm normalizationForm = NormalizationForm.FormC)
+ {
+ CheckNormalizationForm(normalizationForm);
+
+ // In Invariant mode we assume all characters are normalized because we don't support any linguistic operations on strings.
+ // If it's ASCII && one of the 4 main forms, then it's already normalized.
+ if (GlobalizationMode.Invariant || Ascii.IsValid(source))
+ {
+ if (source.TryCopyTo(destination))
+ {
+ charsWritten = source.Length;
+ return true;
+ }
+
+ charsWritten = 0;
+ return false;
+ }
+
+ return GlobalizationMode.UseNls ?
+ NlsTryNormalize(source, destination, out charsWritten, normalizationForm) :
+ IcuTryNormalize(source, destination, out charsWritten, normalizationForm);
+ }
+
+ internal static int GetNormalizedLength(this ReadOnlySpan source, NormalizationForm normalizationForm = NormalizationForm.FormC)
+ {
+ CheckNormalizationForm(normalizationForm);
+
+ // In Invariant mode we assume all characters are normalized because we don't support any linguistic operations on strings.
+ // If it's ASCII && one of the 4 main forms, then it's already normalized.
+ if (GlobalizationMode.Invariant || Ascii.IsValid(source))
+ {
+ return source.Length;
+ }
+
+ return GlobalizationMode.UseNls ?
+ NlsGetNormalizedLength(source, normalizationForm) :
+ IcuGetNormalizedLength(source, normalizationForm);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static void CheckNormalizationForm(NormalizationForm normalizationForm)
+ {
+ if (normalizationForm != NormalizationForm.FormC &&
+ normalizationForm != NormalizationForm.FormD &&
+ normalizationForm != NormalizationForm.FormKC &&
+ normalizationForm != NormalizationForm.FormKD)
+ {
+ throw new ArgumentException(SR.Argument_InvalidNormalizationForm, nameof(normalizationForm));
+ }
+ }
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/IO/RandomAccess.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/IO/RandomAccess.Unix.cs
index bcddd3f4654fc1..147e3815812d0c 100644
--- a/src/libraries/System.Private.CoreLib/src/System/IO/RandomAccess.Unix.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/IO/RandomAccess.Unix.cs
@@ -168,38 +168,30 @@ internal static unsafe void WriteGatherAtOffset(SafeFileHandle handle, IReadOnly
var handles = new MemoryHandle[buffersCount];
Span vectors = buffersCount <= IovStackThreshold ?
- stackalloc Interop.Sys.IOVector[IovStackThreshold] :
+ stackalloc Interop.Sys.IOVector[IovStackThreshold].Slice(0, buffersCount) :
new Interop.Sys.IOVector[buffersCount];
try
{
- int buffersOffset = 0, firstBufferOffset = 0;
- while (true)
+ long totalBytesToWrite = 0;
+ for (int i = 0; i < buffersCount; i++)
{
- long totalBytesToWrite = 0;
-
- for (int i = buffersOffset; i < buffersCount; i++)
- {
- ReadOnlyMemory buffer = buffers[i];
- totalBytesToWrite += buffer.Length;
-
- MemoryHandle memoryHandle = buffer.Pin();
- vectors[i] = new Interop.Sys.IOVector { Base = firstBufferOffset + (byte*)memoryHandle.Pointer, Count = (UIntPtr)(buffer.Length - firstBufferOffset) };
- handles[i] = memoryHandle;
-
- firstBufferOffset = 0;
- }
+ ReadOnlyMemory buffer = buffers[i];
+ totalBytesToWrite += buffer.Length;
- if (totalBytesToWrite == 0)
- {
- break;
- }
+ MemoryHandle memoryHandle = buffer.Pin();
+ vectors[i] = new Interop.Sys.IOVector { Base = (byte*)memoryHandle.Pointer, Count = (UIntPtr)buffer.Length };
+ handles[i] = memoryHandle;
+ }
+ int buffersOffset = 0;
+ while (totalBytesToWrite > 0)
+ {
long bytesWritten;
Span left = vectors.Slice(buffersOffset);
fixed (Interop.Sys.IOVector* pinnedVectors = &MemoryMarshal.GetReference(left))
{
- bytesWritten = Interop.Sys.PWriteV(handle, pinnedVectors, buffersCount - buffersOffset, fileOffset);
+ bytesWritten = Interop.Sys.PWriteV(handle, pinnedVectors, left.Length, fileOffset);
}
FileStreamHelpers.CheckFileCall(bytesWritten, handle.Path);
@@ -211,22 +203,29 @@ internal static unsafe void WriteGatherAtOffset(SafeFileHandle handle, IReadOnly
// The write completed successfully but for fewer bytes than requested.
// We need to perform next write where the previous one has finished.
fileOffset += bytesWritten;
+ totalBytesToWrite -= bytesWritten;
// We need to try again for the remainder.
- for (int i = 0; i < buffersCount; i++)
+ while (buffersOffset < buffersCount && bytesWritten > 0)
{
- int n = buffers[i].Length;
+ int n = (int)vectors[buffersOffset].Count;
if (n <= bytesWritten)
{
- buffersOffset++;
bytesWritten -= n;
- if (bytesWritten == 0)
- {
- break;
- }
+ buffersOffset++;
}
else
{
- firstBufferOffset = (int)(bytesWritten - n);
+ // A partial read: the vector needs to point to the new offset.
+ // But that offset needs to be relative to the previous attempt.
+ // Example: we have a single buffer with 30 bytes and the first read returned 10.
+ // The next read should try to read the remaining 20 bytes, but in case it also reads just 10,
+ // the third attempt should read last 10 bytes (not 20 again).
+ Interop.Sys.IOVector current = vectors[buffersOffset];
+ vectors[buffersOffset] = new Interop.Sys.IOVector
+ {
+ Base = current.Base + (int)(bytesWritten),
+ Count = current.Count - (UIntPtr)(bytesWritten)
+ };
break;
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.ByteMemOps.cs b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.ByteMemOps.cs
index c4831969ccb0c5..e2b33b5d4227f4 100644
--- a/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.ByteMemOps.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/SpanHelpers.ByteMemOps.cs
@@ -33,9 +33,6 @@ private struct Block16 {}
private struct Block64 {}
#endif // HAS_CUSTOM_BLOCKS
-#if NATIVEAOT
- [System.Runtime.RuntimeExport("RhSpanHelpers_MemCopy")]
-#endif
[Intrinsic] // Unrolled for small constant lengths
internal static unsafe void Memmove(ref byte dest, ref byte src, nuint len)
{
@@ -245,9 +242,6 @@ internal static unsafe void Memmove(ref byte dest, ref byte src, nuint len)
Buffer._Memmove(ref dest, ref src, len);
}
-#if NATIVEAOT
- [System.Runtime.RuntimeExport("RhSpanHelpers_MemZero")]
-#endif
[Intrinsic] // Unrolled for small sizes
public static unsafe void ClearWithoutReferences(ref byte dest, nuint len)
{
@@ -434,9 +428,6 @@ public static unsafe void ClearWithoutReferences(ref byte dest, nuint len)
Buffer._ZeroMemory(ref dest, len);
}
-#if NATIVEAOT
- [System.Runtime.RuntimeExport("RhSpanHelpers_MemSet")]
-#endif
internal static void Fill(ref byte dest, byte value, nuint len)
{
if (!Vector.IsHardwareAccelerated)
diff --git a/src/libraries/System.Private.CoreLib/src/System/String.cs b/src/libraries/System.Private.CoreLib/src/System/String.cs
index 4995a972ecd8e8..daa4618fed3ccf 100644
--- a/src/libraries/System.Private.CoreLib/src/System/String.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/String.cs
@@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System.Buffers;
-using System.Buffers.Text;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
@@ -709,15 +708,6 @@ public bool IsNormalized()
public bool IsNormalized(NormalizationForm normalizationForm)
{
- if (Ascii.IsValid(this))
- {
- // If its ASCII && one of the 4 main forms, then its already normalized
- if (normalizationForm == NormalizationForm.FormC ||
- normalizationForm == NormalizationForm.FormKC ||
- normalizationForm == NormalizationForm.FormD ||
- normalizationForm == NormalizationForm.FormKD)
- return true;
- }
return Normalization.IsNormalized(this, normalizationForm);
}
@@ -728,15 +718,6 @@ public string Normalize()
public string Normalize(NormalizationForm normalizationForm)
{
- if (Ascii.IsValid(this))
- {
- // If its ASCII && one of the 4 main forms, then its already normalized
- if (normalizationForm == NormalizationForm.FormC ||
- normalizationForm == NormalizationForm.FormKC ||
- normalizationForm == NormalizationForm.FormD ||
- normalizationForm == NormalizationForm.FormKD)
- return this;
- }
return Normalization.Normalize(this, normalizationForm);
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/StringNormalizationExtensions.cs b/src/libraries/System.Private.CoreLib/src/System/StringNormalizationExtensions.cs
index 712752626fe549..8bb24afc2c9ee9 100644
--- a/src/libraries/System.Private.CoreLib/src/System/StringNormalizationExtensions.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/StringNormalizationExtensions.cs
@@ -1,17 +1,32 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Globalization;
using System.Text;
namespace System
{
+ ///
+ /// Extensions for string normalization.
+ ///
public static partial class StringNormalizationExtensions
{
+ ///
+ /// Determines whether the specified string is in a normalized .
+ ///
+ /// The string to check.
+ /// if the specified string is in a normalized form; otherwise, .
public static bool IsNormalized(this string strInput)
{
return IsNormalized(strInput, NormalizationForm.FormC);
}
+ ///
+ /// Determines whether the specified string is in a normalized form.
+ ///
+ /// The string to check.
+ /// The normalization form to use.
+ /// if the specified string is in a normalized form; otherwise, .
public static bool IsNormalized(this string strInput, NormalizationForm normalizationForm)
{
ArgumentNullException.ThrowIfNull(strInput);
@@ -19,17 +34,60 @@ public static bool IsNormalized(this string strInput, NormalizationForm normaliz
return strInput.IsNormalized(normalizationForm);
}
+ ///
+ /// Determines whether the specified span of characters is in a normalized form.
+ ///
+ /// The span of characters to check.
+ /// The normalization form to use.
+ /// if the specified span of characters is in a normalized form; otherwise, .
+ /// The specified character span contains an invalid code point or the normalization form is invalid.
+ public static bool IsNormalized(this ReadOnlySpan source, NormalizationForm normalizationForm = NormalizationForm.FormC) =>
+ Normalization.IsNormalized(source, normalizationForm);
+
+ ///
+ /// Normalizes the specified string to the .
+ ///
+ /// The string to normalize.
+ /// The normalized string in .
public static string Normalize(this string strInput)
{
// Default to Form C
return Normalize(strInput, NormalizationForm.FormC);
}
+ ///
+ /// Normalizes the specified string to the specified normalization form.
+ ///
+ /// The string to normalize.
+ /// The normalization form to use.
+ /// The normalized string in the specified normalization form.
public static string Normalize(this string strInput, NormalizationForm normalizationForm)
{
ArgumentNullException.ThrowIfNull(strInput);
return strInput.Normalize(normalizationForm);
}
+
+ ///
+ /// Normalizes the specified span of characters to the specified normalization form.
+ ///
+ /// The span of characters to normalize.
+ /// The buffer to write the normalized characters to.
+ /// When this method returns, contains the number of characters written to .
+ /// The normalization form to use.
+ /// if the specified span of characters was successfully normalized; otherwise, .
+ /// The specified character span contains an invalid code point or the normalization form is invalid.
+ public static bool TryNormalize(this ReadOnlySpan source, Span destination, out int charsWritten, NormalizationForm normalizationForm = NormalizationForm.FormC) =>
+ Normalization.TryNormalize(source, destination, out charsWritten, normalizationForm);
+
+ ///
+ /// Gets the estimated length of the normalized form of the specified string in the .
+ ///
+ /// The character span to get the estimated length of the normalized form.
+ /// The normalization form to use.
+ /// The estimated length of the normalized form of the specified string.
+ /// The specified character span contains an invalid code point or the normalization form is invalid.
+ public static int GetNormalizedLength(this ReadOnlySpan source, NormalizationForm normalizationForm = NormalizationForm.FormC) =>
+ Normalization.GetNormalizedLength(source, normalizationForm);
}
}
diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.GateThread.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.GateThread.cs
index 5d1b79a3098e05..1840fd97d5dc92 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.GateThread.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.GateThread.cs
@@ -23,9 +23,9 @@ private static class GateThread
private static void GateThreadStart()
{
bool disableStarvationDetection =
- AppContextConfigHelper.GetBooleanConfig("System.Threading.ThreadPool.DisableStarvationDetection", false);
+ AppContextConfigHelper.GetBooleanComPlusOrDotNetConfig("System.Threading.ThreadPool.DisableStarvationDetection", "ThreadPool_DisableStarvationDetection", false);
bool debuggerBreakOnWorkStarvation =
- AppContextConfigHelper.GetBooleanConfig("System.Threading.ThreadPool.DebugBreakOnWorkerStarvation", false);
+ AppContextConfigHelper.GetBooleanComPlusOrDotNetConfig("System.Threading.ThreadPool.DebugBreakOnWorkerStarvation", "ThreadPool_DebugBreakOnWorkerStarvation", false);
// The first reading is over a time range other than what we are focusing on, so we do not use the read other
// than to send it to any runtime-specific implementation that may also use the CPU utilization.
diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.HillClimbing.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.HillClimbing.cs
index be5741e0ec6e20..cf340c81302878 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.HillClimbing.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.HillClimbing.cs
@@ -17,7 +17,7 @@ private sealed partial class HillClimbing
private const int DefaultSampleIntervalMsLow = 10;
private const int DefaultSampleIntervalMsHigh = 200;
- public static readonly bool IsDisabled = AppContextConfigHelper.GetBooleanConfig("System.Threading.ThreadPool.HillClimbing.Disable", false);
+ public static readonly bool IsDisabled = AppContextConfigHelper.GetBooleanComPlusOrDotNetConfig("System.Threading.ThreadPool.HillClimbing.Disable", "HillClimbing_Disable", false);
// SOS's ThreadPool command depends on this name
public static readonly HillClimbing ThreadPoolHillClimber = new HillClimbing();
@@ -80,16 +80,16 @@ private struct LogEntry
public HillClimbing()
{
- _wavePeriod = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.WavePeriod", 4, false);
- _maxThreadWaveMagnitude = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.MaxWaveMagnitude", 20, false);
- _threadMagnitudeMultiplier = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.WaveMagnitudeMultiplier", 100, false) / 100.0;
- _samplesToMeasure = _wavePeriod * AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.WaveHistorySize", 8, false);
- _targetThroughputRatio = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.Bias", 15, false) / 100.0;
- _targetSignalToNoiseRatio = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.TargetSignalToNoiseRatio", 300, false) / 100.0;
- _maxChangePerSecond = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.MaxChangePerSecond", 4, false);
- _maxChangePerSample = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.MaxChangePerSample", 20, false);
- int sampleIntervalMsLow = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.SampleIntervalLow", DefaultSampleIntervalMsLow, false);
- int sampleIntervalMsHigh = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.SampleIntervalHigh", DefaultSampleIntervalMsHigh, false);
+ _wavePeriod = AppContextConfigHelper.GetInt32ComPlusOrDotNetConfig("System.Threading.ThreadPool.HillClimbing.WavePeriod", "HillClimbing_WavePeriod", 4, false);
+ _maxThreadWaveMagnitude = AppContextConfigHelper.GetInt32ComPlusOrDotNetConfig("System.Threading.ThreadPool.HillClimbing.MaxWaveMagnitude", "HillClimbing_MaxWaveMagnitude", 20, false);
+ _threadMagnitudeMultiplier = AppContextConfigHelper.GetInt32ComPlusOrDotNetConfig("System.Threading.ThreadPool.HillClimbing.WaveMagnitudeMultiplier", "HillClimbing_WaveMagnitudeMultiplier", 100, false) / 100.0;
+ _samplesToMeasure = _wavePeriod * AppContextConfigHelper.GetInt32ComPlusOrDotNetConfig("System.Threading.ThreadPool.HillClimbing.WaveHistorySize", "HillClimbing_WaveHistorySize", 8, false);
+ _targetThroughputRatio = AppContextConfigHelper.GetInt32ComPlusOrDotNetConfig("System.Threading.ThreadPool.HillClimbing.Bias", "HillClimbing_Bias", 15, false) / 100.0;
+ _targetSignalToNoiseRatio = AppContextConfigHelper.GetInt32ComPlusOrDotNetConfig("System.Threading.ThreadPool.HillClimbing.TargetSignalToNoiseRatio", "HillClimbing_TargetSignalToNoiseRatio", 300, false) / 100.0;
+ _maxChangePerSecond = AppContextConfigHelper.GetInt32ComPlusOrDotNetConfig("System.Threading.ThreadPool.HillClimbing.MaxChangePerSecond", "HillClimbing_MaxChangePerSecond", 4, false);
+ _maxChangePerSample = AppContextConfigHelper.GetInt32ComPlusOrDotNetConfig("System.Threading.ThreadPool.HillClimbing.MaxChangePerSample", "HillClimbing_MaxChangePerSample", 20, false);
+ int sampleIntervalMsLow = AppContextConfigHelper.GetInt32ComPlusOrDotNetConfig("System.Threading.ThreadPool.HillClimbing.SampleIntervalLow", "HillClimbing_SampleIntervalLow", DefaultSampleIntervalMsLow, false);
+ int sampleIntervalMsHigh = AppContextConfigHelper.GetInt32ComPlusOrDotNetConfig("System.Threading.ThreadPool.HillClimbing.SampleIntervalHigh", "HillClimbing_SampleIntervalHigh", DefaultSampleIntervalMsHigh, false);
if (sampleIntervalMsLow <= sampleIntervalMsHigh)
{
_sampleIntervalMsLow = sampleIntervalMsLow;
@@ -100,9 +100,9 @@ public HillClimbing()
_sampleIntervalMsLow = DefaultSampleIntervalMsLow;
_sampleIntervalMsHigh = DefaultSampleIntervalMsHigh;
}
- _throughputErrorSmoothingFactor = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.ErrorSmoothingFactor", 1, false) / 100.0;
- _gainExponent = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.GainExponent", 200, false) / 100.0;
- _maxSampleError = AppContextConfigHelper.GetInt32Config("System.Threading.ThreadPool.HillClimbing.MaxSampleErrorPercent", 15, false) / 100.0;
+ _throughputErrorSmoothingFactor = AppContextConfigHelper.GetInt32ComPlusOrDotNetConfig("System.Threading.ThreadPool.HillClimbing.ErrorSmoothingFactor", "HillClimbing_ErrorSmoothingFactor", 1, false) / 100.0;
+ _gainExponent = AppContextConfigHelper.GetInt32ComPlusOrDotNetConfig("System.Threading.ThreadPool.HillClimbing.GainExponent", "HillClimbing_GainExponent", 200, false) / 100.0;
+ _maxSampleError = AppContextConfigHelper.GetInt32ComPlusOrDotNetConfig("System.Threading.ThreadPool.HillClimbing.MaxSampleErrorPercent", "HillClimbing_MaxSampleErrorPercent", 15, false) / 100.0;
_samples = new double[_samplesToMeasure];
_threadCounts = new double[_samplesToMeasure];
diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.WorkerThread.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.WorkerThread.cs
index c2e69c5dfdff09..d7265b345cd56d 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.WorkerThread.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.WorkerThread.cs
@@ -53,8 +53,9 @@ private static short DetermineThreadsToKeepAlive()
new LowLevelLifoSemaphore(
0,
MaxPossibleThreadCount,
- AppContextConfigHelper.GetInt32Config(
+ AppContextConfigHelper.GetInt32ComPlusOrDotNetConfig(
"System.Threading.ThreadPool.UnfairSemaphoreSpinLimit",
+ "ThreadPool_UnfairSemaphoreSpinLimit",
SemaphoreSpinCountDefault,
false),
onWait: () =>
diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.cs
index 8dc875f7bea96c..37a13598e1657f 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Threading/PortableThreadPool.cs
@@ -30,16 +30,10 @@ internal sealed partial class PortableThreadPool
private const int CpuUtilizationHigh = 95;
private const int CpuUtilizationLow = 80;
-#if CORECLR
-#pragma warning disable CA1823
- private static readonly bool s_initialized = ThreadPool.EnsureConfigInitialized();
-#pragma warning restore CA1823
-#endif
-
private static readonly short ForcedMinWorkerThreads =
- AppContextConfigHelper.GetInt16Config("System.Threading.ThreadPool.MinThreads", 0, false);
+ AppContextConfigHelper.GetInt16ComPlusOrDotNetConfig("System.Threading.ThreadPool.MinThreads", "ThreadPool_ForceMinWorkerThreads", 0, false);
private static readonly short ForcedMaxWorkerThreads =
- AppContextConfigHelper.GetInt16Config("System.Threading.ThreadPool.MaxThreads", 0, false);
+ AppContextConfigHelper.GetInt16ComPlusOrDotNetConfig("System.Threading.ThreadPool.MaxThreads", "ThreadPool_ForceMaxWorkerThreads", 0, false);
#if TARGET_WINDOWS
// Continuations of IO completions are dispatched to the ThreadPool from IO completion poller threads. This avoids
diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Unix.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Unix.cs
index 83faa720e3974a..3766266fa671e7 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Unix.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Unix.cs
@@ -22,10 +22,6 @@ public static partial class ThreadPool
internal static bool YieldFromDispatchLoop => false;
#endif
-#if !CORECLR
- internal static bool EnsureConfigInitialized() => true;
-#endif
-
internal static object GetOrCreateThreadLocalCompletionCountObject() =>
PortableThreadPool.ThreadPoolInstance.GetOrCreateThreadLocalCompletionCountObject();
diff --git a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Windows.cs b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Windows.cs
index 9006732641d149..78ea089ad86ae5 100644
--- a/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Windows.cs
+++ b/src/libraries/System.Private.CoreLib/src/System/Threading/ThreadPool.Windows.cs
@@ -56,10 +56,6 @@ public static bool BindHandle(SafeHandle osHandle) =>
WindowsThreadPool.BindHandle(osHandle) :
BindHandlePortableCore(osHandle);
-#if !CORECLR
- internal static bool EnsureConfigInitialized() => true;
-#endif
-
internal static void InitializeForThreadPoolThread()
{
if (ThreadPool.UseWindowsThreadPool)
diff --git a/src/libraries/System.Private.Xml/tests/Xslt/XslCompiledTransformApi/XsltArgumentList.cs b/src/libraries/System.Private.Xml/tests/Xslt/XslCompiledTransformApi/XsltArgumentList.cs
index 21603113f5cec4..71de03fbcabc9e 100644
--- a/src/libraries/System.Private.Xml/tests/Xslt/XslCompiledTransformApi/XsltArgumentList.cs
+++ b/src/libraries/System.Private.Xml/tests/Xslt/XslCompiledTransformApi/XsltArgumentList.cs
@@ -3252,7 +3252,7 @@ public void AddExtObject32(object param, XslInputType xslInputType, ReaderType r
[InlineData("sort.xsl", "sort.txt", XslInputType.Navigator, ReaderType.XmlValidatingReader, OutputType.Writer, NavType.XPathDocument)]
[InlineData("sort.xsl", "sort.txt", XslInputType.Navigator, ReaderType.XmlValidatingReader, OutputType.TextWriter, NavType.XPathDocument)]
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
public void AddExtObject33(object param0, object param1, XslInputType xslInputType, ReaderType readerType, OutputType outputType, NavType navType)
{
ExObj obj = new ExObj(0, _output);
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/JSSignatureContext.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/JSSignatureContext.cs
index 3f058a5c7eeb41..f59bb25bca0f51 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/JSSignatureContext.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/gen/JSImportGenerator/JSSignatureContext.cs
@@ -48,6 +48,7 @@ public static JSSignatureContext Create(
// there could be multiple method signatures with the same name, get unique signature name
uint hash = 17;
+ int typesHash;
unchecked
{
foreach (var param in sigContext.ElementTypeInformation)
@@ -57,8 +58,8 @@ public static JSSignatureContext Create(
foreach (char c in param.ManagedType.FullTypeName)
hash = hash * 31 + c;
}
+ typesHash = (int)(hash & int.MaxValue);
};
- int typesHash = Math.Abs((int)hash);
var fullName = $"{method.ContainingType.ToDisplayString()}.{method.Name}";
string qualifiedName = GetFullyQualifiedMethodName(env, method);
diff --git a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/JSImportGenerator.UnitTest/Compiles.cs b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/JSImportGenerator.UnitTest/Compiles.cs
index ff7af2116d4fb8..466cd3072f1ef4 100644
--- a/src/libraries/System.Runtime.InteropServices.JavaScript/tests/JSImportGenerator.UnitTest/Compiles.cs
+++ b/src/libraries/System.Runtime.InteropServices.JavaScript/tests/JSImportGenerator.UnitTest/Compiles.cs
@@ -69,9 +69,9 @@ unsafe partial class Basic
[global::System.Diagnostics.DebuggerNonUserCode]
internal static partial void Annotated(object a1, long a2, long a3, global::System.Action a4, global::System.Func a5, global::System.Span a6, global::System.ArraySegment a7, global::System.Threading.Tasks.Task a8, object[] a9, global::System.DateTime a10, global::System.DateTimeOffset a11, global::System.Threading.Tasks.Task a12, global::System.Threading.Tasks.Task a13, global::System.Threading.Tasks.Task a14, global::System.Threading.Tasks.Task a15)
{
- if (__signature_Annotated_564258462 == null)
+ if (__signature_Annotated_1583225186 == null)
{
- __signature_Annotated_564258462 = global::System.Runtime.InteropServices.JavaScript.JSFunctionBinding.BindJSFunction("DoesNotExist", null, new global::System.Runtime.InteropServices.JavaScript.JSMarshalerType[] { global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Discard, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Object, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Int52, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.BigInt64, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Action(), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Function(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Int32), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Span(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Byte), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.ArraySegment(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Byte), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Task(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Object), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Array(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Object), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.DateTime, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.DateTimeOffset, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Task(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.DateTime), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Task(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.DateTimeOffset), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Task(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Int52), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Task(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.BigInt64) });
+ __signature_Annotated_1583225186 = global::System.Runtime.InteropServices.JavaScript.JSFunctionBinding.BindJSFunction("DoesNotExist", null, new global::System.Runtime.InteropServices.JavaScript.JSMarshalerType[] { global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Discard, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Object, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Int52, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.BigInt64, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Action(), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Function(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Int32), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Span(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Byte), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.ArraySegment(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Byte), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Task(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Object), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Array(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Object), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.DateTime, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.DateTimeOffset, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Task(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.DateTime), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Task(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.DateTimeOffset), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Task(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Int52), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Task(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.BigInt64) });
}
global::System.Span __arguments_buffer = stackalloc global::System.Runtime.InteropServices.JavaScript.JSMarshalerArgument[17];
@@ -129,10 +129,10 @@ internal static partial void Annotated(object a1, long a2, long a3, global::Syst
__a3_native__js_arg.ToJSBig(a3);
__a2_native__js_arg.ToJS(a2);
__a1_native__js_arg.ToJS(a1);
- global::System.Runtime.InteropServices.JavaScript.JSFunctionBinding.InvokeJS(__signature_Annotated_564258462, __arguments_buffer);
+ global::System.Runtime.InteropServices.JavaScript.JSFunctionBinding.InvokeJS(__signature_Annotated_1583225186, __arguments_buffer);
}
- static global::System.Runtime.InteropServices.JavaScript.JSFunctionBinding __signature_Annotated_564258462;
+ static global::System.Runtime.InteropServices.JavaScript.JSFunctionBinding __signature_Annotated_1583225186;
}
""".ReplaceLineEndings("\r\n"), Encoding.UTF8)),
@@ -152,20 +152,20 @@ static internal void __TrimmingPreserve_()
{
}
- [global::System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute("__Wrapper_AnnotatedExport_564258462", "Basic", "TestProject")]
+ [global::System.Diagnostics.CodeAnalysis.DynamicDependencyAttribute("__Wrapper_AnnotatedExport_1583225186", "Basic", "TestProject")]
static void __Register_()
{
if (initialized || global::System.Runtime.InteropServices.RuntimeInformation.OSArchitecture != global::System.Runtime.InteropServices.Architecture.Wasm)
return;
initialized = true;
- global::System.Runtime.InteropServices.JavaScript.JSFunctionBinding.BindManagedFunction("[TestProject]Basic:AnnotatedExport", 564258462, new global::System.Runtime.InteropServices.JavaScript.JSMarshalerType[] { global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Discard, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Object, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Int52, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.BigInt64, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Action(), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Function(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Int32), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Span(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Byte), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.ArraySegment(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Byte), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Task(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Object), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Array(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Object), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.DateTime, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.DateTimeOffset, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Task(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.DateTime), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Task(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.DateTimeOffset), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Task(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Int52), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Task(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.BigInt64) });
+ global::System.Runtime.InteropServices.JavaScript.JSFunctionBinding.BindManagedFunction("[TestProject]Basic:AnnotatedExport", 1583225186, new global::System.Runtime.InteropServices.JavaScript.JSMarshalerType[] { global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Discard, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Object, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Int52, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.BigInt64, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Action(), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Function(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Int32), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Span(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Byte), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.ArraySegment(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Byte), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Task(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Object), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Array(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Object), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.DateTime, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.DateTimeOffset, global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Task(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.DateTime), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Task(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.DateTimeOffset), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Task(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Int52), global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.Task(global::System.Runtime.InteropServices.JavaScript.JSMarshalerType.BigInt64) });
}
}
}
unsafe partial class Basic
{
[global::System.Diagnostics.DebuggerNonUserCode]
- internal static unsafe void __Wrapper_AnnotatedExport_564258462(global::System.Runtime.InteropServices.JavaScript.JSMarshalerArgument* __arguments_buffer)
+ internal static unsafe void __Wrapper_AnnotatedExport_1583225186(global::System.Runtime.InteropServices.JavaScript.JSMarshalerArgument* __arguments_buffer)
{
object a1;
long a2;
diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulLinearCollectionShapeValidation.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulLinearCollectionShapeValidation.cs
index 2aedfde9936f47..e798e184b6bf76 100644
--- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulLinearCollectionShapeValidation.cs
+++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulLinearCollectionShapeValidation.cs
@@ -171,7 +171,7 @@ public void FromManaged(ManagedType m) {}
public nint ToUnmanaged() => default;
public void Free() {}
public Span GetUnmanagedValuesDestination() => default;
-
+
public ReadOnlySpan GetManagedValuesSource()
{
throw new NotImplementedException();
@@ -602,7 +602,6 @@ public void FromManaged(ManagedType m, Span buffer) {}
public void Free() {}
public ReadOnlySpan GetManagedValuesSource() => default;
public Span GetUnmanagedValuesDestination() => default;
-
public static int BufferSize
{
get
diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulValueShapeValidation.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulValueShapeValidation.cs
index 9a72a5fbc4916f..cb2c5d8caf10ec 100644
--- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulValueShapeValidation.cs
+++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatefulValueShapeValidation.cs
@@ -382,7 +382,6 @@ public void FromManaged(ManagedType m, Span b) {}
public int ToUnmanaged() => default;
public void Free() {}
-
public static int BufferSize
{
get
diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessLinearCollectionShapeValidation.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessLinearCollectionShapeValidation.cs
index fec16b2bc7ff7c..b60bb78f2acc2b 100644
--- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessLinearCollectionShapeValidation.cs
+++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessLinearCollectionShapeValidation.cs
@@ -614,7 +614,6 @@ static class MarshallerType
public static ReadOnlySpan GetManagedValuesSource(ManagedType m) => default;
public static Span GetUnmanagedValuesDestination(nint unmanaged, int numElements) => default;
-
public static int BufferSize
{
get
diff --git a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessValueShapeValidation.cs b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessValueShapeValidation.cs
index 7d94afb9985f79..35c90af32f81b2 100644
--- a/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessValueShapeValidation.cs
+++ b/src/libraries/System.Runtime.InteropServices/tests/LibraryImportGenerator.UnitTests/CustomMarshallerAttributeFixerTests_StatelessValueShapeValidation.cs
@@ -363,7 +363,6 @@ class ManagedType {}
static class MarshallerType
{
public static nint ConvertToUnmanaged(ManagedType m, Span b) => default;
-
public static int BufferSize
{
get
diff --git a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/CollectionsMarshalTests.cs b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/CollectionsMarshalTests.cs
index 325c9a43de6303..867ee99b852e89 100644
--- a/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/CollectionsMarshalTests.cs
+++ b/src/libraries/System.Runtime.InteropServices/tests/System.Runtime.InteropServices.UnitTests/System/Runtime/InteropServices/CollectionsMarshalTests.cs
@@ -527,19 +527,19 @@ public void ListSetCount()
CollectionsMarshal.SetCount(list, 3);
Assert.Equal(3, list.Count);
Assert.Throws(() => list[3]);
- AssertExtensions.SequenceEqual(CollectionsMarshal.AsSpan(list), new int[] { 1, 2, 3 });
+ AssertExtensions.SequenceEqual(CollectionsMarshal.AsSpan(list), new int[] { 1, 2, 3 }.AsSpan());
Assert.True(Unsafe.AreSame(ref intRef, ref MemoryMarshal.GetReference(CollectionsMarshal.AsSpan(list))));
// make sure that size increase preserves content and doesn't clear
CollectionsMarshal.SetCount(list, 5);
- AssertExtensions.SequenceEqual(CollectionsMarshal.AsSpan(list), new int[] { 1, 2, 3, 4, 5 });
+ AssertExtensions.SequenceEqual(CollectionsMarshal.AsSpan(list), new int[] { 1, 2, 3, 4, 5 }.AsSpan());
Assert.True(Unsafe.AreSame(ref intRef, ref MemoryMarshal.GetReference(CollectionsMarshal.AsSpan(list))));
// make sure that reallocations preserve content
int newCount = list.Capacity * 2;
CollectionsMarshal.SetCount(list, newCount);
Assert.Equal(newCount, list.Count);
- AssertExtensions.SequenceEqual(CollectionsMarshal.AsSpan(list)[..3], new int[] { 1, 2, 3 });
+ AssertExtensions.SequenceEqual(CollectionsMarshal.AsSpan(list)[..3], new int[] { 1, 2, 3 }.AsSpan());
Assert.True(!Unsafe.AreSame(ref intRef, ref MemoryMarshal.GetReference(CollectionsMarshal.AsSpan(list))));
List listReference = new() { "a", "b", "c", "d", "e" };
@@ -547,12 +547,12 @@ public void ListSetCount()
CollectionsMarshal.SetCount(listReference, 3);
// verify that reference types aren't cleared
- AssertExtensions.SequenceEqual(CollectionsMarshal.AsSpan(listReference), new string[] { "a", "b", "c" });
+ AssertExtensions.SequenceEqual(CollectionsMarshal.AsSpan(listReference), new string[] { "a", "b", "c" }.AsSpan());
Assert.True(Unsafe.AreSame(ref stringRef, ref MemoryMarshal.GetReference(CollectionsMarshal.AsSpan(listReference))));
CollectionsMarshal.SetCount(listReference, 5);
// verify that removed reference types are cleared
- AssertExtensions.SequenceEqual(CollectionsMarshal.AsSpan(listReference), new string[] { "a", "b", "c", null, null });
+ AssertExtensions.SequenceEqual(CollectionsMarshal.AsSpan(listReference), new string[] { "a", "b", "c", null, null }.AsSpan());
Assert.True(Unsafe.AreSame(ref stringRef, ref MemoryMarshal.GetReference(CollectionsMarshal.AsSpan(listReference))));
}
}
diff --git a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
index 3832028c2dd4a4..418a565dbd812e 100644
--- a/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
+++ b/src/libraries/System.Runtime.Numerics/src/System/Numerics/BigInteger.cs
@@ -384,7 +384,7 @@ public BigInteger(ReadOnlySpan value, bool isUnsigned = false, bool isBigE
// The bytes parameter is in little-endian byte order.
// We can just copy the bytes directly into the uint array.
- value.Slice(0, wholeUInt32Count * 4).CopyTo(MemoryMarshal.AsBytes(val));
+ value.Slice(0, wholeUInt32Count * 4).CopyTo(MemoryMarshal.AsBytes(val.AsSpan()));
}
// In both of the above cases on big-endian architecture, we need to perform
diff --git a/src/libraries/System.Runtime.Serialization.Json/tests/DataContractJsonSerializer.cs b/src/libraries/System.Runtime.Serialization.Json/tests/DataContractJsonSerializer.cs
index 94cc7459d0b9e2..5de787c502988b 100644
--- a/src/libraries/System.Runtime.Serialization.Json/tests/DataContractJsonSerializer.cs
+++ b/src/libraries/System.Runtime.Serialization.Json/tests/DataContractJsonSerializer.cs
@@ -2599,7 +2599,7 @@ public static void DCJS_VerifyDateTimeForFormatStringDCJsonSerSetting()
Assert.Equal(value, actual);
}
- [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))]
[ActiveIssue("https://github.com/dotnet/runtime/issues/60462", TestPlatforms.iOS | TestPlatforms.tvOS)]
public static void DCJS_VerifyDateTimeForFormatStringDCJsonSerSettings()
{
@@ -2660,7 +2660,7 @@ public static void DCJS_VerifyDateTimeForFormatStringDCJsonSerSettings()
Assert.True(actual6 == dateTime);
}
- [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))]
public static void DCJS_VerifyDateTimeForDateTimeFormat()
{
var jsonTypes = new JsonTypes();
diff --git a/src/libraries/System.Runtime.Serialization.Schema/tests/System/Runtime/Serialization/Schema/RoundTripTest.cs b/src/libraries/System.Runtime.Serialization.Schema/tests/System/Runtime/Serialization/Schema/RoundTripTest.cs
index 8e26f7a0704b8a..f1a852b3a510ab 100644
--- a/src/libraries/System.Runtime.Serialization.Schema/tests/System/Runtime/Serialization/Schema/RoundTripTest.cs
+++ b/src/libraries/System.Runtime.Serialization.Schema/tests/System/Runtime/Serialization/Schema/RoundTripTest.cs
@@ -82,7 +82,6 @@ public void RountTripTest()
[Fact]
[ActiveIssue("https://github.com/dotnet/runtime/issues/73961", typeof(PlatformDetection), nameof(PlatformDetection.IsBuiltWithAggressiveTrimming), nameof(PlatformDetection.IsBrowser))]
- [ActiveIssue("https://github.com/dotnet/runtime/issues/95981", typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
public void RoundTripXmlSerializableWithSpecialAttributesTest()
{
XsdDataContractExporter exporter = new XsdDataContractExporter();
diff --git a/src/libraries/System.Runtime.Serialization.Xml/tests/DataContractSerializer.cs b/src/libraries/System.Runtime.Serialization.Xml/tests/DataContractSerializer.cs
index e63c47b8207027..34550236dda8e0 100644
--- a/src/libraries/System.Runtime.Serialization.Xml/tests/DataContractSerializer.cs
+++ b/src/libraries/System.Runtime.Serialization.Xml/tests/DataContractSerializer.cs
@@ -3542,7 +3542,7 @@ public static void DCS_BasicPerSerializerRoundTripAndCompare_SampleTypes()
}
- [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Fact]
public static void DCS_BasicPerSerializerRoundTripAndCompare_DataSet()
{
diff --git a/src/libraries/System.Runtime/System.Runtime.sln b/src/libraries/System.Runtime/System.Runtime.sln
index 3bb4e42789fd32..4af0484c2667c7 100644
--- a/src/libraries/System.Runtime/System.Runtime.sln
+++ b/src/libraries/System.Runtime/System.Runtime.sln
@@ -77,8 +77,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Dynamic.Runtime.Test
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Globalization.CalendarsWithConfigSwitch.Tests", "tests\System.Globalization.Calendars.Tests\CalendarTestWithConfigSwitch\System.Globalization.CalendarsWithConfigSwitch.Tests.csproj", "{B73090B8-20CB-4586-A586-B7F37C1A06FF}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Globalization.Calendars.Hybrid.WASM.Tests", "tests\System.Globalization.Calendars.Tests\Hybrid\System.Globalization.Calendars.Hybrid.WASM.Tests.csproj", "{4C1F2761-857C-40A4-8CDD-7139380DA4D7}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Globalization.Calendars.IOS.Tests", "tests\System.Globalization.Calendars.Tests\Hybrid\System.Globalization.Calendars.IOS.Tests.csproj", "{70441C80-1F14-42F9-8225-A891E3C9A82A}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Globalization.Calendars.Tests", "tests\System.Globalization.Calendars.Tests\System.Globalization.Calendars.Tests.csproj", "{EA3FA657-060E-43A3-9CF0-45FCC8E7E5B6}"
@@ -91,8 +89,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Globalization.Extens
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AppleHybrid.Tests", "tests\System.Globalization.Tests\Hybrid\AppleHybrid.Tests.csproj", "{988AECC5-6EB4-48AB-9467-3FB63619631B}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Globalization.Hybrid.WASM.Tests", "tests\System.Globalization.Tests\Hybrid\System.Globalization.Hybrid.WASM.Tests.csproj", "{C5F86889-E147-4424-9165-D2DF453741F2}"
-EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "System.Globalization.IOS.Tests", "tests\System.Globalization.Tests\Hybrid\System.Globalization.IOS.Tests.csproj", "{67D9B289-AA6D-4FD8-A99D-F8651A51BE7E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IcuAppLocal.Tests", "tests\System.Globalization.Tests\IcuAppLocal\IcuAppLocal.Tests.csproj", "{B6F2F0D5-9275-4F00-A2C3-2048AF0CAF12}"
diff --git a/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/libraries/System.Runtime/ref/System.Runtime.cs
index 0d79bc4c54e23b..da44791d9607cf 100644
--- a/src/libraries/System.Runtime/ref/System.Runtime.cs
+++ b/src/libraries/System.Runtime/ref/System.Runtime.cs
@@ -5819,8 +5819,11 @@ public static partial class StringNormalizationExtensions
{
public static bool IsNormalized(this string strInput) { throw null; }
public static bool IsNormalized(this string strInput, System.Text.NormalizationForm normalizationForm) { throw null; }
+ public static bool IsNormalized(this ReadOnlySpan source, System.Text.NormalizationForm normalizationForm = System.Text.NormalizationForm.FormC) { throw null; }
public static string Normalize(this string strInput) { throw null; }
+ public static bool TryNormalize(this ReadOnlySpan source, Span destination, out int charsWritten, System.Text.NormalizationForm normalizationForm = System.Text.NormalizationForm.FormC) { throw null; }
public static string Normalize(this string strInput, System.Text.NormalizationForm normalizationForm) { throw null; }
+ public static int GetNormalizedLength(this ReadOnlySpan source, System.Text.NormalizationForm normalizationForm = System.Text.NormalizationForm.FormC) { throw null; }
}
[System.FlagsAttribute]
public enum StringSplitOptions
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Calendars.Tests/Hybrid/System.Globalization.Calendars.Hybrid.WASM.Tests.csproj b/src/libraries/System.Runtime/tests/System.Globalization.Calendars.Tests/Hybrid/System.Globalization.Calendars.Hybrid.WASM.Tests.csproj
deleted file mode 100644
index 9c93e65d291eb8..00000000000000
--- a/src/libraries/System.Runtime/tests/System.Globalization.Calendars.Tests/Hybrid/System.Globalization.Calendars.Hybrid.WASM.Tests.csproj
+++ /dev/null
@@ -1,116 +0,0 @@
-
-
- $(NetCoreAppCurrent)-browser
- true
- true
- true
-
-
-
- WasmTestOnChrome
- $(TestArchiveRoot)browseronly/
- $(TestArchiveTestsRoot)$(OSPlatformConfig)/
- $(DefineConstants);TARGET_BROWSER
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Calendars.Tests/System/Globalization/CalendarTestBase.cs b/src/libraries/System.Runtime/tests/System.Globalization.Calendars.Tests/System/Globalization/CalendarTestBase.cs
index 061d07108e526b..62e1b360069875 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Calendars.Tests/System/Globalization/CalendarTestBase.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Calendars.Tests/System/Globalization/CalendarTestBase.cs
@@ -429,8 +429,8 @@ public void GetEra_Invalid_ThrowsArgumentOutOfRangeException()
Calendar calendar = Calendar;
Assert.All(DateTime_TestData(calendar), dt =>
{
- // JapaneseCalendar throws on ICU, but not on NLS or in HybridGlobalization on Browser
- if ((calendar is JapaneseCalendar && (PlatformDetection.IsNlsGlobalization || PlatformDetection.IsHybridGlobalizationOnBrowser)) || calendar is HebrewCalendar || calendar is TaiwanLunisolarCalendar || calendar is JapaneseLunisolarCalendar)
+ // JapaneseCalendar throws on ICU, but not on NLS
+ if ((calendar is JapaneseCalendar && PlatformDetection.IsNlsGlobalization) || calendar is HebrewCalendar || calendar is TaiwanLunisolarCalendar || calendar is JapaneseLunisolarCalendar)
{
calendar.GetEra(dt);
}
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Extensions.Tests/Normalization/NormalizationAll.cs b/src/libraries/System.Runtime/tests/System.Globalization.Extensions.Tests/Normalization/NormalizationAll.cs
index 703988c1cffb39..bedd07baf4637a 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Extensions.Tests/Normalization/NormalizationAll.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Extensions.Tests/Normalization/NormalizationAll.cs
@@ -93,6 +93,18 @@ private static void VerifyConformanceInvariant(NormalizationForm normForm, strin
string normalized4 = c4.Normalize(normForm);
string normalized5 = c5.Normalize(normForm);
+ Span normalizedSpan1 = new char[normalized1.Length];
+ Span normalizedSpan2 = new char[normalized2.Length];
+ Span normalizedSpan3 = new char[normalized3.Length];
+ Span normalizedSpan4 = new char[normalized4.Length];
+ Span normalizedSpan5 = new char[normalized5.Length];
+
+ Assert.True(c1.AsSpan().TryNormalize(normalizedSpan1, out int charsWritten1, normForm), $"'{c1}' is not normalized with form {normForm}");
+ Assert.True(c2.AsSpan().TryNormalize(normalizedSpan2, out int charsWritten2, normForm), $"'{c2}' is not normalized with form {normForm}");
+ Assert.True(c3.AsSpan().TryNormalize(normalizedSpan3, out int charsWritten3, normForm), $"'{c3}' is not normalized with form {normForm}");
+ Assert.True(c4.AsSpan().TryNormalize(normalizedSpan4, out int charsWritten4, normForm), $"'{c4}' is not normalized with form {normForm}");
+ Assert.True(c5.AsSpan().TryNormalize(normalizedSpan5, out int charsWritten5, normForm), $"'{c5}' is not normalized with form {normForm}");
+
switch (normForm)
{
case NormalizationForm.FormC:
@@ -101,15 +113,24 @@ private static void VerifyConformanceInvariant(NormalizationForm normForm, strin
AssertEqualsForm(c2, normalized2);
AssertEqualsForm(c2, normalized3);
+ AssertEqualsForm(c2, normalizedSpan1.Slice(0, charsWritten1).ToString());
+ AssertEqualsForm(c2, normalizedSpan2.Slice(0, charsWritten2).ToString());
+ AssertEqualsForm(c2, normalizedSpan3.Slice(0, charsWritten3).ToString());
+
// c4 == NFC(c4) == NFC(c5)
AssertEqualsForm(c4, normalized4);
AssertEqualsForm(c4, normalized5);
+ AssertEqualsForm(c4, normalizedSpan4.Slice(0, charsWritten4).ToString());
+ AssertEqualsForm(c4, normalizedSpan5.Slice(0, charsWritten5).ToString());
+
// c2 is normalized to Form C
Assert.True(c2.IsNormalized(normForm), $"'{c2}' is marked as not normalized with form {normForm}");
+ Assert.True(c2.AsSpan().IsNormalized(normForm), $"'{c2}' span is marked as not normalized with form {normForm}");
// c4 is normalized to Form C
Assert.True(c4.IsNormalized(normForm), $"'{c4}' is marked as not normalized with form {normForm}");
+ Assert.True(c4.AsSpan().IsNormalized(normForm), $"'{c4}' span is marked as not normalized with form {normForm}");
break;
case NormalizationForm.FormD:
@@ -118,15 +139,24 @@ private static void VerifyConformanceInvariant(NormalizationForm normForm, strin
AssertEqualsForm(c3, normalized2);
AssertEqualsForm(c3, normalized3);
+ AssertEqualsForm(c3, normalizedSpan1.Slice(0, charsWritten1).ToString());
+ AssertEqualsForm(c3, normalizedSpan2.Slice(0, charsWritten2).ToString());
+ AssertEqualsForm(c3, normalizedSpan3.Slice(0, charsWritten3).ToString());
+
// c5 == NFD(c4) == NFD(c5)
AssertEqualsForm(c5, normalized4);
AssertEqualsForm(c5, normalized5);
+ AssertEqualsForm(c5, normalizedSpan4.Slice(0, charsWritten4).ToString());
+ AssertEqualsForm(c5, normalizedSpan5.Slice(0, charsWritten5).ToString());
+
// c3 is normalized to Form D
Assert.True(c3.IsNormalized(normForm), $"'{c3}' is marked as not normalized with form {normForm}");
+ Assert.True(c3.AsSpan().IsNormalized(normForm), $"'{c3}' span is marked as not normalized with form {normForm}");
// c5 is normalized to Form D
Assert.True(c5.IsNormalized(normForm), $"'{c5}' is marked as not normalized with form {normForm}");
+ Assert.True(c5.AsSpan().IsNormalized(normForm), $"'{c5}' span is marked as not normalized with form {normForm}");
break;
case NormalizationForm.FormKC:
@@ -138,8 +168,15 @@ private static void VerifyConformanceInvariant(NormalizationForm normForm, strin
AssertEqualsForm(c4, normalized4);
AssertEqualsForm(c4, normalized5);
+ AssertEqualsForm(c4, normalizedSpan1.Slice(0, charsWritten1).ToString());
+ AssertEqualsForm(c4, normalizedSpan2.Slice(0, charsWritten2).ToString());
+ AssertEqualsForm(c4, normalizedSpan3.Slice(0, charsWritten3).ToString());
+ AssertEqualsForm(c4, normalizedSpan4.Slice(0, charsWritten4).ToString());
+ AssertEqualsForm(c4, normalizedSpan5.Slice(0, charsWritten5).ToString());
+
// c4 is normalized to Form KC
Assert.True(c4.IsNormalized(normForm), $"'{c4}' is marked as not normalized with form {normForm}");
+ Assert.True(c4.AsSpan().IsNormalized(normForm), $"'{c4}' span is marked as not normalized with form {normForm}");
break;
case NormalizationForm.FormKD:
@@ -151,8 +188,15 @@ private static void VerifyConformanceInvariant(NormalizationForm normForm, strin
AssertEqualsForm(c5, normalized4);
AssertEqualsForm(c5, normalized5);
+ AssertEqualsForm(c5, normalizedSpan1.Slice(0, charsWritten1).ToString());
+ AssertEqualsForm(c5, normalizedSpan2.Slice(0, charsWritten2).ToString());
+ AssertEqualsForm(c5, normalizedSpan3.Slice(0, charsWritten3).ToString());
+ AssertEqualsForm(c5, normalizedSpan4.Slice(0, charsWritten4).ToString());
+ AssertEqualsForm(c5, normalizedSpan5.Slice(0, charsWritten5).ToString());
+
// c5 is normalized to Form KD
Assert.True(c5.IsNormalized(normForm), $"'{c5}' is marked as not normalized with form {normForm}");
+ Assert.True(c5.AsSpan().IsNormalized(normForm), $"'{c5}' span is marked as not normalized with form {normForm}");
break;
}
}
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Extensions.Tests/Normalization/StringNormalizationTests.cs b/src/libraries/System.Runtime/tests/System.Globalization.Extensions.Tests/Normalization/StringNormalizationTests.cs
index 1b70a79b6ae6de..bba0ddb088d462 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Extensions.Tests/Normalization/StringNormalizationTests.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Extensions.Tests/Normalization/StringNormalizationTests.cs
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
using System;
+using System.Linq;
using System.Text;
using Xunit;
using System.Collections.Generic;
@@ -21,16 +22,23 @@ public void IsNormalized(string value, NormalizationForm normalizationForm, bool
if (normalizationForm == NormalizationForm.FormC)
{
Assert.Equal(expected, value.IsNormalized());
+ Assert.Equal(expected, value.AsSpan().IsNormalized());
}
Assert.Equal(expected, value.IsNormalized(normalizationForm));
+ Assert.Equal(expected, value.AsSpan().IsNormalized(normalizationForm));
}
[Fact]
public void IsNormalized_Invalid()
{
Assert.Throws(() => "\uFB01".IsNormalized((NormalizationForm)10));
- AssertExtensions.Throws("strInput", () => "\uFFFE".IsNormalized()); // Invalid codepoint
- AssertExtensions.Throws("strInput", () => "\uD800\uD800".IsNormalized()); // Invalid surrogate pair
+ Assert.Throws(() => "\uFB01".AsSpan().IsNormalized((NormalizationForm)10));
+
+ AssertExtensions.Throws("source", () => "\uFFFE".IsNormalized()); // Invalid codepoint
+ AssertExtensions.Throws("source", () => "\uFFFE".AsSpan().IsNormalized()); // Invalid codepoint
+
+ AssertExtensions.Throws("source", () => "\uD800\uD800".IsNormalized()); // Invalid surrogate pair
+ AssertExtensions.Throws("source", () => "\uD800\uD800".AsSpan().IsNormalized()); // Invalid surrogate pair
}
[Fact]
@@ -63,20 +71,61 @@ public static IEnumerable NormalizeTestData()
[MemberData(nameof(NormalizeTestData))]
public void Normalize(string value, NormalizationForm normalizationForm, string expected)
{
+ Span destination = new char[expected.Length + 1]; // NLS sometimes need extra character in the buffer mostly if need to insert the null terminator
+ int charsWritten;
+
if (normalizationForm == NormalizationForm.FormC)
{
Assert.Equal(expected, value.Normalize());
+
+ Assert.True(value.AsSpan().TryNormalize(destination, out charsWritten));
+ Assert.Equal(expected, destination.Slice(0, charsWritten).ToString());
+
+ if (PlatformDetection.IsNlsGlobalization)
+ {
+ // NLS return estimated normalized length that is enough to hold the result but doesn't return the exact length
+ Assert.True(expected.Length <= value.GetNormalizedLength(), $"Expected: {expected.Length}, Actual: {value.GetNormalizedLength()}");
+ }
+ else
+ {
+ // ICU returns the exact normalized length
+ Assert.Equal(expected.Length, value.AsSpan().GetNormalizedLength());
+ }
}
+
Assert.Equal(expected, value.Normalize(normalizationForm));
+
+ if (expected.Length > 0)
+ {
+ Assert.False(value.AsSpan().TryNormalize(destination.Slice(0, expected.Length - 1), out charsWritten, normalizationForm), $"Trying to normalize '{value}' to a buffer of length {expected.Length - 1} succeeded!");
+ }
+
+ Assert.True(value.AsSpan().TryNormalize(destination, out charsWritten, normalizationForm), $"Failed to normalize '{value}' to a buffer of length {destination.Length}");
+ Assert.Equal(expected, destination.Slice(0, charsWritten).ToString());
+ if (PlatformDetection.IsNlsGlobalization)
+ {
+ // NLS return estimated normalized length that is enough to hold the result but doesn't return the exact length
+ Assert.True(expected.Length <= value.AsSpan().GetNormalizedLength(normalizationForm), $"Expected: {expected.Length}, Actual: {value.AsSpan().GetNormalizedLength(normalizationForm)}");
+ }
+ else
+ {
+ // ICU returns the exact normalized length
+ Assert.Equal(expected.Length, value.AsSpan().GetNormalizedLength(normalizationForm));
+ }
}
[Fact]
public void Normalize_Invalid()
{
+ char[] destination = new char[100];
Assert.Throws(() => "\uFB01".Normalize((NormalizationForm)7));
+ Assert.Throws(() => "\uFB01".AsSpan().TryNormalize(destination.AsSpan(), out int charsWritten, (NormalizationForm)7));
AssertExtensions.Throws("strInput", () => "\uFFFE".Normalize()); // Invalid codepoint
+ AssertExtensions.Throws("source", () => "\uFFFE".AsSpan().TryNormalize(destination.AsSpan(), out int charsWritten)); // Invalid codepoint
+
AssertExtensions.Throws("strInput", () => "\uD800\uD800".Normalize()); // Invalid surrogate pair
+ AssertExtensions.Throws("source", () => "\uD800\uD800".AsSpan().TryNormalize(destination, out int charsWritten)); // Invalid surrogate pair
}
[Fact]
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.Compare.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.Compare.cs
index fd20fa33ffbdc7..c3e5fd0e586a81 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.Compare.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.Compare.cs
@@ -15,20 +15,15 @@ public class CompareInfoCompareTests : CompareInfoTestsBase
public static IEnumerable Compare_Kana_TestData()
{
- // HybridGlobalization does not support IgnoreWidth
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser)
- {
- CompareOptions ignoreKanaIgnoreWidthIgnoreCase = CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase;
- yield return new object[] { s_invariantCompare, "\u3070\u3073\u3076\u3079\u307C", "\u30D0\u30D3\u3076\u30D9\uFF8E\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, 0 };
- yield return new object[] { s_invariantCompare, "\u30D0\u30D3\u3076\u30D9\uFF8E\uFF9E", "\u3070\u3073\uFF8C\uFF9E\uFF8D\uFF9E\u307C", ignoreKanaIgnoreWidthIgnoreCase, 0 };
- yield return new object[] { s_invariantCompare, "\u3060", "\uFF80\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, 0 };
- yield return new object[] { s_invariantCompare, "\u30C7\u30BF\u30D9\u30B9", "\uFF83\uFF9E\uFF80\uFF8D\uFF9E\uFF7D", ignoreKanaIgnoreWidthIgnoreCase, 0 };
- yield return new object[] { s_invariantCompare, "\u30C7", "\uFF83\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, 0 };
- yield return new object[] { s_invariantCompare, "\u30C7\u30BF", "\uFF83\uFF9E\uFF80", ignoreKanaIgnoreWidthIgnoreCase, 0 };
- yield return new object[] { s_invariantCompare, "\u30C7\u30BF\u30D9", "\uFF83\uFF9E\uFF80\uFF8D\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, 0 };
- yield return new object[] { s_invariantCompare, "\u3067\u30FC\u305F\u3079\u30FC\u3059", "\uFF83\uFF9E\uFF70\uFF80\uFF8D\uFF9E\uFF70\uFF7D", ignoreKanaIgnoreWidthIgnoreCase, 0 };
- }
-
+ CompareOptions ignoreKanaIgnoreWidthIgnoreCase = CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase;
+ yield return new object[] { s_invariantCompare, "\u3070\u3073\u3076\u3079\u307C", "\u30D0\u30D3\u3076\u30D9\uFF8E\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, 0 };
+ yield return new object[] { s_invariantCompare, "\u30D0\u30D3\u3076\u30D9\uFF8E\uFF9E", "\u3070\u3073\uFF8C\uFF9E\uFF8D\uFF9E\u307C", ignoreKanaIgnoreWidthIgnoreCase, 0 };
+ yield return new object[] { s_invariantCompare, "\u3060", "\uFF80\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, 0 };
+ yield return new object[] { s_invariantCompare, "\u30C7\u30BF\u30D9\u30B9", "\uFF83\uFF9E\uFF80\uFF8D\uFF9E\uFF7D", ignoreKanaIgnoreWidthIgnoreCase, 0 };
+ yield return new object[] { s_invariantCompare, "\u30C7", "\uFF83\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, 0 };
+ yield return new object[] { s_invariantCompare, "\u30C7\u30BF", "\uFF83\uFF9E\uFF80", ignoreKanaIgnoreWidthIgnoreCase, 0 };
+ yield return new object[] { s_invariantCompare, "\u30C7\u30BF\u30D9", "\uFF83\uFF9E\uFF80\uFF8D\uFF9E", ignoreKanaIgnoreWidthIgnoreCase, 0 };
+ yield return new object[] { s_invariantCompare, "\u3067\u30FC\u305F\u3079\u30FC\u3059", "\uFF83\uFF9E\uFF70\uFF80\uFF8D\uFF9E\uFF70\uFF7D", ignoreKanaIgnoreWidthIgnoreCase, 0 };
yield return new object[] { s_invariantCompare, "\u3070\u3073\u3076\u3079\u307C", "\u30D0\u30D3\u3076\u30D9\uFF8E\uFF9E", CompareOptions.None, s_expectedHiraganaToKatakanaCompare };
yield return new object[] { s_invariantCompare, "\u3060", "\uFF80\uFF9E", CompareOptions.None, s_expectedHiraganaToKatakanaCompare };
@@ -43,12 +38,6 @@ public static IEnumerable Compare_Kana_TestData()
public static IEnumerable Compare_TestData()
{
- // PlatformDetection.IsHybridGlobalizationOnBrowser does not support IgnoreNonSpace alone, it needs to be with IgnoreKanaType
- CompareOptions validIgnoreNonSpaceOption =
- PlatformDetection.IsHybridGlobalizationOnBrowser
- ? CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreKanaType
- : CompareOptions.IgnoreNonSpace;
-
#region Numeric ordering
if (PlatformDetection.IsNumericComparisonSupported)
{
@@ -84,7 +73,7 @@ public static IEnumerable Compare_TestData()
yield return new object[] { s_invariantCompare, "A01", "a1", CompareOptions.NumericOrdering, isNls ? -1 : 1 }; // ICU treats 01 == 1
// With diacritics
- yield return new object[] { s_invariantCompare, "1\u00E102", "1a02", CompareOptions.NumericOrdering | validIgnoreNonSpaceOption, 0 };
+ yield return new object[] { s_invariantCompare, "1\u00E102", "1a02", CompareOptions.NumericOrdering | CompareOptions.IgnoreNonSpace, 0 };
yield return new object[] { s_invariantCompare, "\u00E11", "a2", CompareOptions.NumericOrdering, -1 }; // Numerical differences have higher precedence
yield return new object[] { s_invariantCompare, "\u00E101", "a1", CompareOptions.NumericOrdering, isNls ? -1 : 1 }; // ICU treats 01 == 1
@@ -93,30 +82,21 @@ public static IEnumerable Compare_TestData()
}
#endregion
- // PlatformDetection.IsHybridGlobalizationOnBrowser does not support IgnoreKanaType alone, it needs to be e.g. with IgnoreCase
- CompareOptions validIgnoreKanaTypeOption = PlatformDetection.IsHybridGlobalizationOnBrowser ?
- CompareOptions.IgnoreKanaType | CompareOptions.IgnoreCase :
- CompareOptions.IgnoreKanaType;
- yield return new object[] { s_invariantCompare, "\u3042", "\u30A2", validIgnoreKanaTypeOption, 0 };
- yield return new object[] { s_invariantCompare, "\u304D\u3083", "\u30AD\u30E3", validIgnoreKanaTypeOption, 0 };
- yield return new object[] { s_invariantCompare, "\u304D\u3083", "\u30AD\u3083", validIgnoreKanaTypeOption, 0 };
- yield return new object[] { s_invariantCompare, "\u304D \u3083", "\u30AD\u3083", validIgnoreKanaTypeOption, -1 };
- yield return new object[] { s_invariantCompare, "\u3044", "I", validIgnoreKanaTypeOption, 1 };
- yield return new object[] { s_invariantCompare, "\u3070\u3073\u3076\u3079\u307C", "\u30D0\u30D3\u30D6\u30D9\u30DC", validIgnoreKanaTypeOption, 0 };
- yield return new object[] { s_invariantCompare, "\u3070\u3073\u3076\u3079\u307C", "\u30D0\u30D3\u3076\u30D9\u30DC", validIgnoreKanaTypeOption, 0 };
- yield return new object[] { s_invariantCompare, "\u3060", "\u305F", validIgnoreKanaTypeOption, 1 };
- yield return new object[] { s_invariantCompare, "\u3060", "\u30C0", validIgnoreKanaTypeOption, 0 };
- yield return new object[] { s_invariantCompare, "\u68EE\u9D0E\u5916", "\u68EE\u9DD7\u5916", validIgnoreKanaTypeOption, -1 };
- yield return new object[] { s_invariantCompare, "\u2019", "'", validIgnoreKanaTypeOption, 1 };
- yield return new object[] { s_invariantCompare, "", "'", validIgnoreKanaTypeOption, -1 };
+ yield return new object[] { s_invariantCompare, "\u3042", "\u30A2", CompareOptions.IgnoreKanaType, 0 };
+ yield return new object[] { s_invariantCompare, "\u304D\u3083", "\u30AD\u30E3", CompareOptions.IgnoreKanaType, 0 };
+ yield return new object[] { s_invariantCompare, "\u304D\u3083", "\u30AD\u3083", CompareOptions.IgnoreKanaType, 0 };
+ yield return new object[] { s_invariantCompare, "\u304D \u3083", "\u30AD\u3083", CompareOptions.IgnoreKanaType, -1 };
+ yield return new object[] { s_invariantCompare, "\u3044", "I", CompareOptions.IgnoreKanaType, 1 };
+ yield return new object[] { s_invariantCompare, "\u3070\u3073\u3076\u3079\u307C", "\u30D0\u30D3\u30D6\u30D9\u30DC", CompareOptions.IgnoreKanaType, 0 };
+ yield return new object[] { s_invariantCompare, "\u3070\u3073\u3076\u3079\u307C", "\u30D0\u30D3\u3076\u30D9\u30DC", CompareOptions.IgnoreKanaType, 0 };
+ yield return new object[] { s_invariantCompare, "\u3060", "\u305F", CompareOptions.IgnoreKanaType, 1 };
+ yield return new object[] { s_invariantCompare, "\u3060", "\u30C0", CompareOptions.IgnoreKanaType, 0 };
+ yield return new object[] { s_invariantCompare, "\u68EE\u9D0E\u5916", "\u68EE\u9DD7\u5916", CompareOptions.IgnoreKanaType, -1 };
+ yield return new object[] { s_invariantCompare, "\u2019", "'", CompareOptions.IgnoreKanaType, 1 };
+ yield return new object[] { s_invariantCompare, "", "'", CompareOptions.IgnoreKanaType, -1 };
yield return new object[] { s_invariantCompare, "\u30FC", "\uFF70", CompareOptions.IgnoreKanaType | CompareOptions.IgnoreCase, 0 };
- // PlatformDetection.IsHybridGlobalizationOnBrowser does not support IgnoreWidth
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser)
- {
- yield return new object[] { s_invariantCompare, "\u3042", "\uFF71", CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase, 0 };
- yield return new object[] { s_invariantCompare, "'\u3000'", "' '", CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase, PlatformDetection.IsHybridGlobalizationOnApplePlatform ? 1 : 0 };
- }
-
+ yield return new object[] { s_invariantCompare, "\u3042", "\uFF71", CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase, 0 };
+ yield return new object[] { s_invariantCompare, "'\u3000'", "' '", CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase, PlatformDetection.IsHybridGlobalizationOnApplePlatform ? 1 : 0 };
yield return new object[] { s_invariantCompare, "\u6FA4", "\u6CA2", CompareOptions.None, 1 };
yield return new object[] { s_invariantCompare, "\u3070\u3073\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\uFF8E\uFF9E", CompareOptions.None, -1 };
yield return new object[] { s_invariantCompare, "\u3070\u30DC\uFF8C\uFF9E\uFF8D\uFF9E\u307C", "\uFF8E\uFF9E", CompareOptions.None, -1 };
@@ -138,25 +118,21 @@ public static IEnumerable Compare_TestData()
yield return new object[] { s_invariantCompare, "\u30FC", "\u2010", CompareOptions.None, 1 };
yield return new object[] { s_invariantCompare, "\u68EE\u9DD7\u5916", "\u68EE\u9DD7\u5916", CompareOptions.IgnoreCase, 0 };
yield return new object[] { s_invariantCompare, "a", "A", CompareOptions.IgnoreCase, 0 };
- // PlatformDetection.IsHybridGlobalizationOnBrowser does not support IgnoreWidth
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser)
- {
- yield return new object[] { s_invariantCompare, "a", "\uFF41", CompareOptions.IgnoreWidth, 0 };
- yield return new object[] { s_invariantCompare, "ABCDE", "\uFF21\uFF22\uFF23\uFF24\uFF25", CompareOptions.IgnoreWidth, 0 };
- yield return new object[] { s_invariantCompare, "ABCDE", "\uFF21\uFF22\uFF23D\uFF25", CompareOptions.IgnoreWidth, 0 };
- yield return new object[] { s_invariantCompare, "ABCDE", "a\uFF22\uFF23D\uFF25", CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase, 0 };
- yield return new object[] { s_invariantCompare, "ABCDE", "\uFF41\uFF42\uFF23D\uFF25", CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase, 0 };
- yield return new object[] { s_invariantCompare, "ABCDE", "\uFF43D", CompareOptions.IgnoreWidth, -1 };
- yield return new object[] { s_invariantCompare, "ABCDE", "c", CompareOptions.IgnoreWidth, -1 };
- yield return new object[] { s_invariantCompare, "\u30BF", "\uFF80", CompareOptions.IgnoreWidth, 0 };
- yield return new object[] { s_invariantCompare, "0", "\uFF10", CompareOptions.IgnoreWidth, 0 };
- yield return new object[] { s_invariantCompare, "10", "1\uFF10", CompareOptions.IgnoreWidth, 0 };
- yield return new object[] { s_invariantCompare, "\uFF1B", ";", CompareOptions.IgnoreWidth, 0 };
- yield return new object[] { s_invariantCompare, "\uFF08", "(", CompareOptions.IgnoreWidth, 0 };
- yield return new object[] { s_invariantCompare, "/", "\uFF0F", CompareOptions.IgnoreWidth, 0 };
- yield return new object[] { s_invariantCompare, "'", "\uFF07", CompareOptions.IgnoreWidth, 0 };
- yield return new object[] { s_invariantCompare, "\"", "\uFF02", CompareOptions.IgnoreWidth, 0 };
- }
+ yield return new object[] { s_invariantCompare, "a", "\uFF41", CompareOptions.IgnoreWidth, 0 };
+ yield return new object[] { s_invariantCompare, "ABCDE", "\uFF21\uFF22\uFF23\uFF24\uFF25", CompareOptions.IgnoreWidth, 0 };
+ yield return new object[] { s_invariantCompare, "ABCDE", "\uFF21\uFF22\uFF23D\uFF25", CompareOptions.IgnoreWidth, 0 };
+ yield return new object[] { s_invariantCompare, "ABCDE", "a\uFF22\uFF23D\uFF25", CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase, 0 };
+ yield return new object[] { s_invariantCompare, "ABCDE", "\uFF41\uFF42\uFF23D\uFF25", CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase, 0 };
+ yield return new object[] { s_invariantCompare, "ABCDE", "\uFF43D", CompareOptions.IgnoreWidth, -1 };
+ yield return new object[] { s_invariantCompare, "ABCDE", "c", CompareOptions.IgnoreWidth, -1 };
+ yield return new object[] { s_invariantCompare, "\u30BF", "\uFF80", CompareOptions.IgnoreWidth, 0 };
+ yield return new object[] { s_invariantCompare, "0", "\uFF10", CompareOptions.IgnoreWidth, 0 };
+ yield return new object[] { s_invariantCompare, "10", "1\uFF10", CompareOptions.IgnoreWidth, 0 };
+ yield return new object[] { s_invariantCompare, "\uFF1B", ";", CompareOptions.IgnoreWidth, 0 };
+ yield return new object[] { s_invariantCompare, "\uFF08", "(", CompareOptions.IgnoreWidth, 0 };
+ yield return new object[] { s_invariantCompare, "/", "\uFF0F", CompareOptions.IgnoreWidth, 0 };
+ yield return new object[] { s_invariantCompare, "'", "\uFF07", CompareOptions.IgnoreWidth, 0 };
+ yield return new object[] { s_invariantCompare, "\"", "\uFF02", CompareOptions.IgnoreWidth, 0 };
yield return new object[] { s_invariantCompare, "\u3042", "\u30A1", CompareOptions.None, PlatformDetection.IsHybridGlobalizationOnApplePlatform ? 1 : s_expectedHiraganaToKatakanaCompare };
yield return new object[] { s_invariantCompare, "\u3042", "\u30A2", CompareOptions.None, s_expectedHiraganaToKatakanaCompare };
yield return new object[] { s_invariantCompare, "\u3042", "\uFF71", CompareOptions.None, s_expectedHiraganaToKatakanaCompare };
@@ -247,7 +223,7 @@ public static IEnumerable Compare_TestData()
yield return new object[] { s_invariantCompare, "\u00C0", "a\u0300", CompareOptions.Ordinal, 1 };
yield return new object[] { s_invariantCompare, "\u00C0", "a\u0300", CompareOptions.OrdinalIgnoreCase, 1 };
yield return new object[] { s_invariantCompare, "FooBar", "Foo\u0400Bar", CompareOptions.Ordinal, -1 };
- yield return new object[] { s_invariantCompare, "FooBA\u0300R", "FooB\u00C0R", validIgnoreNonSpaceOption, 0 };
+ yield return new object[] { s_invariantCompare, "FooBA\u0300R", "FooB\u00C0R", CompareOptions.IgnoreNonSpace, 0 };
// In HybridGlobalization on Apple platforms IgnoreSymbols is not supported
if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
@@ -268,11 +244,11 @@ public static IEnumerable Compare_TestData()
yield return new object[] { s_invariantCompare, "", "", CompareOptions.None, 0 };
yield return new object[] { s_invariantCompare, new string('a', 5555), new string('a', 5555), CompareOptions.None, 0 };
- yield return new object[] { s_invariantCompare, "foobar", "FooB\u00C0R", supportedIgnoreCaseIgnoreNonSpaceOptions, 0 };
- yield return new object[] { s_invariantCompare, "foobar", "FooB\u00C0R", validIgnoreNonSpaceOption, -1 };
+ yield return new object[] { s_invariantCompare, "foobar", "FooB\u00C0R", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, 0 };
+ yield return new object[] { s_invariantCompare, "foobar", "FooB\u00C0R", CompareOptions.IgnoreNonSpace, -1 };
- yield return new object[] { s_invariantCompare, "\uFF9E", "\u3099", validIgnoreNonSpaceOption, 0 };
- yield return new object[] { s_invariantCompare, "\uFF9E", "\u3099", CompareOptions.IgnoreCase, PlatformDetection.IsHybridGlobalizationOnBrowser ? 1 : 0 };
+ yield return new object[] { s_invariantCompare, "\uFF9E", "\u3099", CompareOptions.IgnoreNonSpace, 0 };
+ yield return new object[] { s_invariantCompare, "\uFF9E", "\u3099", CompareOptions.IgnoreCase, 0 };
yield return new object[] { s_invariantCompare, "\u20A9", "\uFFE6", CompareOptions.IgnoreCase, -1 };
yield return new object[] { s_invariantCompare, "\u20A9", "\uFFE6", CompareOptions.None, -1 };
@@ -281,21 +257,13 @@ public static IEnumerable Compare_TestData()
{
yield return new object[] { s_invariantCompare, "\u0021", "\uFF01", CompareOptions.IgnoreSymbols, 0 };
yield return new object[] { s_invariantCompare, "\uFF65", "\u30FB", CompareOptions.IgnoreSymbols, 0 };
- // some symbols e.g. currencies are not ignored correctly in HybridGlobalization
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser)
- {
- yield return new object[] { s_invariantCompare, "\u00A2", "\uFFE0", CompareOptions.IgnoreSymbols, 0 };
- yield return new object[] { s_invariantCompare, "$", "&", CompareOptions.IgnoreSymbols, 0 };
- }
+ yield return new object[] { s_invariantCompare, "\u00A2", "\uFFE0", CompareOptions.IgnoreSymbols, 0 };
+ yield return new object[] { s_invariantCompare, "$", "&", CompareOptions.IgnoreSymbols, 0 };
}
yield return new object[] { s_invariantCompare, "\u0021", "\uFF01", CompareOptions.None, -1 };
-
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser)
- {
- yield return new object[] { s_invariantCompare, "\u20A9", "\uFFE6", CompareOptions.IgnoreWidth, 0 };
- yield return new object[] { s_invariantCompare, "\u0021", "\uFF01", CompareOptions.IgnoreWidth, 0 };
- yield return new object[] { s_invariantCompare, "\uFF66", "\u30F2", CompareOptions.IgnoreWidth, 0 };
- }
+ yield return new object[] { s_invariantCompare, "\u20A9", "\uFFE6", CompareOptions.IgnoreWidth, 0 };
+ yield return new object[] { s_invariantCompare, "\u0021", "\uFF01", CompareOptions.IgnoreWidth, 0 };
+ yield return new object[] { s_invariantCompare, "\uFF66", "\u30F2", CompareOptions.IgnoreWidth, 0 };
// In HybridGlobalization mode on Apple platforms IgnoreSymbols is not supported
if(PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
@@ -304,16 +272,10 @@ public static IEnumerable Compare_TestData()
}
yield return new object[] { s_invariantCompare, "\uFF66", "\u30F2", CompareOptions.IgnoreCase, s_expectedHalfToFullFormsComparison };
- // in HybridGlobalization on Browser IgnoreNonSpace is not supported and comparison of katakana/hiragana equivalents with supportedIgnoreNonSpaceOption gives 0
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser)
- yield return new object[] { s_invariantCompare, "\uFF66", "\u30F2", CompareOptions.IgnoreNonSpace, s_expectedHalfToFullFormsComparison };
+ yield return new object[] { s_invariantCompare, "\uFF66", "\u30F2", CompareOptions.IgnoreNonSpace, s_expectedHalfToFullFormsComparison };
yield return new object[] { s_invariantCompare, "\uFF66", "\u30F2", CompareOptions.None, s_expectedHalfToFullFormsComparison };
-
- // in HybridGlobalization on Browser IgnoreKanaType is supported only for "ja"
- var kanaComparison = PlatformDetection.IsHybridGlobalizationOnBrowser ? s_japaneseCompare : s_invariantCompare;
-
- yield return new object[] { kanaComparison, "\u3060", "\u30C0", CompareOptions.IgnoreKanaType, 0 };
- yield return new object[] { kanaComparison, "c", "C", CompareOptions.IgnoreKanaType, -1 };
+ yield return new object[] { s_invariantCompare, "\u3060", "\u30C0", CompareOptions.IgnoreKanaType, 0 };
+ yield return new object[] { s_invariantCompare, "c", "C", CompareOptions.IgnoreKanaType, -1 };
yield return new object[] { s_invariantCompare, "\u3060", "\u30C0", CompareOptions.IgnoreCase, PlatformDetection.IsHybridGlobalizationOnApplePlatform ? 1 : s_expectedHiraganaToKatakanaCompare };
@@ -324,12 +286,12 @@ public static IEnumerable Compare_TestData()
yield return new object[] { s_invariantCompare, "\u30CF", "\u30D0", CompareOptions.IgnoreCase, -1 };
yield return new object[] { s_invariantCompare, "\u30CF", "\u30D1", CompareOptions.IgnoreCase, -1 };
yield return new object[] { s_invariantCompare, "\u30D0", "\u30D1", CompareOptions.IgnoreCase, -1 };
- yield return new object[] { s_invariantCompare, "\u306F", "\u3070", validIgnoreNonSpaceOption, 0 };
- yield return new object[] { s_invariantCompare, "\u306F", "\u3071", validIgnoreNonSpaceOption, 0 };
- yield return new object[] { s_invariantCompare, "\u3070", "\u3071", validIgnoreNonSpaceOption, 0 };
- yield return new object[] { s_invariantCompare, "\u30CF", "\u30D0", validIgnoreNonSpaceOption, 0 };
- yield return new object[] { s_invariantCompare, "\u30CF", "\u30D1", validIgnoreNonSpaceOption, 0 };
- yield return new object[] { s_invariantCompare, "\u30D0", "\u30D1", validIgnoreNonSpaceOption, 0 };
+ yield return new object[] { s_invariantCompare, "\u306F", "\u3070", CompareOptions.IgnoreNonSpace, 0 };
+ yield return new object[] { s_invariantCompare, "\u306F", "\u3071", CompareOptions.IgnoreNonSpace, 0 };
+ yield return new object[] { s_invariantCompare, "\u3070", "\u3071", CompareOptions.IgnoreNonSpace, 0 };
+ yield return new object[] { s_invariantCompare, "\u30CF", "\u30D0", CompareOptions.IgnoreNonSpace, 0 };
+ yield return new object[] { s_invariantCompare, "\u30CF", "\u30D1", CompareOptions.IgnoreNonSpace, 0 };
+ yield return new object[] { s_invariantCompare, "\u30D0", "\u30D1", CompareOptions.IgnoreNonSpace, 0 };
// Spanish
yield return new object[] { new CultureInfo("es-ES").CompareInfo, "llegar", "lugar", CompareOptions.None, -1 };
@@ -337,10 +299,7 @@ public static IEnumerable Compare_TestData()
// Misc differences between platforms
bool useNls = PlatformDetection.IsNlsGlobalization;
- var japaneseCmp = PlatformDetection.IsHybridGlobalizationOnBrowser ?
- CompareOptions.IgnoreKanaType | CompareOptions.IgnoreCase :
- CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase;
-
+ var japaneseCmp = CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase;
yield return new object[] { s_invariantCompare, "\u3042", "\u30A1", japaneseCmp, useNls || PlatformDetection.IsHybridGlobalizationOnApplePlatform ? 1: 0 };
yield return new object[] { s_invariantCompare, "'\u3000'", "''", japaneseCmp, useNls ? 1 : -1 };
@@ -376,7 +335,7 @@ public void CompareWithUnassignedChars()
{
int result = PlatformDetection.IsNlsGlobalization ? 0 : -1;
Compare(s_invariantCompare, "FooBar", "Foo\uFFFFBar", CompareOptions.None, result);
- Compare(s_invariantCompare, "FooBar", "Foo\uFFFFBar", supportedIgnoreNonSpaceOption, result);
+ Compare(s_invariantCompare, "FooBar", "Foo\uFFFFBar", CompareOptions.IgnoreNonSpace, result);
}
[ConditionalTheory(nameof(IsNotWindowsKanaRegressedVersion))]
@@ -622,22 +581,7 @@ public void TestIgnoreKanaAndWidthCases()
public static IEnumerable Compare_HiraganaAndKatakana_TestData()
{
- CompareOptions[] optionsPositive = PlatformDetection.IsHybridGlobalizationOnBrowser ?
- new[] {
- CompareOptions.None,
- CompareOptions.IgnoreCase,
- CompareOptions.IgnoreSymbols,
- CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase,
- CompareOptions.IgnoreKanaType | CompareOptions.IgnoreSymbols,
- CompareOptions.IgnoreKanaType | CompareOptions.IgnoreCase,
- CompareOptions.IgnoreKanaType | CompareOptions.IgnoreNonSpace,
- CompareOptions.IgnoreKanaType | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase,
- CompareOptions.IgnoreKanaType | CompareOptions.IgnoreCase | CompareOptions.IgnoreSymbols,
- CompareOptions.IgnoreKanaType | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace,
- CompareOptions.IgnoreKanaType | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase,
- CompareOptions.Ordinal,
- CompareOptions.OrdinalIgnoreCase,
- } : PlatformDetection.IsHybridGlobalizationOnApplePlatform ?
+ CompareOptions[] data = PlatformDetection.IsHybridGlobalizationOnApplePlatform ?
new[] {
CompareOptions.None,
CompareOptions.IgnoreCase,
@@ -675,45 +619,21 @@ public static IEnumerable Compare_HiraganaAndKatakana_TestData()
CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreNonSpace,
CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace,
};
- CompareOptions[] optionsNegative = PlatformDetection.IsHybridGlobalizationOnBrowser ?
- new[] {
- CompareOptions.IgnoreNonSpace,
- CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase,
- CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace,
- CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase,
- CompareOptions.IgnoreWidth,
- CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase,
- CompareOptions.IgnoreWidth | CompareOptions.IgnoreNonSpace,
- CompareOptions.IgnoreWidth | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase,
- CompareOptions.IgnoreWidth | CompareOptions.IgnoreSymbols,
- CompareOptions.IgnoreWidth | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase,
- CompareOptions.IgnoreWidth | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace,
- CompareOptions.IgnoreWidth | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase,
- CompareOptions.IgnoreKanaType,
- CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth,
- CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase,
- CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreNonSpace,
- CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase,
- CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreSymbols,
- CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreCase,
- CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace,
- CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreSymbols | CompareOptions.IgnoreNonSpace | CompareOptions.IgnoreCase,
- } :
+ CompareOptions[] optionsNegative =
Array.Empty();
if (PlatformDetection.IsNumericComparisonSupported)
{
// Adding NumericOrdering does not affect whether an option set is supported or not
- optionsPositive = optionsPositive.Concat(from opt in optionsPositive where opt != CompareOptions.Ordinal && opt != CompareOptions.OrdinalIgnoreCase select opt | CompareOptions.NumericOrdering).ToArray();
- optionsNegative = optionsNegative.Concat(from opt in optionsNegative where opt != CompareOptions.Ordinal && opt != CompareOptions.OrdinalIgnoreCase select opt | CompareOptions.NumericOrdering).ToArray();
+ data = data.Concat(from opt in data where opt != CompareOptions.Ordinal && opt != CompareOptions.OrdinalIgnoreCase select opt | CompareOptions.NumericOrdering).ToArray();
}
- yield return new object[] { optionsPositive, optionsNegative };
+ yield return new object[] { data };
}
[Theory]
[MemberData(nameof(Compare_HiraganaAndKatakana_TestData))]
- public void TestHiraganaAndKatakana(CompareOptions[] optionsPositive, CompareOptions[] optionsNegative)
+ public void TestHiraganaAndKatakana(CompareOptions[] data)
{
const char hiraganaStart = '\u3041';
const char hiraganaEnd = '\u3096';
@@ -747,7 +667,7 @@ public void TestHiraganaAndKatakana(CompareOptions[] optionsPositive, CompareOpt
{
hiraganaList.Add(c);
}
- foreach (var option in optionsPositive)
+ foreach (var option in data)
{
for (int i = 0; i < hiraganaList.Count; i++)
{
@@ -766,13 +686,6 @@ public void TestHiraganaAndKatakana(CompareOptions[] optionsPositive, CompareOpt
}
}
}
- foreach (var option in optionsNegative)
- {
- char hiraganaChar1 = hiraganaList[0];
- char katakanaChar1 = (char)(hiraganaChar1 + hiraganaToKatakanaOffset);
- Assert.Throws(
- () => s_invariantCompare.Compare(new string(hiraganaChar1, 1), new string(katakanaChar1, 1), option));
- }
}
}
}
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.IndexOf.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.IndexOf.cs
index 2750a648bb80d9..77a972222a4a27 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.IndexOf.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.IndexOf.cs
@@ -33,7 +33,7 @@ public static IEnumerable IndexOf_TestData()
yield return new object[] { s_invariantCompare, "foobardzsdzs", "rddzs", 0, 12, CompareOptions.Ordinal, -1, 0 };
// Slovak
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
+ if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
yield return new object[] { s_slovakCompare, "ch", "h", 0, 2, CompareOptions.None, -1, 0 };
// Android has its own ICU, which doesn't work well with slovak
@@ -66,23 +66,16 @@ public static IEnumerable IndexOf_TestData()
yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", 0, 9, CompareOptions.IgnoreCase, 8, 1 };
yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", 0, 9, CompareOptions.OrdinalIgnoreCase, -1, 0 };
yield return new object[] { s_invariantCompare, "FooBar", "Foo\u0400Bar", 0, 6, CompareOptions.Ordinal, -1, 0 };
- yield return new object[] { s_invariantCompare, "TestFooBA\u0300R", "FooB\u00C0R", 0, 11, supportedIgnoreNonSpaceOption, 4, 7 };
+ yield return new object[] { s_invariantCompare, "TestFooBA\u0300R", "FooB\u00C0R", 0, 11, CompareOptions.IgnoreNonSpace, 4, 7 };
yield return new object[] { s_invariantCompare, "o\u0308", "o", 0, 2, CompareOptions.None, -1, 0 };
- if (PlatformDetection.IsHybridGlobalizationOnBrowser)
- {
- yield return new object[] { s_invariantCompare, "\r\n", "\n", 0, 2, CompareOptions.None, -1, 0 };
- }
- else
- {
- yield return new object[] { s_invariantCompare, "\r\n", "\n", 0, 2, CompareOptions.None, 1, 1 };
- }
+ yield return new object[] { s_invariantCompare, "\r\n", "\n", 0, 2, CompareOptions.None, 1, 1 };
// Weightless characters
yield return new object[] { s_invariantCompare, "", "\u200d", 0, 0, CompareOptions.None, 0, 0 };
yield return new object[] { s_invariantCompare, "hello", "\u200d", 1, 3, CompareOptions.IgnoreCase, 1, 0 };
// Ignore symbols
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
+ if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
yield return new object[] { s_invariantCompare, "More Test's", "Tests", 0, 11, CompareOptions.IgnoreSymbols, 5, 6 };
yield return new object[] { s_invariantCompare, "More Test's", "Tests", 0, 11, CompareOptions.None, -1, 0 };
yield return new object[] { s_invariantCompare, "cbabababdbaba", "ab", 0, 13, CompareOptions.None, 2, 2 };
@@ -126,16 +119,12 @@ public static IEnumerable IndexOf_TestData()
yield return new object[] { s_currentCompare, "\u0131", "\u0131", 0, 1, CompareOptions.Ordinal, 0, 1 };
yield return new object[] { s_currentCompare, "\u0130", "\u0131", 0, 1, CompareOptions.Ordinal, -1, 0 };
yield return new object[] { s_currentCompare, "\u0131", "\u0130", 0, 1, CompareOptions.Ordinal, -1, 0 };
-
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser)
- {
- yield return new object[] { s_invariantCompare, "est", "est", 0, 2, CompareOptions.IgnoreCase, 0, 2 };
- yield return new object[] { s_invariantCompare, " est", "est", 0, 3, CompareOptions.IgnoreCase, 1, 2 };
- yield return new object[] { s_invariantCompare, " st", "st", 0, 2, CompareOptions.IgnoreCase, 1, 1 };
- yield return new object[] { s_invariantCompare, "est", "est", 0, 3, CompareOptions.IgnoreCase, 0, 3 };
- yield return new object[] { s_invariantCompare, " est", "est", 0, 4, CompareOptions.IgnoreCase, 1, 3 };
- yield return new object[] { s_invariantCompare, " st", "st", 0, 3, CompareOptions.IgnoreCase, 1, 2 };
- }
+ yield return new object[] { s_invariantCompare, "est", "est", 0, 2, CompareOptions.IgnoreCase, 0, 2 };
+ yield return new object[] { s_invariantCompare, " est", "est", 0, 3, CompareOptions.IgnoreCase, 1, 2 };
+ yield return new object[] { s_invariantCompare, " st", "st", 0, 2, CompareOptions.IgnoreCase, 1, 1 };
+ yield return new object[] { s_invariantCompare, "est", "est", 0, 3, CompareOptions.IgnoreCase, 0, 3 };
+ yield return new object[] { s_invariantCompare, " est", "est", 0, 4, CompareOptions.IgnoreCase, 1, 3 };
+ yield return new object[] { s_invariantCompare, " st", "st", 0, 3, CompareOptions.IgnoreCase, 1, 2 };
// Platform differences
if (PlatformDetection.IsNlsGlobalization)
@@ -148,18 +137,18 @@ public static IEnumerable IndexOf_TestData()
}
// Inputs where matched length does not equal value string length
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
+ if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
- yield return new object[] { s_germanCompare, "abc Strasse Strasse xyz", "stra\u00DFe", 0, 23, supportedIgnoreCaseIgnoreNonSpaceOptions, 4, 7 };
- yield return new object[] { s_germanCompare, "abc stra\u00DFe stra\u00DFe xyz", "Strasse", 0, 21, supportedIgnoreCaseIgnoreNonSpaceOptions, 4, 6 };
+ yield return new object[] { s_germanCompare, "abc Strasse Strasse xyz", "stra\u00DFe", 0, 23, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, 4, 7 };
+ yield return new object[] { s_germanCompare, "abc stra\u00DFe stra\u00DFe xyz", "Strasse", 0, 21, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, 4, 6 };
if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
- yield return new object[] { s_invariantCompare, "abcdzxyz", "\u01F3", 0, 8, supportedIgnoreNonSpaceOption, 3, 2 };
- yield return new object[] { s_invariantCompare, "abc\u01F3xyz", "dz", 0, 7, supportedIgnoreNonSpaceOption, 3, 1 };
+ yield return new object[] { s_invariantCompare, "abcdzxyz", "\u01F3", 0, 8, CompareOptions.IgnoreNonSpace, 3, 2 };
+ yield return new object[] { s_invariantCompare, "abc\u01F3xyz", "dz", 0, 7, CompareOptions.IgnoreNonSpace, 3, 1 };
}
}
- yield return new object[] { s_germanCompare, "abc Strasse Strasse xyz", "xtra\u00DFe", 0, 23, supportedIgnoreCaseIgnoreNonSpaceOptions, -1, 0 };
- yield return new object[] { s_germanCompare, "abc stra\u00DFe stra\u00DFe xyz", "Xtrasse", 0, 21, supportedIgnoreCaseIgnoreNonSpaceOptions, -1, 0 };
+ yield return new object[] { s_germanCompare, "abc Strasse Strasse xyz", "xtra\u00DFe", 0, 23, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, -1, 0 };
+ yield return new object[] { s_germanCompare, "abc stra\u00DFe stra\u00DFe xyz", "Xtrasse", 0, 21, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, -1, 0 };
}
public static IEnumerable IndexOf_Aesc_Ligature_TestData()
@@ -256,7 +245,7 @@ static void RunSpanIndexOfTest(CompareInfo compareInfo, ReadOnlySpan sourc
valueBoundedMemory.MakeReadonly();
Assert.Equal(expected, compareInfo.IndexOf(sourceBoundedMemory.Span, valueBoundedMemory.Span, options));
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
+ if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
Assert.Equal(expected, compareInfo.IndexOf(sourceBoundedMemory.Span, valueBoundedMemory.Span, options, out int actualMatchLength));
Assert.Equal(expectedMatchLength, actualMatchLength);
@@ -303,7 +292,7 @@ public void IndexOf_UnassignedUnicode()
bool useNls = PlatformDetection.IsNlsGlobalization;
int expectedMatchLength = (useNls) ? 6 : 0;
IndexOf_String(s_invariantCompare, "FooBar", "Foo\uFFFFBar", 0, 6, CompareOptions.None, useNls ? 0 : -1, expectedMatchLength);
- IndexOf_String(s_invariantCompare, "~FooBar", "Foo\uFFFFBar", 0, 7, supportedIgnoreNonSpaceOption, useNls ? 1 : -1, expectedMatchLength);
+ IndexOf_String(s_invariantCompare, "~FooBar", "Foo\uFFFFBar", 0, 7, CompareOptions.IgnoreNonSpace, useNls ? 1 : -1, expectedMatchLength);
}
[Fact]
@@ -353,7 +342,7 @@ public void IndexOf_Invalid()
AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's", 'c', 0, 2, CompareOptions.NumericOrdering));
AssertExtensions.Throws("options", () => s_invariantCompare.IndexOf("Test's".AsSpan(), "b".AsSpan(), CompareOptions.NumericOrdering));
- if (PlatformDetection.IsHybridGlobalizationOnBrowser || PlatformDetection.IsHybridGlobalizationOnApplePlatform)
+ if (PlatformDetection.IsHybridGlobalizationOnApplePlatform)
{
Assert.Throws(() => s_invariantCompare.IndexOf("Test's".AsSpan(), "b".AsSpan(), CompareOptions.StringSort, out _));
Assert.Throws(() => s_invariantCompare.IndexOf("Test's".AsSpan(), "b".AsSpan(), CompareOptions.NumericOrdering, out _));
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.IsPrefix.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.IsPrefix.cs
index 7dba521344e1c0..3fba71b155c171 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.IsPrefix.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.IsPrefix.cs
@@ -25,7 +25,7 @@ public static IEnumerable IsPrefix_TestData()
yield return new object[] { s_invariantCompare, "dzsdzsfoobar", "ddzsf", CompareOptions.Ordinal, false, 0 };
yield return new object[] { s_hungarianCompare, "dzsdzsfoobar", "ddzsf", CompareOptions.Ordinal, false, 0 };
yield return new object[] { s_invariantCompare, "dz", "d", CompareOptions.None, true, 1 };
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
+ if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
yield return new object[] { s_hungarianCompare, "dz", "d", CompareOptions.None, false, 0 };
yield return new object[] { s_hungarianCompare, "dz", "d", CompareOptions.Ordinal, true, 1 };
@@ -52,7 +52,7 @@ public static IEnumerable IsPrefix_TestData()
yield return new object[] { s_invariantCompare, "\u00C0nimal", "a\u0300", CompareOptions.Ordinal, false, 0 };
yield return new object[] { s_invariantCompare, "\u00C0nimal", "a\u0300", CompareOptions.OrdinalIgnoreCase, false, 0 };
yield return new object[] { s_invariantCompare, "FooBar", "Foo\u0400Bar", CompareOptions.Ordinal, false, 0 };
- yield return new object[] { s_invariantCompare, "FooBA\u0300R", "FooB\u00C0R", supportedIgnoreNonSpaceOption, true, 7 };
+ yield return new object[] { s_invariantCompare, "FooBA\u0300R", "FooB\u00C0R", CompareOptions.IgnoreNonSpace, true, 7 };
yield return new object[] { s_invariantCompare, "o\u0308", "o", CompareOptions.None, false, 0 };
yield return new object[] { s_invariantCompare, "o\u0308", "o", CompareOptions.Ordinal, true, 1 };
yield return new object[] { s_invariantCompare, "o\u0000\u0308", "o", CompareOptions.None, true, 1 };
@@ -72,19 +72,16 @@ public static IEnumerable IsPrefix_TestData()
yield return new object[] { s_invariantCompare, "\uD800\uD800", "\uD800\uD800", CompareOptions.None, true, 2 };
// Ignore symbols
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
+ if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
yield return new object[] { s_invariantCompare, "Test's can be interesting", "Tests", CompareOptions.IgnoreSymbols, true, 6 };
yield return new object[] { s_invariantCompare, "Test's can be interesting", "Tests", CompareOptions.None, false, 0 };
}
// Platform differences
- // in HybridGlobalization on Browser we use TextEncoder that is not supported for v8 and the manual decoding works like NLS
- bool behavesLikeNls = PlatformDetection.IsNlsGlobalization ||
- (PlatformDetection.IsHybridGlobalizationOnBrowser && !PlatformDetection.IsBrowserDomSupportedOrNodeJS);
- if (behavesLikeNls)
+ if (PlatformDetection.IsNlsGlobalization)
{
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
+ if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
yield return new object[] { s_hungarianCompare, "dzsdzsfoobar", "ddzsf", CompareOptions.None, true, 7 };
yield return new object[] { s_invariantCompare, "''Tests", "Tests", CompareOptions.IgnoreSymbols, true, 7 };
@@ -96,7 +93,7 @@ public static IEnumerable IsPrefix_TestData()
else
{
yield return new object[] { s_hungarianCompare, "dzsdzsfoobar", "ddzsf", CompareOptions.None, false, 0 };
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
+ if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
yield return new object[] { s_invariantCompare, "''Tests", "Tests", CompareOptions.IgnoreSymbols, false, 0 };
yield return new object[] { s_frenchCompare, "\u0153", "oe", CompareOptions.None, false, 0 };
if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
@@ -114,15 +111,15 @@ public static IEnumerable IsPrefix_TestData()
}
// Prefixes where matched length does not equal value string length
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
+ if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
- yield return new object[] { s_invariantCompare, "dzxyz", "\u01F3", supportedIgnoreNonSpaceOption, true, 2 };
- yield return new object[] { s_invariantCompare, "\u01F3xyz", "dz", supportedIgnoreNonSpaceOption, true, 1 };
- yield return new object[] { s_germanCompare, "Strasse xyz", "stra\u00DFe", supportedIgnoreCaseIgnoreNonSpaceOptions, true, 7 };
- yield return new object[] { s_germanCompare, "stra\u00DFe xyz", "Strasse", supportedIgnoreCaseIgnoreNonSpaceOptions, true, 6 };
+ yield return new object[] { s_invariantCompare, "dzxyz", "\u01F3", CompareOptions.IgnoreNonSpace, true, 2 };
+ yield return new object[] { s_invariantCompare, "\u01F3xyz", "dz", CompareOptions.IgnoreNonSpace, true, 1 };
+ yield return new object[] { s_germanCompare, "Strasse xyz", "stra\u00DFe", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, true, 7 };
+ yield return new object[] { s_germanCompare, "stra\u00DFe xyz", "Strasse", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, true, 6 };
}
- yield return new object[] { s_germanCompare, "Strasse xyz", "xtra\u00DFe", supportedIgnoreCaseIgnoreNonSpaceOptions, false, 0 };
- yield return new object[] { s_germanCompare, "stra\u00DFe xyz", "Xtrasse", supportedIgnoreCaseIgnoreNonSpaceOptions, false, 0 };
+ yield return new object[] { s_germanCompare, "Strasse xyz", "xtra\u00DFe", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, false, 0 };
+ yield return new object[] { s_germanCompare, "stra\u00DFe xyz", "Xtrasse", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, false, 0 };
}
[Theory]
@@ -151,7 +148,7 @@ public void IsPrefix(CompareInfo compareInfo, string source, string value, Compa
valueBoundedMemory.MakeReadonly();
Assert.Equal(expected, compareInfo.IsPrefix(sourceBoundedMemory.Span, valueBoundedMemory.Span, options));
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
+ if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
Assert.Equal(expected, compareInfo.IsPrefix(sourceBoundedMemory.Span, valueBoundedMemory.Span, options, out int actualMatchLength));
Assert.Equal(expectedMatchLength, actualMatchLength);
@@ -164,7 +161,7 @@ public void IsPrefix_UnassignedUnicode()
bool result = PlatformDetection.IsNlsGlobalization ? true : false;
int expectedMatchLength = (result) ? 6 : 0;
IsPrefix(s_invariantCompare, "FooBar", "Foo\uFFFFBar", CompareOptions.None, result, expectedMatchLength);
- IsPrefix(s_invariantCompare, "FooBar", "Foo\uFFFFBar", supportedIgnoreNonSpaceOption, result, expectedMatchLength);
+ IsPrefix(s_invariantCompare, "FooBar", "Foo\uFFFFBar", CompareOptions.IgnoreNonSpace, result, expectedMatchLength);
}
[Fact]
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.IsSuffix.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.IsSuffix.cs
index e2506d7fdd84b7..d545be88e67476 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.IsSuffix.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.IsSuffix.cs
@@ -25,12 +25,12 @@ public static IEnumerable IsSuffix_TestData()
yield return new object[] { s_invariantCompare, "foobardzsdzs", "rddzs", CompareOptions.None, false, 0 };
yield return new object[] { s_invariantCompare, "foobardzsdzs", "rddzs", CompareOptions.Ordinal, false, 0 };
yield return new object[] { s_invariantCompare, "dz", "z", CompareOptions.None, true, 1 };
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
+ if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
yield return new object[] { s_hungarianCompare, "dz", "z", CompareOptions.None, false, 0 };
yield return new object[] { s_hungarianCompare, "dz", "z", CompareOptions.Ordinal, true, 1 };
// Slovak
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
+ if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
yield return new object[] { s_slovakCompare, "ch", "h", CompareOptions.None, false, 0 };
yield return new object[] { s_slovakCompare, "velmi chora", "hora", CompareOptions.None, false, 0 };
@@ -59,7 +59,7 @@ public static IEnumerable IsSuffix_TestData()
yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", CompareOptions.Ordinal, false, 0 };
yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", CompareOptions.OrdinalIgnoreCase, false, 0 };
yield return new object[] { s_invariantCompare, "FooBar", "Foo\u0400Bar", CompareOptions.Ordinal, false, 0 };
- yield return new object[] { s_invariantCompare, "FooBA\u0300R", "FooB\u00C0R", supportedIgnoreNonSpaceOption, true, 7 };
+ yield return new object[] { s_invariantCompare, "FooBA\u0300R", "FooB\u00C0R", CompareOptions.IgnoreNonSpace, true, 7 };
yield return new object[] { s_invariantCompare, "o\u0308", "o", CompareOptions.None, false, 0 };
yield return new object[] { s_invariantCompare, "o\u0308", "o", CompareOptions.Ordinal, false, 0 };
yield return new object[] { s_invariantCompare, "o\u0308o", "o", CompareOptions.None, true, 1 };
@@ -80,7 +80,7 @@ public static IEnumerable IsSuffix_TestData()
yield return new object[] { s_invariantCompare, "\uD800\uD800", "\uD800\uD800", CompareOptions.None, true, 2 };
// Ignore symbols
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
+ if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
yield return new object[] { s_invariantCompare, "More Test's", "Tests", CompareOptions.IgnoreSymbols, true, 6 };
yield return new object[] { s_invariantCompare, "More Test's", "Tests", CompareOptions.None, false, 0 };
@@ -91,16 +91,10 @@ public static IEnumerable IsSuffix_TestData()
yield return new object[] { s_invariantCompare, "a\u0000b", "b\u0000b", CompareOptions.None, false, 0 };
// Platform differences
- // in HybridGlobalization on Browser we use TextEncoder that is not supported for v8 and the manual decoding works like NLS
- bool behavesLikeNls = PlatformDetection.IsNlsGlobalization ||
- (PlatformDetection.IsHybridGlobalizationOnBrowser && !PlatformDetection.IsBrowserDomSupportedOrNodeJS);
- if (behavesLikeNls)
+ if (PlatformDetection.IsNlsGlobalization)
{
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser)
- {
- yield return new object[] { s_hungarianCompare, "foobardzsdzs", "rddzs", CompareOptions.None, true, 7 };
- yield return new object[] { s_frenchCompare, "\u0153", "oe", CompareOptions.None, true, 1 };
- }
+ yield return new object[] { s_hungarianCompare, "foobardzsdzs", "rddzs", CompareOptions.None, true, 7 };
+ yield return new object[] { s_frenchCompare, "\u0153", "oe", CompareOptions.None, true, 1 };
yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uDC00", CompareOptions.None, true, 1 };
yield return new object[] { s_invariantCompare, "\uD800\uDC00", "\uDC00", CompareOptions.IgnoreCase, true, 1 };
} else
@@ -115,15 +109,15 @@ public static IEnumerable IsSuffix_TestData()
}
// Suffixes where matched length does not equal value string length
- yield return new object[] { s_germanCompare, "xyz Strasse", "xtra\u00DFe", supportedIgnoreCaseIgnoreNonSpaceOptions, false, 0 };
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
+ yield return new object[] { s_germanCompare, "xyz Strasse", "xtra\u00DFe", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, false, 0 };
+ if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
- yield return new object[] { s_invariantCompare, "xyzdz", "\u01F3", supportedIgnoreNonSpaceOption, true, 2 };
- yield return new object[] { s_invariantCompare, "xyz\u01F3", "dz", supportedIgnoreNonSpaceOption, true, 1 };
- yield return new object[] { s_germanCompare, "xyz stra\u00DFe", "Strasse", supportedIgnoreCaseIgnoreNonSpaceOptions, true, 6 };
- yield return new object[] { s_germanCompare, "xyz Strasse", "stra\u00DFe", supportedIgnoreCaseIgnoreNonSpaceOptions, true, 7 };
+ yield return new object[] { s_invariantCompare, "xyzdz", "\u01F3", CompareOptions.IgnoreNonSpace, true, 2 };
+ yield return new object[] { s_invariantCompare, "xyz\u01F3", "dz", CompareOptions.IgnoreNonSpace, true, 1 };
+ yield return new object[] { s_germanCompare, "xyz stra\u00DFe", "Strasse", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, true, 6 };
+ yield return new object[] { s_germanCompare, "xyz Strasse", "stra\u00DFe", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, true, 7 };
}
- yield return new object[] { s_germanCompare, "xyz stra\u00DFe", "Xtrasse", supportedIgnoreCaseIgnoreNonSpaceOptions, false, 0 };
+ yield return new object[] { s_germanCompare, "xyz stra\u00DFe", "Xtrasse", CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, false, 0 };
}
[Theory]
@@ -152,7 +146,7 @@ public void IsSuffix(CompareInfo compareInfo, string source, string value, Compa
valueBoundedMemory.MakeReadonly();
Assert.Equal(expected, compareInfo.IsSuffix(sourceBoundedMemory.Span, valueBoundedMemory.Span, options));
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
+ if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
Assert.Equal(expected, compareInfo.IsSuffix(sourceBoundedMemory.Span, valueBoundedMemory.Span, options, out int actualMatchLength));
Assert.Equal(expectedMatchLength, actualMatchLength);
@@ -166,7 +160,7 @@ public void IsSuffix_UnassignedUnicode()
int expectedMatchLength = (result) ? 6 : 0;
IsSuffix(s_invariantCompare, "FooBar", "Foo\uFFFFBar", CompareOptions.None, result, expectedMatchLength);
- IsSuffix(s_invariantCompare, "FooBar", "Foo\uFFFFBar", supportedIgnoreNonSpaceOption, result, expectedMatchLength);
+ IsSuffix(s_invariantCompare, "FooBar", "Foo\uFFFFBar", CompareOptions.IgnoreNonSpace, result, expectedMatchLength);
}
[Fact]
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.LastIndexOf.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.LastIndexOf.cs
index 380610e4412b27..da76d1c08810ee 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.LastIndexOf.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.LastIndexOf.cs
@@ -49,12 +49,10 @@ public static IEnumerable LastIndexOf_TestData()
// Slovak
yield return new object[] { s_slovakCompare, "ch", "h", 0, 1, CompareOptions.None, -1, 0 };
// Android has its own ICU, which doesn't work well with slovak
- if (!PlatformDetection.IsAndroid && !PlatformDetection.IsLinuxBionic && !PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
+ if (!PlatformDetection.IsAndroid && !PlatformDetection.IsLinuxBionic && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
yield return new object[] { s_slovakCompare, "hore chodit", "HO", 11, 12, CompareOptions.IgnoreCase, 0, 2 };
- }
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser)
- yield return new object[] { s_slovakCompare, "chh", "h", 2, 2, CompareOptions.None, 2, 1 };
+ }yield return new object[] { s_slovakCompare, "chh", "h", 2, 2, CompareOptions.None, 2, 1 };
// Turkish
// Android has its own ICU, which doesn't work well with tr
@@ -79,16 +77,9 @@ public static IEnumerable LastIndexOf_TestData()
yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", 8, 9, CompareOptions.OrdinalIgnoreCase, -1, 0 };
yield return new object[] { s_invariantCompare, "Exhibit \u00C0", "a\u0300", 8, 9, CompareOptions.Ordinal, -1, 0 };
yield return new object[] { s_invariantCompare, "FooBar", "Foo\u0400Bar", 5, 6, CompareOptions.Ordinal, -1, 0 };
- yield return new object[] { s_invariantCompare, "TestFooBA\u0300R", "FooB\u00C0R", 10, 11, supportedIgnoreNonSpaceOption, 4, 7 };
+ yield return new object[] { s_invariantCompare, "TestFooBA\u0300R", "FooB\u00C0R", 10, 11, CompareOptions.IgnoreNonSpace, 4, 7 };
yield return new object[] { s_invariantCompare, "o\u0308", "o", 1, 2, CompareOptions.None, -1, 0 };
- if (PlatformDetection.IsHybridGlobalizationOnBrowser)
- {
- yield return new object[] { s_invariantCompare, "\r\n", "\n", 1, 2, CompareOptions.None, -1, 0 };
- }
- else
- {
- yield return new object[] { s_invariantCompare, "\r\n", "\n", 1, 1, CompareOptions.None, 1, 1 };
- }
+ yield return new object[] { s_invariantCompare, "\r\n", "\n", 1, 1, CompareOptions.None, 1, 1 };
// Weightless characters
// NLS matches weightless characters at the end of the string
@@ -104,7 +95,7 @@ public static IEnumerable LastIndexOf_TestData()
yield return new object[] { s_invariantCompare, "AA\u200DA", "\u200d", 3, 4, CompareOptions.None, 4, 0};
// Ignore symbols
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
+ if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
yield return new object[] { s_invariantCompare, "More Test's", "Tests", 10, 11, CompareOptions.IgnoreSymbols, 5, 6 };
yield return new object[] { s_invariantCompare, "More Test's", "Tests", 10, 11, CompareOptions.None, -1, 0 };
yield return new object[] { s_invariantCompare, "cbabababdbaba", "ab", 12, 13, CompareOptions.None, 10, 2 };
@@ -120,15 +111,15 @@ public static IEnumerable LastIndexOf_TestData()
}
// Inputs where matched length does not equal value string length
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
+ if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
- yield return new object[] { s_germanCompare, "abc Strasse Strasse xyz", "stra\u00DFe", 22, 23, supportedIgnoreCaseIgnoreNonSpaceOptions, 12, 7 };
- yield return new object[] { s_germanCompare, "abc stra\u00DFe stra\u00DFe xyz", "Strasse", 20, 21, supportedIgnoreCaseIgnoreNonSpaceOptions, 11, 6 };
- yield return new object[] { s_invariantCompare, "abcdzxyz", "\u01F3", 7, 8, supportedIgnoreNonSpaceOption, 3, 2 };
- yield return new object[] { s_invariantCompare, "abc\u01F3xyz", "dz", 6, 7, supportedIgnoreNonSpaceOption, 3, 1 };
+ yield return new object[] { s_germanCompare, "abc Strasse Strasse xyz", "stra\u00DFe", 22, 23, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, 12, 7 };
+ yield return new object[] { s_germanCompare, "abc stra\u00DFe stra\u00DFe xyz", "Strasse", 20, 21, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, 11, 6 };
+ yield return new object[] { s_invariantCompare, "abcdzxyz", "\u01F3", 7, 8, CompareOptions.IgnoreNonSpace, 3, 2 };
+ yield return new object[] { s_invariantCompare, "abc\u01F3xyz", "dz", 6, 7, CompareOptions.IgnoreNonSpace, 3, 1 };
}
- yield return new object[] { s_germanCompare, "abc Strasse Strasse xyz", "xtra\u00DFe", 22, 23, supportedIgnoreCaseIgnoreNonSpaceOptions, -1, 0 };
- yield return new object[] { s_germanCompare, "abc stra\u00DFe stra\u00DFe xyz", "Xtrasse", 20, 21, supportedIgnoreCaseIgnoreNonSpaceOptions, -1, 0 };
+ yield return new object[] { s_germanCompare, "abc Strasse Strasse xyz", "xtra\u00DFe", 22, 23, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, -1, 0 };
+ yield return new object[] { s_germanCompare, "abc stra\u00DFe stra\u00DFe xyz", "Xtrasse", 20, 21, CompareOptions.IgnoreCase | CompareOptions.IgnoreNonSpace, -1, 0 };
}
public static IEnumerable LastIndexOf_Aesc_Ligature_TestData()
@@ -253,7 +244,7 @@ static void RunSpanLastIndexOfTest(CompareInfo compareInfo, ReadOnlySpan s
valueBoundedMemory.MakeReadonly();
Assert.Equal(expected, compareInfo.LastIndexOf(sourceBoundedMemory.Span, valueBoundedMemory.Span, options));
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser && PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
+ if (PlatformDetection.IsNotHybridGlobalizationOnApplePlatform)
{
Assert.Equal(expected, compareInfo.LastIndexOf(sourceBoundedMemory.Span, valueBoundedMemory.Span, options, out int actualMatchLength));
Assert.Equal(expectedMatchLength, actualMatchLength);
@@ -307,7 +298,7 @@ public void LastIndexOf_UnassignedUnicode()
bool useNls = PlatformDetection.IsNlsGlobalization;
int expectedMatchLength = (useNls) ? 6 : 0;
LastIndexOf_String(s_invariantCompare, "FooBar", "Foo\uFFFFBar", 5, 6, CompareOptions.None, useNls ? 0 : -1, expectedMatchLength);
- LastIndexOf_String(s_invariantCompare, "~FooBar", "Foo\uFFFFBar", 6, 7, supportedIgnoreNonSpaceOption, useNls ? 1 : -1, expectedMatchLength);
+ LastIndexOf_String(s_invariantCompare, "~FooBar", "Foo\uFFFFBar", 6, 7, CompareOptions.IgnoreNonSpace, useNls ? 1 : -1, expectedMatchLength);
}
[Fact]
@@ -357,7 +348,7 @@ public void LastIndexOf_Invalid()
AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", 'a', 0, 1, CompareOptions.NumericOrdering));
AssertExtensions.Throws("options", () => s_invariantCompare.LastIndexOf("Test's", "a".AsSpan(), CompareOptions.NumericOrdering));
- if (PlatformDetection.IsHybridGlobalizationOnBrowser || PlatformDetection.IsHybridGlobalizationOnApplePlatform)
+ if (PlatformDetection.IsHybridGlobalizationOnApplePlatform)
{
Assert.Throws(() => s_invariantCompare.LastIndexOf("Test's", "a".AsSpan(), CompareOptions.StringSort, out int matchLength));
Assert.Throws(() => s_invariantCompare.LastIndexOf("Test's", "a".AsSpan(), CompareOptions.NumericOrdering, out int matchLength));
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.SortKey.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.SortKey.cs
index 193b55baf47b5b..51533fa4552542 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.SortKey.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/CompareInfo/CompareInfoTests.SortKey.cs
@@ -272,14 +272,14 @@ public static IEnumerable SortKey_Kana_TestData()
yield return new object[] { s_invariantCompare, "\u3060", "\uFF80\uFF9E", CompareOptions.None, s_expectedHiraganaToKatakanaCompare };
}
- [ConditionalTheory(typeof(CompareInfoSortKeyTests), nameof(IsNotWindowsKanaRegressedVersionAndNotHybridGlobalizationOnWasm))]
+ [ConditionalTheory(typeof(CompareInfoSortKeyTests), nameof(IsNotWindowsKanaRegressedVersion))]
[MemberData(nameof(SortKey_Kana_TestData))]
public void SortKeyKanaTest(CompareInfo compareInfo, string string1, string string2, CompareOptions options, int expected)
{
SortKeyTest(compareInfo, string1, string2, options, expected);
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Theory]
[MemberData(nameof(SortKey_TestData))]
public void SortKeyTest(CompareInfo compareInfo, string string1, string string2, CompareOptions options, int expectedSign)
{
@@ -328,7 +328,7 @@ unsafe static void RunSpanSortKeyTest(CompareInfo compareInfo, ReadOnlySpan !PlatformDetection.IsWindows10Version1903OrGreater ||
PlatformDetection.IsIcuGlobalization ||
s_invariantCompare.Compare("\u3060", "\uFF80\uFF9E", CompareOptions.IgnoreKanaType | CompareOptions.IgnoreWidth | CompareOptions.IgnoreCase) == 0;
- protected static bool IsNotWindowsKanaRegressedVersionAndNotHybridGlobalizationOnWasm() => !PlatformDetection.IsHybridGlobalizationOnBrowser && IsNotWindowsKanaRegressedVersion();
-
public class CustomComparer : StringComparer
{
private readonly CompareInfo _compareInfo;
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/CultureInfo/CultureInfoCtor.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/CultureInfo/CultureInfoCtor.cs
index 9a9523784716ce..e5fd8c7fd0a123 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/CultureInfo/CultureInfoCtor.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/CultureInfo/CultureInfoCtor.cs
@@ -446,7 +446,7 @@ public void TestCreationWithTemporaryLCID(int lcid)
[InlineData("de-DE-u-co-phonebk-t-xx", "de-DE-t-xx", "de-DE-t-xx_phoneboo")]
[InlineData("de-DE-u-co-phonebk-t-xx-u-yy", "de-DE-t-xx-u-yy", "de-DE-t-xx-u-yy_phoneboo")]
[InlineData("de-DE", "de-DE", "de-DE")]
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsIcuGlobalization), nameof(PlatformDetection.IsNotHybridGlobalizationOnApplePlatform), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsIcuGlobalization), nameof(PlatformDetection.IsNotHybridGlobalizationOnApplePlatform))]
public void TestCreationWithMangledSortName(string cultureName, string expectedCultureName, string expectedSortName)
{
CultureInfo ci = CultureInfo.GetCultureInfo(cultureName);
@@ -461,7 +461,7 @@ public void TestCreationWithMangledSortName(string cultureName, string expectedC
[InlineData("qps-plocm", "qps-PLOCM")] // ICU normalize this name to "qps--plocm" which we normalize it back to "qps-plocm"
[InlineData("zh_CN", "zh_cn")]
[InlineData("km_KH", "km_kh")]
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsIcuGlobalization), nameof(PlatformDetection.IsNotHybridGlobalizationOnApplePlatform), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser), nameof(PlatformDetection.IsNotWindowsServerCore))]
+ [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsIcuGlobalization), nameof(PlatformDetection.IsNotHybridGlobalizationOnApplePlatform), nameof(PlatformDetection.IsNotWindowsServerCore))]
public void TestCreationWithICUNormalizedNames(string cultureName, string expectedCultureName)
{
CultureInfo ci = CultureInfo.GetCultureInfo(cultureName);
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoAMDesignator.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoAMDesignator.cs
index 927c88c5bcb4db..1e8a615d3c2663 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoAMDesignator.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoAMDesignator.cs
@@ -14,207 +14,6 @@ public void AMDesignator_GetInvariantInfo_ReturnsExpected()
Assert.Equal("AM", DateTimeFormatInfo.InvariantInfo.AMDesignator);
}
- public static IEnumerable AMDesignator_Get_TestData_HybridGlobalization()
- {
- // see the comments on the right to check the non-Hybrid result, if it differs
- yield return new object[] { "ar-SA", "ص" };
- yield return new object[] { "am-ET", "ጥዋት" };
- yield return new object[] { "bg-BG", "пр.об." };
- yield return new object[] { "bn-BD", "AM" };
- yield return new object[] { "bn-IN", "AM" };
- yield return new object[] { "ca-AD", "a.\u00A0m." };
- yield return new object[] { "ca-ES", "a.\u00A0m." };
- yield return new object[] { "cs-CZ", "dop." };
- yield return new object[] { "da-DK", "AM" };
- yield return new object[] { "de-AT", "AM" };
- yield return new object[] { "de-BE", "AM" };
- yield return new object[] { "de-CH", "AM" };
- yield return new object[] { "de-DE", "AM" };
- yield return new object[] { "de-IT", "AM" };
- yield return new object[] { "de-LI", "AM" };
- yield return new object[] { "de-LU", "AM" };
- yield return new object[] { "el-CY", "π.μ." };
- yield return new object[] { "el-GR", "π.μ." };
- yield return new object[] { "en-AE", "AM" };
- yield return new object[] { "en-AG", "am" };
- yield return new object[] { "en-AI", "am" };
- yield return new object[] { "en-AS", "AM" };
- yield return new object[] { "en-AT", "am" };
- yield return new object[] { "en-AU", "am" };
- yield return new object[] { "en-BB", "am" };
- yield return new object[] { "en-BE", "am" };
- yield return new object[] { "en-BI", "AM" };
- yield return new object[] { "en-BM", "am" };
- yield return new object[] { "en-BS", "am" };
- yield return new object[] { "en-BW", "am" };
- yield return new object[] { "en-BZ", "am" };
- yield return new object[] { "en-CA", "a.m." };
- yield return new object[] { "en-CC", "am" };
- yield return new object[] { "en-CH", "am" };
- yield return new object[] { "en-CK", "am" };
- yield return new object[] { "en-CM", "am" };
- yield return new object[] { "en-CX", "am" };
- yield return new object[] { "en-CY", "am" };
- yield return new object[] { "en-DE", "am" };
- yield return new object[] { "en-DK", "am" };
- yield return new object[] { "en-DM", "am" };
- yield return new object[] { "en-ER", "am" };
- yield return new object[] { "en-FI", "am" };
- yield return new object[] { "en-FJ", "am" };
- yield return new object[] { "en-FK", "am" };
- yield return new object[] { "en-FM", "am" };
- yield return new object[] { "en-GB", "am" };
- yield return new object[] { "en-GD", "am" };
- yield return new object[] { "en-GG", "am" };
- yield return new object[] { "en-GH", "am" };
- yield return new object[] { "en-GI", "am" };
- yield return new object[] { "en-GM", "am" };
- yield return new object[] { "en-GU", "AM" };
- yield return new object[] { "en-GY", "am" };
- yield return new object[] { "en-HK", "am" };
- yield return new object[] { "en-IE", "a.m." };
- yield return new object[] { "en-IL", "am" };
- yield return new object[] { "en-IM", "am" };
- yield return new object[] { "en-IN", "am" };
- yield return new object[] { "en-IO", "am" };
- yield return new object[] { "en-JE", "am" };
- yield return new object[] { "en-JM", "am" };
- yield return new object[] { "en-KE", "am" };
- yield return new object[] { "en-KI", "am" };
- yield return new object[] { "en-KN", "am" };
- yield return new object[] { "en-KY", "am" };
- yield return new object[] { "en-LC", "am" };
- yield return new object[] { "en-LR", "am" };
- yield return new object[] { "en-LS", "am" };
- yield return new object[] { "en-MG", "am" };
- yield return new object[] { "en-MH", "AM" };
- yield return new object[] { "en-MO", "am" };
- yield return new object[] { "en-MP", "AM" };
- yield return new object[] { "en-MS", "am" };
- yield return new object[] { "en-MT", "am" };
- yield return new object[] { "en-MU", "am" };
- yield return new object[] { "en-MW", "am" };
- yield return new object[] { "en-MY", "am" };
- yield return new object[] { "en-NA", "am" };
- yield return new object[] { "en-NF", "am" };
- yield return new object[] { "en-NG", "am" };
- yield return new object[] { "en-NL", "am" };
- yield return new object[] { "en-NR", "am" };
- yield return new object[] { "en-NU", "am" };
- yield return new object[] { "en-NZ", "am" };
- yield return new object[] { "en-PG", "am" };
- yield return new object[] { "en-PH", "AM" }; // am
- yield return new object[] { "en-PK", "am" };
- yield return new object[] { "en-PN", "am" };
- yield return new object[] { "en-PR", "AM" };
- yield return new object[] { "en-PW", "am" };
- yield return new object[] { "en-RW", "am" };
- yield return new object[] { "en-SB", "am" };
- yield return new object[] { "en-SC", "am" };
- yield return new object[] { "en-SD", "am" };
- yield return new object[] { "en-SE", "am" };
- yield return new object[] { "en-SG", "am" };
- yield return new object[] { "en-SH", "am" };
- yield return new object[] { "en-SI", "am" };
- yield return new object[] { "en-SL", "am" };
- yield return new object[] { "en-SS", "am" };
- yield return new object[] { "en-SX", "am" };
- yield return new object[] { "en-SZ", "am" };
- yield return new object[] { "en-TC", "am" };
- yield return new object[] { "en-TK", "am" };
- yield return new object[] { "en-TO", "am" };
- yield return new object[] { "en-TT", "am" };
- yield return new object[] { "en-TV", "am" };
- yield return new object[] { "en-TZ", "am" };
- yield return new object[] { "en-UG", "am" };
- yield return new object[] { "en-UM", "AM" };
- yield return new object[] { "en-US", "AM" };
- yield return new object[] { "en-VC", "am" };
- yield return new object[] { "en-VG", "am" };
- yield return new object[] { "en-VI", "AM" };
- yield return new object[] { "en-VU", "am" };
- yield return new object[] { "en-WS", "am" };
- yield return new object[] { "en-ZA", "am" };
- yield return new object[] { "en-ZM", "am" };
- yield return new object[] { "en-ZW", "am" };
- string latinAmericaSpanishAMDesignator = PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "a.\u00A0m." : "a.m.";
- yield return new object[] { "es-419", latinAmericaSpanishAMDesignator };
- yield return new object[] { "es-ES", "a.\u00A0m." };
- yield return new object[] { "es-MX", latinAmericaSpanishAMDesignator };
- yield return new object[] { "et-EE", "AM" };
- yield return new object[] { "fa-IR", "قبلازظهر" };
- yield return new object[] { "fi-FI", "ap." };
- yield return new object[] { "fil-PH", "AM" };
- yield return new object[] { "fr-BE", "AM" };
- yield return new object[] { "fr-CA", "a.m." };
- yield return new object[] { "fr-CH", "AM" };
- yield return new object[] { "fr-FR", "AM" };
- yield return new object[] { "gu-IN", "AM" };
- yield return new object[] { "he-IL", "לפנה״צ" };
- yield return new object[] { "hi-IN", "am" };
- yield return new object[] { "hr-BA", "AM" };
- yield return new object[] { "hr-HR", "AM" };
- yield return new object[] { "hu-HU", "de." };
- yield return new object[] { "id-ID", "AM" };
- yield return new object[] { "it-CH", "AM" };
- yield return new object[] { "it-IT", "AM" };
- yield return new object[] { "ja-JP", "午前" };
- yield return new object[] { "kn-IN", "ಪೂರ್ವಾಹ್ನ" };
- yield return new object[] { "ko-KR", "오전" };
- yield return new object[] { "lt-LT", "priešpiet" };
- yield return new object[] { "lv-LV", "priekšpusdienā" };
- yield return new object[] { "ml-IN", "AM" };
- yield return new object[] { "mr-IN", "AM" }; // म.पू.
- yield return new object[] { "ms-BN", "PG" };
- yield return new object[] { "ms-MY", "PG" };
- yield return new object[] { "ms-SG", "PG" };
- yield return new object[] { "nb-NO", "a.m." };
- yield return new object[] { "no", "a.m." };
- yield return new object[] { "no-NO", "a.m." };
- yield return new object[] { "nl-AW", "a.m." };
- yield return new object[] { "nl-BE", "a.m." };
- yield return new object[] { "nl-NL", "a.m." };
- yield return new object[] { "pl-PL", "AM" };
- yield return new object[] { "pt-BR", "AM" };
- yield return new object[] { "pt-PT", "da manhã" };
- yield return new object[] { "ro-RO", "a.m." };
- yield return new object[] { "ru-RU", "AM" };
- yield return new object[] { "sk-SK", "AM" };
- yield return new object[] { "sl-SI", "dop." };
- yield return new object[] { "sr-Cyrl-RS", "AM" }; // пре подне
- yield return new object[] { "sr-Latn-RS", "AM" }; // pre podne
- yield return new object[] { "sv-AX", "fm" };
- yield return new object[] { "sv-SE", "fm" };
- yield return new object[] { "sw-CD", "AM" };
- yield return new object[] { "sw-KE", "AM" };
- yield return new object[] { "sw-TZ", "AM" };
- yield return new object[] { "sw-UG", "AM" };
- string tamilAMDesignator = PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "முற்பகல்" : "AM"; // முற்பகல்
- yield return new object[] { "ta-IN", tamilAMDesignator };
- yield return new object[] { "ta-LK", tamilAMDesignator };
- yield return new object[] { "ta-MY", tamilAMDesignator };
- yield return new object[] { "ta-SG", tamilAMDesignator };
- yield return new object[] { "te-IN", "AM" };
- yield return new object[] { "th-TH", "ก่อนเที่ยง" };
- yield return new object[] { "tr-CY", "ÖÖ" };
- yield return new object[] { "tr-TR", "ÖÖ" };
- yield return new object[] { "uk-UA", "дп" };
- yield return new object[] { "vi-VN", "SA" };
- yield return new object[] { "zh-CN", "上午" };
- yield return new object[] { "zh-Hans-HK", "上午" };
- yield return new object[] { "zh-SG", "上午" };
- yield return new object[] { "zh-HK", "上午" };
- yield return new object[] { "zh-TW", "上午" };
- }
-
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
- [MemberData(nameof(AMDesignator_Get_TestData_HybridGlobalization))]
- public void AMDesignator_Get_ReturnsExpected_HybridGlobalization(string cultureName, string expected)
- {
- var format = new CultureInfo(cultureName).DateTimeFormat;
- Assert.True(expected == format.AMDesignator, $"Failed for culture: {cultureName}. Expected: {expected}, Actual: {format.AMDesignator}");
- }
-
[Theory]
[InlineData("")]
[InlineData("AA")]
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoAbbreviatedDayNames.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoAbbreviatedDayNames.cs
index da84d4bb51984f..1d94d9b32631a6 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoAbbreviatedDayNames.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoAbbreviatedDayNames.cs
@@ -34,63 +34,6 @@ public static IEnumerable AbbreviatedDayNames_Get_TestData_ICU()
yield return new object[] { CultureInfo.GetCultureInfo("fr-FR").DateTimeFormat, new string[] { "dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam." } };
}
- public static IEnumerable AbbreviatedDayNames_Get_TestData_HybridGlobalization()
- {
- // see the comments on the right to check the non-Hybrid result, if it differs
- yield return new object[] { "ar-SA", new string[] { "الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت" } };
- yield return new object[] { "am-ET", new string[] { "እሑድ", "ሰኞ", "ማክሰ", "ረቡዕ", "ሐሙስ", "ዓርብ", "ቅዳሜ" } };
- yield return new object[] { "bg-BG", new string[] { "нд", "пн", "вт", "ср", "чт", "пт", "сб" } };
- yield return new object[] { "bn-BD", new string[] { "রবি", "সোম", "মঙ্গল", "বুধ", "বৃহস্পতি", "শুক্র", "শনি" } };
- yield return new object[] { "ca-AD", new string[] { "dg.", "dl.", "dt.", "dc.", "dj.", "dv.", "ds." } };
- yield return new object[] { "cs-CZ", new string[] { "ne", "po", "út", "st", "čt", "pá", "so" } };
- yield return new object[] { "da-DK", new string[] { "søn.", "man.", "tirs.", "ons.", "tors.", "fre.", "lør." } };
- yield return new object[] { "de-DE", new string[] { "So", "Mo", "Di", "Mi", "Do", "Fr", "Sa" } };
- yield return new object[] { "el-GR", new string[] { "Κυρ", "Δευ", "Τρί", "Τετ", "Πέμ", "Παρ", "Σάβ" } };
- yield return new object[] { "en-CA", new string[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" } }; // should be with dots
- yield return new object[] { "en-US", new string[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" } };
- yield return new object[] { "es-419", new string[] { "dom", "lun", "mar", "mié", "jue", "vie", "sáb" } }; // should be with dots like all "es-*"
- yield return new object[] { "et-EE", new string[] { "P", "E", "T", "K", "N", "R", "L" } };
- yield return new object[] { "fa-IR", new string[] { "یکشنبه", "دوشنبه", "سهشنبه", "چهارشنبه", "پنجشنبه", "جمعه", "شنبه" } };
- yield return new object[] { "fi-FI", new string[] { "su", "ma", "ti", "ke", "to", "pe", "la" } };
- yield return new object[] { "fil-PH", new string[] { "Lin", "Lun", "Mar", "Miy", "Huw", "Biy", "Sab" } };
- yield return new object[] { "fr-BE", new string[] { "dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam." } };
- yield return new object[] { "gu-IN", new string[] { "રવિ", "સોમ", "મંગળ", "બુધ", "ગુરુ", "શુક્ર", "શનિ" } };
- yield return new object[] { "he-IL", new string[] { "יום א׳", "יום ב׳", "יום ג׳", "יום ד׳", "יום ה׳", "יום ו׳", "שבת" } };
- yield return new object[] { "hr-BA", new string[] { "ned", "pon", "uto", "sri", "čet", "pet", "sub" } };
- yield return new object[] { "hu-HU", new string[] { "V", "H", "K", "Sze", "Cs", "P", "Szo" } };
- yield return new object[] { "id-ID", new string[] { "Min", "Sen", "Sel", "Rab", "Kam", "Jum", "Sab" } };
- yield return new object[] { "it-CH", new string[] { "dom", "lun", "mar", "mer", "gio", "ven", "sab" } };
- yield return new object[] { "it-IT", new string[] { "dom", "lun", "mar", "mer", "gio", "ven", "sab" } };
- yield return new object[] { "ja-JP", new string[] { "日", "月", "火", "水", "木", "金", "土" } };
- yield return new object[] { "kn-IN", new string[] { "ಭಾನು", "ಸೋಮ", "ಮಂಗಳ", "ಬುಧ", "ಗುರು", "ಶುಕ್ರ", "ಶನಿ" } };
- yield return new object[] { "ko-KR", new string[] { "일", "월", "화", "수", "목", "금", "토" } };
- yield return new object[] { "lt-LT", new string[] { "sk", "pr", "an", "tr", "kt", "pn", "št" } };
- yield return new object[] { "lv-LV", new string[] { "Svētd.", "Pirmd.", "Otrd.", "Trešd.", "Ceturtd.", "Piektd.", "Sestd." } };
- yield return new object[] { "ml-IN", new string[] { "ഞായർ", "തിങ്കൾ", "ചൊവ്വ", "ബുധൻ", "വ്യാഴം", "വെള്ളി", "ശനി" } };
- yield return new object[] { "mr-IN", new string[] { "रवि", "सोम", "मंगळ", "बुध", "गुरु", "शुक्र", "शनि" } };
- yield return new object[] { "ms-BN", new string[] { "Ahd", "Isn", "Sel", "Rab", "Kha", "Jum", "Sab" } };
- yield return new object[] { "nb-NO", new string[] { "søn.", "man.", "tir.", "ons.", "tor.", "fre.", "lør." } };
- yield return new object[] { "nl-AW", new string[] { "zo", "ma", "di", "wo", "do", "vr", "za" } };
- yield return new object[] { "pl-PL", new string[] { "niedz.", "pon.", "wt.", "śr.", "czw.", "pt.", "sob." } };
- yield return new object[] { "pt-BR", new string[] { "dom.", "seg.", "ter.", "qua.", "qui.", "sex.", "sáb." } };
- yield return new object[] { "pt-PT", new string[] { "domingo", "segunda", "terça", "quarta", "quinta", "sexta", "sábado" } };
- yield return new object[] { "ro-RO", new string[] { "dum.", "lun.", "mar.", "mie.", "joi", "vin.", "sâm." } };
- yield return new object[] { "ru-RU", new string[] { "вс", "пн", "вт", "ср", "чт", "пт", "сб" } };
- yield return new object[] { "sk-SK", new string[] { "ne", "po", "ut", "st", "št", "pi", "so" } };
- yield return new object[] { "sl-SI", new string[] { "ned.", "pon.", "tor.", "sre.", "čet.", "pet.", "sob." } };
- yield return new object[] { "sr-Cyrl-RS", new string[] { "нед", "пон", "уто", "сре", "чет", "пет", "суб" } };
- yield return new object[] { "sr-Latn-RS", new string[] { "ned", "pon", "uto", "sre", "čet", "pet", "sub" } };
- yield return new object[] { "sv-AX", new string[] { "sön", "mån", "tis", "ons", "tors", "fre", "lör" } };
- yield return new object[] { "sv-SE", new string[] { "sön", "mån", "tis", "ons", "tors", "fre", "lör" } };
- yield return new object[] { "sw-CD", new string[] { "Jumapili", "Jumatatu", "Jumanne", "Jumatano", "Alhamisi", "Ijumaa", "Jumamosi" } };
- yield return new object[] { "ta-IN", new string[] { "ஞாயி.", "திங்.", "செவ்.", "புத.", "வியா.", "வெள்.", "சனி" } };
- yield return new object[] { "te-IN", new string[] { "ఆది", "సోమ", "మంగళ", "బుధ", "గురు", "శుక్ర", "శని" } };
- yield return new object[] { "th-TH", new string[] { "อา.", "จ.", "อ.", "พ.", "พฤ.", "ศ.", "ส." } };
- yield return new object[] { "tr-CY", new string[] { "Paz", "Pzt", "Sal", "Çar", "Per", "Cum", "Cmt" } };
- yield return new object[] { "uk-UA", new string[] { "нд", "пн", "вт", "ср", "чт", "пт", "сб" } };
- yield return new object[] { "vi-VN", new string[] { "CN", "Th 2", "Th 3", "Th 4", "Th 5", "Th 6", "Th 7" } };
- yield return new object[] { "zh-CN", new string[] { "周日", "周一", "周二", "周三", "周四", "周五", "周六" } };
- }
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsIcuGlobalization))]
[MemberData(nameof(AbbreviatedDayNames_Get_TestData_ICU))]
@@ -99,16 +42,6 @@ public void AbbreviatedDayNames_Get_ReturnsExpected_ICU(DateTimeFormatInfo forma
Assert.Equal(expected, format.AbbreviatedDayNames);
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
- [MemberData(nameof(AbbreviatedDayNames_Get_TestData_HybridGlobalization))]
- public void AbbreviatedDayNames_Get_ReturnsExpected_HybridGlobalization(string cultureName, string[] expected)
- {
- var format = new CultureInfo(cultureName).DateTimeFormat;
- int length = format.AbbreviatedDayNames.Length;
- Assert.True(length == expected.Length, $"Length comparison failed for culture: {cultureName}. Expected: {expected.Length}, Actual: {length}");
- for (int i = 0; i AbbreviatedMonthGenitiveNames_Get_TestData_I
yield return new object[] { CultureInfo.GetCultureInfo("en-US").DateTimeFormat, new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
yield return new object[] { CultureInfo.GetCultureInfo("fr-FR").DateTimeFormat, new string[] { "janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc.", "" } };
}
- public static IEnumerable AbbreviatedMonthGenitiveNames_Get_TestData_HybridGlobalization()
- {
- // see the comments on the right to check the non-Hybrid result, if it differs
- yield return new object[] { "ar-SA", new string[] { "محرم", "صفر", "ربيع الأول", "ربيع الآخر", "جمادى الأولى", "جمادى الآخرة", "رجب", "شعبان", "رمضان", "شوال", "ذو القعدة", "ذو الحجة", "" } };
- if (PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS)
- {
- yield return new object[] { "am-ET", new string[] { "ጃንዩ", "ፌብሩ", "ማርች", "ኤፕሪ", "ሜይ", "ጁን", "ጁላይ", "ኦገስ", "ሴፕቴ", "ኦክቶ", "ኖቬም", "ዲሴም", "" } };
- yield return new object[] { "es-MX", new string[] { "ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sept", "oct", "nov", "dic", "" } }; // "ene.", "feb.", "mar.", "abr.", "may.", "jun.", "jul.", "ago.", "sep.", "oct.", "nov.", "dic.", ""
- }
- else
- {
- yield return new object[] { "am-ET", new string[] { "ጃን", "ፌብ", "ማርች", "ኤፕሪ", "ሜይ", "ጁን", "ጁላይ", "ኦገስ", "ሴፕቴ", "ኦክቶ", "ኖቬም", "ዲሴም", "" } }; // "ጃንዩ", "ፌብሩ", "ማርች", "ኤፕሪ", "ሜይ", "ጁን", "ጁላይ", "ኦገስ", "ሴፕቴ", "ኦክቶ", "ኖቬም", "ዲሴም", ""
- yield return new object[] { "es-MX", new string[] { "ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic", "" } }; // "ene.", "feb.", "mar.", "abr.", "may.", "jun.", "jul.", "ago.", "sep.", "oct.", "nov.", "dic.", ""
- }
- yield return new object[] { "bg-BG", new string[] { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "" } }; //"яну", "фев", "март", "апр", "май", "юни", "юли", "авг", "сеп", "окт", "ное", "дек", ""
- yield return new object[] { "bn-BD", new string[] { "জানু", "ফেব", "মার্চ", "এপ্রি", "মে", "জুন", "জুল", "আগ", "সেপ", "অক্টো", "নভে", "ডিসে", "" } }; // "জানু", "ফেব", "মার্চ", "এপ্রিল", "মে", "জুন", "জুলাই", "আগস্ট", "সেপ্টেম্বর", "অক্টোবর", "নভেম্বর", "ডিসেম্বর", ""
- yield return new object[] { "bn-IN", new string[] { "জানু", "ফেব", "মার্চ", "এপ্রি", "মে", "জুন", "জুল", "আগ", "সেপ্টেঃ", "অক্টোঃ", "নভেঃ", "ডিসেঃ", "" } }; // "জানু", "ফেব", "মার্চ", "এপ্রিল", "মে", "জুন", "জুলাই", "আগস্ট", "সেপ্টেম্বর", "অক্টোবর", "নভেম্বর", "ডিসেম্বর", ""
- yield return new object[] { "ca-AD", new string[] { "gen.", "febr.", "març", "abr.", "maig", "juny", "jul.", "ag.", "set.", "oct.", "nov.", "des.", "" } }; // "de gen.", "de febr.", "de març", "d’abr.", "de maig", "de juny", "de jul.", "d’ag.", "de set.", "d’oct.", "de nov.", "de des.", ""
- yield return new object[] { "ca-ES", new string[] { "gen.", "febr.", "març", "abr.", "maig", "juny", "jul.", "ag.", "set.", "oct.", "nov.", "des.", "" } };
- yield return new object[] { "cs-CZ", new string[] { "led", "úno", "bře", "dub", "kvě", "čvn", "čvc", "srp", "zář", "říj", "lis", "pro", "" } };
- yield return new object[] { "da-DK", new string[] { "jan.", "feb.", "mar.", "apr.", "maj", "jun.", "jul.", "aug.", "sep.", "okt.", "nov.", "dec.", "" } };
- yield return new object[] { "de-AT", new string[] { "Jän.", "Feb.", "März", "Apr.", "Mai", "Juni", "Juli", "Aug.", "Sep.", "Okt.", "Nov.", "Dez.", "" } };
- yield return new object[] { "de-BE", new string[] { "Jan.", "Feb.", "März", "Apr.", "Mai", "Juni", "Juli", "Aug.", "Sept.", "Okt.", "Nov.", "Dez.", "" } };
- yield return new object[] { "de-CH", new string[] { "Jan.", "Feb.", "März", "Apr.", "Mai", "Juni", "Juli", "Aug.", "Sept.", "Okt.", "Nov.", "Dez.", "" } };
- yield return new object[] { "de-DE", new string[] { "Jan.", "Feb.", "März", "Apr.", "Mai", "Juni", "Juli", "Aug.", "Sept.", "Okt.", "Nov.", "Dez.", "" } };
- yield return new object[] { "de-IT", new string[] { "Jän.", "Feb.", "März", "Apr.", "Mai", "Juni", "Juli", "Aug.", "Sep.", "Okt.", "Nov.", "Dez.", "" } };
- yield return new object[] { "de-LI", new string[] { "Jan.", "Feb.", "März", "Apr.", "Mai", "Juni", "Juli", "Aug.", "Sept.", "Okt.", "Nov.", "Dez.", "" } };
- yield return new object[] { "de-LU", new string[] { "Jan.", "Feb.", "März", "Apr.", "Mai", "Juni", "Juli", "Aug.", "Sept.", "Okt.", "Nov.", "Dez.", "" } };
- yield return new object[] { "el-CY", new string[] { "Ιαν", "Φεβ", "Μαρ", "Απρ", "Μαΐ", "Ιουν", "Ιουλ", "Αυγ", "Σεπ", "Οκτ", "Νοε", "Δεκ", "" } };
- yield return new object[] { "el-GR", new string[] { "Ιαν", "Φεβ", "Μαρ", "Απρ", "Μαΐ", "Ιουν", "Ιουλ", "Αυγ", "Σεπ", "Οκτ", "Νοε", "Δεκ", "" } };
- yield return new object[] { "en-AE", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "en-AG", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-AI", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-AS", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "en-AT", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-AU", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Jun", "Jul", .., "Sep"
- yield return new object[] { "en-BB", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-BE", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-BI", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "en-BM", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-BS", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-BW", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-BZ", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-CA", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } }; // "Jan.", "Feb.", "Mar.", "Apr.", "May", "Jun.", "Jul.", "Aug.", "Sep.", "Oct.", "Nov.", "Dec.", ""
- yield return new object[] { "en-CC", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-CH", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-CK", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-CM", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-CX", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-CY", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-DE", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-DK", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-DM", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-ER", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-FI", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-FJ", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-FK", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-FM", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-GB", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-GD", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-GG", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-GH", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-GI", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-GM", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-GU", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "en-GY", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-HK", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-IE", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-IL", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-IM", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-IN", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-IO", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-JE", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-JM", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-KE", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-KI", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-KN", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-KY", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-LC", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-LR", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-LS", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-MG", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-MH", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "en-MO", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-MP", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "en-MS", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-MT", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-MU", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-MW", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-MY", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-NA", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-NF", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-NG", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-NL", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-NR", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-NU", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-NZ", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-PG", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-PH", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "en-PK", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-PN", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-PR", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "en-PW", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-RW", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-SB", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-SC", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-SD", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-SE", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-SG", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-SH", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-SI", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-SL", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-SS", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-SX", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-SZ", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-TC", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-TK", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-TO", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-TT", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-TV", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-TZ", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-UG", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-UM", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "en-US", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "en-VC", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-VG", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-VI", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "en-VU", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-WS", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-ZA", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-ZM", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-ZW", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "es-419", new string[] { "ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sept", "oct", "nov", "dic", "" } }; // "ene.", "feb.", "mar.", "abr.", "may.", "jun.", "jul.", "ago.", "sep.", "oct.", "nov.", "dic.", ""
- yield return new object[] { "es-ES", new string[] { "ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sept", "oct", "nov", "dic", "" } }; // "ene.", "feb.", "mar.", "abr.", "may.", "jun.", "jul.", "ago.", "sep.", "oct.", "nov.", "dic.", ""
- yield return new object[] { "et-EE", new string[] { "jaan", "veebr", "märts", "apr", "mai", "juuni", "juuli", "aug", "sept", "okt", "nov", "dets", "" } };
- yield return new object[] { "fa-IR", new string[] { "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" } };
- yield return new object[] { "fi-FI", new string[] { "tammik.", "helmik.", "maalisk.", "huhtik.", "toukok.", "kesäk.", "heinäk.", "elok.", "syysk.", "lokak.", "marrask.", "jouluk.", "" } };
- yield return new object[] { "fil-PH", new string[] { "Ene", "Peb", "Mar", "Abr", "May", "Hun", "Hul", "Ago", "Set", "Okt", "Nob", "Dis", "" } };
- yield return new object[] { "fr-BE", new string[] { "janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc.", "" } };
- yield return new object[] { "fr-CA", new string[] { "janv.", "févr.", "mars", "avr.", "mai", "juin", "juill.", "août", "sept.", "oct.", "nov.", "déc.", "" } };
- yield return new object[] { "fr-CH", new string[] { "janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc.", "" } };
- yield return new object[] { "fr-FR", new string[] { "janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc.", "" } };
- yield return new object[] { "gu-IN", new string[] { "જાન્યુ", "ફેબ્રુ", "માર્ચ", "એપ્રિલ", "મે", "જૂન", "જુલાઈ", "ઑગસ્ટ", "સપ્ટે", "ઑક્ટો", "નવે", "ડિસે", "" } };
- yield return new object[] { "he-IL", new string[] { "ינו׳", "פבר׳", "מרץ", "אפר׳", "מאי", "יוני", "יולי", "אוג׳", "ספט׳", "אוק׳", "נוב׳", "דצמ׳", "" } };
- yield return new object[] { "hi-IN", new string[] { "जन॰", "फ़र॰", "मार्च", "अप्रैल", "मई", "जून", "जुल॰", "अग॰", "सित॰", "अक्तू॰", "नव॰", "दिस॰", "" } };
- yield return new object[] { "hr-BA", new string[] { "sij", "velj", "ožu", "tra", "svi", "lip", "srp", "kol", "ruj", "lis", "stu", "pro", "" } };
- yield return new object[] { "hr-HR", new string[] { "sij", "velj", "ožu", "tra", "svi", "lip", "srp", "kol", "ruj", "lis", "stu", "pro", "" } };
- yield return new object[] { "hu-HU", new string[] { "jan.", "febr.", "márc.", "ápr.", "máj.", "jún.", "júl.", "aug.", "szept.", "okt.", "nov.", "dec.", "" } };
- yield return new object[] { "id-ID", new string[] { "Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Agu", "Sep", "Okt", "Nov", "Des", "" } };
- yield return new object[] { "it-CH", new string[] { "gen", "feb", "mar", "apr", "mag", "giu", "lug", "ago", "set", "ott", "nov", "dic", "" } };
- yield return new object[] { "it-IT", new string[] { "gen", "feb", "mar", "apr", "mag", "giu", "lug", "ago", "set", "ott", "nov", "dic", "" } };
- yield return new object[] { "ja-JP", new string[] { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", "" } };
- yield return new object[] { "kn-IN", new string[] { "ಜನವರಿ", "ಫೆಬ್ರವರಿ", "ಮಾರ್ಚ್", "ಏಪ್ರಿ", "ಮೇ", "ಜೂನ್", "ಜುಲೈ", "ಆಗಸ್ಟ್", "ಸೆಪ್ಟೆಂ", "ಅಕ್ಟೋ", "ನವೆಂ", "ಡಿಸೆಂ", "" } }; // "ಜನವರಿ", "ಫೆಬ್ರವರಿ", "ಮಾರ್ಚ್", "ಏಪ್ರಿ", "ಮೇ", "ಜೂನ್", "ಜುಲೈ", "ಆಗ", "ಸೆಪ್ಟೆಂ", "ಅಕ್ಟೋ", "ನವೆಂ", "ಡಿಸೆಂ", ""
- yield return new object[] { "ko-KR", new string[] { "1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월", "" } };
- yield return new object[] { "lt-LT", new string[] { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "" } }; // "saus.", "vas.", "kov.", "bal.", "geg.", "birž.", "liep.", "rugp.", "rugs.", "spal.", "lapkr.", "gruod."
- yield return new object[] { "lv-LV", new string[] { "janv.", "febr.", "marts", "apr.", "maijs", "jūn.", "jūl.", "aug.", "sept.", "okt.", "nov.", "dec.", "" } };
- yield return new object[] { "ml-IN", new string[] { "ജനു", "ഫെബ്രു", "മാർ", "ഏപ്രി", "മേയ്", "ജൂൺ", "ജൂലൈ", "ഓഗ", "സെപ്റ്റം", "ഒക്ടോ", "നവം", "ഡിസം", "" } };
- yield return new object[] { "mr-IN", new string[] { "जाने", "फेब्रु", "मार्च", "एप्रि", "मे", "जून", "जुलै", "ऑग", "सप्टें", "ऑक्टो", "नोव्हें", "डिसें", "" } };
- yield return new object[] { "ms-BN", new string[] { "Jan", "Feb", "Mac", "Apr", "Mei", "Jun", "Jul", "Ogo", "Sep", "Okt", "Nov", "Dis", "" } };
- yield return new object[] { "ms-MY", new string[] { "Jan", "Feb", "Mac", "Apr", "Mei", "Jun", "Jul", "Ogo", "Sep", "Okt", "Nov", "Dis", "" } };
- yield return new object[] { "ms-SG", new string[] { "Jan", "Feb", "Mac", "Apr", "Mei", "Jun", "Jul", "Ogo", "Sep", "Okt", "Nov", "Dis", "" } };
- string[] norwegianMonths = new string [] { "jan.", "feb.", "mars", "apr.", "mai", "juni", "juli", "aug.", "sep.", "okt.", "nov.", "des.", "" }; // "jan.", "feb.", "mar.", "apr.", "mai", "jun.", "jul.", "aug.", "sep.", "okt.", "nov.", "des.", "
- yield return new object[] { "nb-NO", norwegianMonths };
- yield return new object[] { "no-NO", norwegianMonths };
- string[] dutchMonths = new string[] { "jan", "feb", "mrt", "apr", "mei", "jun", "jul", "aug", "sep", "okt", "nov", "dec", "" }; // "jan.", "feb.", "mrt.", "apr.", "mei", "jun.", "jul.", "aug.", "sep.", "okt.", "nov.", "dec.", ""
- yield return new object[] { "nl-AW", dutchMonths };
- yield return new object[] { "nl-BE", dutchMonths };
- yield return new object[] { "nl-NL", dutchMonths };
- yield return new object[] { "pl-PL", new string[] { "sty", "lut", "mar", "kwi", "maj", "cze", "lip", "sie", "wrz", "paź", "lis", "gru", "" } };
- yield return new object[] { "pt-BR", new string[] { "jan.", "fev.", "mar.", "abr.", "mai.", "jun.", "jul.", "ago.", "set.", "out.", "nov.", "dez.", "" } };
- yield return new object[] { "pt-PT", new string[] { "jan.", "fev.", "mar.", "abr.", "mai.", "jun.", "jul.", "ago.", "set.", "out.", "nov.", "dez.", "" } };
- yield return new object[] { "ro-RO", new string[] { "ian.", "feb.", "mar.", "apr.", "mai", "iun.", "iul.", "aug.", "sept.", "oct.", "nov.", "dec.", "" } };
- yield return new object[] { "ru-RU", new string[] { "янв.", "февр.", "мар.", "апр.", "мая", "июн.", "июл.", "авг.", "сент.", "окт.", "нояб.", "дек.", "" } };
- yield return new object[] { "sk-SK", new string[] { "jan", "feb", "mar", "apr", "máj", "jún", "júl", "aug", "sep", "okt", "nov", "dec", "" } };
- yield return new object[] { "sl-SI", new string[] { "jan.", "feb.", "mar.", "apr.", "maj", "jun.", "jul.", "avg.", "sep.", "okt.", "nov.", "dec.", "" } };
- yield return new object[] { "sr-Cyrl-RS", new string[] { "јан", "феб", "мар", "апр", "мај", "јун", "јул", "авг", "сеп", "окт", "нов", "дец", "" } };
- yield return new object[] { "sr-Latn-RS", new string[] { "jan", "feb", "mar", "apr", "maj", "jun", "jul", "avg", "sep", "okt", "nov", "dec", "" } };
- yield return new object[] { "sv-AX", new string[] { "jan.", "feb.", "mars", "apr.", "maj", "juni", "juli", "aug.", "sep.", "okt.", "nov.", "dec.", "" } };
- yield return new object[] { "sv-SE", new string[] { "jan.", "feb.", "mars", "apr.", "maj", "juni", "juli", "aug.", "sep.", "okt.", "nov.", "dec.", "" } };
- yield return new object[] { "sw-CD", new string[] { "Jan", "Feb", "Mac", "Apr", "Mei", "Jun", "Jul", "Ago", "Sep", "Okt", "Nov", "Des", "" } };
- yield return new object[] { "sw-KE", new string[] { "Jan", "Feb", "Mac", "Apr", "Mei", "Jun", "Jul", "Ago", "Sep", "Okt", "Nov", "Des", "" } };
- yield return new object[] { "sw-TZ", new string[] { "Jan", "Feb", "Mac", "Apr", "Mei", "Jun", "Jul", "Ago", "Sep", "Okt", "Nov", "Des", "" } };
- yield return new object[] { "sw-UG", new string[] { "Jan", "Feb", "Mac", "Apr", "Mei", "Jun", "Jul", "Ago", "Sep", "Okt", "Nov", "Des", "" } };
- yield return new object[] { "ta-IN", new string[] { "ஜன.", "பிப்.", "மார்.", "ஏப்.", "மே", "ஜூன்", "ஜூலை", "ஆக.", "செப்.", "அக்.", "நவ.", "டிச.", "" } };
- yield return new object[] { "ta-LK", new string[] { "ஜன.", "பிப்.", "மார்.", "ஏப்.", "மே", "ஜூன்", "ஜூலை", "ஆக.", "செப்.", "அக்.", "நவ.", "டிச.", "" } };
- yield return new object[] { "ta-MY", new string[] { "ஜன.", "பிப்.", "மார்.", "ஏப்.", "மே", "ஜூன்", "ஜூலை", "ஆக.", "செப்.", "அக்.", "நவ.", "டிச.", "" } };
- yield return new object[] { "ta-SG", new string[] { "ஜன.", "பிப்.", "மார்.", "ஏப்.", "மே", "ஜூன்", "ஜூலை", "ஆக.", "செப்.", "அக்.", "நவ.", "டிச.", "" } };
- yield return new object[] { "te-IN", new string[] { "జన", "ఫిబ్ర", "మార్చి", "ఏప్రి", "మే", "జూన్", "జులై", "ఆగ", "సెప్టెం", "అక్టో", "నవం", "డిసెం", "" } };
- yield return new object[] { "th-TH", new string[] { "ม.ค.", "ก.พ.", "มี.ค.", "เม.ย.", "พ.ค.", "มิ.ย.", "ก.ค.", "ส.ค.", "ก.ย.", "ต.ค.", "พ.ย.", "ธ.ค.", "" } };
- yield return new object[] { "tr-CY", new string[] { "Oca", "Şub", "Mar", "Nis", "May", "Haz", "Tem", "Ağu", "Eyl", "Eki", "Kas", "Ara", "" } };
- yield return new object[] { "tr-TR", new string[] { "Oca", "Şub", "Mar", "Nis", "May", "Haz", "Tem", "Ağu", "Eyl", "Eki", "Kas", "Ara", "" } };
- yield return new object[] { "uk-UA", new string[] { "січ.", "лют.", "бер.", "квіт.", "трав.", "черв.", "лип.", "серп.", "вер.", "жовт.", "лист.", "груд.", "" } };
- string vietnameseAbbrMonth = PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "Thg" : "Tháng"; // thg
- yield return new object[] { "vi-VN", new string[] { $"{vietnameseAbbrMonth} 1", $"{vietnameseAbbrMonth} 2", $"{vietnameseAbbrMonth} 3", $"{vietnameseAbbrMonth} 4", $"{vietnameseAbbrMonth} 5", $"{vietnameseAbbrMonth} 6", $"{vietnameseAbbrMonth} 7", $"{vietnameseAbbrMonth} 8", $"{vietnameseAbbrMonth} 9", $"{vietnameseAbbrMonth} 10", $"{vietnameseAbbrMonth} 11", $"{vietnameseAbbrMonth} 12", "" } };
- yield return new object[] { "zh-CN", new string[] { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", "" } };
- yield return new object[] { "zh-Hans-HK", new string[] { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", "" } };
- yield return new object[] { "zh-SG", new string[] { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", "" } };
- yield return new object[] { "zh-HK", new string[] { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", "" } };
- yield return new object[] { "zh-TW", new string[] { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", "" } };
- }
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsIcuGlobalization))]
[MemberData(nameof(AbbreviatedMonthGenitiveNames_Get_TestData_ICU))]
@@ -221,17 +21,6 @@ public void AbbreviatedMonthGenitiveNames_Get_ReturnsExpected_ICU(DateTimeFormat
Assert.Equal(expected, format.AbbreviatedMonthGenitiveNames);
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
- [MemberData(nameof(AbbreviatedMonthGenitiveNames_Get_TestData_HybridGlobalization))]
- public void AbbreviatedMonthGenitiveNames_Get_ReturnsExpected_HybridGlobalization(string cultureName, string[] expected)
- {
- var format = new CultureInfo(cultureName).DateTimeFormat;
- int length = format.AbbreviatedMonthGenitiveNames.Length;
- Assert.True(length == expected.Length, $"Length comparison failed for culture: {cultureName}. Expected: {expected.Length}, Actual: {length}");
- for (int i = 0; i AbbreviatedMonthNames_Get_TestData_ICU()
}
- public static IEnumerable AbbreviatedMonthNames_Get_TestData_HybridGlobalization()
- {
- // see the comments on the right to check the non-Hybrid result, if it differs
- yield return new object[] { "ar-SA", new string[] { "محرم", "صفر", "ربيع الأول", "ربيع الآخر", "جمادى الأولى", "جمادى الآخرة", "رجب", "شعبان", "رمضان", "شوال", "ذو القعدة", "ذو الحجة", "" } };
- if (PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS)
- {
- yield return new object[] { "am-ET", new string[] { "ጃንዩ", "ፌብሩ", "ማርች", "ኤፕሪ", "ሜይ", "ጁን", "ጁላይ", "ኦገስ", "ሴፕቴ", "ኦክቶ", "ኖቬም", "ዲሴም", "" } };
- yield return new object[] { "en-AU", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "es-MX", new string[] { "ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sept", "oct", "nov", "dic", "" } }; // "ene.", "feb.", "mar.", "abr.", "may.", "jun.", "jul.", "ago.", "sep.", "oct.", "nov.", "dic.", ""
- yield return new object[] { "uk-UA", new string[] { "січ", "лют", "бер", "кві", "тра", "чер", "лип", "сер", "вер", "жов", "лис", "гру", "" } };
- yield return new object[] { "vi-VN", new string[] { "Thg 1", "Thg 2", "Thg 3", "Thg 4", "Thg 5", "Thg 6", "Thg 7", "Thg 8", "Thg 9", "Thg 10", "Thg 11", "Thg 12", "" } };
- }
- else
- {
- yield return new object[] { "am-ET", new string[] { "ጃን", "ፌብ", "ማርች", "ኤፕሪ", "ሜይ", "ጁን", "ጁላይ", "ኦገስ", "ሴፕቴ", "ኦክቶ", "ኖቬም", "ዲሴም", "" } }; // "ጃንዩ", "ፌብሩ", "ማርች", "ኤፕሪ", "ሜይ", "ጁን", "ጁላይ", "ኦገስ", "ሴፕቴ", "ኦክቶ", "ኖቬም", "ዲሴም", ""
- yield return new object[] { "en-AU", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Jun", "Jul"
- yield return new object[] { "es-MX", new string[] { "ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic", "" } }; // "ene.", "feb.", "mar.", "abr.", "may.", "jun.", "jul.", "ago.", "sep.", "oct.", "nov.", "dic.", ""
- yield return new object[] { "uk-UA", new string[] { "січ.", "лют.", "бер.", "квіт.", "трав.", "черв.", "лип.", "серп.", "вер.", "жовт.", "лист.", "груд.", "" } }; // "січ", "лют", "бер", "кві", "тра", "чер", "лип", "сер", "вер", "жов", "лис", "гру", ""
- yield return new object[] { "vi-VN", new string[] { "Tháng 1", "Tháng 2", "Tháng 3", "Tháng 4", "Tháng 5", "Tháng 6", "Tháng 7", "Tháng 8", "Tháng 9", "Tháng 10", "Tháng 11", "Tháng 12", "" } };
- }
- yield return new object[] { "bg-BG", new string[] { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "" } }; // "яну", "фев", "март", "апр", "май", "юни", "юли", "авг", "сеп", "окт", "ное", "дек", ""
- yield return new object[] { "bn-BD", new string[] { "জানু", "ফেব", "মার্চ", "এপ্রিল", "মে", "জুন", "জুলাই", "আগস্ট", "সেপ্টেম্বর", "অক্টোবর", "নভেম্বর", "ডিসেম্বর", "" } }; // "জানুয়ারী", "ফেব্রুয়ারী", "মার্চ", "এপ্রিল", "মে", "জুন", "জুলাই", "আগস্ট", "সেপ্টেম্বর", "অক্টোবর", "নভেম্বর", "ডিসেম্বর", ""
- yield return new object[] { "bn-IN", new string[] { "জানু", "ফেব", "মার্চ", "এপ্রিল", "মে", "জুন", "জুলাই", "আগস্ট", "সেপ্টেঃ", "অক্টোঃ", "নভেঃ", "ডিসেঃ", "" } }; // BUG. JS returns Genitive even though we expect Nominative; "জানু", "ফেব", "মার্চ", "এপ্রিল", "মে", "জুন", "জুলাই", "আগস্ট", "সেপ্টেম্বর", "অক্টোবর", "নভেম্বর", "ডিসেম্বর", ""
- yield return new object[] { "ca-AD", new string[] { "gen.", "febr.", "març", "abr.", "maig", "juny", "jul.", "ag.", "set.", "oct.", "nov.", "des.", "" } };
- yield return new object[] { "ca-ES", new string[] { "gen.", "febr.", "març", "abr.", "maig", "juny", "jul.", "ag.", "set.", "oct.", "nov.", "des.", "" } };
- yield return new object[] { "cs-CZ", new string[] { "led", "úno", "bře", "dub", "kvě", "čvn", "čvc", "srp", "zář", "říj", "lis", "pro", "" } };
- yield return new object[] { "da-DK", new string[] { "jan.", "feb.", "mar.", "apr.", "maj", "jun.", "jul.", "aug.", "sep.", "okt.", "nov.", "dec.", "" } };
- yield return new object[] { "de-AT", new string[] { "Jän", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez", "" } };
- yield return new object[] { "de-BE", new string[] { "Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez", "" } };
- yield return new object[] { "de-CH", new string[] { "Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez", "" } };
- yield return new object[] { "de-DE", new string[] { "Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez", "" } };
- yield return new object[] { "de-IT", new string[] { "Jän", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez", "" } };
- yield return new object[] { "de-LI", new string[] { "Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez", "" } };
- yield return new object[] { "de-LU", new string[] { "Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez", "" } };
- yield return new object[] { "el-CY", new string[] { "Ιαν", "Φεβ", "Μαρ", "Απρ", "Μαΐ", "Ιουν", "Ιουλ", "Αυγ", "Σεπ", "Οκτ", "Νοε", "Δεκ", "" } }; // BUG. JS returns Genitive for Greek even though we expect Nominative; "Ιαν", "Φεβ", "Μάρ", "Απρ", "Μάι", "Ιούν", "Ιούλ", "Αύγ", "Σεπ", "Οκτ", "Νοέ", "Δεκ", ""
- yield return new object[] { "el-GR", new string[] { "Ιαν", "Φεβ", "Μαρ", "Απρ", "Μαΐ", "Ιουν", "Ιουλ", "Αυγ", "Σεπ", "Οκτ", "Νοε", "Δεκ", "" } }; // BUG.
- yield return new object[] { "en-AE", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "en-AG", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-AI", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-AS", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "en-AT", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-BB", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-BE", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-BI", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "en-BM", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-BS", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-BW", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-BZ", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-CA", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } }; // "Jan.", "Feb.", "Mar.", "Apr.", "May", "Jun.", "Jul.", "Aug.", "Sep.", "Oct.", "Nov.", "Dec.", ""
- yield return new object[] { "en-CC", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-CH", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-CK", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-CM", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-CX", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-CY", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-DE", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-DK", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-DM", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-ER", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-FI", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-FJ", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-FK", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-FM", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-GB", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-GD", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-GG", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-GH", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-GI", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-GM", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-GU", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "en-GY", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-HK", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-IE", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-IL", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-IM", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-IN", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-IO", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-JE", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-JM", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-KE", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-KI", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-KN", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-KY", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-LC", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-LR", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-LS", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-MG", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-MH", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "en-MO", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-MP", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "en-MS", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-MT", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-MU", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-MW", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-MY", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-NA", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-NF", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-NG", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-NL", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-NR", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-NU", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-NZ", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-PG", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-PH", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "en-PK", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-PN", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-PR", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "en-PW", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-RW", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-SB", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-SC", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-SD", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-SE", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-SG", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-SH", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-SI", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-SL", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-SS", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-SX", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-SZ", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-TC", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-TK", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-TO", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-TT", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-TV", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-TZ", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-UG", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-UM", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "en-US", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "en-VC", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-VG", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-VI", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "" } };
- yield return new object[] { "en-VU", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-WS", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-ZA", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-ZM", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "en-ZW", new string[] { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sept", "Oct", "Nov", "Dec", "" } }; // "Sep"
- yield return new object[] { "es-419", new string[] { "ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sept", "oct", "nov", "dic", "" } }; // "ene.", "feb.", "mar.", "abr.", "may.", "jun.", "jul.", "ago.", "sep.", "oct.", "nov.", "dic.", ""
- yield return new object[] { "es-ES", new string[] { "ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sept", "oct", "nov", "dic", "" } }; // "ene.", "feb.", "mar.", "abr.", "may.", "jun.", "jul.", "ago.", "sep.", "oct.", "nov.", "dic.", ""
- yield return new object[] { "et-EE", new string[] { "jaanuar", "veebruar", "märts", "aprill", "mai", "juuni", "juuli", "august", "september", "oktoober", "november", "detsember", "" } }; // "jaan", "veebr", "märts", "apr", "mai", "juuni", "juuli", "aug", "sept", "okt", "nov", "dets", ""
- yield return new object[] { "fa-IR", new string[] { "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" } };
- yield return new object[] { "fi-FI", new string[] { "tammi", "helmi", "maalis", "huhti", "touko", "kesä", "heinä", "elo", "syys", "loka", "marras", "joulu", "" } };
- yield return new object[] { "fil-PH", new string[] { "Ene", "Peb", "Mar", "Abr", "May", "Hun", "Hul", "Ago", "Set", "Okt", "Nob", "Dis", "" } };
- yield return new object[] { "fr-BE", new string[] { "janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc.", "" } };
- yield return new object[] { "fr-CA", new string[] { "janv.", "févr.", "mars", "avr.", "mai", "juin", "juill.", "août", "sept.", "oct.", "nov.", "déc.", "" } };
- yield return new object[] { "fr-CH", new string[] { "janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc.", "" } };
- yield return new object[] { "fr-FR", new string[] { "janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc.", "" } };
- yield return new object[] { "gu-IN", new string[] { "જાન્યુ", "ફેબ્રુ", "માર્ચ", "એપ્રિલ", "મે", "જૂન", "જુલાઈ", "ઑગસ્ટ", "સપ્ટે", "ઑક્ટો", "નવે", "ડિસે", "" } };
- yield return new object[] { "he-IL", new string[] { "ינו׳", "פבר׳", "מרץ", "אפר׳", "מאי", "יוני", "יולי", "אוג׳", "ספט׳", "אוק׳", "נוב׳", "דצמ׳", "" } };
- yield return new object[] { "hi-IN", new string[] { "जन॰", "फ़र॰", "मार्च", "अप्रैल", "मई", "जून", "जुल॰", "अग॰", "सित॰", "अक्तू॰", "नव॰", "दिस॰", "" } };
- yield return new object[] { "hr-BA", new string[] { "sij", "velj", "ožu", "tra", "svi", "lip", "srp", "kol", "ruj", "lis", "stu", "pro", "" } };
- yield return new object[] { "hr-HR", new string[] { "sij", "velj", "ožu", "tra", "svi", "lip", "srp", "kol", "ruj", "lis", "stu", "pro", "" } };
- yield return new object[] { "hu-HU", new string[] { "jan.", "febr.", "márc.", "ápr.", "máj.", "jún.", "júl.", "aug.", "szept.", "okt.", "nov.", "dec.", "" } };
- yield return new object[] { "id-ID", new string[] { "Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Agu", "Sep", "Okt", "Nov", "Des", "" } };
- yield return new object[] { "it-CH", new string[] { "gen", "feb", "mar", "apr", "mag", "giu", "lug", "ago", "set", "ott", "nov", "dic", "" } };
- yield return new object[] { "it-IT", new string[] { "gen", "feb", "mar", "apr", "mag", "giu", "lug", "ago", "set", "ott", "nov", "dic", "" } };
- yield return new object[] { "ja-JP", new string[] { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", "" } };
- yield return new object[] { "kn-IN", new string[] { "ಜನ", "ಫೆಬ್ರ", "ಮಾರ್ಚ್", "ಏಪ್ರಿ", "ಮೇ", "ಜೂನ್", "ಜುಲೈ", "ಆಗ", "ಸೆಪ್ಟೆಂ", "ಅಕ್ಟೋ", "ನವೆಂ", "ಡಿಸೆಂ", "" } };
- yield return new object[] { "ko-KR", new string[] { "1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월", "" } };
- yield return new object[] { "lt-LT", new string[] { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "" } }; // "saus.", "vas.", "kov.", "bal.", "geg.", "birž.", "liep.", "rugp.", "rugs.", "spal.", "lapkr.", "gruod."
- yield return new object[] { "lv-LV", new string[] { "janv.", "febr.", "marts", "apr.", "maijs", "jūn.", "jūl.", "aug.", "sept.", "okt.", "nov.", "dec.", "" } };
- yield return new object[] { "ml-IN", new string[] { "ജനു", "ഫെബ്രു", "മാർ", "ഏപ്രി", "മേയ്", "ജൂൺ", "ജൂലൈ", "ഓഗ", "സെപ്റ്റം", "ഒക്ടോ", "നവം", "ഡിസം", "" } };
- yield return new object[] { "mr-IN", new string[] { "जाने", "फेब्रु", "मार्च", "एप्रि", "मे", "जून", "जुलै", "ऑग", "सप्टें", "ऑक्टो", "नोव्हें", "डिसें", "" } };
- yield return new object[] { "ms-BN", new string[] { "Jan", "Feb", "Mac", "Apr", "Mei", "Jun", "Jul", "Ogo", "Sep", "Okt", "Nov", "Dis", "" } };
- yield return new object[] { "ms-MY", new string[] { "Jan", "Feb", "Mac", "Apr", "Mei", "Jun", "Jul", "Ogo", "Sep", "Okt", "Nov", "Dis", "" } };
- yield return new object[] { "ms-SG", new string[] { "Jan", "Feb", "Mac", "Apr", "Mei", "Jun", "Jul", "Ogo", "Sep", "Okt", "Nov", "Dis", "" } };
- yield return new object[] { "nb-NO", new string[] { "jan", "feb", "mar", "apr", "mai", "jun", "jul", "aug", "sep", "okt", "nov", "des", "" } };
- yield return new object[] { "no", new string[] { "jan", "feb", "mar", "apr", "mai", "jun", "jul", "aug", "sep", "okt", "nov", "des", "" } };
- yield return new object[] { "no-NO", new string[] { "jan", "feb", "mar", "apr", "mai", "jun", "jul", "aug", "sep", "okt", "nov", "des", "" } };
- var dutchMonths = new string[] { "jan", "feb", "mrt", "apr", "mei", "jun", "jul", "aug", "sep", "okt", "nov", "dec", "" }; // "jan.", "feb.", "mrt.", "apr.", "mei", "jun.", "jul.", "aug.", "sep.", "okt.", "nov.", "dec.", ""
- yield return new object[] { "nl-AW", dutchMonths };
- yield return new object[] { "nl-BE", dutchMonths };
- yield return new object[] { "nl-NL", dutchMonths };
- yield return new object[] { "pl-PL", new string[] { "sty", "lut", "mar", "kwi", "maj", "cze", "lip", "sie", "wrz", "paź", "lis", "gru", "" } };
- yield return new object[] { "pt-BR", new string[] { "jan.", "fev.", "mar.", "abr.", "mai.", "jun.", "jul.", "ago.", "set.", "out.", "nov.", "dez.", "" } };
- yield return new object[] { "pt-PT", new string[] { "jan.", "fev.", "mar.", "abr.", "mai.", "jun.", "jul.", "ago.", "set.", "out.", "nov.", "dez.", "" } };
- yield return new object[] { "ro-RO", new string[] { "ian.", "feb.", "mar.", "apr.", "mai", "iun.", "iul.", "aug.", "sept.", "oct.", "nov.", "dec.", "" } };
- yield return new object[] { "ru-RU", new string[] { "янв.", "февр.", "март", "апр.", "май", "июнь", "июль", "авг.", "сент.", "окт.", "нояб.", "дек.", "" } };
- yield return new object[] { "sk-SK", new string[] { "jan", "feb", "mar", "apr", "máj", "jún", "júl", "aug", "sep", "okt", "nov", "dec", "" } };
- yield return new object[] { "sl-SI", new string[] { "jan.", "feb.", "mar.", "apr.", "maj", "jun.", "jul.", "avg.", "sep.", "okt.", "nov.", "dec.", "" } };
- yield return new object[] { "sr-Cyrl-RS", new string[] { "јан", "феб", "мар", "апр", "мај", "јун", "јул", "авг", "сеп", "окт", "нов", "дец", "" } };
- yield return new object[] { "sr-Latn-RS", new string[] { "jan", "feb", "mar", "apr", "maj", "jun", "jul", "avg", "sep", "okt", "nov", "dec", "" } };
- yield return new object[] { "sv-AX", new string[] { "jan.", "feb.", "mars", "apr.", "maj", "juni", "juli", "aug.", "sep.", "okt.", "nov.", "dec.", "" } };
- yield return new object[] { "sv-SE", new string[] { "jan.", "feb.", "mars", "apr.", "maj", "juni", "juli", "aug.", "sep.", "okt.", "nov.", "dec.", "" } };
- yield return new object[] { "sw-CD", new string[] { "Jan", "Feb", "Mac", "Apr", "Mei", "Jun", "Jul", "Ago", "Sep", "Okt", "Nov", "Des", "" } };
- yield return new object[] { "sw-KE", new string[] { "Jan", "Feb", "Mac", "Apr", "Mei", "Jun", "Jul", "Ago", "Sep", "Okt", "Nov", "Des", "" } };
- yield return new object[] { "sw-TZ", new string[] { "Jan", "Feb", "Mac", "Apr", "Mei", "Jun", "Jul", "Ago", "Sep", "Okt", "Nov", "Des", "" } };
- yield return new object[] { "sw-UG", new string[] { "Jan", "Feb", "Mac", "Apr", "Mei", "Jun", "Jul", "Ago", "Sep", "Okt", "Nov", "Des", "" } };
- yield return new object[] { "ta-IN", new string[] { "ஜன.", "பிப்.", "மார்.", "ஏப்.", "மே", "ஜூன்", "ஜூலை", "ஆக.", "செப்.", "அக்.", "நவ.", "டிச.", "" } };
- yield return new object[] { "ta-LK", new string[] { "ஜன.", "பிப்.", "மார்.", "ஏப்.", "மே", "ஜூன்", "ஜூலை", "ஆக.", "செப்.", "அக்.", "நவ.", "டிச.", "" } };
- yield return new object[] { "ta-MY", new string[] { "ஜன.", "பிப்.", "மார்.", "ஏப்.", "மே", "ஜூன்", "ஜூலை", "ஆக.", "செப்.", "அக்.", "நவ.", "டிச.", "" } };
- yield return new object[] { "ta-SG", new string[] { "ஜன.", "பிப்.", "மார்.", "ஏப்.", "மே", "ஜூன்", "ஜூலை", "ஆக.", "செப்.", "அக்.", "நவ.", "டிச.", "" } };
- yield return new object[] { "te-IN", new string[] { "జన", "ఫిబ్ర", "మార్చి", "ఏప్రి", "మే", "జూన్", "జులై", "ఆగ", "సెప్టెం", "అక్టో", "నవం", "డిసెం", "" } };
- yield return new object[] { "th-TH", new string[] { "ม.ค.", "ก.พ.", "มี.ค.", "เม.ย.", "พ.ค.", "มิ.ย.", "ก.ค.", "ส.ค.", "ก.ย.", "ต.ค.", "พ.ย.", "ธ.ค.", "" } };
- yield return new object[] { "tr-CY", new string[] { "Oca", "Şub", "Mar", "Nis", "May", "Haz", "Tem", "Ağu", "Eyl", "Eki", "Kas", "Ara", "" } };
- yield return new object[] { "tr-TR", new string[] { "Oca", "Şub", "Mar", "Nis", "May", "Haz", "Tem", "Ağu", "Eyl", "Eki", "Kas", "Ara", "" } };
-
- yield return new object[] { "zh-CN", new string[] { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", "" } };
- yield return new object[] { "zh-Hans-HK", new string[] { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", "" } };
- yield return new object[] { "zh-SG", new string[] { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", "" } };
- yield return new object[] { "zh-HK", new string[] { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", "" } };
- yield return new object[] { "zh-TW", new string[] { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", "" } };
- }
-
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsIcuGlobalization))]
[MemberData(nameof(AbbreviatedMonthNames_Get_TestData_ICU))]
public void AbbreviatedMonthNames_Get_ReturnsExpected_ICU(DateTimeFormatInfo format, string[] expected)
@@ -246,17 +42,6 @@ public void AbbreviatedMonthNames_Get_ReturnsExpected_ICU(DateTimeFormatInfo for
Assert.Equal(expected, format.AbbreviatedMonthNames);
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
- [MemberData(nameof(AbbreviatedMonthNames_Get_TestData_HybridGlobalization))]
- public void AbbreviatedMonthNames_Get_ReturnsExpected_HybridGlobalization(string cultureName, string[] expected)
- {
- var format = new CultureInfo(cultureName).DateTimeFormat;
- int length = format.AbbreviatedMonthNames.Length;
- Assert.True(length == expected.Length, $"Length comparison failed for culture: {cultureName}. Expected: {expected.Length}, Actual: {length}");
- for (int i = 0; i CalendarWeekRule_Get_TestData()
// "br-FR" is not presented in Browser's ICU. Let's test ru-RU instead.
yield return new object[] { "ru-RU", CalendarWeekRule.FirstFourDayWeek };
}
-
- if (PlatformDetection.IsHybridGlobalizationOnBrowser)
- {
- yield return new object[] { "ar-SA", CalendarWeekRule.FirstDay };
- yield return new object[] { "am-ET", CalendarWeekRule.FirstDay };
- yield return new object[] { "bg-BG", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "bn-BD", CalendarWeekRule.FirstDay };
- yield return new object[] { "bn-IN", CalendarWeekRule.FirstDay };
- yield return new object[] { "ca-AD", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "ca-ES", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "cs-CZ", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "da-DK", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "de-AT", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "de-BE", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "de-CH", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "de-DE", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "de-IT", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "de-LI", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "de-LU", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "el-CY", CalendarWeekRule.FirstDay };
- yield return new object[] { "el-GR", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "en-AE", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-AG", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-AI", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-AS", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-AT", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "en-AU", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-BB", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-BE", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "en-BI", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-BM", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-BS", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-BW", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-BZ", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-CA", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-CC", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-CH", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "en-CK", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-CM", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-CX", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-CY", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-DE", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "en-DK", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "en-DM", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-ER", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-FI", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "en-FJ", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "en-FK", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-FM", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-GB", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "en-GD", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-GG", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "en-GH", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-GI", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "en-GM", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-GU", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-GY", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-HK", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-IE", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "en-IL", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-IM", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "en-IN", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-IO", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-JE", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "en-JM", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-KE", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-KI", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-KN", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-KY", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-LC", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-LR", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-LS", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-MG", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-MH", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-MO", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-MP", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-MS", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-MT", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-MU", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-MW", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-MY", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-NA", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-NF", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-NG", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-NL", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "en-NR", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-NU", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-NZ", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-PG", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-PH", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-PK", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-PN", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-PR", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-PW", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-RW", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-SB", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-SC", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-SD", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-SE", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "en-SG", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-SH", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-SI", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-SL", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-SS", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-SX", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-SZ", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-TC", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-TK", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-TO", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-TT", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-TV", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-TZ", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-UG", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-UM", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-US", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-VC", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-VG", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-VI", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-VU", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-WS", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-ZA", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-ZM", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-ZW", CalendarWeekRule.FirstDay };
- yield return new object[] { "en-US", CalendarWeekRule.FirstDay };
- yield return new object[] { "es-419", CalendarWeekRule.FirstDay };
- yield return new object[] { "es-ES", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "es-MX", CalendarWeekRule.FirstDay };
- yield return new object[] { "et-EE", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "fa-IR", CalendarWeekRule.FirstDay };
- yield return new object[] { "fi-FI", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "fil-PH", CalendarWeekRule.FirstDay };
- yield return new object[] { "fr-BE", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "fr-CA", CalendarWeekRule.FirstDay };
- yield return new object[] { "fr-CH", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "fr-FR", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "gu-IN", CalendarWeekRule.FirstDay };
- yield return new object[] { "he-IL", CalendarWeekRule.FirstDay };
- yield return new object[] { "hi-IN", CalendarWeekRule.FirstDay };
- yield return new object[] { "hr-BA", CalendarWeekRule.FirstDay };
- yield return new object[] { "hr-HR", CalendarWeekRule.FirstDay };
- yield return new object[] { "hu-HU", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "id-ID", CalendarWeekRule.FirstDay };
- yield return new object[] { "it-CH", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "it-IT", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "ja-JP", CalendarWeekRule.FirstDay };
- yield return new object[] { "kn-IN", CalendarWeekRule.FirstDay };
- yield return new object[] { "ko-KR", CalendarWeekRule.FirstDay };
- yield return new object[] { "lt-LT", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "lv-LV", CalendarWeekRule.FirstDay };
- yield return new object[] { "ml-IN", CalendarWeekRule.FirstDay };
- yield return new object[] { "mr-IN", CalendarWeekRule.FirstDay };
- yield return new object[] { "ms-BN", CalendarWeekRule.FirstDay };
- yield return new object[] { "ms-MY", CalendarWeekRule.FirstDay };
- yield return new object[] { "ms-SG", CalendarWeekRule.FirstDay };
- yield return new object[] { "nb-NO", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "no-NO", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "nl-AW", CalendarWeekRule.FirstDay };
- yield return new object[] { "nl-BE", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "nl-NL", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "pl-PL", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "pt-BR", CalendarWeekRule.FirstDay };
- yield return new object[] { "pt-PT", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "ro-RO", CalendarWeekRule.FirstDay };
- yield return new object[] { "ru-RU", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "sk-SK", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "sl-SI", CalendarWeekRule.FirstDay };
- yield return new object[] { "sr-Cyrl-RS", CalendarWeekRule.FirstDay };
- yield return new object[] { "sr-Latn-RS", CalendarWeekRule.FirstDay };
- yield return new object[] { "sv-AX", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "sv-SE", CalendarWeekRule.FirstFourDayWeek };
- yield return new object[] { "sw-CD", CalendarWeekRule.FirstDay };
- yield return new object[] { "sw-KE", CalendarWeekRule.FirstDay };
- yield return new object[] { "sw-TZ", CalendarWeekRule.FirstDay };
- yield return new object[] { "sw-UG", CalendarWeekRule.FirstDay };
- yield return new object[] { "ta-IN", CalendarWeekRule.FirstDay };
- yield return new object[] { "ta-LK", CalendarWeekRule.FirstDay };
- yield return new object[] { "ta-MY", CalendarWeekRule.FirstDay };
- yield return new object[] { "ta-SG", CalendarWeekRule.FirstDay };
- yield return new object[] { "te-IN", CalendarWeekRule.FirstDay };
- yield return new object[] { "th-TH", CalendarWeekRule.FirstDay };
- yield return new object[] { "tr-CY", CalendarWeekRule.FirstDay };
- yield return new object[] { "tr-TR", CalendarWeekRule.FirstDay };
- yield return new object[] { "uk-UA", CalendarWeekRule.FirstDay };
- yield return new object[] { "vi-VN", CalendarWeekRule.FirstDay };
- yield return new object[] { "zh-CN", CalendarWeekRule.FirstDay };
- yield return new object[] { "zh-Hans-HK", CalendarWeekRule.FirstDay };
- yield return new object[] { "zh-SG", CalendarWeekRule.FirstDay };
- yield return new object[] { "zh-HK", CalendarWeekRule.FirstDay };
- yield return new object[] { "zh-TW", CalendarWeekRule.FirstDay };
- }
}
[Theory]
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoData.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoData.cs
index 253d610184750e..40de319b78c5d3 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoData.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoData.cs
@@ -69,7 +69,7 @@ public static Exception GetCultureNotSupportedException(CultureInfo cultureInfo)
};
public static bool HasBadIcuTimePatterns(CultureInfo culture)
{
- return PlatformDetection.IsIcuGlobalizationAndNotHybridOnBrowser
+ return PlatformDetection.IsIcuGlobalization
&& _badIcuTimePatterns.TryGetValue(culture.Name, out var version)
&& PlatformDetection.ICUVersion < version;
}
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoDayNames.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoDayNames.cs
index e84949d20d8c19..203e4d003acf7c 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoDayNames.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoDayNames.cs
@@ -34,56 +34,6 @@ public static IEnumerable DayNames_Get_TestData_ICU()
yield return new object[] { CultureInfo.GetCultureInfo("fr-FR").DateTimeFormat, new string[] { "dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi" } };
}
- public static IEnumerable DayNames_Get_TestData_HybridGlobalization()
- {
- yield return new object[] { "ar-SA", new string[] { "الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت" } };
- yield return new object[] { "am-ET", new string[] { "እሑድ", "ሰኞ", "ማክሰኞ", "ረቡዕ", "ሐሙስ", "ዓርብ", "ቅዳሜ" } };
- yield return new object[] { "bg-BG", new string[] { "неделя", "понеделник", "вторник", "сряда", "четвъртък", "петък", "събота" } };
- yield return new object[] { "bn-BD", new string[] { "রবিবার", "সোমবার", "মঙ্গলবার", "বুধবার", "বৃহস্পতিবার", "শুক্রবার", "শনিবার" } };
- yield return new object[] { "ca-ES", new string[] { "diumenge", "dilluns", "dimarts", "dimecres", "dijous", "divendres", "dissabte" } };
- yield return new object[] { "cs-CZ", new string[] { "neděle", "pondělí", "úterý", "středa", "čtvrtek", "pátek", "sobota" } };
- yield return new object[] { "de-AT", new string[] { "Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag" } };
- yield return new object[] { "el-GR", new string[] { "Κυριακή", "Δευτέρα", "Τρίτη", "Τετάρτη", "Πέμπτη", "Παρασκευή", "Σάββατο" } };
- yield return new object[] { "en-US", new string[] { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" } };
- yield return new object[] { "es-419", new string[] { "domingo", "lunes", "martes", "miércoles", "jueves", "viernes", "sábado" } };
- yield return new object[] { "es-ES", new string[] { "domingo", "lunes", "martes", "miércoles", "jueves", "viernes", "sábado" } };
- yield return new object[] { "es-MX", new string[] { "domingo", "lunes", "martes", "miércoles", "jueves", "viernes", "sábado" } };
- yield return new object[] { "et-EE", new string[] { "pühapäev", "esmaspäev", "teisipäev", "kolmapäev", "neljapäev", "reede", "laupäev" } };
- yield return new object[] { "fa-IR", new string[] { "یکشنبه", "دوشنبه", "سهشنبه", "چهارشنبه", "پنجشنبه", "جمعه", "شنبه" } };
- yield return new object[] { "fi-FI", new string[] { "sunnuntai", "maanantai", "tiistai", "keskiviikko", "torstai", "perjantai", "lauantai" } };
- yield return new object[] { "fil-PH", new string[] { "Linggo", "Lunes", "Martes", "Miyerkules", "Huwebes", "Biyernes", "Sabado" } };
- yield return new object[] { "fr-FR", new string[] { "dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi" } };
- yield return new object[] { "gu-IN", new string[] { "રવિવાર", "સોમવાર", "મંગળવાર", "બુધવાર", "ગુરુવાર", "શુક્રવાર", "શનિવાર" } };
- yield return new object[] { "he-IL", new string[] { "יום ראשון", "יום שני", "יום שלישי", "יום רביעי", "יום חמישי", "יום שישי", "יום שבת" } };
- yield return new object[] { "hi-IN", new string[] { "रविवार", "सोमवार", "मंगलवार", "बुधवार", "गुरुवार", "शुक्रवार", "शनिवार" } };
- yield return new object[] { "hr-HR", new string[] { "nedjelja", "ponedjeljak", "utorak", "srijeda", "četvrtak", "petak", "subota" } };
- yield return new object[] { "hu-HU", new string[] { "vasárnap", "hétfő", "kedd", "szerda", "csütörtök", "péntek", "szombat" } };
- yield return new object[] { "id-ID", new string[] { "Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu" } };
- yield return new object[] { "it-IT", new string[] { "domenica", "lunedì", "martedì", "mercoledì", "giovedì", "venerdì", "sabato" } };
- yield return new object[] { "ja-JP", new string[] { "日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日" } };
- yield return new object[] { "kn-IN", new string[] { "ಭಾನುವಾರ", "ಸೋಮವಾರ", "ಮಂಗಳವಾರ", "ಬುಧವಾರ", "ಗುರುವಾರ", "ಶುಕ್ರವಾರ", "ಶನಿವಾರ" } };
- yield return new object[] { "ko-KR", new string[] { "일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일" } };
- yield return new object[] { "lt-LT", new string[] { "sekmadienis", "pirmadienis", "antradienis", "trečiadienis", "ketvirtadienis", "penktadienis", "šeštadienis" } };
- yield return new object[] { "lv-LV", new string[] { "Svētdiena", "Pirmdiena", "Otrdiena", "Trešdiena", "Ceturtdiena", "Piektdiena", "Sestdiena" } };
- yield return new object[] { "ml-IN", new string[] { "ഞായറാഴ്ച", "തിങ്കളാഴ്ച", "ചൊവ്വാഴ്ച", "ബുധനാഴ്ച", "വ്യാഴാഴ്ച", "വെള്ളിയാഴ്ച", "ശനിയാഴ്ച" } };
- yield return new object[] { "ms-BN", new string[] { "Ahad", "Isnin", "Selasa", "Rabu", "Khamis", "Jumaat", "Sabtu" } };
- yield return new object[] { "no-NO", new string[] { "søndag", "mandag", "tirsdag", "onsdag", "torsdag", "fredag", "lørdag" } };
- yield return new object[] { "nl-AW", new string[] { "zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag" } };
- yield return new object[] { "pl-PL", new string[] { "niedziela", "poniedziałek", "wtorek", "środa", "czwartek", "piątek", "sobota" } };
- yield return new object[] { "pt-PT", new string[] { "domingo", "segunda-feira", "terça-feira", "quarta-feira", "quinta-feira", "sexta-feira", "sábado" } };
- yield return new object[] { "ro-RO", new string[] { "duminică", "luni", "marți", "miercuri", "joi", "vineri", "sâmbătă" } };
- yield return new object[] { "sk-SK", new string[] { "nedeľa", "pondelok", "utorok", "streda", "štvrtok", "piatok", "sobota" } };
- yield return new object[] { "sv-AX", new string[] { "söndag", "måndag", "tisdag", "onsdag", "torsdag", "fredag", "lördag" } };
- yield return new object[] { "sw-CD", new string[] { "Jumapili", "Jumatatu", "Jumanne", "Jumatano", "Alhamisi", "Ijumaa", "Jumamosi" } };
- yield return new object[] { "ta-IN", new string[] { "ஞாயிறு", "திங்கள்", "செவ்வாய்", "புதன்", "வியாழன்", "வெள்ளி", "சனி" } };
- yield return new object[] { "te-IN", new string[] { "ఆదివారం", "సోమవారం", "మంగళవారం", "బుధవారం", "గురువారం", "శుక్రవారం", "శనివారం" } };
- yield return new object[] { "th-TH", new string[] { "วันอาทิตย์", "วันจันทร์", "วันอังคาร", "วันพุธ", "วันพฤหัสบดี", "วันศุกร์", "วันเสาร์" } };
- yield return new object[] { "tr-CY", new string[] { "Pazar", "Pazartesi", "Salı", "Çarşamba", "Perşembe", "Cuma", "Cumartesi" } };
- yield return new object[] { "uk-UA", new string[] { "неділя", "понеділок", "вівторок", "середа", "четвер", "пʼятниця", "субота" } };
- yield return new object[] { "vi-VN", new string[] { "Chủ Nhật", "Thứ Hai", "Thứ Ba", "Thứ Tư", "Thứ Năm", "Thứ Sáu", "Thứ Bảy" } };
- yield return new object[] { "zh-TW", new string[] { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" } };
- }
-
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsIcuGlobalization))]
[MemberData(nameof(DayNames_Get_TestData_ICU))]
public void DayNames_Get_ReturnsExpected_ICU(DateTimeFormatInfo format, string[] expected)
@@ -91,17 +41,6 @@ public void DayNames_Get_ReturnsExpected_ICU(DateTimeFormatInfo format, string[]
Assert.Equal(expected, format.DayNames);
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
- [MemberData(nameof(DayNames_Get_TestData_HybridGlobalization))]
- public void DayNames_Get_ReturnsExpected_HybridGlobalization(string cultureName, string[] expected)
- {
- var format = new CultureInfo(cultureName).DateTimeFormat;
- int length = format.DayNames.Length;
- Assert.True(length == expected.Length, $"Length comparison failed for culture: {cultureName}. Expected: {expected.Length}, Actual: {length}");
- for (int i = 0; i FirstDayOfWeek_Get_TestData()
yield return new object[] { new CultureInfo("fr-FR", false).DateTimeFormat, DayOfWeek.Monday, "fr-FR" };
}
- public static IEnumerable FirstDayOfWeek_Get_TestData_HybridGlobalization()
- {
- // see the comments on the right to check the non-Hybrid result, if it differs
- yield return new object[] { "ar-SA", DayOfWeek.Sunday };
- yield return new object[] { "am-ET", DayOfWeek.Sunday };
- yield return new object[] { "bg-BG", DayOfWeek.Monday };
- yield return new object[] { "bn-BD", DayOfWeek.Sunday };
- yield return new object[] { "bn-IN", DayOfWeek.Sunday };
- yield return new object[] { "ca-AD", DayOfWeek.Monday };
- yield return new object[] { "ca-ES", DayOfWeek.Monday };
- yield return new object[] { "cs-CZ", DayOfWeek.Monday };
- yield return new object[] { "da-DK", DayOfWeek.Monday };
- yield return new object[] { "de-AT", DayOfWeek.Monday };
- yield return new object[] { "de-BE", DayOfWeek.Monday };
- yield return new object[] { "de-CH", DayOfWeek.Monday };
- yield return new object[] { "de-DE", DayOfWeek.Monday };
- yield return new object[] { "de-IT", DayOfWeek.Monday };
- yield return new object[] { "de-LI", DayOfWeek.Monday };
- yield return new object[] { "de-LU", DayOfWeek.Monday };
- yield return new object[] { "el-CY", DayOfWeek.Monday };
- yield return new object[] { "el-GR", DayOfWeek.Monday };
- yield return new object[] { "en-AE", DayOfWeek.Saturday };
- yield return new object[] { "en-AG", DayOfWeek.Sunday };
- yield return new object[] { "en-AI", DayOfWeek.Monday };
- yield return new object[] { "en-AS", DayOfWeek.Sunday };
- yield return new object[] { "en-AT", DayOfWeek.Monday };
- yield return new object[] { "en-AU", DayOfWeek.Monday }; // originally in ICU: Sunday, even though ISO 8601 states: Monday
- yield return new object[] { "en-BB", DayOfWeek.Monday };
- yield return new object[] { "en-BE", DayOfWeek.Monday };
- yield return new object[] { "en-BI", DayOfWeek.Monday };
- yield return new object[] { "en-BM", DayOfWeek.Monday };
- yield return new object[] { "en-BS", DayOfWeek.Sunday };
- yield return new object[] { "en-BW", DayOfWeek.Sunday };
- yield return new object[] { "en-BZ", DayOfWeek.Sunday };
- yield return new object[] { "en-CA", DayOfWeek.Sunday };
- yield return new object[] { "en-CC", DayOfWeek.Monday };
- yield return new object[] { "en-CH", DayOfWeek.Monday };
- yield return new object[] { "en-CK", DayOfWeek.Monday };
- yield return new object[] { "en-CM", DayOfWeek.Monday };
- yield return new object[] { "en-CX", DayOfWeek.Monday };
- yield return new object[] { "en-CY", DayOfWeek.Monday };
- yield return new object[] { "en-DE", DayOfWeek.Monday };
- yield return new object[] { "en-DK", DayOfWeek.Monday };
- yield return new object[] { "en-DM", DayOfWeek.Sunday };
- yield return new object[] { "en-ER", DayOfWeek.Monday };
- yield return new object[] { "en-FI", DayOfWeek.Monday };
- yield return new object[] { "en-FJ", DayOfWeek.Monday };
- yield return new object[] { "en-FK", DayOfWeek.Monday };
- yield return new object[] { "en-FM", DayOfWeek.Monday };
- yield return new object[] { "en-GB", DayOfWeek.Monday };
- yield return new object[] { "en-GD", DayOfWeek.Monday };
- yield return new object[] { "en-GG", DayOfWeek.Monday };
- yield return new object[] { "en-GH", DayOfWeek.Monday };
- yield return new object[] { "en-GI", DayOfWeek.Monday };
- yield return new object[] { "en-GM", DayOfWeek.Monday };
- yield return new object[] { "en-GU", DayOfWeek.Sunday };
- yield return new object[] { "en-GY", DayOfWeek.Monday };
- yield return new object[] { "en-HK", DayOfWeek.Sunday };
- yield return new object[] { "en-IE", DayOfWeek.Monday };
- yield return new object[] { "en-IL", DayOfWeek.Sunday };
- yield return new object[] { "en-IM", DayOfWeek.Monday };
- yield return new object[] { "en-IN", DayOfWeek.Sunday };
- yield return new object[] { "en-IO", DayOfWeek.Monday };
- yield return new object[] { "en-JE", DayOfWeek.Monday };
- yield return new object[] { "en-JM", DayOfWeek.Sunday };
- yield return new object[] { "en-KE", DayOfWeek.Sunday };
- yield return new object[] { "en-KI", DayOfWeek.Monday };
- yield return new object[] { "en-KN", DayOfWeek.Monday };
- yield return new object[] { "en-KY", DayOfWeek.Monday };
- yield return new object[] { "en-LC", DayOfWeek.Monday };
- yield return new object[] { "en-LR", DayOfWeek.Monday };
- yield return new object[] { "en-LS", DayOfWeek.Monday };
- yield return new object[] { "en-MG", DayOfWeek.Monday };
- yield return new object[] { "en-MH", DayOfWeek.Sunday };
- yield return new object[] { "en-MO", DayOfWeek.Sunday };
- yield return new object[] { "en-MP", DayOfWeek.Monday };
- yield return new object[] { "en-MS", DayOfWeek.Monday };
- yield return new object[] { "en-MT", DayOfWeek.Sunday };
- yield return new object[] { "en-MU", DayOfWeek.Monday };
- yield return new object[] { "en-MW", DayOfWeek.Monday };
- yield return new object[] { "en-MY", DayOfWeek.Monday };
- yield return new object[] { "en-NA", DayOfWeek.Monday };
- yield return new object[] { "en-NF", DayOfWeek.Monday };
- yield return new object[] { "en-NG", DayOfWeek.Monday };
- yield return new object[] { "en-NL", DayOfWeek.Monday };
- yield return new object[] { "en-NR", DayOfWeek.Monday };
- yield return new object[] { "en-NU", DayOfWeek.Monday };
- yield return new object[] { "en-NZ", DayOfWeek.Monday };
- yield return new object[] { "en-PG", DayOfWeek.Monday };
- yield return new object[] { "en-PH", DayOfWeek.Sunday };
- yield return new object[] { "en-PK", DayOfWeek.Sunday };
- yield return new object[] { "en-PN", DayOfWeek.Monday };
- yield return new object[] { "en-PR", DayOfWeek.Sunday };
- yield return new object[] { "en-PW", DayOfWeek.Monday };
- yield return new object[] { "en-RW", DayOfWeek.Monday };
- yield return new object[] { "en-SB", DayOfWeek.Monday };
- yield return new object[] { "en-SC", DayOfWeek.Monday };
- yield return new object[] { "en-SD", DayOfWeek.Saturday };
- yield return new object[] { "en-SE", DayOfWeek.Monday };
- yield return new object[] { "en-SG", DayOfWeek.Sunday };
- yield return new object[] { "en-SH", DayOfWeek.Monday };
- yield return new object[] { "en-SI", DayOfWeek.Monday };
- yield return new object[] { "en-SL", DayOfWeek.Monday };
- yield return new object[] { "en-SS", DayOfWeek.Monday };
- yield return new object[] { "en-SX", DayOfWeek.Monday };
- yield return new object[] { "en-SZ", DayOfWeek.Monday };
- yield return new object[] { "en-TC", DayOfWeek.Monday };
- yield return new object[] { "en-TK", DayOfWeek.Monday };
- yield return new object[] { "en-TO", DayOfWeek.Monday };
- yield return new object[] { "en-TT", DayOfWeek.Sunday };
- yield return new object[] { "en-TV", DayOfWeek.Monday };
- yield return new object[] { "en-TZ", DayOfWeek.Monday };
- yield return new object[] { "en-UG", DayOfWeek.Monday };
- yield return new object[] { "en-UM", DayOfWeek.Sunday };
- yield return new object[] { "en-VC", DayOfWeek.Monday };
- yield return new object[] { "en-VG", DayOfWeek.Monday };
- yield return new object[] { "en-VI", DayOfWeek.Sunday };
- yield return new object[] { "en-VU", DayOfWeek.Monday };
- yield return new object[] { "en-WS", DayOfWeek.Sunday };
- yield return new object[] { "en-ZA", DayOfWeek.Sunday };
- yield return new object[] { "en-ZM", DayOfWeek.Monday };
- yield return new object[] { "en-ZW", DayOfWeek.Sunday };
- yield return new object[] { "en-US", DayOfWeek.Sunday };
- yield return new object[] { "es-419", DayOfWeek.Monday };
- yield return new object[] { "es-ES", DayOfWeek.Monday };
- yield return new object[] { "es-MX", DayOfWeek.Sunday };
- yield return new object[] { "et-EE", DayOfWeek.Monday };
- yield return new object[] { "fa-IR", DayOfWeek.Saturday };
- yield return new object[] { "fi-FI", DayOfWeek.Monday };
- yield return new object[] { "fil-PH", DayOfWeek.Sunday };
- yield return new object[] { "fr-BE", DayOfWeek.Monday };
- yield return new object[] { "fr-CA", DayOfWeek.Sunday };
- yield return new object[] { "fr-CH", DayOfWeek.Monday };
- yield return new object[] { "fr-FR", DayOfWeek.Monday };
- yield return new object[] { "gu-IN", DayOfWeek.Sunday };
- yield return new object[] { "he-IL", DayOfWeek.Sunday };
- yield return new object[] { "hi-IN", DayOfWeek.Sunday };
- yield return new object[] { "hr-BA", DayOfWeek.Monday };
- yield return new object[] { "hr-HR", DayOfWeek.Monday };
- yield return new object[] { "hu-HU", DayOfWeek.Monday };
- yield return new object[] { "id-ID", DayOfWeek.Sunday };
- yield return new object[] { "it-CH", DayOfWeek.Monday };
- yield return new object[] { "it-IT", DayOfWeek.Monday };
- yield return new object[] { "ja-JP", DayOfWeek.Sunday };
- yield return new object[] { "kn-IN", DayOfWeek.Sunday };
- yield return new object[] { "ko-KR", DayOfWeek.Sunday };
- yield return new object[] { "lt-LT", DayOfWeek.Monday };
- yield return new object[] { "lv-LV", DayOfWeek.Monday };
- yield return new object[] { "ml-IN", DayOfWeek.Sunday };
- yield return new object[] { "mr-IN", DayOfWeek.Sunday };
- yield return new object[] { "ms-BN", DayOfWeek.Monday };
- yield return new object[] { "ms-MY", DayOfWeek.Monday };
- yield return new object[] { "ms-SG", DayOfWeek.Sunday };
- yield return new object[] { "nb-NO", DayOfWeek.Monday };
- yield return new object[] { "no", DayOfWeek.Monday };
- yield return new object[] { "no-NO", DayOfWeek.Monday };
- yield return new object[] { "nl-AW", DayOfWeek.Monday };
- yield return new object[] { "nl-BE", DayOfWeek.Monday };
- yield return new object[] { "nl-NL", DayOfWeek.Monday };
- yield return new object[] { "pl-PL", DayOfWeek.Monday };
- yield return new object[] { "pt-BR", DayOfWeek.Sunday };
- yield return new object[] { "pt-PT", DayOfWeek.Sunday };
- yield return new object[] { "ro-RO", DayOfWeek.Monday };
- yield return new object[] { "ru-RU", DayOfWeek.Monday };
- yield return new object[] { "sk-SK", DayOfWeek.Monday };
- yield return new object[] { "sl-SI", DayOfWeek.Monday };
- yield return new object[] { "sr-Cyrl-RS", DayOfWeek.Monday };
- yield return new object[] { "sr-Latn-RS", DayOfWeek.Monday };
- yield return new object[] { "sv-AX", DayOfWeek.Monday };
- yield return new object[] { "sv-SE", DayOfWeek.Monday };
- yield return new object[] { "sw-CD", DayOfWeek.Monday };
- yield return new object[] { "sw-KE", DayOfWeek.Sunday };
- yield return new object[] { "sw-TZ", DayOfWeek.Monday };
- yield return new object[] { "sw-UG", DayOfWeek.Monday };
- yield return new object[] { "ta-IN", DayOfWeek.Sunday };
- yield return new object[] { "ta-LK", DayOfWeek.Monday };
- yield return new object[] { "ta-MY", DayOfWeek.Monday };
- yield return new object[] { "ta-SG", DayOfWeek.Sunday };
- yield return new object[] { "te-IN", DayOfWeek.Sunday };
- yield return new object[] { "th-TH", DayOfWeek.Sunday };
- yield return new object[] { "tr-CY", DayOfWeek.Monday };
- yield return new object[] { "tr-TR", DayOfWeek.Monday };
- yield return new object[] { "uk-UA", DayOfWeek.Monday };
- yield return new object[] { "vi-VN", DayOfWeek.Monday };
- yield return new object[] { "zh-CN", DayOfWeek.Monday };
- yield return new object[] { "zh-Hans-HK", DayOfWeek.Sunday };
- yield return new object[] { "zh-SG", DayOfWeek.Sunday };
- yield return new object[] { "zh-HK", DayOfWeek.Sunday };
- yield return new object[] { "zh-TW", DayOfWeek.Sunday };
- }
-
[Theory]
[MemberData(nameof(FirstDayOfWeek_Get_TestData))]
public void FirstDayOfWeek(DateTimeFormatInfo format, DayOfWeek expected, string cultureName)
@@ -213,14 +22,6 @@ public void FirstDayOfWeek(DateTimeFormatInfo format, DayOfWeek expected, string
Assert.True(expected == format.FirstDayOfWeek, $"Failed for culture: {cultureName}. Expected: {expected}, Actual: {format.FirstDayOfWeek}");
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
- [MemberData(nameof(FirstDayOfWeek_Get_TestData_HybridGlobalization))]
- public void FirstDayOfWeekHybridGlobalization(string culture, DayOfWeek expected)
- {
- DateTimeFormatInfo format = new CultureInfo(culture).DateTimeFormat;
- FirstDayOfWeek(format, expected, culture);
- }
-
[Theory]
[InlineData(DayOfWeek.Sunday)]
[InlineData(DayOfWeek.Monday)]
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoFullDateTimePattern.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoFullDateTimePattern.cs
index f84360d35dee9e..fa95f525304265 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoFullDateTimePattern.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoFullDateTimePattern.cs
@@ -24,204 +24,6 @@ public static IEnumerable FullDateTimePattern_Set_TestData()
yield return new object[] { "HH:mm:ss dddd, dd MMMM yyyy" };
}
- public static IEnumerable FullDateTimePattern_Get_TestData_HybridGlobalization()
- {
- yield return new object[] { new CultureInfo("ar-SA").DateTimeFormat, "dddd، d MMMM yyyy h:mm:ss tt" }; // dddd، d MMMM yyyy g h:mm:ss tt
- yield return new object[] { new CultureInfo("am-ET").DateTimeFormat, "yyyy MMMM d, dddd h:mm:ss tt" };
- yield return new object[] { new CultureInfo("bg-BG").DateTimeFormat, PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "dddd, d MMMM yyyy 'г'. H:mm:ss ч." : "dddd, d MMMM yyyy 'г'. H:mm:ss" }; // dddd, d MMMM yyyy 'г'. H:mm:ss
- yield return new object[] { new CultureInfo("bn-BD").DateTimeFormat, "dddd, d MMMM, yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("bn-IN").DateTimeFormat, "dddd, d MMMM, yyyy h:mm:ss tt" };
- string catalanPattern = PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "dddd, d 'de' MMMM 'de' yyyy H:mm:ss" : "dddd, d 'de' MMMM 'del' yyyy H:mm:ss"; // dddd, d MMMM 'de' yyyy H:mm:ss
- yield return new object[] { new CultureInfo("ca-AD").DateTimeFormat, catalanPattern };
- yield return new object[] { new CultureInfo("ca-ES").DateTimeFormat, catalanPattern };
- yield return new object[] { new CultureInfo("cs-CZ").DateTimeFormat, "dddd d. MMMM yyyy H:mm:ss" };
- yield return new object[] { new CultureInfo("da-DK").DateTimeFormat, "dddd 'den' d. MMMM yyyy HH.mm.ss" };
- yield return new object[] { new CultureInfo("de-AT").DateTimeFormat, "dddd, d. MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("de-BE").DateTimeFormat, "dddd, d. MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("de-CH").DateTimeFormat, "dddd, d. MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("de-DE").DateTimeFormat, "dddd, d. MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("de-IT").DateTimeFormat, "dddd, d. MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("de-LI").DateTimeFormat, "dddd, d. MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("de-LU").DateTimeFormat, "dddd, d. MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("el-CY").DateTimeFormat, "dddd d MMMM yyyy h:mm:ss tt" }; // dddd, d MMMM yyyy h:mm:ss tt
- yield return new object[] { new CultureInfo("el-GR").DateTimeFormat, "dddd d MMMM yyyy h:mm:ss tt" }; // dddd, d MMMM yyyy h:mm:ss tt
- yield return new object[] { new CultureInfo("en-AE").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-AG").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-AI").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-AS").DateTimeFormat, "dddd, MMMM d, yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-AT").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-AU").DateTimeFormat, PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "dddd, d MMMM yyyy h:mm:ss tt" : "dddd d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-BB").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-BE").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-BI").DateTimeFormat, "dddd, MMMM d, yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-BM").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-BS").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-BW").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" }; // dddd, dd MMMM yyyy HH:mm:ss
- yield return new object[] { new CultureInfo("en-BZ").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" }; // dddd, dd MMMM yyyy HH:mm:ss
- yield return new object[] { new CultureInfo("en-CA").DateTimeFormat, "dddd, MMMM d, yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-CC").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-CH").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-CK").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-CM").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-CX").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-CY").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-DE").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-DK").DateTimeFormat, "dddd, d MMMM yyyy HH.mm.ss" };
- yield return new object[] { new CultureInfo("en-DM").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-ER").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-FI").DateTimeFormat, "dddd, d MMMM yyyy H.mm.ss" };
- yield return new object[] { new CultureInfo("en-FJ").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-FK").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-FM").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-GB").DateTimeFormat, PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "dddd, d MMMM yyyy HH:mm:ss" : "dddd d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-GD").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-GG").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-GH").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-GI").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-GM").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-GU").DateTimeFormat, "dddd, MMMM d, yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-GY").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-HK").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-IE").DateTimeFormat, "dddd d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-IL").DateTimeFormat, "dddd, d MMMM yyyy H:mm:ss" };
- yield return new object[] { new CultureInfo("en-IM").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-IN").DateTimeFormat, PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "dddd, d MMMM, yyyy h:mm:ss tt" : "dddd d MMMM, yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-IO").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-JE").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-JM").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-KE").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-KI").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-KN").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-KY").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-LC").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-LR").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-LS").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-MG").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-MH").DateTimeFormat, "dddd, MMMM d, yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-MO").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-MP").DateTimeFormat, "dddd, MMMM d, yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-MS").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-MT").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-MU").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-MW").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-MY").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-NA").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-NF").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-NG").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-NL").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-NR").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-NU").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-NZ").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-PG").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-PH").DateTimeFormat, "dddd, MMMM d, yyyy h:mm:ss tt" }; // dddd, d MMMM yyyy h:mm:ss tt
- yield return new object[] { new CultureInfo("en-PK").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-PN").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-PR").DateTimeFormat, "dddd, MMMM d, yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-PW").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-RW").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-SB").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-SC").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-SD").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-SE").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-SG").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-SH").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-SI").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-SL").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-SS").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-SX").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-SZ").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-TC").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-TK").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-TO").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-TT").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-TV").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-TZ").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-UG").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-UM").DateTimeFormat, "dddd, MMMM d, yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-US").DateTimeFormat, "dddd, MMMM d, yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-VC").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-VG").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-VI").DateTimeFormat, "dddd, MMMM d, yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-VU").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-WS").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-ZA").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" }; // dddd, dd MMMM yyyy HH:mm:ss
- yield return new object[] { new CultureInfo("en-ZM").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-ZW").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" }; // dddd, dd MMMM yyyy HH:mm:ss
- string latinAmericaSpanishFormat = PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "dddd, d 'de' MMMM 'de' yyyy HH:mm:ss" : "dddd, d 'de' MMMM 'de' yyyy h:mm:ss tt"; // dddd, d 'de' MMMM 'de' yyyy HH:mm:ss
- yield return new object[] { new CultureInfo("es-419").DateTimeFormat, latinAmericaSpanishFormat };
- yield return new object[] { new CultureInfo("es-ES").DateTimeFormat, "dddd, d 'de' MMMM 'de' yyyy H:mm:ss" };
- yield return new object[] { new CultureInfo("es-MX").DateTimeFormat, latinAmericaSpanishFormat };
- yield return new object[] { new CultureInfo("et-EE").DateTimeFormat, "dddd, d. MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("fa-IR").DateTimeFormat, "yyyy MMMM d, dddd H:mm:ss" };
- yield return new object[] { new CultureInfo("fi-FI").DateTimeFormat, "dddd d. MMMM yyyy H.mm.ss" };
- yield return new object[] { new CultureInfo("fil-PH").DateTimeFormat, "dddd, MMMM d, yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("fr-BE").DateTimeFormat, "dddd d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("fr-CA").DateTimeFormat, "dddd d MMMM yyyy HH 'h' mm 'min' ss 's'" };
- yield return new object[] { new CultureInfo("fr-CH").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("fr-FR").DateTimeFormat, "dddd d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("gu-IN").DateTimeFormat, "dddd, d MMMM, yyyy hh:mm:ss tt" };
- yield return new object[] { new CultureInfo("he-IL").DateTimeFormat, "dddd, d בMMMM yyyy H:mm:ss" };
- yield return new object[] { new CultureInfo("hi-IN").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("hr-BA").DateTimeFormat, "dddd, d. MMMM yyyy. HH:mm:ss" };
- yield return new object[] { new CultureInfo("hr-HR").DateTimeFormat, "dddd, d. MMMM yyyy. HH:mm:ss" };
- yield return new object[] { new CultureInfo("hu-HU").DateTimeFormat, "yyyy. MMMM d., dddd H:mm:ss" };
- yield return new object[] { new CultureInfo("id-ID").DateTimeFormat, "dddd, d MMMM yyyy HH.mm.ss" }; // dddd, dd MMMM yyyy HH.mm.ss
- yield return new object[] { new CultureInfo("it-CH").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("it-IT").DateTimeFormat, "dddd d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("ja-JP").DateTimeFormat, "yyyy年M月d日dddd H:mm:ss" };
- yield return new object[] { new CultureInfo("kn-IN").DateTimeFormat, "dddd, MMMM d, yyyy hh:mm:ss tt" };
- yield return new object[] { new CultureInfo("ko-KR").DateTimeFormat, "yyyy년 M월 d일 dddd tt h:mm:ss" };
- yield return new object[] { new CultureInfo("lt-LT").DateTimeFormat, "yyyy 'm'. MMMM d 'd'., dddd HH:mm:ss" };
- yield return new object[] { new CultureInfo("lv-LV").DateTimeFormat, "dddd, yyyy. 'gada' d. MMMM HH:mm:ss" };
- yield return new object[] { new CultureInfo("ml-IN").DateTimeFormat, "yyyy, MMMM d, dddd h:mm:ss tt" };
- yield return new object[] { new CultureInfo("mr-IN").DateTimeFormat, "dddd, d MMMM, yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("ms-BN").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" }; // dd MMMM yyyy h:mm:ss tt
- yield return new object[] { new CultureInfo("ms-MY").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("ms-SG").DateTimeFormat, "dddd, d MMMM yyyy h:mm:ss tt" };
- yield return new object[] { new CultureInfo("nb-NO").DateTimeFormat, "dddd d. MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("no-NO").DateTimeFormat, "dddd d. MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("nl-AW").DateTimeFormat, "dddd d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("nl-BE").DateTimeFormat, "dddd d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("nl-NL").DateTimeFormat, "dddd d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("pl-PL").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("pt-BR").DateTimeFormat, "dddd, d 'de' MMMM 'de' yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("pt-PT").DateTimeFormat, "dddd, d 'de' MMMM 'de' yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("ro-RO").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("ru-RU").DateTimeFormat, "dddd, d MMMM yyyy 'г'. HH:mm:ss" };
- yield return new object[] { new CultureInfo("sk-SK").DateTimeFormat, "dddd d. MMMM yyyy H:mm:ss" };
- yield return new object[] { new CultureInfo("sl-SI").DateTimeFormat, "dddd, d. MMMM yyyy HH:mm:ss" }; // dddd, dd. MMMM yyyy HH:mm:ss
- yield return new object[] { new CultureInfo("sr-Cyrl-RS").DateTimeFormat, "dddd, d. MMMM yyyy. HH:mm:ss" }; // dddd, dd. MMMM yyyy. HH:mm:ss
- yield return new object[] { new CultureInfo("sr-Latn-RS").DateTimeFormat, "dddd, d. MMMM yyyy. HH:mm:ss" }; // dddd, dd. MMMM yyyy. HH:mm:ss
- yield return new object[] { new CultureInfo("sv-AX").DateTimeFormat, "dddd d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("sv-SE").DateTimeFormat, "dddd d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("sw-CD").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("sw-KE").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("sw-TZ").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("sw-UG").DateTimeFormat, "dddd, d MMMM yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("ta-IN").DateTimeFormat, "dddd, d MMMM, yyyy tt h:mm:ss" };
- yield return new object[] { new CultureInfo("ta-LK").DateTimeFormat, "dddd, d MMMM, yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("ta-MY").DateTimeFormat, "dddd, d MMMM, yyyy tt h:mm:ss" };
- yield return new object[] { new CultureInfo("ta-SG").DateTimeFormat, "dddd, d MMMM, yyyy tt h:mm:ss" };
- yield return new object[] { new CultureInfo("te-IN").DateTimeFormat, "d, MMMM yyyy, dddd h:mm:ss tt" };
- yield return new object[] { new CultureInfo("th-TH").DateTimeFormat, "ddddที่ d MMMM g yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("tr-CY").DateTimeFormat, "d MMMM yyyy dddd h:mm:ss tt" };
- yield return new object[] { new CultureInfo("tr-TR").DateTimeFormat, "d MMMM yyyy dddd HH:mm:ss" };
- yield return new object[] { new CultureInfo("uk-UA").DateTimeFormat, "dddd, d MMMM yyyy 'р'. HH:mm:ss" };
- yield return new object[] { new CultureInfo("vi-VN").DateTimeFormat, "dddd, d MMMM, yyyy HH:mm:ss" };
- yield return new object[] { new CultureInfo("zh-CN").DateTimeFormat, "yyyy年M月d日dddd HH:mm:ss" }; // yyyy年M月d日dddd tth:mm:ss
- yield return new object[] { new CultureInfo("zh-Hans-HK").DateTimeFormat, "yyyy年M月d日dddd tth:mm:ss" };
- yield return new object[] { new CultureInfo("zh-SG").DateTimeFormat, "yyyy年M月d日dddd tth:mm:ss" };
- yield return new object[] { new CultureInfo("zh-HK").DateTimeFormat, "yyyy年M月d日dddd tth:mm:ss" };
- yield return new object[] { new CultureInfo("zh-TW").DateTimeFormat, "yyyy年M月d日 dddd tth:mm:ss" };
- }
-
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
- [MemberData(nameof(FullDateTimePattern_Get_TestData_HybridGlobalization))]
- public void FullDateTimePattern_Get_ReturnsExpected_HybridGlobalization(DateTimeFormatInfo format, string value)
- {
- Assert.Equal(value, format.FullDateTimePattern);
- }
-
[Theory]
[MemberData(nameof(FullDateTimePattern_Set_TestData))]
public void FullDateTimePattern_Set_GetReturnsExpected(string value)
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoGetAbbreviatedEraName.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoGetAbbreviatedEraName.cs
index 18de097fff17ee..bff773b9038c2f 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoGetAbbreviatedEraName.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoGetAbbreviatedEraName.cs
@@ -15,197 +15,6 @@ public static IEnumerable GetAbbreviatedEraName_TestData()
yield return new object[] { "invariant", 0, "AD" };
yield return new object[] { "invariant", 1, "AD" };
yield return new object[] { "ja-JP", 1, DateTimeFormatInfoData.JaJPAbbreviatedEraName() };
-
- if (PlatformDetection.IsHybridGlobalizationOnBrowser)
- {
- // see the comments on the right to check the non-Hybrid result, if it differs
- yield return new object[] { "ar-SA", 1, "هـ" };
- yield return new object[] { "am-ET", 1, "ዓ/ም" };
- yield return new object[] { "bg-BG", 1, "сл.Хр." };
- yield return new object[] { "bn-BD", 1, "খৃষ্টাব্দ" };
- yield return new object[] { "bn-IN", 1, "খ্রিঃ" }; // "খৃষ্টাব্দ"
- yield return new object[] { "ca-AD", 1, "dC" };
- yield return new object[] { "ca-ES", 1, "dC" };
- yield return new object[] { "cs-CZ", 1, "n.l." };
- yield return new object[] { "da-DK", 1, "eKr" };
- yield return new object[] { "de-AT", 1, "n. Chr." };
- yield return new object[] { "de-BE", 1, "n. Chr." };
- yield return new object[] { "de-CH", 1, "n. Chr." };
- yield return new object[] { "de-DE", 1, "n. Chr." };
- yield return new object[] { "de-IT", 1, "n. Chr." };
- yield return new object[] { "de-LI", 1, "n. Chr." };
- yield return new object[] { "de-LU", 1, "n. Chr." };
- yield return new object[] { "el-CY", 1, "μ.Χ." };
- yield return new object[] { "el-GR", 1, "μ.Χ." };
- yield return new object[] { "en-AE", 1, "A" }; // AD
- yield return new object[] { "en-AG", 1, "A" }; // AD
- yield return new object[] { "en-AI", 1, "A" }; // AD
- yield return new object[] { "en-AS", 1, "A" };
- yield return new object[] { "en-AT", 1, "A" }; // AD
- yield return new object[] { "en-AU", 1, "A" }; // AD
- yield return new object[] { "en-BB", 1, "A" }; // AD
- yield return new object[] { "en-BE", 1, "A" }; // AD
- yield return new object[] { "en-BI", 1, "A" }; // AD
- yield return new object[] { "en-BM", 1, "A" }; // AD
- yield return new object[] { "en-BS", 1, "A" }; // AD
- yield return new object[] { "en-BW", 1, "A" }; // AD
- yield return new object[] { "en-BZ", 1, "A" }; // AD
- yield return new object[] { "en-CA", 1, "A" }; // AD
- yield return new object[] { "en-CC", 1, "A" }; // AD
- yield return new object[] { "en-CH", 1, "A" }; // AD
- yield return new object[] { "en-CK", 1, "A" }; // AD
- yield return new object[] { "en-CM", 1, "A" }; // AD
- yield return new object[] { "en-CX", 1, "A" }; // AD
- yield return new object[] { "en-CY", 1, "A" }; // AD
- yield return new object[] { "en-DE", 1, "A" }; // AD
- yield return new object[] { "en-DK", 1, "A" }; // AD
- yield return new object[] { "en-DM", 1, "A" }; // AD
- yield return new object[] { "en-ER", 1, "A" }; // AD
- yield return new object[] { "en-FI", 1, "A" }; // AD
- yield return new object[] { "en-FJ", 1, "A" }; // AD
- yield return new object[] { "en-FK", 1, "A" }; // AD
- yield return new object[] { "en-FM", 1, "A" }; // AD
- yield return new object[] { "en-GB", 1, "A" }; // AD
- yield return new object[] { "en-GD", 1, "A" }; // AD
- yield return new object[] { "en-GG", 1, "A" }; // AD
- yield return new object[] { "en-GH", 1, "A" }; // AD
- yield return new object[] { "en-GI", 1, "A" }; // AD
- yield return new object[] { "en-GM", 1, "A" }; // AD
- yield return new object[] { "en-GU", 1, "A" };
- yield return new object[] { "en-GY", 1, "A" }; // AD
- yield return new object[] { "en-HK", 1, "A" }; // AD
- yield return new object[] { "en-IE", 1, "A" }; // AD
- yield return new object[] { "en-IL", 1, "A" }; // AD
- yield return new object[] { "en-IM", 1, "A" }; // AD
- yield return new object[] { "en-IN", 1, "A" }; // AD
- yield return new object[] { "en-IO", 1, "A" }; // AD
- yield return new object[] { "en-JE", 1, "A" }; // AD
- yield return new object[] { "en-JM", 1, "A" }; // AD
- yield return new object[] { "en-KE", 1, "A" }; // AD
- yield return new object[] { "en-KI", 1, "A" }; // AD
- yield return new object[] { "en-KN", 1, "A" }; // AD
- yield return new object[] { "en-KY", 1, "A" }; // AD
- yield return new object[] { "en-LC", 1, "A" }; // AD
- yield return new object[] { "en-LR", 1, "A" }; // AD
- yield return new object[] { "en-LS", 1, "A" }; // AD
- yield return new object[] { "en-MG", 1, "A" }; // AD
- yield return new object[] { "en-MH", 1, "A" };
- yield return new object[] { "en-MO", 1, "A" }; // AD
- yield return new object[] { "en-MP", 1, "A" };
- yield return new object[] { "en-MS", 1, "A" }; // AD
- yield return new object[] { "en-MT", 1, "A" }; // AD
- yield return new object[] { "en-MU", 1, "A" }; // AD
- yield return new object[] { "en-MW", 1, "A" }; // AD
- yield return new object[] { "en-MY", 1, "A" }; // AD
- yield return new object[] { "en-NA", 1, "A" }; // AD
- yield return new object[] { "en-NF", 1, "A" }; // AD
- yield return new object[] { "en-NG", 1, "A" }; // AD
- yield return new object[] { "en-NL", 1, "A" }; // AD
- yield return new object[] { "en-NR", 1, "A" }; // AD
- yield return new object[] { "en-NU", 1, "A" }; // AD
- yield return new object[] { "en-NZ", 1, "A" }; // AD
- yield return new object[] { "en-PG", 1, "A" }; // AD
- yield return new object[] { "en-PH", 1, "A" }; // AD
- yield return new object[] { "en-PK", 1, "A" }; // AD
- yield return new object[] { "en-PN", 1, "A" }; // AD
- yield return new object[] { "en-PR", 1, "A" };
- yield return new object[] { "en-PW", 1, "A" }; // AD
- yield return new object[] { "en-RW", 1, "A" }; // AD
- yield return new object[] { "en-SB", 1, "A" }; // AD
- yield return new object[] { "en-SC", 1, "A" }; // AD
- yield return new object[] { "en-SD", 1, "A" }; // AD
- yield return new object[] { "en-SE", 1, "A" }; // AD
- yield return new object[] { "en-SG", 1, "A" }; // AD
- yield return new object[] { "en-SH", 1, "A" }; // AD
- yield return new object[] { "en-SI", 1, "A" }; // AD
- yield return new object[] { "en-SL", 1, "A" }; // AD
- yield return new object[] { "en-SS", 1, "A" }; // AD
- yield return new object[] { "en-SX", 1, "A" }; // AD
- yield return new object[] { "en-SZ", 1, "A" }; // AD
- yield return new object[] { "en-TC", 1, "A" }; // AD
- yield return new object[] { "en-TK", 1, "A" }; // AD
- yield return new object[] { "en-TO", 1, "A" }; // AD
- yield return new object[] { "en-TT", 1, "A" }; // AD
- yield return new object[] { "en-TV", 1, "A" }; // AD
- yield return new object[] { "en-TZ", 1, "A" }; // AD
- yield return new object[] { "en-UG", 1, "A" }; // AD
- yield return new object[] { "en-UM", 1, "A" };
- yield return new object[] { "en-US", 1, "A" };
- yield return new object[] { "en-VC", 1, "A" }; // AD
- yield return new object[] { "en-VG", 1, "A" }; // AD
- yield return new object[] { "en-VI", 1, "A" };
- yield return new object[] { "en-VU", 1, "A" }; // AD
- yield return new object[] { "en-WS", 1, "A" }; // AD
- yield return new object[] { "en-ZA", 1, "A" }; // AD
- yield return new object[] { "en-ZM", 1, "A" }; // AD
- yield return new object[] { "en-ZW", 1, "A" }; // AD
- yield return new object[] { "es-ES", 1, "d. C." };
- yield return new object[] { "es-419", 1, "d.C." }; // "d. C."
- yield return new object[] { "es-MX", 1, "d.C." }; // "d. C."
- yield return new object[] { "et-EE", 1, "pKr" };
- yield return new object[] { "fa-IR", 1, "ه.ش" }; // ه.ش.
- yield return new object[] { "fi-FI", 1, "jKr" };
- yield return new object[] { "fil-PH", 1, "AD" };
- yield return new object[] { "fr-BE", 1, "ap. J.-C." };
- yield return new object[] { "fr-CA", 1, "ap. J.-C." };
- yield return new object[] { "fr-CH", 1, "ap. J.-C." };
- yield return new object[] { "fr-FR", 1, "ap. J.-C." };
- yield return new object[] { "gu-IN", 1, "ઇસ" };
- yield return new object[] { "he-IL", 1, "אחריי" }; // לספירה
- yield return new object[] { "hi-IN", 1, "ईस्वी" };
- yield return new object[] { "hr-BA", 1, "AD" }; // po. Kr.
- yield return new object[] { "hr-HR", 1, "AD" };
- yield return new object[] { "hu-HU", 1, "isz." };
- yield return new object[] { "id-ID", 1, "M" };
- yield return new object[] { "it-CH", 1, "dC" }; // d.C.
- yield return new object[] { "it-IT", 1, "dC" };
- yield return new object[] { "ja-JP", 1, "AD" };
- yield return new object[] { "kn-IN", 1, "ಕ್ರಿ.ಶ" };
- yield return new object[] { "ko-KR", 1, "AD" };
- yield return new object[] { "lt-LT", 1, "po Kr." };
- yield return new object[] { "lv-LV", 1, "m.ē." };
- yield return new object[] { "ml-IN", 1, "എഡി" };
- yield return new object[] { "mr-IN", 1, "इ. स." };
- yield return new object[] { "ms-BN", 1, "TM" };
- yield return new object[] { "ms-MY", 1, "TM" };
- yield return new object[] { "ms-SG", 1, "TM" };
- yield return new object[] { "nb-NO", 1, "e.Kr." };
- yield return new object[] { "no", 1, "e.Kr." };
- yield return new object[] { "no-NO", 1, "e.Kr." };
- yield return new object[] { "nl-AW", 1, "n.C." };
- yield return new object[] { "nl-BE", 1, "n.C." }; // n.Chr.
- yield return new object[] { "nl-NL", 1, "n.C." };
- yield return new object[] { "pl-PL", 1, "n.e." };
- yield return new object[] { "pt-BR", 1, "d.C." };
- yield return new object[] { "pt-PT", 1, "d.C." };
- yield return new object[] { "ro-RO", 1, "d.Hr." };
- yield return new object[] { "ru-RU", 1, "н.э." };
- yield return new object[] { "sk-SK", 1, "po Kr." };
- yield return new object[] { "sl-SI", 1, "po Kr." };
- yield return new object[] { "sr-Cyrl-RS", 1, "н.е." };
- yield return new object[] { "sr-Latn-RS", 1, "n.e." };
- yield return new object[] { "sv-AX", 1, "e.Kr." };
- yield return new object[] { "sv-SE", 1, "e.Kr." };
- yield return new object[] { "sw-CD", 1, "BK" };
- yield return new object[] { "sw-KE", 1, "BK" };
- yield return new object[] { "sw-TZ", 1, "BK" };
- yield return new object[] { "sw-UG", 1, "BK" };
- yield return new object[] { "ta-IN", 1, "கி.பி." };
- yield return new object[] { "ta-LK", 1, "கி.பி." };
- yield return new object[] { "ta-MY", 1, "கி.பி." };
- yield return new object[] { "ta-SG", 1, "கி.பி." };
- yield return new object[] { "te-IN", 1, "క్రీశ" };
- yield return new object[] { "th-TH", 1, "พ.ศ." };
- yield return new object[] { "tr-CY", 1, "MS" };
- yield return new object[] { "tr-TR", 1, "MS" };
- yield return new object[] { "uk-UA", 1, "н.е." };
- yield return new object[] { "vi-VN", 1, PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "sau CN" : "CN" }; // sau CN
- yield return new object[] { "zh-CN", 1, "公元" };
- yield return new object[] { "zh-Hans-HK", 1, "公元" };
- yield return new object[] { "zh-SG", 1, "公元" };
- yield return new object[] { "zh-HK", 1, "公元" };
- yield return new object[] { "zh-TW", 1, "西元" };
- }
}
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnApplePlatform))]
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoGetEraName.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoGetEraName.cs
index c007c7e11059a0..dd47204ea5d2a1 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoGetEraName.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoGetEraName.cs
@@ -12,394 +12,10 @@ public static IEnumerable GetEraName_TestData()
{
yield return new object[] { "invariant", 1, "A.D." };
yield return new object[] { "invariant", 0, "A.D." };
-
- if (!PlatformDetection.IsHybridGlobalizationOnBrowser)
- {
- var enUS = "en-US";
- yield return new object[] { enUS, 1, DateTimeFormatInfoData.EnUSEraName() };
- yield return new object[] { enUS, 0, DateTimeFormatInfoData.EnUSEraName() };
-
- var frFR = "fr-FR";
- yield return new object[] { frFR, 1, "ap. J.-C." };
- yield return new object[] { frFR, 0, "ap. J.-C." };
- }
- else
- {
- yield return new object[] { "ar-SA", 0, "بعد الهجرة" };
- yield return new object[] { "ar-SA", 1, "بعد الهجرة" };
- yield return new object[] { "am-ET", 0, "ዓ/ም" };
- yield return new object[] { "am-ET", 1, "ዓ/ም" };
- yield return new object[] { "bg-BG", 0, "сл.Хр." };
- yield return new object[] { "bg-BG", 1, "сл.Хр." };
- yield return new object[] { "bn-BD", 0, "খৃষ্টাব্দ" };
- yield return new object[] { "bn-BD", 1, "খৃষ্টাব্দ" };
- yield return new object[] { "bn-IN", 0, "খ্রিঃ" };
- yield return new object[] { "bn-IN", 1, "খ্রিঃ" };
- yield return new object[] { "ca-AD", 0, "dC" };
- yield return new object[] { "ca-AD", 1, "dC" };
- yield return new object[] { "ca-ES", 0, "dC" };
- yield return new object[] { "ca-ES", 1, "dC" };
- yield return new object[] { "cs-CZ", 0, "n. l." };
- yield return new object[] { "cs-CZ", 1, "n. l." };
- yield return new object[] { "da-DK", 0, "e.Kr." };
- yield return new object[] { "da-DK", 1, "e.Kr." };
- yield return new object[] { "de-AT", 0, "n. Chr." };
- yield return new object[] { "de-AT", 1, "n. Chr." };
- yield return new object[] { "de-BE", 0, "n. Chr." };
- yield return new object[] { "de-BE", 1, "n. Chr." };
- yield return new object[] { "de-CH", 0, "n. Chr." };
- yield return new object[] { "de-CH", 1, "n. Chr." };
- yield return new object[] { "de-DE", 0, "n. Chr." };
- yield return new object[] { "de-DE", 1, "n. Chr." };
- yield return new object[] { "de-IT", 0, "n. Chr." };
- yield return new object[] { "de-IT", 1, "n. Chr." };
- yield return new object[] { "de-LI", 0, "n. Chr." };
- yield return new object[] { "de-LI", 1, "n. Chr." };
- yield return new object[] { "de-LU", 0, "n. Chr." };
- yield return new object[] { "de-LU", 1, "n. Chr." };
- yield return new object[] { "el-CY", 0, "μ.Χ." };
- yield return new object[] { "el-CY", 1, "μ.Χ." };
- yield return new object[] { "el-GR", 0, "μ.Χ." };
- yield return new object[] { "el-GR", 1, "μ.Χ." };
- yield return new object[] { "en-AE", 0, "AD" };
- yield return new object[] { "en-AE", 1, "AD" };
- yield return new object[] { "en-AG", 0, "AD" };
- yield return new object[] { "en-AG", 1, "AD" };
- yield return new object[] { "en-AI", 0, "AD" };
- yield return new object[] { "en-AI", 1, "AD" };
- yield return new object[] { "en-AS", 0, "AD" };
- yield return new object[] { "en-AS", 1, "AD" };
- yield return new object[] { "en-AT", 0, "AD" };
- yield return new object[] { "en-AT", 1, "AD" };
- yield return new object[] { "en-AU", 0, "AD" };
- yield return new object[] { "en-AU", 1, "AD" };
- yield return new object[] { "en-BB", 0, "AD" };
- yield return new object[] { "en-BB", 1, "AD" };
- yield return new object[] { "en-BE", 0, "AD" };
- yield return new object[] { "en-BE", 1, "AD" };
- yield return new object[] { "en-BI", 0, "AD" };
- yield return new object[] { "en-BI", 1, "AD" };
- yield return new object[] { "en-BM", 0, "AD" };
- yield return new object[] { "en-BM", 1, "AD" };
- yield return new object[] { "en-BS", 0, "AD" };
- yield return new object[] { "en-BS", 1, "AD" };
- yield return new object[] { "en-BW", 0, "AD" };
- yield return new object[] { "en-BW", 1, "AD" };
- yield return new object[] { "en-BZ", 0, "AD" };
- yield return new object[] { "en-BZ", 1, "AD" };
- yield return new object[] { "en-CA", 0, "AD" };
- yield return new object[] { "en-CA", 1, "AD" };
- yield return new object[] { "en-CC", 0, "AD" };
- yield return new object[] { "en-CC", 1, "AD" };
- yield return new object[] { "en-CH", 0, "AD" };
- yield return new object[] { "en-CH", 1, "AD" };
- yield return new object[] { "en-CK", 0, "AD" };
- yield return new object[] { "en-CK", 1, "AD" };
- yield return new object[] { "en-CM", 0, "AD" };
- yield return new object[] { "en-CM", 1, "AD" };
- yield return new object[] { "en-CX", 0, "AD" };
- yield return new object[] { "en-CX", 1, "AD" };
- yield return new object[] { "en-CY", 0, "AD" };
- yield return new object[] { "en-CY", 1, "AD" };
- yield return new object[] { "en-DE", 0, "AD" };
- yield return new object[] { "en-DE", 1, "AD" };
- yield return new object[] { "en-DK", 0, "AD" };
- yield return new object[] { "en-DK", 1, "AD" };
- yield return new object[] { "en-DM", 0, "AD" };
- yield return new object[] { "en-DM", 1, "AD" };
- yield return new object[] { "en-ER", 0, "AD" };
- yield return new object[] { "en-ER", 1, "AD" };
- yield return new object[] { "en-FI", 0, "AD" };
- yield return new object[] { "en-FI", 1, "AD" };
- yield return new object[] { "en-FJ", 0, "AD" };
- yield return new object[] { "en-FJ", 1, "AD" };
- yield return new object[] { "en-FK", 0, "AD" };
- yield return new object[] { "en-FK", 1, "AD" };
- yield return new object[] { "en-FM", 0, "AD" };
- yield return new object[] { "en-FM", 1, "AD" };
- yield return new object[] { "en-GB", 0, "AD" };
- yield return new object[] { "en-GB", 1, "AD" };
- yield return new object[] { "en-GD", 0, "AD" };
- yield return new object[] { "en-GD", 1, "AD" };
- yield return new object[] { "en-GG", 0, "AD" };
- yield return new object[] { "en-GG", 1, "AD" };
- yield return new object[] { "en-GH", 0, "AD" };
- yield return new object[] { "en-GH", 1, "AD" };
- yield return new object[] { "en-GI", 0, "AD" };
- yield return new object[] { "en-GI", 1, "AD" };
- yield return new object[] { "en-GM", 0, "AD" };
- yield return new object[] { "en-GM", 1, "AD" };
- yield return new object[] { "en-GU", 0, "AD" };
- yield return new object[] { "en-GU", 1, "AD" };
- yield return new object[] { "en-GY", 0, "AD" };
- yield return new object[] { "en-GY", 1, "AD" };
- yield return new object[] { "en-HK", 0, "AD" };
- yield return new object[] { "en-HK", 1, "AD" };
- yield return new object[] { "en-IE", 0, "AD" };
- yield return new object[] { "en-IE", 1, "AD" };
- yield return new object[] { "en-IL", 0, "AD" };
- yield return new object[] { "en-IL", 1, "AD" };
- yield return new object[] { "en-IM", 0, "AD" };
- yield return new object[] { "en-IM", 1, "AD" };
- yield return new object[] { "en-IN", 0, "AD" };
- yield return new object[] { "en-IN", 1, "AD" };
- yield return new object[] { "en-IO", 0, "AD" };
- yield return new object[] { "en-IO", 1, "AD" };
- yield return new object[] { "en-JE", 0, "AD" };
- yield return new object[] { "en-JE", 1, "AD" };
- yield return new object[] { "en-JM", 0, "AD" };
- yield return new object[] { "en-JM", 1, "AD" };
- yield return new object[] { "en-KE", 0, "AD" };
- yield return new object[] { "en-KE", 1, "AD" };
- yield return new object[] { "en-KI", 0, "AD" };
- yield return new object[] { "en-KI", 1, "AD" };
- yield return new object[] { "en-KN", 0, "AD" };
- yield return new object[] { "en-KN", 1, "AD" };
- yield return new object[] { "en-KY", 0, "AD" };
- yield return new object[] { "en-KY", 1, "AD" };
- yield return new object[] { "en-LC", 0, "AD" };
- yield return new object[] { "en-LC", 1, "AD" };
- yield return new object[] { "en-LR", 0, "AD" };
- yield return new object[] { "en-LR", 1, "AD" };
- yield return new object[] { "en-LS", 0, "AD" };
- yield return new object[] { "en-LS", 1, "AD" };
- yield return new object[] { "en-MG", 0, "AD" };
- yield return new object[] { "en-MG", 1, "AD" };
- yield return new object[] { "en-MH", 0, "AD" };
- yield return new object[] { "en-MH", 1, "AD" };
- yield return new object[] { "en-MO", 0, "AD" };
- yield return new object[] { "en-MO", 1, "AD" };
- yield return new object[] { "en-MP", 0, "AD" };
- yield return new object[] { "en-MP", 1, "AD" };
- yield return new object[] { "en-MS", 0, "AD" };
- yield return new object[] { "en-MS", 1, "AD" };
- yield return new object[] { "en-MT", 0, "AD" };
- yield return new object[] { "en-MT", 1, "AD" };
- yield return new object[] { "en-MU", 0, "AD" };
- yield return new object[] { "en-MU", 1, "AD" };
- yield return new object[] { "en-MW", 0, "AD" };
- yield return new object[] { "en-MW", 1, "AD" };
- yield return new object[] { "en-MY", 0, "AD" };
- yield return new object[] { "en-MY", 1, "AD" };
- yield return new object[] { "en-NA", 0, "AD" };
- yield return new object[] { "en-NA", 1, "AD" };
- yield return new object[] { "en-NF", 0, "AD" };
- yield return new object[] { "en-NF", 1, "AD" };
- yield return new object[] { "en-NG", 0, "AD" };
- yield return new object[] { "en-NG", 1, "AD" };
- yield return new object[] { "en-NL", 0, "AD" };
- yield return new object[] { "en-NL", 1, "AD" };
- yield return new object[] { "en-NR", 0, "AD" };
- yield return new object[] { "en-NR", 1, "AD" };
- yield return new object[] { "en-NU", 0, "AD" };
- yield return new object[] { "en-NU", 1, "AD" };
- yield return new object[] { "en-NZ", 0, "AD" };
- yield return new object[] { "en-NZ", 1, "AD" };
- yield return new object[] { "en-PG", 0, "AD" };
- yield return new object[] { "en-PG", 1, "AD" };
- yield return new object[] { "en-PH", 0, "AD" };
- yield return new object[] { "en-PH", 1, "AD" };
- yield return new object[] { "en-PK", 0, "AD" };
- yield return new object[] { "en-PK", 1, "AD" };
- yield return new object[] { "en-PN", 0, "AD" };
- yield return new object[] { "en-PN", 1, "AD" };
- yield return new object[] { "en-PR", 0, "AD" };
- yield return new object[] { "en-PR", 1, "AD" };
- yield return new object[] { "en-PW", 0, "AD" };
- yield return new object[] { "en-PW", 1, "AD" };
- yield return new object[] { "en-RW", 0, "AD" };
- yield return new object[] { "en-RW", 1, "AD" };
- yield return new object[] { "en-SB", 0, "AD" };
- yield return new object[] { "en-SB", 1, "AD" };
- yield return new object[] { "en-SC", 0, "AD" };
- yield return new object[] { "en-SC", 1, "AD" };
- yield return new object[] { "en-SD", 0, "AD" };
- yield return new object[] { "en-SD", 1, "AD" };
- yield return new object[] { "en-SE", 0, "AD" };
- yield return new object[] { "en-SE", 1, "AD" };
- yield return new object[] { "en-SG", 0, "AD" };
- yield return new object[] { "en-SG", 1, "AD" };
- yield return new object[] { "en-SH", 0, "AD" };
- yield return new object[] { "en-SH", 1, "AD" };
- yield return new object[] { "en-SI", 0, "AD" };
- yield return new object[] { "en-SI", 1, "AD" };
- yield return new object[] { "en-SL", 0, "AD" };
- yield return new object[] { "en-SL", 1, "AD" };
- yield return new object[] { "en-SS", 0, "AD" };
- yield return new object[] { "en-SS", 1, "AD" };
- yield return new object[] { "en-SX", 0, "AD" };
- yield return new object[] { "en-SX", 1, "AD" };
- yield return new object[] { "en-SZ", 0, "AD" };
- yield return new object[] { "en-SZ", 1, "AD" };
- yield return new object[] { "en-TC", 0, "AD" };
- yield return new object[] { "en-TC", 1, "AD" };
- yield return new object[] { "en-TK", 0, "AD" };
- yield return new object[] { "en-TK", 1, "AD" };
- yield return new object[] { "en-TO", 0, "AD" };
- yield return new object[] { "en-TO", 1, "AD" };
- yield return new object[] { "en-TT", 0, "AD" };
- yield return new object[] { "en-TT", 1, "AD" };
- yield return new object[] { "en-TV", 0, "AD" };
- yield return new object[] { "en-TV", 1, "AD" };
- yield return new object[] { "en-TZ", 0, "AD" };
- yield return new object[] { "en-TZ", 1, "AD" };
- yield return new object[] { "en-UG", 0, "AD" };
- yield return new object[] { "en-UG", 1, "AD" };
- yield return new object[] { "en-UM", 0, "AD" };
- yield return new object[] { "en-UM", 1, "AD" };
- yield return new object[] { "en-US", 0, "AD" };
- yield return new object[] { "en-US", 1, "AD" };
- yield return new object[] { "en-VC", 0, "AD" };
- yield return new object[] { "en-VC", 1, "AD" };
- yield return new object[] { "en-VG", 0, "AD" };
- yield return new object[] { "en-VG", 1, "AD" };
- yield return new object[] { "en-VI", 0, "AD" };
- yield return new object[] { "en-VI", 1, "AD" };
- yield return new object[] { "en-VU", 0, "AD" };
- yield return new object[] { "en-VU", 1, "AD" };
- yield return new object[] { "en-WS", 0, "AD" };
- yield return new object[] { "en-WS", 1, "AD" };
- yield return new object[] { "en-ZA", 0, "AD" };
- yield return new object[] { "en-ZA", 1, "AD" };
- yield return new object[] { "en-ZM", 0, "AD" };
- yield return new object[] { "en-ZM", 1, "AD" };
- yield return new object[] { "en-ZW", 0, "AD" };
- yield return new object[] { "en-ZW", 1, "AD" };
- yield return new object[] { "en-US", 0, "AD" };
- yield return new object[] { "en-US", 1, "AD" };
- yield return new object[] { "es-ES", 0, "d. C." };
- yield return new object[] { "es-ES", 1, "d. C." };
- yield return new object[] { "es-419", 0, "d.C." };
- yield return new object[] { "es-419", 1, "d.C." };
- yield return new object[] { "es-MX", 0, "d.C." };
- yield return new object[] { "es-MX", 1, "d.C." };
- yield return new object[] { "et-EE", 0, "pKr" };
- yield return new object[] { "et-EE", 1, "pKr" };
- yield return new object[] { "fa-IR", 0, "ه.ش" }; // ه.ش.
- yield return new object[] { "fa-IR", 1, "ه.ش" };
- yield return new object[] { "fi-FI", 0, "jKr." };
- yield return new object[] { "fi-FI", 1, "jKr." };
- yield return new object[] { "fil-PH", 0, "AD" };
- yield return new object[] { "fil-PH", 1, "AD" };
- yield return new object[] { "fr-BE", 0, "ap. J.-C." };
- yield return new object[] { "fr-BE", 1, "ap. J.-C." };
- yield return new object[] { "fr-CA", 0, "ap. J.-C." };
- yield return new object[] { "fr-CA", 1, "ap. J.-C." };
- yield return new object[] { "fr-CH", 0, "ap. J.-C." };
- yield return new object[] { "fr-CH", 1, "ap. J.-C." };
- yield return new object[] { "fr-FR", 0, "ap. J.-C." };
- yield return new object[] { "fr-FR", 1, "ap. J.-C." };
- yield return new object[] { "gu-IN", 0, "ઈ.સ." };
- yield return new object[] { "gu-IN", 1, "ઈ.સ." };
- yield return new object[] { "he-IL", 0, "לספירה" };
- yield return new object[] { "he-IL", 1, "לספירה" };
- yield return new object[] { "hi-IN", 0, "ईस्वी" };
- yield return new object[] { "hi-IN", 1, "ईस्वी" };
- yield return new object[] { "hr-BA", 0, "po. Kr." };
- yield return new object[] { "hr-BA", 1, "po. Kr." };
- yield return new object[] { "hr-HR", 0, "po. Kr." };
- yield return new object[] { "hr-HR", 1, "po. Kr." };
- yield return new object[] { "hu-HU", 0, "i. sz." };
- yield return new object[] { "hu-HU", 1, "i. sz." };
- yield return new object[] { "id-ID", 0, "M" };
- yield return new object[] { "id-ID", 1, "M" };
- yield return new object[] { "it-CH", 0, "d.C." };
- yield return new object[] { "it-CH", 1, "d.C." };
- yield return new object[] { "it-IT", 0, "d.C." };
- yield return new object[] { "it-IT", 1, "d.C." };
- yield return new object[] { "ja-JP", 0, "西暦" };
- yield return new object[] { "ja-JP", 1, "西暦" };
- yield return new object[] { "kn-IN", 0, "ಕ್ರಿ.ಶ" };
- yield return new object[] { "kn-IN", 1, "ಕ್ರಿ.ಶ" };
- yield return new object[] { "ko-KR", 0, "AD" };
- yield return new object[] { "ko-KR", 1, "AD" };
- yield return new object[] { "lt-LT", 0, "po Kr." };
- yield return new object[] { "lt-LT", 1, "po Kr." };
- yield return new object[] { "lv-LV", 0, "m.ē." };
- yield return new object[] { "lv-LV", 1, "m.ē." };
- yield return new object[] { "ml-IN", 0, "എഡി" };
- yield return new object[] { "ml-IN", 1, "എഡി" };
- yield return new object[] { "mr-IN", 0, "इ. स." };
- yield return new object[] { "mr-IN", 1, "इ. स." };
- yield return new object[] { "ms-BN", 0, "TM" };
- yield return new object[] { "ms-BN", 1, "TM" };
- yield return new object[] { "ms-MY", 0, "TM" };
- yield return new object[] { "ms-MY", 1, "TM" };
- yield return new object[] { "ms-SG", 0, "TM" };
- yield return new object[] { "ms-SG", 1, "TM" };
- yield return new object[] { "nb-NO", 0, "e.Kr." };
- yield return new object[] { "nb-NO", 1, "e.Kr." };
- yield return new object[] { "no", 0, "e.Kr." };
- yield return new object[] { "no", 1, "e.Kr." };
- yield return new object[] { "no-NO", 0, "e.Kr." };
- yield return new object[] { "no-NO", 1, "e.Kr." };
- yield return new object[] { "nl-AW", 0, "n.Chr." };
- yield return new object[] { "nl-AW", 1, "n.Chr." };
- yield return new object[] { "nl-BE", 0, "n.Chr." };
- yield return new object[] { "nl-BE", 1, "n.Chr." };
- yield return new object[] { "nl-NL", 0, "n.Chr." };
- yield return new object[] { "nl-NL", 1, "n.Chr." };
- yield return new object[] { "pl-PL", 0, "n.e." };
- yield return new object[] { "pl-PL", 1, "n.e." };
- yield return new object[] { "pt-BR", 0, "d.C." };
- yield return new object[] { "pt-BR", 1, "d.C." };
- yield return new object[] { "pt-PT", 0, "d.C." };
- yield return new object[] { "pt-PT", 1, "d.C." };
- yield return new object[] { "ro-RO", 0, "d.Hr." };
- yield return new object[] { "ro-RO", 1, "d.Hr." };
- yield return new object[] { "ru-RU", 0, "н. э." };
- yield return new object[] { "ru-RU", 1, "н. э." };
- yield return new object[] { "sk-SK", 0, "po Kr." };
- yield return new object[] { "sk-SK", 1, "po Kr." };
- yield return new object[] { "sl-SI", 0, "po Kr." };
- yield return new object[] { "sl-SI", 1, "po Kr." };
- yield return new object[] { "sr-Cyrl-RS", 0, "н. е." };
- yield return new object[] { "sr-Cyrl-RS", 1, "н. е." };
- yield return new object[] { "sr-Latn-RS", 0, "n. e." };
- yield return new object[] { "sr-Latn-RS", 1, "n. e." };
- yield return new object[] { "sv-AX", 0, "e.Kr." };
- yield return new object[] { "sv-AX", 1, "e.Kr." };
- yield return new object[] { "sv-SE", 0, "e.Kr." };
- yield return new object[] { "sv-SE", 1, "e.Kr." };
- yield return new object[] { "sw-CD", 0, "BK" };
- yield return new object[] { "sw-CD", 1, "BK" };
- yield return new object[] { "sw-KE", 0, "BK" };
- yield return new object[] { "sw-KE", 1, "BK" };
- yield return new object[] { "sw-TZ", 0, "BK" };
- yield return new object[] { "sw-TZ", 1, "BK" };
- yield return new object[] { "sw-UG", 0, "BK" };
- yield return new object[] { "sw-UG", 1, "BK" };
- yield return new object[] { "ta-IN", 0, "கி.பி." };
- yield return new object[] { "ta-IN", 1, "கி.பி." };
- yield return new object[] { "ta-LK", 0, "கி.பி." };
- yield return new object[] { "ta-LK", 1, "கி.பி." };
- yield return new object[] { "ta-MY", 0, "கி.பி." };
- yield return new object[] { "ta-MY", 1, "கி.பி." };
- yield return new object[] { "ta-SG", 0, "கி.பி." };
- yield return new object[] { "ta-SG", 1, "கி.பி." };
- yield return new object[] { "te-IN", 0, "క్రీశ" };
- yield return new object[] { "te-IN", 1, "క్రీశ" };
- yield return new object[] { "th-TH", 0, "พ.ศ." };
- yield return new object[] { "th-TH", 1, "พ.ศ." };
- yield return new object[] { "tr-CY", 0, "MS" };
- yield return new object[] { "tr-CY", 1, "MS" };
- yield return new object[] { "tr-TR", 0, "MS" };
- yield return new object[] { "tr-TR", 1, "MS" };
- yield return new object[] { "uk-UA", 0, "н. е." };
- yield return new object[] { "uk-UA", 1, "н. е." };
- yield return new object[] { "vi-VN", 0, PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "CN" : "SCN" }; // sau CN
- yield return new object[] { "vi-VN", 1, PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "CN" : "SCN" }; // sau CN
- yield return new object[] { "zh-CN", 0, "公元" };
- yield return new object[] { "zh-CN", 1, "公元" };
- yield return new object[] { "zh-Hans-HK", 0, "公元" };
- yield return new object[] { "zh-Hans-HK", 1, "公元" };
- yield return new object[] { "zh-SG", 0, "公元" };
- yield return new object[] { "zh-SG", 1, "公元" };
- yield return new object[] { "zh-HK", 0, "公元" };
- yield return new object[] { "zh-HK", 1, "公元" };
- yield return new object[] { "zh-TW", 0, "西元" };
- yield return new object[] { "zh-TW", 1, "西元" };
- }
+ yield return new object[] { "en-US", 1, DateTimeFormatInfoData.EnUSEraName() };
+ yield return new object[] { "en-US", 0, DateTimeFormatInfoData.EnUSEraName() };
+ yield return new object[] { "fr-FR", 1, "ap. J.-C." };
+ yield return new object[] { "fr-FR", 0, "ap. J.-C." };
}
[Theory]
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoLongDatePattern.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoLongDatePattern.cs
index 53720bf5bffbfd..20be2cf3f22112 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoLongDatePattern.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoLongDatePattern.cs
@@ -31,199 +31,6 @@ public static IEnumerable LongDatePattern_Get_TestData_ICU()
yield return new object[] { CultureInfo.GetCultureInfo("fr-FR").DateTimeFormat, "dddd d MMMM yyyy" };
}
- public static IEnumerable LongDatePattern_Get_TestData_HybridGlobalization()
- {
- // see the comments on the right to check the non-Hybrid result, if it differs
- yield return new object[] {"ar-SA", "dddd، d MMMM yyyy" }; // dddd، d MMMM yyyy g
- yield return new object[] {"am-ET", "yyyy MMMM d, dddd" };
- yield return new object[] {"bg-BG", "dddd, d MMMM yyyy 'г'." };
- yield return new object[] {"bn-BD", "dddd, d MMMM, yyyy" };
- yield return new object[] {"bn-IN", "dddd, d MMMM, yyyy" };
- string catalanianPattern = PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "dddd, d 'de' MMMM 'de' yyyy" : "dddd, d 'de' MMMM 'del' yyyy"; // "dddd, d MMMM 'de' yyyy"
- yield return new object[] {"ca-AD", catalanianPattern };
- yield return new object[] {"ca-ES", catalanianPattern };
- yield return new object[] {"cs-CZ", "dddd d. MMMM yyyy" };
- yield return new object[] {"da-DK", "dddd 'den' d. MMMM yyyy" };
- yield return new object[] {"de-AT", "dddd, d. MMMM yyyy" };
- yield return new object[] {"de-BE", "dddd, d. MMMM yyyy" };
- yield return new object[] {"de-CH", "dddd, d. MMMM yyyy" };
- yield return new object[] {"de-DE", "dddd, d. MMMM yyyy" };
- yield return new object[] {"de-IT", "dddd, d. MMMM yyyy" };
- yield return new object[] {"de-LI", "dddd, d. MMMM yyyy" };
- yield return new object[] {"de-LU", "dddd, d. MMMM yyyy" };
- yield return new object[] {"el-CY", "dddd d MMMM yyyy" }; // "dddd, d MMMM yyyy"
- yield return new object[] {"el-GR", "dddd d MMMM yyyy" }; // "dddd, d MMMM yyyy"
- yield return new object[] {"en-AE", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-AG", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-AI", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-AS", "dddd, MMMM d, yyyy" };
- yield return new object[] {"en-AT", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-AU", PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "dddd, d MMMM yyyy" : "dddd d MMMM yyyy" };
- yield return new object[] {"en-BB", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-BE", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-BI", "dddd, MMMM d, yyyy" };
- yield return new object[] {"en-BM", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-BS", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-BW", "dddd, d MMMM yyyy" }; // "dddd, dd MMMM yyyy"
- yield return new object[] {"en-BZ", "dddd, d MMMM yyyy" }; // "dddd, dd MMMM yyyy"
- yield return new object[] {"en-CA", "dddd, MMMM d, yyyy" };
- yield return new object[] {"en-CC", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-CH", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-CK", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-CM", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-CX", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-CY", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-DE", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-DK", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-DM", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-ER", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-FI", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-FJ", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-FK", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-FM", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-GB", PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "dddd, d MMMM yyyy" :"dddd d MMMM yyyy" };
- yield return new object[] {"en-GD", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-GG", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-GH", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-GI", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-GM", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-GU", "dddd, MMMM d, yyyy" };
- yield return new object[] {"en-GY", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-HK", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-IE", "dddd d MMMM yyyy" };
- yield return new object[] {"en-IL", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-IM", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-IN", PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "dddd, d MMMM, yyyy" : "dddd d MMMM, yyyy" }; // dddd, d MMMM, yyyy
- yield return new object[] {"en-IO", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-JE", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-JM", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-KE", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-KI", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-KN", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-KY", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-LC", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-LR", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-LS", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-MG", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-MH", "dddd, MMMM d, yyyy" };
- yield return new object[] {"en-MO", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-MP", "dddd, MMMM d, yyyy" };
- yield return new object[] {"en-MS", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-MT", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-MU", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-MW", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-MY", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-NA", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-NF", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-NG", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-NL", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-NR", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-NU", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-NZ", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-PG", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-PH", "dddd, MMMM d, yyyy" }; // "dddd, d MMMM yyyy"
- yield return new object[] {"en-PK", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-PN", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-PR", "dddd, MMMM d, yyyy" };
- yield return new object[] {"en-PW", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-RW", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-SB", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-SC", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-SD", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-SE", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-SG", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-SH", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-SI", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-SL", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-SS", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-SX", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-SZ", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-TC", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-TK", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-TO", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-TT", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-TV", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-TZ", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-UG", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-UM", "dddd, MMMM d, yyyy" };
- yield return new object[] {"en-US", "dddd, MMMM d, yyyy" };
- yield return new object[] {"en-VC", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-VG", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-VI", "dddd, MMMM d, yyyy" };
- yield return new object[] {"en-VU", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-WS", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-ZA", "dddd, d MMMM yyyy" }; // "dddd, dd MMMM yyyy"
- yield return new object[] {"en-ZM", "dddd, d MMMM yyyy" };
- yield return new object[] {"en-ZW", "dddd, d MMMM yyyy" }; // "dddd, dd MMMM yyyy"
- yield return new object[] {"en-US", "dddd, MMMM d, yyyy" };
- string spanishPattern = "dddd, d 'de' MMMM 'de' yyyy";
- yield return new object[] {"es-419", spanishPattern };
- yield return new object[] {"es-ES", spanishPattern };
- yield return new object[] {"es-MX", spanishPattern };
- yield return new object[] {"et-EE", "dddd, d. MMMM yyyy" };
- yield return new object[] {"fa-IR", "yyyy MMMM d, dddd" };
- yield return new object[] {"fi-FI", "dddd d. MMMM yyyy" };
- yield return new object[] {"fil-PH", "dddd, MMMM d, yyyy" };
- yield return new object[] {"fr-BE", "dddd d MMMM yyyy" };
- yield return new object[] {"fr-CA", "dddd d MMMM yyyy" };
- yield return new object[] {"fr-CH", "dddd, d MMMM yyyy" };
- yield return new object[] {"fr-FR", "dddd d MMMM yyyy" };
- yield return new object[] {"gu-IN", "dddd, d MMMM, yyyy" };
- yield return new object[] {"he-IL", "dddd, d בMMMM yyyy" };
- yield return new object[] {"hi-IN", "dddd, d MMMM yyyy" };
- yield return new object[] {"hr-BA", "dddd, d. MMMM yyyy." };
- yield return new object[] {"hr-HR", "dddd, d. MMMM yyyy." };
- yield return new object[] {"hu-HU", "yyyy. MMMM d., dddd" };
- yield return new object[] {"id-ID", "dddd, d MMMM yyyy" }; // "dddd, dd MMMM yyyy"
- yield return new object[] {"it-CH", "dddd, d MMMM yyyy" };
- yield return new object[] {"it-IT", "dddd d MMMM yyyy" };
- yield return new object[] {"ja-JP", "yyyy年M月d日dddd" };
- yield return new object[] {"kn-IN", "dddd, MMMM d, yyyy" };
- yield return new object[] {"ko-KR", "yyyy년 M월 d일 dddd" };
- yield return new object[] {"lt-LT", "yyyy 'm'. MMMM d 'd'., dddd" };
- yield return new object[] {"lv-LV", "dddd, yyyy. 'gada' d. MMMM" };
- yield return new object[] {"ml-IN", "yyyy, MMMM d, dddd" };
- yield return new object[] {"mr-IN", "dddd, d MMMM, yyyy" };
- yield return new object[] {"ms-BN", "dddd, d MMMM yyyy" }; // "dd MMMM yyyy"
- yield return new object[] {"ms-MY", "dddd, d MMMM yyyy" };
- yield return new object[] {"ms-SG", "dddd, d MMMM yyyy" };
- yield return new object[] {"nb-NO", "dddd d. MMMM yyyy" };
- yield return new object[] {"no-NO", "dddd d. MMMM yyyy" };
- yield return new object[] {"nl-AW", "dddd d MMMM yyyy" };
- yield return new object[] {"nl-BE", "dddd d MMMM yyyy" };
- yield return new object[] {"nl-NL", "dddd d MMMM yyyy" };
- yield return new object[] {"pl-PL", "dddd, d MMMM yyyy" };
- yield return new object[] {"pt-BR", "dddd, d 'de' MMMM 'de' yyyy" };
- yield return new object[] {"pt-PT", "dddd, d 'de' MMMM 'de' yyyy" };
- yield return new object[] {"ro-RO", "dddd, d MMMM yyyy" };
- yield return new object[] {"ru-RU", "dddd, d MMMM yyyy 'г'." };
- yield return new object[] {"sk-SK", "dddd d. MMMM yyyy" };
- yield return new object[] {"sl-SI", "dddd, d. MMMM yyyy" }; // "dddd, dd. MMMM yyyy"
- yield return new object[] {"sr-Cyrl-RS", "dddd, d. MMMM yyyy." }; // "dddd, dd. MMMM yyyy"
- yield return new object[] {"sr-Latn-RS", "dddd, d. MMMM yyyy." }; // "dddd, dd. MMMM yyyy"
- yield return new object[] {"sv-AX", "dddd d MMMM yyyy" };
- yield return new object[] {"sv-SE", "dddd d MMMM yyyy" };
- yield return new object[] {"sw-CD", "dddd, d MMMM yyyy" };
- yield return new object[] {"sw-KE", "dddd, d MMMM yyyy" };
- yield return new object[] {"sw-TZ", "dddd, d MMMM yyyy" };
- yield return new object[] {"sw-UG", "dddd, d MMMM yyyy" };
- yield return new object[] {"ta-IN", "dddd, d MMMM, yyyy" };
- yield return new object[] {"ta-LK", "dddd, d MMMM, yyyy" };
- yield return new object[] {"ta-MY", "dddd, d MMMM, yyyy" };
- yield return new object[] {"ta-SG", "dddd, d MMMM, yyyy" };
- yield return new object[] {"te-IN", "d, MMMM yyyy, dddd" };
- yield return new object[] {"th-TH", "ddddที่ d MMMM g yyyy" };
- yield return new object[] {"tr-CY", "d MMMM yyyy dddd" };
- yield return new object[] {"tr-TR", "d MMMM yyyy dddd" };
- yield return new object[] {"uk-UA", "dddd, d MMMM yyyy 'р'." };
- yield return new object[] {"vi-VN", "dddd, d MMMM, yyyy" };
- yield return new object[] {"zh-CN", "yyyy年M月d日dddd" };
- yield return new object[] {"zh-Hans-HK", "yyyy年M月d日dddd" };
- yield return new object[] {"zh-SG", "yyyy年M月d日dddd" };
- yield return new object[] {"zh-HK", "yyyy年M月d日dddd" };
- yield return new object[] {"zh-TW", "yyyy年M月d日 dddd" };
- }
-
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsIcuGlobalization))]
[MemberData(nameof(LongDatePattern_Get_TestData_ICU))]
public void LongDatePattern_Get_ReturnsExpected_ICU(DateTimeFormatInfo format, string expected)
@@ -231,14 +38,6 @@ public void LongDatePattern_Get_ReturnsExpected_ICU(DateTimeFormatInfo format, s
Assert.Equal(expected, format.LongDatePattern);
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
- [MemberData(nameof(LongDatePattern_Get_TestData_HybridGlobalization))]
- public void LongDatePattern_Get_ReturnsExpected_HybridGlobalization(string cultureName, string expected)
- {
- var format = new CultureInfo(cultureName).DateTimeFormat;
- Assert.True(expected == format.LongDatePattern, $"Failed for culture: {cultureName}. Expected: {expected}, Actual: {format.LongDatePattern}");
- }
-
[Theory]
[MemberData(nameof(LongDatePattern_Set_TestData))]
public void LongDatePattern_Set_GetReturnsExpected(string value)
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoLongTimePattern.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoLongTimePattern.cs
index dc02bcba5869dd..455726b844d51a 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoLongTimePattern.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoLongTimePattern.cs
@@ -14,205 +14,6 @@ public void LongTimePattern_GetInvariantInfo_ReturnsExpected()
Assert.Equal("HH:mm:ss", DateTimeFormatInfo.InvariantInfo.LongTimePattern);
}
- public static IEnumerable LongTimePattern_Get_TestData_HybridGlobalization()
- {
- // see the comments on the right to check the non-Hybrid result, if it differs
- yield return new object[] { new CultureInfo("ar-SA").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("am-ET").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("bg-BG").DateTimeFormat, PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "H:mm:ss ч." : "H:mm:ss" }; // H:mm:ss ч.
- yield return new object[] { new CultureInfo("bn-BD").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("bn-IN").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("ca-AD").DateTimeFormat, "H:mm:ss" };
- yield return new object[] { new CultureInfo("ca-ES").DateTimeFormat, "H:mm:ss" };
- yield return new object[] { new CultureInfo("cs-CZ").DateTimeFormat, "H:mm:ss" };
- yield return new object[] { new CultureInfo("da-DK").DateTimeFormat, "HH.mm.ss" };
- yield return new object[] { new CultureInfo("de-AT").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("de-BE").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("de-CH").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("de-DE").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("de-IT").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("de-LI").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("de-LU").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("el-CY").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("el-GR").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-AE").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-AG").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-AI").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-AS").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-AT").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-AU").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-BB").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-BE").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-BI").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-BM").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-BS").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-BW").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-BZ").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-CA").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-CC").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-CH").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-CK").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-CM").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-CX").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-CY").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-DE").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-DK").DateTimeFormat, "HH.mm.ss" };
- yield return new object[] { new CultureInfo("en-DM").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-ER").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-FI").DateTimeFormat, "H.mm.ss" };
- yield return new object[] { new CultureInfo("en-FJ").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-FK").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-FM").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-GB").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-GD").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-GG").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-GH").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-GI").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-GM").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-GU").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-GY").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-HK").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-IE").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-IL").DateTimeFormat, "H:mm:ss" };
- yield return new object[] { new CultureInfo("en-IM").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-IN").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-IO").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-JE").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-JM").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-KE").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-KI").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-KN").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-KY").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-LC").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-LR").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-LS").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-MG").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-MH").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-MO").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-MP").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-MS").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-MT").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-MU").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-MW").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-MY").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-NA").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-NF").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-NG").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-NL").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-NR").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-NU").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-NZ").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-PG").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-PH").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-PK").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-PN").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-PR").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-PW").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-RW").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-SB").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-SC").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-SD").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-SE").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-SG").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-SH").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-SI").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-SL").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-SS").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-SX").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-SZ").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-TC").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-TK").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-TO").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-TT").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-TV").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-TZ").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-UG").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-UM").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-US").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-VC").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-VG").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-VI").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-VU").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-WS").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-ZA").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("en-ZM").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("en-ZW").DateTimeFormat, "HH:mm:ss" };
- string latinAmericaSpanishPattern = PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "HH:mm:ss" : "h:mm:ss tt"; // H:mm:ss
- yield return new object[] { new CultureInfo("es-419").DateTimeFormat, latinAmericaSpanishPattern };
- yield return new object[] { new CultureInfo("es-ES").DateTimeFormat, "H:mm:ss" };
- yield return new object[] { new CultureInfo("es-MX").DateTimeFormat, latinAmericaSpanishPattern };
- yield return new object[] { new CultureInfo("et-EE").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("fa-IR").DateTimeFormat, "H:mm:ss" };
- yield return new object[] { new CultureInfo("fi-FI").DateTimeFormat, "H.mm.ss" };
- yield return new object[] { new CultureInfo("fil-PH").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("fr-BE").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("fr-CA").DateTimeFormat, "HH 'h' mm 'min' ss 's'" };
- yield return new object[] { new CultureInfo("fr-CH").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("fr-FR").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("gu-IN").DateTimeFormat, "hh:mm:ss tt" };
- yield return new object[] { new CultureInfo("he-IL").DateTimeFormat, "H:mm:ss" };
- yield return new object[] { new CultureInfo("hi-IN").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("hr-BA").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("hr-HR").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("hu-HU").DateTimeFormat, "H:mm:ss" };
- yield return new object[] { new CultureInfo("id-ID").DateTimeFormat, "HH.mm.ss" };
- yield return new object[] { new CultureInfo("it-CH").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("it-IT").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("ja-JP").DateTimeFormat, "H:mm:ss" };
- yield return new object[] { new CultureInfo("kn-IN").DateTimeFormat, "hh:mm:ss tt" };
- yield return new object[] { new CultureInfo("ko-KR").DateTimeFormat, "tt h:mm:ss" };
- yield return new object[] { new CultureInfo("lt-LT").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("lv-LV").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("ml-IN").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("mr-IN").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("ms-BN").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("ms-MY").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("ms-SG").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("nb-NO").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("no").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("no-NO").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("nl-AW").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("nl-BE").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("nl-NL").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("pl-PL").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("pt-BR").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("pt-PT").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("ro-RO").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("ru-RU").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("sk-SK").DateTimeFormat, "H:mm:ss" };
- yield return new object[] { new CultureInfo("sl-SI").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("sr-Cyrl-RS").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("sr-Latn-RS").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("sv-AX").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("sv-SE").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("sw-CD").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("sw-KE").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("sw-TZ").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("sw-UG").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("ta-IN").DateTimeFormat, "tt h:mm:ss" };
- yield return new object[] { new CultureInfo("ta-LK").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("ta-MY").DateTimeFormat, "tt h:mm:ss" };
- yield return new object[] { new CultureInfo("ta-SG").DateTimeFormat, "tt h:mm:ss" };
- yield return new object[] { new CultureInfo("te-IN").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("th-TH").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("tr-CY").DateTimeFormat, "h:mm:ss tt" };
- yield return new object[] { new CultureInfo("tr-TR").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("uk-UA").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("vi-VN").DateTimeFormat, "HH:mm:ss" };
- yield return new object[] { new CultureInfo("zh-CN").DateTimeFormat, "HH:mm:ss" }; // tth:mm:ss
- yield return new object[] { new CultureInfo("zh-Hans-HK").DateTimeFormat, "tth:mm:ss" };
- yield return new object[] { new CultureInfo("zh-SG").DateTimeFormat, "tth:mm:ss" };
- yield return new object[] { new CultureInfo("zh-HK").DateTimeFormat, "tth:mm:ss" };
- yield return new object[] { new CultureInfo("zh-TW").DateTimeFormat, "tth:mm:ss" };
- }
-
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
- [MemberData(nameof(LongTimePattern_Get_TestData_HybridGlobalization))]
- public void LongTimePattern_Get_ReturnsExpected_HybridGlobalization(DateTimeFormatInfo format, string value)
- {
- Assert.Equal(value, format.LongTimePattern);
- }
-
public static IEnumerable LongTimePattern_Set_TestData()
{
yield return new object[] { string.Empty };
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoMonthDayPattern.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoMonthDayPattern.cs
index 4cce8b20864987..8708cc49417dad 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoMonthDayPattern.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoMonthDayPattern.cs
@@ -31,196 +31,6 @@ public static IEnumerable MonthDayPattern_Get_TestData_ICU()
yield return new object[] { CultureInfo.GetCultureInfo("en-US").DateTimeFormat, "MMMM d" };
yield return new object[] { CultureInfo.GetCultureInfo("fr-FR").DateTimeFormat, "d MMMM" };
}
-
- public static IEnumerable MonthDayPattern_Get_TestData_HybridGlobalization()
- {
- // see the comments on the right to check the non-Hybrid result, if it differs
- yield return new object[] { new CultureInfo("ar-SA").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("am-ET").DateTimeFormat, "MMMM d" };
- yield return new object[] { new CultureInfo("bg-BG").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("bn-BD").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("bn-IN").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("ca-AD").DateTimeFormat, "d de MMMM" }; // d MMMM
- yield return new object[] { new CultureInfo("ca-ES").DateTimeFormat, "d de MMMM" }; // d MMMM
- yield return new object[] { new CultureInfo("cs-CZ").DateTimeFormat, "d. MMMM" };
- yield return new object[] { new CultureInfo("da-DK").DateTimeFormat, "d. MMMM" };
- yield return new object[] { new CultureInfo("de-AT").DateTimeFormat, "d. MMMM" };
- yield return new object[] { new CultureInfo("de-BE").DateTimeFormat, "d. MMMM" };
- yield return new object[] { new CultureInfo("de-CH").DateTimeFormat, "d. MMMM" };
- yield return new object[] { new CultureInfo("de-DE").DateTimeFormat, "d. MMMM" };
- yield return new object[] { new CultureInfo("de-IT").DateTimeFormat, "d. MMMM" };
- yield return new object[] { new CultureInfo("de-LI").DateTimeFormat, "d. MMMM" };
- yield return new object[] { new CultureInfo("de-LU").DateTimeFormat, "d. MMMM" };
- yield return new object[] { new CultureInfo("el-CY").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("el-GR").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-AE").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-AG").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-AI").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-AS").DateTimeFormat, "MMMM d" };
- yield return new object[] { new CultureInfo("en-AT").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-AU").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-BB").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-BE").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-BI").DateTimeFormat, "MMMM d" };
- yield return new object[] { new CultureInfo("en-BM").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-BS").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-BW").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-BZ").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-CA").DateTimeFormat, "MMMM d" };
- yield return new object[] { new CultureInfo("en-CC").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-CH").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-CK").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-CM").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-CX").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-CY").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-DE").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-DK").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-DM").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-ER").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-FI").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-FJ").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-FK").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-FM").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-GB").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-GD").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-GG").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-GH").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-GI").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-GM").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-GU").DateTimeFormat, "MMMM d" };
- yield return new object[] { new CultureInfo("en-GY").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-HK").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-IE").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-IL").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-IM").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-IN").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-IO").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-JE").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-JM").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-KE").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-KI").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-KN").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-KY").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-LC").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-LR").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-LS").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-MG").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-MH").DateTimeFormat, "MMMM d" };
- yield return new object[] { new CultureInfo("en-MO").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-MP").DateTimeFormat, "MMMM d" };
- yield return new object[] { new CultureInfo("en-MS").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-MT").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-MU").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-MW").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-MY").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-NA").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-NF").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-NG").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-NL").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-NR").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-NU").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-NZ").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-PG").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-PH").DateTimeFormat, "MMMM d" }; // "d MMMM"
- yield return new object[] { new CultureInfo("en-PK").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-PN").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-PR").DateTimeFormat, "MMMM d" };
- yield return new object[] { new CultureInfo("en-PW").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-RW").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-SB").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-SC").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-SD").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-SE").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-SG").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-SH").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-SI").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-SL").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-SS").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-SX").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-SZ").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-TC").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-TK").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-TO").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-TT").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-TV").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-TZ").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-UG").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-UM").DateTimeFormat, "MMMM d" };
- yield return new object[] { new CultureInfo("en-US").DateTimeFormat, "MMMM d" };
- yield return new object[] { new CultureInfo("en-VC").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-VG").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-VI").DateTimeFormat, "MMMM d" };
- yield return new object[] { new CultureInfo("en-VU").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-WS").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-ZA").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-ZM").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("en-ZW").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("es-419").DateTimeFormat, "d de MMMM" }; // d 'de' MMMM
- yield return new object[] { new CultureInfo("es-ES").DateTimeFormat, "d de MMMM" }; // d 'de' MMMM
- yield return new object[] { new CultureInfo("es-MX").DateTimeFormat, "d de MMMM" }; // d 'de' MMMM
- yield return new object[] { new CultureInfo("et-EE").DateTimeFormat, "d. MMMM" };
- yield return new object[] { new CultureInfo("fa-IR").DateTimeFormat, "d MMMM" }; // "MMMM d"
- yield return new object[] { new CultureInfo("fi-FI").DateTimeFormat, "d. MMMM" };
- yield return new object[] { new CultureInfo("fil-PH").DateTimeFormat, "MMMM d" };
- yield return new object[] { new CultureInfo("fr-BE").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("fr-CA").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("fr-CH").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("fr-FR").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("gu-IN").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("he-IL").DateTimeFormat, "d בMMMM" };
- yield return new object[] { new CultureInfo("hi-IN").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("hr-BA").DateTimeFormat, "d. MMMM" };
- yield return new object[] { new CultureInfo("hr-HR").DateTimeFormat, "d. MMMM" };
- yield return new object[] { new CultureInfo("hu-HU").DateTimeFormat, "MMMM d." };
- yield return new object[] { new CultureInfo("id-ID").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("it-CH").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("it-IT").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("ja-JP").DateTimeFormat, "M月d日" };
- yield return new object[] { new CultureInfo("kn-IN").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("ko-KR").DateTimeFormat, "MMMM d일" };
- yield return new object[] { new CultureInfo("lt-LT").DateTimeFormat, "MMMM d d." }; // MMMM d 'd'.
- yield return new object[] { new CultureInfo("lv-LV").DateTimeFormat, "d. MMMM" };
- yield return new object[] { new CultureInfo("ml-IN").DateTimeFormat, "MMMM d" };
- yield return new object[] { new CultureInfo("mr-IN").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("ms-BN").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("ms-MY").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("ms-SG").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("nb-NO").DateTimeFormat, "d. MMMM" };
- yield return new object[] { new CultureInfo("no").DateTimeFormat, "d. MMMM" };
- yield return new object[] { new CultureInfo("no-NO").DateTimeFormat, "d. MMMM" };
- yield return new object[] { new CultureInfo("nl-AW").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("nl-BE").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("nl-NL").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("pl-PL").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("pt-BR").DateTimeFormat, "d de MMMM" }; // d 'de' MMMM
- yield return new object[] { new CultureInfo("pt-PT").DateTimeFormat, "d de MMMM" }; // d 'de' MMMM
- yield return new object[] { new CultureInfo("ro-RO").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("ru-RU").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("sk-SK").DateTimeFormat, "d. MMMM" };
- yield return new object[] { new CultureInfo("sl-SI").DateTimeFormat, "d. MMMM" };
- yield return new object[] { new CultureInfo("sr-Cyrl-RS").DateTimeFormat, "d. MMMM" };
- yield return new object[] { new CultureInfo("sr-Latn-RS").DateTimeFormat, "d. MMMM" };
- yield return new object[] { new CultureInfo("sv-AX").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("sv-SE").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("sw-CD").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("sw-KE").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("sw-TZ").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("sw-UG").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("ta-IN").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("ta-LK").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("ta-MY").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("ta-SG").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("te-IN").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("th-TH").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("tr-CY").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("tr-TR").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("uk-UA").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("vi-VN").DateTimeFormat, "d MMMM" };
- yield return new object[] { new CultureInfo("zh-Hans-HK").DateTimeFormat, "M月d日" };
- yield return new object[] { new CultureInfo("zh-SG").DateTimeFormat, "M月d日" };
- yield return new object[] { new CultureInfo("zh-HK").DateTimeFormat, "M月d日" };
- yield return new object[] { new CultureInfo("zh-TW").DateTimeFormat, "M月d日" };
- }
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsIcuGlobalization))]
[MemberData(nameof(MonthDayPattern_Get_TestData_ICU))]
@@ -229,13 +39,6 @@ public void MonthDayPattern_Get_ReturnsExpected_ICU(DateTimeFormatInfo format, s
Assert.Equal(expected, format.MonthDayPattern);
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
- [MemberData(nameof(MonthDayPattern_Get_TestData_HybridGlobalization))]
- public void MonthDayPattern_Get_ReturnsExpected_HybridGlobalization(DateTimeFormatInfo format, string expected)
- {
- Assert.Equal(expected, format.MonthDayPattern);
- }
-
[Theory]
[MemberData(nameof(MonthDayPattern_Set_TestData))]
public void MonthDayPattern_Set_GetReturnsExpected(string value)
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoMonthGenitiveNames.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoMonthGenitiveNames.cs
index 5167679d8cb2bf..68fcfd6e08a62e 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoMonthGenitiveNames.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoMonthGenitiveNames.cs
@@ -36,204 +36,6 @@ public static IEnumerable MonthGenitiveNames_Get_TestData()
yield return new object[] { CultureInfo.GetCultureInfo("en-US").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
yield return new object[] { CultureInfo.GetCultureInfo("fr-FR").DateTimeFormat, new string[] { "janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre", "" } };
}
- if (PlatformDetection.IsHybridGlobalizationOnBrowser)
- {
- // see the comments on the right to check the non-Hybrid result, if it differs
- yield return new object[] { new CultureInfo("ar-SA").DateTimeFormat, new string[] { "محرم", "صفر", "ربيع الأول", "ربيع الآخر", "جمادى الأولى", "جمادى الآخرة", "رجب", "شعبان", "رمضان", "شوال", "ذو القعدة", "ذو الحجة", "" } };
- if (PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS)
- {
- yield return new object[] { new CultureInfo("am-ET").DateTimeFormat, new string[] { "ጃንዩወሪ", "ፌብሩወሪ", "ማርች", "ኤፕሪል", "ሜይ", "ጁን", "ጁላይ", "ኦገስት", "ሴፕቴምበር", "ኦክቶበር", "ኖቬምበር", "ዲሴምበር", "" } };
- }
- else
- {
- yield return new object[] { new CultureInfo("am-ET").DateTimeFormat, new string[] { "ጃንዋሪ", "ፌብሩዋሪ", "ማርች", "ኤፕሪል", "ሜይ", "ጁን", "ጁላይ", "ኦገስት", "ሴፕቴምበር", "ኦክቶበር", "ኖቬምበር", "ዲሴምበር", "" } }; // "ጃንዩወሪ", "ፌብሩወሪ", "ማርች", "ኤፕሪል", "ሜይ", "ጁን", "ጁላይ", "ኦገስት", "ሴፕቴምበር", "ኦክቶበር", "ኖቬምበር", "ዲሴምበር", ""
- }
- yield return new object[] { new CultureInfo("bg-BG").DateTimeFormat, new string[] { "януари", "февруари", "март", "април", "май", "юни", "юли", "август", "септември", "октомври", "ноември", "декември", "" } };
- yield return new object[] { new CultureInfo("bn-BD").DateTimeFormat, new string[] { "জানুয়ারী", "ফেব্রুয়ারী", "মার্চ", "এপ্রিল", "মে", "জুন", "জুলাই", "আগস্ট", "সেপ্টেম্বর", "অক্টোবর", "নভেম্বর", "ডিসেম্বর", "" } };
- yield return new object[] { new CultureInfo("bn-IN").DateTimeFormat, new string[] { "জানুয়ারী", "ফেব্রুয়ারী", "মার্চ", "এপ্রিল", "মে", "জুন", "জুলাই", "আগস্ট", "সেপ্টেম্বর", "অক্টোবর", "নভেম্বর", "ডিসেম্বর", "" } };
- yield return new object[] { new CultureInfo("ca-AD").DateTimeFormat, new string[] { "gener", "febrer", "març", "abril", "maig", "juny", "juliol", "agost", "setembre", "octubre", "novembre", "desembre", "" } }; // "de gener", "de febrer", "de març", "d’abril", "de maig", "de juny", "de juliol", "d’agost", "de setembre", "d’octubre", "de novembre", "de desembre", ""
- yield return new object[] { new CultureInfo("ca-ES").DateTimeFormat, new string[] { "gener", "febrer", "març", "abril", "maig", "juny", "juliol", "agost", "setembre", "octubre", "novembre", "desembre", "" } }; // "de gener", "de febrer", "de març", "d’abril", "de maig", "de juny", "de juliol", "d’agost", "de setembre", "d’octubre", "de novembre", "de desembre", ""
- yield return new object[] { new CultureInfo("cs-CZ").DateTimeFormat, new string[] { "ledna", "února", "března", "dubna", "května", "června", "července", "srpna", "září", "října", "listopadu", "prosince", "" } };
- yield return new object[] { new CultureInfo("da-DK").DateTimeFormat, new string[] { "januar", "februar", "marts", "april", "maj", "juni", "juli", "august", "september", "oktober", "november", "december", "" } };
- yield return new object[] { new CultureInfo("de-AT").DateTimeFormat, new string[] { "Jänner", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember", "" } };
- yield return new object[] { new CultureInfo("de-BE").DateTimeFormat, new string[] { "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember", "" } };
- yield return new object[] { new CultureInfo("de-CH").DateTimeFormat, new string[] { "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember", "" } };
- yield return new object[] { new CultureInfo("de-DE").DateTimeFormat, new string[] { "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember", "" } };
- yield return new object[] { new CultureInfo("de-IT").DateTimeFormat, new string[] { "Jänner", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember", "" } };
- yield return new object[] { new CultureInfo("de-LI").DateTimeFormat, new string[] { "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember", "" } };
- yield return new object[] { new CultureInfo("de-LU").DateTimeFormat, new string[] { "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember", "" } };
- yield return new object[] { new CultureInfo("el-CY").DateTimeFormat, new string[] { "Ιανουαρίου", "Φεβρουαρίου", "Μαρτίου", "Απριλίου", "Μαΐου", "Ιουνίου", "Ιουλίου", "Αυγούστου", "Σεπτεμβρίου", "Οκτωβρίου", "Νοεμβρίου", "Δεκεμβρίου", "" } };
- yield return new object[] { new CultureInfo("el-GR").DateTimeFormat, new string[] { "Ιανουαρίου", "Φεβρουαρίου", "Μαρτίου", "Απριλίου", "Μαΐου", "Ιουνίου", "Ιουλίου", "Αυγούστου", "Σεπτεμβρίου", "Οκτωβρίου", "Νοεμβρίου", "Δεκεμβρίου", "" } };
- yield return new object[] { new CultureInfo("en-AE").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-AG").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-AI").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-AS").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-AT").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-AU").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-BB").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-BE").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-BI").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-BM").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-BS").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-BW").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-BZ").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-CA").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-CC").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-CH").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-CK").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-CM").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-CX").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-CY").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-DE").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-DK").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-DM").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-ER").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-FI").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-FJ").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-FK").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-FM").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-GB").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-GD").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-GG").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-GH").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-GI").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-GM").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-GU").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-GY").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-HK").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-IE").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-IL").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-IM").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-IN").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-IO").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-JE").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-JM").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-KE").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-KI").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-KN").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-KY").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-LC").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-LR").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-LS").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-MG").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-MH").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-MO").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-MP").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-MS").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-MT").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-MU").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-MW").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-MY").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-NA").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-NF").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-NG").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-NL").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-NR").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-NU").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-NZ").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-PG").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-PH").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-PK").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-PN").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-PR").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-PW").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-RW").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-SB").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-SC").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-SD").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-SE").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-SG").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-SH").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-SI").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-SL").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-SS").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-SX").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-SZ").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-TC").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-TK").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-TO").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-TT").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-TV").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-TZ").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-UG").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-UM").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-US").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-VC").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-VG").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-VI").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-VU").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-WS").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-ZA").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-ZM").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-ZW").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-US").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("es-419").DateTimeFormat, new string[] { "enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre", "" } };
- yield return new object[] { new CultureInfo("es-ES").DateTimeFormat, new string[] { "enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre", "" } };
- yield return new object[] { new CultureInfo("es-MX").DateTimeFormat, new string[] { "enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre", "" } };
- yield return new object[] { new CultureInfo("et-EE").DateTimeFormat, new string[] { "jaanuar", "veebruar", "märts", "aprill", "mai", "juuni", "juuli", "august", "september", "oktoober", "november", "detsember", "" } };
- yield return new object[] { new CultureInfo("fa-IR").DateTimeFormat, new string[] { "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" } };
- yield return new object[] { new CultureInfo("fi-FI").DateTimeFormat, new string[] { "tammikuuta", "helmikuuta", "maaliskuuta", "huhtikuuta", "toukokuuta", "kesäkuuta", "heinäkuuta", "elokuuta", "syyskuuta", "lokakuuta", "marraskuuta", "joulukuuta", "" } };
- yield return new object[] { new CultureInfo("fil-PH").DateTimeFormat, new string[] { "Enero", "Pebrero", "Marso", "Abril", "Mayo", "Hunyo", "Hulyo", "Agosto", "Setyembre", "Oktubre", "Nobyembre", "Disyembre", "" } };
- yield return new object[] { new CultureInfo("fr-BE").DateTimeFormat, new string[] { "janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre", "" } };
- yield return new object[] { new CultureInfo("fr-CA").DateTimeFormat, new string[] { "janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre", "" } };
- yield return new object[] { new CultureInfo("fr-CH").DateTimeFormat, new string[] { "janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre", "" } };
- yield return new object[] { new CultureInfo("fr-FR").DateTimeFormat, new string[] { "janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre", "" } };
- yield return new object[] { new CultureInfo("gu-IN").DateTimeFormat, new string[] { "જાન્યુઆરી", "ફેબ્રુઆરી", "માર્ચ", "એપ્રિલ", "મે", "જૂન", "જુલાઈ", "ઑગસ્ટ", "સપ્ટેમ્બર", "ઑક્ટોબર", "નવેમ્બર", "ડિસેમ્બર", "" } };
- yield return new object[] { new CultureInfo("he-IL").DateTimeFormat, new string[] { "ינואר", "פברואר", "מרץ", "אפריל", "מאי", "יוני", "יולי", "אוגוסט", "ספטמבר", "אוקטובר", "נובמבר", "דצמבר", "" } };
- yield return new object[] { new CultureInfo("hi-IN").DateTimeFormat, new string[] { "जनवरी", "फ़रवरी", "मार्च", "अप्रैल", "मई", "जून", "जुलाई", "अगस्त", "सितंबर", "अक्तूबर", "नवंबर", "दिसंबर", "" } };
- yield return new object[] { new CultureInfo("hr-BA").DateTimeFormat, new string[] { "siječnja", "veljače", "ožujka", "travnja", "svibnja", "lipnja", "srpnja", "kolovoza", "rujna", "listopada", "studenoga", "prosinca", "" } };
- yield return new object[] { new CultureInfo("hr-HR").DateTimeFormat, new string[] { "siječnja", "veljače", "ožujka", "travnja", "svibnja", "lipnja", "srpnja", "kolovoza", "rujna", "listopada", "studenoga", "prosinca", "" } };
- yield return new object[] { new CultureInfo("hu-HU").DateTimeFormat, new string[] { "január", "február", "március", "április", "május", "június", "július", "augusztus", "szeptember", "október", "november", "december", "" } };
- yield return new object[] { new CultureInfo("id-ID").DateTimeFormat, new string[] { "Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember", "" } };
- yield return new object[] { new CultureInfo("it-CH").DateTimeFormat, new string[] { "gennaio", "febbraio", "marzo", "aprile", "maggio", "giugno", "luglio", "agosto", "settembre", "ottobre", "novembre", "dicembre", "" } };
- yield return new object[] { new CultureInfo("it-IT").DateTimeFormat, new string[] { "gennaio", "febbraio", "marzo", "aprile", "maggio", "giugno", "luglio", "agosto", "settembre", "ottobre", "novembre", "dicembre", "" } };
- yield return new object[] { new CultureInfo("ja-JP").DateTimeFormat, new string[] { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", "" } };
- yield return new object[] { new CultureInfo("kn-IN").DateTimeFormat, new string[] { "ಜನವರಿ", "ಫೆಬ್ರವರಿ", "ಮಾರ್ಚ್", "ಏಪ್ರಿಲ್", "ಮೇ", "ಜೂನ್", "ಜುಲೈ", "ಆಗಸ್ಟ್", "ಸೆಪ್ಟೆಂಬರ್", "ಅಕ್ಟೋಬರ್", "ನವೆಂಬರ್", "ಡಿಸೆಂಬರ್", "" } };
- yield return new object[] { new CultureInfo("ko-KR").DateTimeFormat, new string[] { "1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월", "" } };
- yield return new object[] { new CultureInfo("lt-LT").DateTimeFormat, new string[] { "sausio", "vasario", "kovo", "balandžio", "gegužės", "birželio", "liepos", "rugpjūčio", "rugsėjo", "spalio", "lapkričio", "gruodžio", "" } };
- yield return new object[] { new CultureInfo("lv-LV").DateTimeFormat, new string[] { "janvāris", "februāris", "marts", "aprīlis", "maijs", "jūnijs", "jūlijs", "augusts", "septembris", "oktobris", "novembris", "decembris", "" } };
- yield return new object[] { new CultureInfo("ml-IN").DateTimeFormat, new string[] { "ജനുവരി", "ഫെബ്രുവരി", "മാർച്ച്", "ഏപ്രിൽ", "മേയ്", "ജൂൺ", "ജൂലൈ", "ഓഗസ്റ്റ്", "സെപ്റ്റംബർ", "ഒക്ടോബർ", "നവംബർ", "ഡിസംബർ", "" } };
- yield return new object[] { new CultureInfo("mr-IN").DateTimeFormat, new string[] { "जानेवारी", "फेब्रुवारी", "मार्च", "एप्रिल", "मे", "जून", "जुलै", "ऑगस्ट", "सप्टेंबर", "ऑक्टोबर", "नोव्हेंबर", "डिसेंबर", "" } };
- yield return new object[] { new CultureInfo("ms-BN").DateTimeFormat, new string[] { "Januari", "Februari", "Mac", "April", "Mei", "Jun", "Julai", "Ogos", "September", "Oktober", "November", "Disember", "" } };
- yield return new object[] { new CultureInfo("ms-MY").DateTimeFormat, new string[] { "Januari", "Februari", "Mac", "April", "Mei", "Jun", "Julai", "Ogos", "September", "Oktober", "November", "Disember", "" } };
- yield return new object[] { new CultureInfo("ms-SG").DateTimeFormat, new string[] { "Januari", "Februari", "Mac", "April", "Mei", "Jun", "Julai", "Ogos", "September", "Oktober", "November", "Disember", "" } };
- yield return new object[] { new CultureInfo("nb-NO").DateTimeFormat, new string[] { "januar", "februar", "mars", "april", "mai", "juni", "juli", "august", "september", "oktober", "november", "desember", "" } };
- yield return new object[] { new CultureInfo("no").DateTimeFormat, new string[] { "januar", "februar", "mars", "april", "mai", "juni", "juli", "august", "september", "oktober", "november", "desember", "" } };
- yield return new object[] { new CultureInfo("no-NO").DateTimeFormat, new string[] { "januar", "februar", "mars", "april", "mai", "juni", "juli", "august", "september", "oktober", "november", "desember", "" } };
- yield return new object[] { new CultureInfo("nl-AW").DateTimeFormat, new string[] { "januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december", "" } };
- yield return new object[] { new CultureInfo("nl-BE").DateTimeFormat, new string[] { "januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december", "" } };
- yield return new object[] { new CultureInfo("nl-NL").DateTimeFormat, new string[] { "januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december", "" } };
- yield return new object[] { new CultureInfo("pl-PL").DateTimeFormat, new string[] { "stycznia", "lutego", "marca", "kwietnia", "maja", "czerwca", "lipca", "sierpnia", "września", "października", "listopada", "grudnia", "" } };
- yield return new object[] { new CultureInfo("pt-BR").DateTimeFormat, new string[] { "janeiro", "fevereiro", "março", "abril", "maio", "junho", "julho", "agosto", "setembro", "outubro", "novembro", "dezembro", "" } };
- yield return new object[] { new CultureInfo("pt-PT").DateTimeFormat, new string[] { "janeiro", "fevereiro", "março", "abril", "maio", "junho", "julho", "agosto", "setembro", "outubro", "novembro", "dezembro", "" } };
- yield return new object[] { new CultureInfo("ro-RO").DateTimeFormat, new string[] { "ianuarie", "februarie", "martie", "aprilie", "mai", "iunie", "iulie", "august", "septembrie", "octombrie", "noiembrie", "decembrie", "" } };
- yield return new object[] { new CultureInfo("ru-RU").DateTimeFormat, new string[] { "января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря", "" } };
- yield return new object[] { new CultureInfo("sk-SK").DateTimeFormat, new string[] { "januára", "februára", "marca", "apríla", "mája", "júna", "júla", "augusta", "septembra", "októbra", "novembra", "decembra", "" } };
- yield return new object[] { new CultureInfo("sl-SI").DateTimeFormat, new string[] { "januar", "februar", "marec", "april", "maj", "junij", "julij", "avgust", "september", "oktober", "november", "december", "" } };
- yield return new object[] { new CultureInfo("sr-Cyrl-RS").DateTimeFormat, new string[] { "јануар", "фебруар", "март", "април", "мај", "јун", "јул", "август", "септембар", "октобар", "новембар", "децембар", "" } };
- yield return new object[] { new CultureInfo("sr-Latn-RS").DateTimeFormat, new string[] { "januar", "februar", "mart", "april", "maj", "jun", "jul", "avgust", "septembar", "oktobar", "novembar", "decembar", "" } };
- yield return new object[] { new CultureInfo("sv-AX").DateTimeFormat, new string[] { "januari", "februari", "mars", "april", "maj", "juni", "juli", "augusti", "september", "oktober", "november", "december", "" } };
- yield return new object[] { new CultureInfo("sv-SE").DateTimeFormat, new string[] { "januari", "februari", "mars", "april", "maj", "juni", "juli", "augusti", "september", "oktober", "november", "december", "" } };
- yield return new object[] { new CultureInfo("sw-CD").DateTimeFormat, new string[] { "Januari", "Februari", "Machi", "Aprili", "Mei", "Juni", "Julai", "Agosti", "Septemba", "Oktoba", "Novemba", "Desemba", "" } };
- yield return new object[] { new CultureInfo("sw-KE").DateTimeFormat, new string[] { "Januari", "Februari", "Machi", "Aprili", "Mei", "Juni", "Julai", "Agosti", "Septemba", "Oktoba", "Novemba", "Desemba", "" } };
- yield return new object[] { new CultureInfo("sw-TZ").DateTimeFormat, new string[] { "Januari", "Februari", "Machi", "Aprili", "Mei", "Juni", "Julai", "Agosti", "Septemba", "Oktoba", "Novemba", "Desemba", "" } };
- yield return new object[] { new CultureInfo("sw-UG").DateTimeFormat, new string[] { "Januari", "Februari", "Machi", "Aprili", "Mei", "Juni", "Julai", "Agosti", "Septemba", "Oktoba", "Novemba", "Desemba", "" } };
- yield return new object[] { new CultureInfo("ta-IN").DateTimeFormat, new string[] { "ஜனவரி", "பிப்ரவரி", "மார்ச்", "ஏப்ரல்", "மே", "ஜூன்", "ஜூலை", "ஆகஸ்ட்", "செப்டம்பர்", "அக்டோபர்", "நவம்பர்", "டிசம்பர்", "" } };
- yield return new object[] { new CultureInfo("ta-LK").DateTimeFormat, new string[] { "ஜனவரி", "பிப்ரவரி", "மார்ச்", "ஏப்ரல்", "மே", "ஜூன்", "ஜூலை", "ஆகஸ்ட்", "செப்டம்பர்", "அக்டோபர்", "நவம்பர்", "டிசம்பர்", "" } };
- yield return new object[] { new CultureInfo("ta-MY").DateTimeFormat, new string[] { "ஜனவரி", "பிப்ரவரி", "மார்ச்", "ஏப்ரல்", "மே", "ஜூன்", "ஜூலை", "ஆகஸ்ட்", "செப்டம்பர்", "அக்டோபர்", "நவம்பர்", "டிசம்பர்", "" } };
- yield return new object[] { new CultureInfo("ta-SG").DateTimeFormat, new string[] { "ஜனவரி", "பிப்ரவரி", "மார்ச்", "ஏப்ரல்", "மே", "ஜூன்", "ஜூலை", "ஆகஸ்ட்", "செப்டம்பர்", "அக்டோபர்", "நவம்பர்", "டிசம்பர்", "" } };
- yield return new object[] { new CultureInfo("te-IN").DateTimeFormat, new string[] { "జనవరి", "ఫిబ్రవరి", "మార్చి", "ఏప్రిల్", "మే", "జూన్", "జులై", "ఆగస్టు", "సెప్టెంబర్", "అక్టోబర్", "నవంబర్", "డిసెంబర్", "" } };
- yield return new object[] { new CultureInfo("th-TH").DateTimeFormat, new string[] { "มกราคม", "กุมภาพันธ์", "มีนาคม", "เมษายน", "พฤษภาคม", "มิถุนายน", "กรกฎาคม", "สิงหาคม", "กันยายน", "ตุลาคม", "พฤศจิกายน", "ธันวาคม", "" } };
- yield return new object[] { new CultureInfo("tr-CY").DateTimeFormat, new string[] { "Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık", "" } };
- yield return new object[] { new CultureInfo("tr-TR").DateTimeFormat, new string[] { "Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık", "" } };
- yield return new object[] { new CultureInfo("uk-UA").DateTimeFormat, new string[] { "січня", "лютого", "березня", "квітня", "травня", "червня", "липня", "серпня", "вересня", "жовтня", "листопада", "грудня", "" } };
- yield return new object[] { new CultureInfo("vi-VN").DateTimeFormat, new string[] { "Tháng 1", "Tháng 2", "Tháng 3", "Tháng 4", "Tháng 5", "Tháng 6", "Tháng 7", "Tháng 8", "Tháng 9", "Tháng 10", "Tháng 11", "Tháng 12", "" } }; // ICU: tháng
- yield return new object[] { new CultureInfo("zh-CN").DateTimeFormat, new string[] { "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月", "" } };
- yield return new object[] { new CultureInfo("zh-Hans-HK").DateTimeFormat, new string[] { "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月", "" } };
- yield return new object[] { new CultureInfo("zh-SG").DateTimeFormat, new string[] { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", "" } }; // "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月", ""
- yield return new object[] { new CultureInfo("zh-HK").DateTimeFormat, new string[] { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", "" } };
- yield return new object[] { new CultureInfo("zh-TW").DateTimeFormat, new string[] { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", "" } };
- }
}
[Theory]
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoMonthNames.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoMonthNames.cs
index e4d1b6084dd1c8..aa4c05574b54bc 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoMonthNames.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoMonthNames.cs
@@ -34,205 +34,6 @@ public static IEnumerable MonthNames_Get_TestData_ICU()
yield return new object[] { CultureInfo.GetCultureInfo("fr-FR").DateTimeFormat, new string[] { "janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre", "" } };
}
- public static IEnumerable MonthNames_Get_TestData_HybridGlobalization()
- {
- // see the comments on the right to check the non-Hybrid result, if it differs
- yield return new object[] { new CultureInfo("ar-SA").DateTimeFormat, new string[] { "محرم", "صفر", "ربيع الأول", "ربيع الآخر", "جمادى الأولى", "جمادى الآخرة", "رجب", "شعبان", "رمضان", "شوال", "ذو القعدة", "ذو الحجة", "" } };
- if (PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS)
- {
- yield return new object[] { new CultureInfo("am-ET").DateTimeFormat, new string[] { "ጃንዩወሪ", "ፌብሩወሪ", "ማርች", "ኤፕሪል", "ሜይ", "ጁን", "ጁላይ", "ኦገስት", "ሴፕቴምበር", "ኦክቶበር", "ኖቬምበር", "ዲሴምበር", "" } };
- }
- else
- {
- yield return new object[] { new CultureInfo("am-ET").DateTimeFormat, new string[] { "ጃንዋሪ", "ፌብሩዋሪ", "ማርች", "ኤፕሪል", "ሜይ", "ጁን", "ጁላይ", "ኦገስት", "ሴፕቴምበር", "ኦክቶበር", "ኖቬምበር", "ዲሴምበር", "" } }; // "ጃንዩወሪ", "ፌብሩወሪ", "ማርች", "ኤፕሪል", "ሜይ", "ጁን", "ጁላይ", "ኦገስት", "ሴፕቴምበር", "ኦክቶበር", "ኖቬምበር", "ዲሴምበር", ""
- }
- yield return new object[] { new CultureInfo("bg-BG").DateTimeFormat, new string[] { "януари", "февруари", "март", "април", "май", "юни", "юли", "август", "септември", "октомври", "ноември", "декември", "" } };
- yield return new object[] { new CultureInfo("bn-BD").DateTimeFormat, new string[] { "জানুয়ারী", "ফেব্রুয়ারী", "মার্চ", "এপ্রিল", "মে", "জুন", "জুলাই", "আগস্ট", "সেপ্টেম্বর", "অক্টোবর", "নভেম্বর", "ডিসেম্বর", "" } };
- yield return new object[] { new CultureInfo("bn-IN").DateTimeFormat, new string[] { "জানুয়ারী", "ফেব্রুয়ারী", "মার্চ", "এপ্রিল", "মে", "জুন", "জুলাই", "আগস্ট", "সেপ্টেম্বর", "অক্টোবর", "নভেম্বর", "ডিসেম্বর", "" } };
- yield return new object[] { new CultureInfo("ca-AD").DateTimeFormat, new string[] { "gener", "febrer", "març", "abril", "maig", "juny", "juliol", "agost", "setembre", "octubre", "novembre", "desembre", "" } };
- yield return new object[] { new CultureInfo("ca-ES").DateTimeFormat, new string[] { "gener", "febrer", "març", "abril", "maig", "juny", "juliol", "agost", "setembre", "octubre", "novembre", "desembre", "" } };
- yield return new object[] { new CultureInfo("cs-CZ").DateTimeFormat, new string[] { "leden", "únor", "březen", "duben", "květen", "červen", "červenec", "srpen", "září", "říjen", "listopad", "prosinec", "" } };
- yield return new object[] { new CultureInfo("da-DK").DateTimeFormat, new string[] { "januar", "februar", "marts", "april", "maj", "juni", "juli", "august", "september", "oktober", "november", "december", "" } };
- yield return new object[] { new CultureInfo("de-AT").DateTimeFormat, new string[] { "Jänner", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember", "" } };
- yield return new object[] { new CultureInfo("de-BE").DateTimeFormat, new string[] { "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember", "" } };
- yield return new object[] { new CultureInfo("de-CH").DateTimeFormat, new string[] { "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember", "" } };
- yield return new object[] { new CultureInfo("de-DE").DateTimeFormat, new string[] { "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember", "" } };
- yield return new object[] { new CultureInfo("de-IT").DateTimeFormat, new string[] { "Jänner", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember", "" } };
- yield return new object[] { new CultureInfo("de-LI").DateTimeFormat, new string[] { "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember", "" } };
- yield return new object[] { new CultureInfo("de-LU").DateTimeFormat, new string[] { "Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember", "" } };
- yield return new object[] { new CultureInfo("el-CY").DateTimeFormat, new string[] { "Ιανουαρίου", "Φεβρουαρίου", "Μαρτίου", "Απριλίου", "Μαΐου", "Ιουνίου", "Ιουλίου", "Αυγούστου", "Σεπτεμβρίου", "Οκτωβρίου", "Νοεμβρίου", "Δεκεμβρίου", "" } }; // BUG!!! JS returns Genitive for Greek even though we expect Nominative; "Ιανουάριος", "Φεβρουάριος", "Μάρτιος", "Απρίλιος", "Μάιος", "Ιούνιος", "Ιούλιος", "Αύγουστος", "Σεπτέμβριος", "Οκτώβριος", "Νοέμβριος", "Δεκέμβριος"
- yield return new object[] { new CultureInfo("el-GR").DateTimeFormat, new string[] { "Ιανουαρίου", "Φεβρουαρίου", "Μαρτίου", "Απριλίου", "Μαΐου", "Ιουνίου", "Ιουλίου", "Αυγούστου", "Σεπτεμβρίου", "Οκτωβρίου", "Νοεμβρίου", "Δεκεμβρίου", "" } }; // BUG!!! JS returns Genitive for Greek even though we expect Nominative; "Ιανουάριος", "Φεβρουάριος", "Μάρτιος", "Απρίλιος", "Μάιος", "Ιούνιος", "Ιούλιος", "Αύγουστος", "Σεπτέμβριος", "Οκτώβριος", "Νοέμβριος", "Δεκέμβριος"
- yield return new object[] { new CultureInfo("en-AE").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-AG").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-AI").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-AS").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-AT").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-AU").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-BB").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-BE").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-BI").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-BM").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-BS").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-BW").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-BZ").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-CA").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-CC").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-CH").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-CK").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-CM").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-CX").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-CY").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-DE").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-DK").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-DM").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-ER").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-FI").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-FJ").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-FK").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-FM").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-GB").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-GD").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-GG").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-GH").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-GI").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-GM").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-GU").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-GY").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-HK").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-IE").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-IL").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-IM").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-IN").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-IO").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-JE").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-JM").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-KE").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-KI").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-KN").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-KY").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-LC").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-LR").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-LS").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-MG").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-MH").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-MO").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-MP").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-MS").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-MT").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-MU").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-MW").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-MY").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-NA").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-NF").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-NG").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-NL").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-NR").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-NU").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-NZ").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-PG").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-PH").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-PK").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-PN").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-PR").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-PW").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-RW").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-SB").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-SC").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-SD").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-SE").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-SG").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-SH").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-SI").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-SL").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-SS").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-SX").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-SZ").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-TC").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-TK").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-TO").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-TT").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-TV").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-TZ").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-UG").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-UM").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-US").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-VC").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-VG").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-VI").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-VU").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-WS").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-ZA").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-ZM").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-ZW").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("en-US").DateTimeFormat, new string[] { "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", "" } };
- yield return new object[] { new CultureInfo("es-419").DateTimeFormat, new string[] { "enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre", "" } };
- yield return new object[] { new CultureInfo("es-ES").DateTimeFormat, new string[] { "enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre", "" } };
- yield return new object[] { new CultureInfo("es-MX").DateTimeFormat, new string[] { "enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre", "" } };
- yield return new object[] { new CultureInfo("et-EE").DateTimeFormat, new string[] { "jaanuar", "veebruar", "märts", "aprill", "mai", "juuni", "juuli", "august", "september", "oktoober", "november", "detsember", "" } };
- yield return new object[] { new CultureInfo("fa-IR").DateTimeFormat, new string[] { "فروردین", "اردیبهشت", "خرداد", "تیر", "مرداد", "شهریور", "مهر", "آبان", "آذر", "دی", "بهمن", "اسفند", "" } };
- yield return new object[] { new CultureInfo("fi-FI").DateTimeFormat, new string[] { "tammikuu", "helmikuu", "maaliskuu", "huhtikuu", "toukokuu", "kesäkuu", "heinäkuu", "elokuu", "syyskuu", "lokakuu", "marraskuu", "joulukuu", "" } };
- yield return new object[] { new CultureInfo("fil-PH").DateTimeFormat, new string[] { "Enero", "Pebrero", "Marso", "Abril", "Mayo", "Hunyo", "Hulyo", "Agosto", "Setyembre", "Oktubre", "Nobyembre", "Disyembre", "" } };
- yield return new object[] { new CultureInfo("fr-BE").DateTimeFormat, new string[] { "janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre", "" } };
- yield return new object[] { new CultureInfo("fr-CA").DateTimeFormat, new string[] { "janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre", "" } };
- yield return new object[] { new CultureInfo("fr-CH").DateTimeFormat, new string[] { "janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre", "" } };
- yield return new object[] { new CultureInfo("fr-FR").DateTimeFormat, new string[] { "janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre", "" } };
- yield return new object[] { new CultureInfo("gu-IN").DateTimeFormat, new string[] { "જાન્યુઆરી", "ફેબ્રુઆરી", "માર્ચ", "એપ્રિલ", "મે", "જૂન", "જુલાઈ", "ઑગસ્ટ", "સપ્ટેમ્બર", "ઑક્ટોબર", "નવેમ્બર", "ડિસેમ્બર", "" } };
- yield return new object[] { new CultureInfo("he-IL").DateTimeFormat, new string[] { "ינואר", "פברואר", "מרץ", "אפריל", "מאי", "יוני", "יולי", "אוגוסט", "ספטמבר", "אוקטובר", "נובמבר", "דצמבר", "" } };
- yield return new object[] { new CultureInfo("hi-IN").DateTimeFormat, new string[] { "जनवरी", "फ़रवरी", "मार्च", "अप्रैल", "मई", "जून", "जुलाई", "अगस्त", "सितंबर", "अक्तूबर", "नवंबर", "दिसंबर", "" } };
- yield return new object[] { new CultureInfo("hr-BA").DateTimeFormat, new string[] { "siječanj", "veljača", "ožujak", "travanj", "svibanj", "lipanj", "srpanj", "kolovoz", "rujan", "listopad", "studeni", "prosinac", "" } };
- yield return new object[] { new CultureInfo("hr-HR").DateTimeFormat, new string[] { "siječanj", "veljača", "ožujak", "travanj", "svibanj", "lipanj", "srpanj", "kolovoz", "rujan", "listopad", "studeni", "prosinac", "" } };
- yield return new object[] { new CultureInfo("hu-HU").DateTimeFormat, new string[] { "január", "február", "március", "április", "május", "június", "július", "augusztus", "szeptember", "október", "november", "december", "" } };
- yield return new object[] { new CultureInfo("id-ID").DateTimeFormat, new string[] { "Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember", "" } };
- yield return new object[] { new CultureInfo("it-CH").DateTimeFormat, new string[] { "gennaio", "febbraio", "marzo", "aprile", "maggio", "giugno", "luglio", "agosto", "settembre", "ottobre", "novembre", "dicembre", "" } };
- yield return new object[] { new CultureInfo("it-IT").DateTimeFormat, new string[] { "gennaio", "febbraio", "marzo", "aprile", "maggio", "giugno", "luglio", "agosto", "settembre", "ottobre", "novembre", "dicembre", "" } };
- yield return new object[] { new CultureInfo("ja-JP").DateTimeFormat, new string[] { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", "" } };
- yield return new object[] { new CultureInfo("kn-IN").DateTimeFormat, new string[] { "ಜನವರಿ", "ಫೆಬ್ರವರಿ", "ಮಾರ್ಚ್", "ಏಪ್ರಿಲ್", "ಮೇ", "ಜೂನ್", "ಜುಲೈ", "ಆಗಸ್ಟ್", "ಸೆಪ್ಟೆಂಬರ್", "ಅಕ್ಟೋಬರ್", "ನವೆಂಬರ್", "ಡಿಸೆಂಬರ್", "" } };
- yield return new object[] { new CultureInfo("ko-KR").DateTimeFormat, new string[] { "1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월", "" } };
- yield return new object[] { new CultureInfo("lt-LT").DateTimeFormat, new string[] { "sausis", "vasaris", "kovas", "balandis", "gegužė", "birželis", "liepa", "rugpjūtis", "rugsėjis", "spalis", "lapkritis", "gruodis", "" } };
- yield return new object[] { new CultureInfo("lv-LV").DateTimeFormat, new string[] { "janvāris", "februāris", "marts", "aprīlis", "maijs", "jūnijs", "jūlijs", "augusts", "septembris", "oktobris", "novembris", "decembris", "" } };
- yield return new object[] { new CultureInfo("ml-IN").DateTimeFormat, new string[] { "ജനുവരി", "ഫെബ്രുവരി", "മാർച്ച്", "ഏപ്രിൽ", "മേയ്", "ജൂൺ", "ജൂലൈ", "ഓഗസ്റ്റ്", "സെപ്റ്റംബർ", "ഒക്ടോബർ", "നവംബർ", "ഡിസംബർ", "" } };
- yield return new object[] { new CultureInfo("mr-IN").DateTimeFormat, new string[] { "जानेवारी", "फेब्रुवारी", "मार्च", "एप्रिल", "मे", "जून", "जुलै", "ऑगस्ट", "सप्टेंबर", "ऑक्टोबर", "नोव्हेंबर", "डिसेंबर", "" } };
- yield return new object[] { new CultureInfo("ms-BN").DateTimeFormat, new string[] { "Januari", "Februari", "Mac", "April", "Mei", "Jun", "Julai", "Ogos", "September", "Oktober", "November", "Disember", "" } };
- yield return new object[] { new CultureInfo("ms-MY").DateTimeFormat, new string[] { "Januari", "Februari", "Mac", "April", "Mei", "Jun", "Julai", "Ogos", "September", "Oktober", "November", "Disember", "" } };
- yield return new object[] { new CultureInfo("ms-SG").DateTimeFormat, new string[] { "Januari", "Februari", "Mac", "April", "Mei", "Jun", "Julai", "Ogos", "September", "Oktober", "November", "Disember", "" } };
- yield return new object[] { new CultureInfo("nb-NO").DateTimeFormat, new string[] { "januar", "februar", "mars", "april", "mai", "juni", "juli", "august", "september", "oktober", "november", "desember", "" } };
- yield return new object[] { new CultureInfo("no").DateTimeFormat, new string[] { "januar", "februar", "mars", "april", "mai", "juni", "juli", "august", "september", "oktober", "november", "desember", "" } };
- yield return new object[] { new CultureInfo("no-NO").DateTimeFormat, new string[] { "januar", "februar", "mars", "april", "mai", "juni", "juli", "august", "september", "oktober", "november", "desember", "" } };
- yield return new object[] { new CultureInfo("nl-AW").DateTimeFormat, new string[] { "januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december", "" } };
- yield return new object[] { new CultureInfo("nl-BE").DateTimeFormat, new string[] { "januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december", "" } };
- yield return new object[] { new CultureInfo("nl-NL").DateTimeFormat, new string[] { "januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december", "" } };
- yield return new object[] { new CultureInfo("pl-PL").DateTimeFormat, new string[] { "styczeń", "luty", "marzec", "kwiecień", "maj", "czerwiec", "lipiec", "sierpień", "wrzesień", "październik", "listopad", "grudzień", "" } };
- yield return new object[] { new CultureInfo("pt-BR").DateTimeFormat, new string[] { "janeiro", "fevereiro", "março", "abril", "maio", "junho", "julho", "agosto", "setembro", "outubro", "novembro", "dezembro", "" } };
- yield return new object[] { new CultureInfo("pt-PT").DateTimeFormat, new string[] { "janeiro", "fevereiro", "março", "abril", "maio", "junho", "julho", "agosto", "setembro", "outubro", "novembro", "dezembro", "" } };
- yield return new object[] { new CultureInfo("ro-RO").DateTimeFormat, new string[] { "ianuarie", "februarie", "martie", "aprilie", "mai", "iunie", "iulie", "august", "septembrie", "octombrie", "noiembrie", "decembrie", "" } };
- yield return new object[] { new CultureInfo("ru-RU").DateTimeFormat, new string[] { "январь", "февраль", "март", "апрель", "май", "июнь", "июль", "август", "сентябрь", "октябрь", "ноябрь", "декабрь", "" } };
- yield return new object[] { new CultureInfo("sk-SK").DateTimeFormat, new string[] { "január", "február", "marec", "apríl", "máj", "jún", "júl", "august", "september", "október", "november", "december", "" } };
- yield return new object[] { new CultureInfo("sl-SI").DateTimeFormat, new string[] { "januar", "februar", "marec", "april", "maj", "junij", "julij", "avgust", "september", "oktober", "november", "december", "" } };
- yield return new object[] { new CultureInfo("sr-Cyrl-RS").DateTimeFormat, new string[] { "јануар", "фебруар", "март", "април", "мај", "јун", "јул", "август", "септембар", "октобар", "новембар", "децембар", "" } };
- yield return new object[] { new CultureInfo("sr-Latn-RS").DateTimeFormat, new string[] { "januar", "februar", "mart", "april", "maj", "jun", "jul", "avgust", "septembar", "oktobar", "novembar", "decembar", "" } };
- yield return new object[] { new CultureInfo("sv-AX").DateTimeFormat, new string[] { "januari", "februari", "mars", "april", "maj", "juni", "juli", "augusti", "september", "oktober", "november", "december", "" } };
- yield return new object[] { new CultureInfo("sv-SE").DateTimeFormat, new string[] { "januari", "februari", "mars", "april", "maj", "juni", "juli", "augusti", "september", "oktober", "november", "december", "" } };
- yield return new object[] { new CultureInfo("sw-CD").DateTimeFormat, new string[] { "Januari", "Februari", "Machi", "Aprili", "Mei", "Juni", "Julai", "Agosti", "Septemba", "Oktoba", "Novemba", "Desemba", "" } };
- yield return new object[] { new CultureInfo("sw-KE").DateTimeFormat, new string[] { "Januari", "Februari", "Machi", "Aprili", "Mei", "Juni", "Julai", "Agosti", "Septemba", "Oktoba", "Novemba", "Desemba", "" } };
- yield return new object[] { new CultureInfo("sw-TZ").DateTimeFormat, new string[] { "Januari", "Februari", "Machi", "Aprili", "Mei", "Juni", "Julai", "Agosti", "Septemba", "Oktoba", "Novemba", "Desemba", "" } };
- yield return new object[] { new CultureInfo("sw-UG").DateTimeFormat, new string[] { "Januari", "Februari", "Machi", "Aprili", "Mei", "Juni", "Julai", "Agosti", "Septemba", "Oktoba", "Novemba", "Desemba", "" } };
- yield return new object[] { new CultureInfo("ta-IN").DateTimeFormat, new string[] { "ஜனவரி", "பிப்ரவரி", "மார்ச்", "ஏப்ரல்", "மே", "ஜூன்", "ஜூலை", "ஆகஸ்ட்", "செப்டம்பர்", "அக்டோபர்", "நவம்பர்", "டிசம்பர்", "" } };
- yield return new object[] { new CultureInfo("ta-LK").DateTimeFormat, new string[] { "ஜனவரி", "பிப்ரவரி", "மார்ச்", "ஏப்ரல்", "மே", "ஜூன்", "ஜூலை", "ஆகஸ்ட்", "செப்டம்பர்", "அக்டோபர்", "நவம்பர்", "டிசம்பர்", "" } };
- yield return new object[] { new CultureInfo("ta-MY").DateTimeFormat, new string[] { "ஜனவரி", "பிப்ரவரி", "மார்ச்", "ஏப்ரல்", "மே", "ஜூன்", "ஜூலை", "ஆகஸ்ட்", "செப்டம்பர்", "அக்டோபர்", "நவம்பர்", "டிசம்பர்", "" } };
- yield return new object[] { new CultureInfo("ta-SG").DateTimeFormat, new string[] { "ஜனவரி", "பிப்ரவரி", "மார்ச்", "ஏப்ரல்", "மே", "ஜூன்", "ஜூலை", "ஆகஸ்ட்", "செப்டம்பர்", "அக்டோபர்", "நவம்பர்", "டிசம்பர்", "" } };
- yield return new object[] { new CultureInfo("te-IN").DateTimeFormat, new string[] { "జనవరి", "ఫిబ్రవరి", "మార్చి", "ఏప్రిల్", "మే", "జూన్", "జులై", "ఆగస్టు", "సెప్టెంబర్", "అక్టోబర్", "నవంబర్", "డిసెంబర్", "" } };
- yield return new object[] { new CultureInfo("th-TH").DateTimeFormat, new string[] { "มกราคม", "กุมภาพันธ์", "มีนาคม", "เมษายน", "พฤษภาคม", "มิถุนายน", "กรกฎาคม", "สิงหาคม", "กันยายน", "ตุลาคม", "พฤศจิกายน", "ธันวาคม", "" } };
- yield return new object[] { new CultureInfo("tr-CY").DateTimeFormat, new string[] { "Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık", "" } };
- yield return new object[] { new CultureInfo("tr-TR").DateTimeFormat, new string[] { "Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık", "" } };
- yield return new object[] { new CultureInfo("uk-UA").DateTimeFormat, new string[] { "січень", "лютий", "березень", "квітень", "травень", "червень", "липень", "серпень", "вересень", "жовтень", "листопад", "грудень", "" } };
- yield return new object[] { new CultureInfo("vi-VN").DateTimeFormat, new string[] { "Tháng 1", "Tháng 2", "Tháng 3", "Tháng 4", "Tháng 5", "Tháng 6", "Tháng 7", "Tháng 8", "Tháng 9", "Tháng 10", "Tháng 11", "Tháng 12", "" } };
- yield return new object[] { new CultureInfo("zh-CN").DateTimeFormat, new string[] { "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月", "" } };
- yield return new object[] { new CultureInfo("zh-Hans-HK").DateTimeFormat, new string[] { "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月", "" } };
- yield return new object[] { new CultureInfo("zh-SG").DateTimeFormat, new string[] { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", "" } }; // "一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月", ""
- yield return new object[] { new CultureInfo("zh-HK").DateTimeFormat, new string[] { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", "" } };
- yield return new object[] { new CultureInfo("zh-TW").DateTimeFormat, new string[] { "1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月", "" } };
- }
-
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsIcuGlobalization))]
[MemberData(nameof(MonthNames_Get_TestData_ICU))]
public void MonthNames_Get_ReturnsExpected_ICU(DateTimeFormatInfo format, string[] expected)
@@ -240,13 +41,6 @@ public void MonthNames_Get_ReturnsExpected_ICU(DateTimeFormatInfo format, string
Assert.Equal(expected, format.MonthNames);
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
- [MemberData(nameof(MonthNames_Get_TestData_HybridGlobalization))]
- public void MonthNames_Get_ReturnsExpected(DateTimeFormatInfo format, string[] expected)
- {
- Assert.Equal(expected, format.MonthNames);
- }
-
[Theory]
[MemberData(nameof(MonthNames_Set_TestData))]
public void MonthNames_Set_GetReturnsExpected(string[] value)
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoNativeCalendarName.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoNativeCalendarName.cs
deleted file mode 100644
index 377e6d30d597bc..00000000000000
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoNativeCalendarName.cs
+++ /dev/null
@@ -1,214 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-using Xunit;
-using System.Collections.Generic;
-
-namespace System.Globalization.Tests
-{
- public class DateTimeFormatInfoNativeCalendarName
- {
- public static IEnumerable NativeCalendarName_Get_TestData_HybridGlobalization()
- {
- // see the comments on the right to check the non-Hybrid result, in this collection it always differs
- string islamicName = PlatformDetection.IsFirefox ? "UMALQURA" : "islamic-umalqura";
- string gregorianName = PlatformDetection.IsFirefox ? "GREGORIAN" : "gregory";
- string persianName = PlatformDetection.IsFirefox ? "PERSIAN" : "persian";
- string bhuddistName = PlatformDetection.IsFirefox ? "THAI" : "buddhist";
- yield return new object[] { new CultureInfo("ar-SA").DateTimeFormat, islamicName }; // التقويم الإسلامي (أم القرى)
- yield return new object[] { new CultureInfo("am-ET").DateTimeFormat, gregorianName }; // የግሪጎሪያን የቀን አቆጣጠር
- yield return new object[] { new CultureInfo("bg-BG").DateTimeFormat, gregorianName }; // григориански календар
- yield return new object[] { new CultureInfo("bn-BD").DateTimeFormat, gregorianName }; // গ্রিগোরিয়ান ক্যালেন্ডার
- yield return new object[] { new CultureInfo("bn-IN").DateTimeFormat, gregorianName }; // গ্রিগোরিয়ান ক্যালেন্ডার
- yield return new object[] { new CultureInfo("ca-AD").DateTimeFormat, gregorianName }; // calendari gregorià
- yield return new object[] { new CultureInfo("ca-ES").DateTimeFormat, gregorianName }; // calendari gregorià
- yield return new object[] { new CultureInfo("cs-CZ").DateTimeFormat, gregorianName }; // Gregoriánský kalendář
- yield return new object[] { new CultureInfo("da-DK").DateTimeFormat, gregorianName }; // gregoriansk kalender
- yield return new object[] { new CultureInfo("de-AT").DateTimeFormat, gregorianName }; // Gregorianischer Kalender
- yield return new object[] { new CultureInfo("de-BE").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("de-CH").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("de-DE").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("de-IT").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("de-LI").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("de-LU").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("el-CY").DateTimeFormat, gregorianName }; // Γρηγοριανό ημερολόγιο
- yield return new object[] { new CultureInfo("el-GR").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-AE").DateTimeFormat, gregorianName }; // Gregorian Calendar
- yield return new object[] { new CultureInfo("en-AG").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-AI").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-AS").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-AT").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-AU").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-BB").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-BE").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-BI").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-BM").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-BS").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-BW").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-BZ").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-CA").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-CC").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-CH").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-CK").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-CM").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-CX").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-CY").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-DE").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-DK").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-DM").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-ER").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-FI").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-FJ").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-FK").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-FM").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-GB").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-GD").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-GG").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-GH").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-GI").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-GM").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-GU").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-GY").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-HK").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-IE").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-IL").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-IM").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-IN").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-IO").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-JE").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-JM").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-KE").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-KI").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-KN").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-KY").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-LC").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-LR").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-LS").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-MG").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-MH").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-MO").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-MP").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-MS").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-MT").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-MU").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-MW").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-MY").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-NA").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-NF").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-NG").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-NL").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-NR").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-NU").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-NZ").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-PG").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-PH").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-PK").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-PN").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-PR").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-PW").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-RW").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-SB").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-SC").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-SD").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-SE").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-SG").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-SH").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-SI").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-SL").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-SS").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-SX").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-SZ").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-TC").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-TK").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-TO").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-TT").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-TV").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-TZ").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-UG").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-UM").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-US").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-VC").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-VG").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-VI").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-VU").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-WS").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-ZA").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-ZM").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-ZW").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("en-US").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("es-419").DateTimeFormat, gregorianName }; // calendario gregoriano
- yield return new object[] { new CultureInfo("es-ES").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("es-MX").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("et-EE").DateTimeFormat, gregorianName }; // Gregoriuse kalender
- yield return new object[] { new CultureInfo("fa-IR").DateTimeFormat, persianName }; // تقویم هجری شمسی
- yield return new object[] { new CultureInfo("fi-FI").DateTimeFormat, gregorianName }; // gregoriaaninen kalenteri
- yield return new object[] { new CultureInfo("fil-PH").DateTimeFormat, gregorianName }; // Gregorian na Kalendaryo
- yield return new object[] { new CultureInfo("fr-BE").DateTimeFormat, gregorianName }; // calendrier grégorien
- yield return new object[] { new CultureInfo("fr-CA").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("fr-CH").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("fr-FR").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("gu-IN").DateTimeFormat, gregorianName }; // ગ્રેગોરિઅન કેલેન્ડર
- yield return new object[] { new CultureInfo("he-IL").DateTimeFormat, gregorianName }; // לוח השנה הגרגוריאני
- yield return new object[] { new CultureInfo("hi-IN").DateTimeFormat, gregorianName }; // ग्रेगोरियन कैलेंडर"
- yield return new object[] { new CultureInfo("hr-BA").DateTimeFormat, gregorianName }; // gregorijanski kalendar
- yield return new object[] { new CultureInfo("hr-HR").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("hu-HU").DateTimeFormat, gregorianName }; // Gergely-naptár
- yield return new object[] { new CultureInfo("id-ID").DateTimeFormat, gregorianName }; // Kalender Gregorian"
- yield return new object[] { new CultureInfo("it-CH").DateTimeFormat, gregorianName }; // Calendario gregoriano
- yield return new object[] { new CultureInfo("it-IT").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("ja-JP").DateTimeFormat, gregorianName }; // 西暦(グレゴリオ暦)
- yield return new object[] { new CultureInfo("kn-IN").DateTimeFormat, gregorianName }; // ಗ್ರೆಗೋರಿಯನ್ ಕ್ಯಾಲೆಂಡರ್
- yield return new object[] { new CultureInfo("ko-KR").DateTimeFormat, gregorianName }; // 양력
- yield return new object[] { new CultureInfo("lt-LT").DateTimeFormat, gregorianName }; // Grigaliaus kalendorius
- yield return new object[] { new CultureInfo("lv-LV").DateTimeFormat, gregorianName }; // Gregora kalendārs
- yield return new object[] { new CultureInfo("ml-IN").DateTimeFormat, gregorianName }; // ഇംഗ്ലീഷ് കലണ്ടർ
- yield return new object[] { new CultureInfo("mr-IN").DateTimeFormat, gregorianName }; // ग्रेगोरियन दिनदर्शिका
- yield return new object[] { new CultureInfo("ms-BN").DateTimeFormat, gregorianName }; // Kalendar Gregory
- yield return new object[] { new CultureInfo("ms-MY").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("ms-SG").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("nb-NO").DateTimeFormat, gregorianName }; // gregoriansk kalender
- yield return new object[] { new CultureInfo("no").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("no-NO").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("nl-AW").DateTimeFormat, gregorianName }; // Gregoriaanse kalender
- yield return new object[] { new CultureInfo("nl-BE").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("nl-NL").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("pl-PL").DateTimeFormat, gregorianName }; // kalendarz gregoriański
- yield return new object[] { new CultureInfo("pt-BR").DateTimeFormat, gregorianName }; // Calendário Gregoriano
- yield return new object[] { new CultureInfo("pt-PT").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("ro-RO").DateTimeFormat, gregorianName }; // calendar gregory
- yield return new object[] { new CultureInfo("ru-RU").DateTimeFormat, gregorianName }; // григорианский календарь
- yield return new object[] { new CultureInfo("sk-SK").DateTimeFormat, gregorianName }; // gregoriánsky kalendár
- yield return new object[] { new CultureInfo("sl-SI").DateTimeFormat, gregorianName }; // gregorijanski koledar
- yield return new object[] { new CultureInfo("sr-Cyrl-RS").DateTimeFormat, gregorianName }; // грегоријански календар
- yield return new object[] { new CultureInfo("sr-Latn-RS").DateTimeFormat, gregorianName }; // gregorijanski kalendar
- yield return new object[] { new CultureInfo("sv-AX").DateTimeFormat, gregorianName }; // gregoriansk kalender
- yield return new object[] { new CultureInfo("sv-SE").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("sw-CD").DateTimeFormat, gregorianName }; // Kalenda ya Kigregori
- yield return new object[] { new CultureInfo("sw-KE").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("sw-TZ").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("sw-UG").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("ta-IN").DateTimeFormat, gregorianName }; // கிரிகோரியன் நாள்காட்டி
- yield return new object[] { new CultureInfo("ta-LK").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("ta-MY").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("ta-SG").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("te-IN").DateTimeFormat, gregorianName };// గ్రేగోరియన్ క్యాలెండర్
- yield return new object[] { new CultureInfo("th-TH").DateTimeFormat, bhuddistName }; // ปฏิทินพุทธ
- yield return new object[] { new CultureInfo("tr-CY").DateTimeFormat, gregorianName }; // Miladi Takvim
- yield return new object[] { new CultureInfo("tr-TR").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("uk-UA").DateTimeFormat, gregorianName }; // григоріанський календар
- yield return new object[] { new CultureInfo("vi-VN").DateTimeFormat, gregorianName }; // Lịch Gregory
- yield return new object[] { new CultureInfo("zh-CN").DateTimeFormat, gregorianName }; // 公历
- yield return new object[] { new CultureInfo("zh-Hans-HK").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("zh-SG").DateTimeFormat, gregorianName };
- yield return new object[] { new CultureInfo("zh-HK").DateTimeFormat, gregorianName }; // 公曆
- yield return new object[] { new CultureInfo("zh-TW").DateTimeFormat, gregorianName };
- }
-
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
- [MemberData(nameof(NativeCalendarName_Get_TestData_HybridGlobalization))]
- public void NativeCalendarName_Get_ReturnsExpected_HybridGlobalization(DateTimeFormatInfo format, string expected)
- {
- Assert.Equal(expected, format.NativeCalendarName);
- }
- }
-}
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoPMDesignator.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoPMDesignator.cs
index c85029aabfc4e2..cf0504082c5430 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoPMDesignator.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoPMDesignator.cs
@@ -14,206 +14,6 @@ public void PMDesignator_GetInvariantInfo_ReturnsExpected()
Assert.Equal("PM", DateTimeFormatInfo.InvariantInfo.PMDesignator);
}
- public static IEnumerable PMDesignator_Get_TestData_HybridGlobalization()
- {
- // see the comments on the right to check the non-Hybrid result, if it differs
- yield return new object[] { new CultureInfo("ar-SA").DateTimeFormat, "م" };
- yield return new object[] { new CultureInfo("am-ET").DateTimeFormat, "ከሰዓት" };
- yield return new object[] { new CultureInfo("bg-BG").DateTimeFormat, "сл.об." };
- yield return new object[] { new CultureInfo("bn-BD").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("bn-IN").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("ca-AD").DateTimeFormat, "p.\u00A0m." };
- yield return new object[] { new CultureInfo("ca-ES").DateTimeFormat, "p.\u00A0m." };
- yield return new object[] { new CultureInfo("cs-CZ").DateTimeFormat, "odp." };
- yield return new object[] { new CultureInfo("da-DK").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("de-AT").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("de-BE").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("de-CH").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("de-DE").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("de-IT").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("de-LI").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("de-LU").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("el-CY").DateTimeFormat, "μ.μ." };
- yield return new object[] { new CultureInfo("el-GR").DateTimeFormat, "μ.μ." };
- yield return new object[] { new CultureInfo("en-AE").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("en-AG").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-AI").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-AS").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("en-AT").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-AU").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-BB").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-BE").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-BI").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("en-BM").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-BS").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-BW").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-BZ").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-CA").DateTimeFormat, "p.m." };
- yield return new object[] { new CultureInfo("en-CC").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-CH").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-CK").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-CM").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-CX").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-CY").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-DE").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-DK").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-DM").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-ER").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-FI").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-FJ").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-FK").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-FM").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-GB").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-GD").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-GG").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-GH").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-GI").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-GM").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-GU").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("en-GY").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-HK").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-IE").DateTimeFormat, "p.m." };
- yield return new object[] { new CultureInfo("en-IL").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-IM").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-IN").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-IO").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-JE").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-JM").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-KE").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-KI").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-KN").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-KY").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-LC").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-LR").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-LS").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-MG").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-MH").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("en-MO").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-MP").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("en-MS").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-MT").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-MU").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-MW").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-MY").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-NA").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-NF").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-NG").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-NL").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-NR").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-NU").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-NZ").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-PG").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-PH").DateTimeFormat, "PM" }; // "pm"
- yield return new object[] { new CultureInfo("en-PK").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-PN").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-PR").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("en-PW").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-RW").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-SB").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-SC").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-SD").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-SE").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-SG").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-SH").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-SI").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-SL").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-SS").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-SX").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-SZ").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-TC").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-TK").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-TO").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-TT").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-TV").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-TZ").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-UG").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-UM").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("en-US").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("en-VC").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-VG").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-VI").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("en-VU").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-WS").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-ZA").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-ZM").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("en-ZW").DateTimeFormat, "pm" };
- string latinAmericaSpanishDesignator = PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "p.\u00A0m." : "p.m."; // p.m.
- yield return new object[] { new CultureInfo("es-419").DateTimeFormat, latinAmericaSpanishDesignator };
- yield return new object[] { new CultureInfo("es-ES").DateTimeFormat, "p.\u00A0m." }; // p.m.
- yield return new object[] { new CultureInfo("es-MX").DateTimeFormat, latinAmericaSpanishDesignator };
- yield return new object[] { new CultureInfo("et-EE").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("fa-IR").DateTimeFormat, "بعدازظهر" };
- yield return new object[] { new CultureInfo("fi-FI").DateTimeFormat, "ip." };
- yield return new object[] { new CultureInfo("fil-PH").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("fr-BE").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("fr-CA").DateTimeFormat, "p.m." };
- yield return new object[] { new CultureInfo("fr-CH").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("fr-FR").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("gu-IN").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("he-IL").DateTimeFormat, "אחה״צ" };
- yield return new object[] { new CultureInfo("hi-IN").DateTimeFormat, "pm" };
- yield return new object[] { new CultureInfo("hr-BA").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("hr-HR").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("hu-HU").DateTimeFormat, "du." };
- yield return new object[] { new CultureInfo("id-ID").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("it-CH").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("it-IT").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("ja-JP").DateTimeFormat, "午後" };
- yield return new object[] { new CultureInfo("kn-IN").DateTimeFormat, "ಅಪರಾಹ್ನ" };
- yield return new object[] { new CultureInfo("ko-KR").DateTimeFormat, "오후" };
- yield return new object[] { new CultureInfo("lt-LT").DateTimeFormat, "popiet" };
- yield return new object[] { new CultureInfo("lv-LV").DateTimeFormat, "pēcpusdienā" };
- yield return new object[] { new CultureInfo("ml-IN").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("mr-IN").DateTimeFormat, "PM" }; // म.उ.
- yield return new object[] { new CultureInfo("ms-BN").DateTimeFormat, "PTG" };
- yield return new object[] { new CultureInfo("ms-MY").DateTimeFormat, "PTG" };
- yield return new object[] { new CultureInfo("ms-SG").DateTimeFormat, "PTG" };
- yield return new object[] { new CultureInfo("nb-NO").DateTimeFormat, "p.m." };
- yield return new object[] { new CultureInfo("no").DateTimeFormat, "p.m." };
- yield return new object[] { new CultureInfo("no-NO").DateTimeFormat, "p.m." };
- yield return new object[] { new CultureInfo("nl-AW").DateTimeFormat, "p.m." };
- yield return new object[] { new CultureInfo("nl-BE").DateTimeFormat, "p.m." };
- yield return new object[] { new CultureInfo("nl-NL").DateTimeFormat, "p.m." };
- yield return new object[] { new CultureInfo("pl-PL").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("pt-BR").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("pt-PT").DateTimeFormat, "da tarde" };
- yield return new object[] { new CultureInfo("ro-RO").DateTimeFormat, "p.m." };
- yield return new object[] { new CultureInfo("ru-RU").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("sk-SK").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("sl-SI").DateTimeFormat, "pop." };
- yield return new object[] { new CultureInfo("sr-Cyrl-RS").DateTimeFormat, "PM" }; // по подне
- yield return new object[] { new CultureInfo("sr-Latn-RS").DateTimeFormat, "PM" }; // po podne
- yield return new object[] { new CultureInfo("sv-AX").DateTimeFormat, "em" };
- yield return new object[] { new CultureInfo("sv-SE").DateTimeFormat, "em" };
- yield return new object[] { new CultureInfo("sw-CD").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("sw-KE").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("sw-TZ").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("sw-UG").DateTimeFormat, "PM" };
- string tamilDesignator = PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "பிற்பகல்" : "PM"; // பிற்பகல்
- yield return new object[] { new CultureInfo("ta-IN").DateTimeFormat, tamilDesignator };
- yield return new object[] { new CultureInfo("ta-LK").DateTimeFormat, tamilDesignator };
- yield return new object[] { new CultureInfo("ta-MY").DateTimeFormat, tamilDesignator };
- yield return new object[] { new CultureInfo("ta-SG").DateTimeFormat, tamilDesignator };
- yield return new object[] { new CultureInfo("te-IN").DateTimeFormat, "PM" };
- yield return new object[] { new CultureInfo("th-TH").DateTimeFormat, "หลังเที่ยง" };
- yield return new object[] { new CultureInfo("tr-CY").DateTimeFormat, "ÖS" };
- yield return new object[] { new CultureInfo("tr-TR").DateTimeFormat, "ÖS" };
- yield return new object[] { new CultureInfo("uk-UA").DateTimeFormat, "пп" };
- yield return new object[] { new CultureInfo("vi-VN").DateTimeFormat, "CH" };
- yield return new object[] { new CultureInfo("zh-CN").DateTimeFormat, "下午" };
- yield return new object[] { new CultureInfo("zh-Hans-HK").DateTimeFormat, "下午" };
- yield return new object[] { new CultureInfo("zh-SG").DateTimeFormat, "下午" };
- yield return new object[] { new CultureInfo("zh-HK").DateTimeFormat, "下午" };
- yield return new object[] { new CultureInfo("zh-TW").DateTimeFormat, "下午" };
- }
-
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
- [MemberData(nameof(PMDesignator_Get_TestData_HybridGlobalization))]
- public void PMDesignator_Get_ReturnsExpected_HybridGlobalization(DateTimeFormatInfo format, string value)
- {
- Assert.Equal(value, format.PMDesignator);
- }
-
[Theory]
[InlineData("")]
[InlineData("PP")]
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoShortDatePattern.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoShortDatePattern.cs
index 8922b19610e436..a15f1196481315 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoShortDatePattern.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoShortDatePattern.cs
@@ -14,197 +14,6 @@ public static IEnumerable ShortDatePattern_Get_TestData_ICU()
yield return new object[] { CultureInfo.GetCultureInfo("fr-FR").DateTimeFormat, "dd/MM/yyyy" };
}
- public static IEnumerable ShortDatePattern_Get_TestData_HybridGlobalization()
- {
- // see the comments on the right to check the non-Hybrid result, if it differs
- yield return new object[] { "ar-SA", "d\u200f/M\u200f/yyyy" }; // "d\u200f/M\u200f/yyyy g"
- yield return new object[] { "am-ET", "dd/MM/yyyy" };
- yield return new object[] { "bg-BG", "d.MM.yyyy г." }; // "d.MM.yyyy 'г'."
- yield return new object[] { "bn-BD", "d/M/yyyy" };
- yield return new object[] { "bn-IN", "d/M/yyyy" };
- yield return new object[] { "ca-AD", "d/M/yyyy" };
- yield return new object[] { "ca-ES", "d/M/yyyy" };
- yield return new object[] { "cs-CZ", "dd.MM.yyyy" };
- yield return new object[] { "da-DK", "dd.MM.yyyy" };
- yield return new object[] { "de-AT", "dd.MM.yyyy" };
- yield return new object[] { "de-BE", "dd.MM.yyyy" };
- yield return new object[] { "de-CH", "dd.MM.yyyy" };
- yield return new object[] { "de-DE", "dd.MM.yyyy" };
- yield return new object[] { "de-IT", "dd.MM.yyyy" };
- yield return new object[] { "de-LI", "dd.MM.yyyy" };
- yield return new object[] { "de-LU", "dd.MM.yyyy" };
- yield return new object[] { "el-CY", "d/M/yyyy" };
- yield return new object[] { "el-GR", "d/M/yyyy" };
- yield return new object[] { "en-AE", "dd/MM/yyyy" };
- yield return new object[] { "en-AG", "dd/MM/yyyy" };
- yield return new object[] { "en-AI", "dd/MM/yyyy" };
- yield return new object[] { "en-AS", "M/d/yyyy" };
- yield return new object[] { "en-AT", "dd/MM/yyyy" };
- yield return new object[] { "en-AU", "d/M/yyyy" };
- yield return new object[] { "en-BB", "dd/MM/yyyy" };
- yield return new object[] { "en-BE", "dd/MM/yyyy" };
- yield return new object[] { "en-BI", "M/d/yyyy" };
- yield return new object[] { "en-BM", "dd/MM/yyyy" };
- yield return new object[] { "en-BS", "dd/MM/yyyy" };
- yield return new object[] { "en-BW", "dd/MM/yyyy" };
- yield return new object[] { "en-BZ", "dd/MM/yyyy" };
- yield return new object[] { "en-CA", "yyyy-MM-dd" };
- yield return new object[] { "en-CC", "dd/MM/yyyy" };
- yield return new object[] { "en-CH", "dd.MM.yyyy" }; // "dd/MM/yyyy"
- yield return new object[] { "en-CK", "dd/MM/yyyy" };
- yield return new object[] { "en-CM", "dd/MM/yyyy" };
- yield return new object[] { "en-CX", "dd/MM/yyyy" };
- yield return new object[] { "en-CY", "dd/MM/yyyy" };
- yield return new object[] { "en-DE", "dd/MM/yyyy" };
- yield return new object[] { "en-DK", "dd/MM/yyyy" };
- yield return new object[] { "en-DM", "dd/MM/yyyy" };
- yield return new object[] { "en-ER", "dd/MM/yyyy" };
- yield return new object[] { "en-FI", "dd/MM/yyyy" };
- yield return new object[] { "en-FJ", "dd/MM/yyyy" };
- yield return new object[] { "en-FK", "dd/MM/yyyy" };
- yield return new object[] { "en-FM", "dd/MM/yyyy" };
- yield return new object[] { "en-GB", "dd/MM/yyyy" };
- yield return new object[] { "en-GD", "dd/MM/yyyy" };
- yield return new object[] { "en-GG", "dd/MM/yyyy" };
- yield return new object[] { "en-GH", "dd/MM/yyyy" };
- yield return new object[] { "en-GI", "dd/MM/yyyy" };
- yield return new object[] { "en-GM", "dd/MM/yyyy" };
- yield return new object[] { "en-GU", "M/d/yyyy" };
- yield return new object[] { "en-GY", "dd/MM/yyyy" };
- yield return new object[] { "en-HK", "d/M/yyyy" };
- yield return new object[] { "en-IE", "dd/MM/yyyy" };
- yield return new object[] { "en-IL", "dd/MM/yyyy" };
- yield return new object[] { "en-IM", "dd/MM/yyyy" };
- yield return new object[] { "en-IN", "dd/MM/yyyy" };
- yield return new object[] { "en-IO", "dd/MM/yyyy" };
- yield return new object[] { "en-JE", "dd/MM/yyyy" };
- yield return new object[] { "en-JM", "dd/MM/yyyy" };
- yield return new object[] { "en-KE", "dd/MM/yyyy" };
- yield return new object[] { "en-KI", "dd/MM/yyyy" };
- yield return new object[] { "en-KN", "dd/MM/yyyy" };
- yield return new object[] { "en-KY", "dd/MM/yyyy" };
- yield return new object[] { "en-LC", "dd/MM/yyyy" };
- yield return new object[] { "en-LR", "dd/MM/yyyy" };
- yield return new object[] { "en-LS", "dd/MM/yyyy" };
- yield return new object[] { "en-MG", "dd/MM/yyyy" };
- yield return new object[] { "en-MH", "M/d/yyyy" };
- yield return new object[] { "en-MO", "dd/MM/yyyy" };
- yield return new object[] { "en-MP", "M/d/yyyy" };
- yield return new object[] { "en-MS", "dd/MM/yyyy" };
- yield return new object[] { "en-MT", "dd/MM/yyyy" };
- yield return new object[] { "en-MU", "dd/MM/yyyy" };
- yield return new object[] { "en-MW", "dd/MM/yyyy" };
- yield return new object[] { "en-MY", "dd/MM/yyyy" };
- yield return new object[] { "en-NA", "dd/MM/yyyy" };
- yield return new object[] { "en-NF", "dd/MM/yyyy" };
- yield return new object[] { "en-NG", "dd/MM/yyyy" };
- yield return new object[] { "en-NL", "dd/MM/yyyy" };
- yield return new object[] { "en-NR", "dd/MM/yyyy" };
- yield return new object[] { "en-NU", "dd/MM/yyyy" };
- yield return new object[] { "en-NZ", PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "d/MM/yyyy" : "dd/MM/yyyy" }; // "d/MM/yyyy"
- yield return new object[] { "en-PG", "dd/MM/yyyy" };
- yield return new object[] { "en-PH", "M/d/yyyy" }; // "dd/MM/yyyy"
- yield return new object[] { "en-PK", "dd/MM/yyyy" };
- yield return new object[] { "en-PN", "dd/MM/yyyy" };
- yield return new object[] { "en-PR", "M/d/yyyy" };
- yield return new object[] { "en-PW", "dd/MM/yyyy" };
- yield return new object[] { "en-RW", "dd/MM/yyyy" };
- yield return new object[] { "en-SB", "dd/MM/yyyy" };
- yield return new object[] { "en-SC", "dd/MM/yyyy" };
- yield return new object[] { "en-SD", "dd/MM/yyyy" };
- yield return new object[] { "en-SE", "yyyy-MM-dd" };
- yield return new object[] { "en-SG", "d/M/yyyy" };
- yield return new object[] { "en-SH", "dd/MM/yyyy" };
- yield return new object[] { "en-SI", "dd/MM/yyyy" };
- yield return new object[] { "en-SL", "dd/MM/yyyy" };
- yield return new object[] { "en-SS", "dd/MM/yyyy" };
- yield return new object[] { "en-SX", "dd/MM/yyyy" };
- yield return new object[] { "en-SZ", "dd/MM/yyyy" };
- yield return new object[] { "en-TC", "dd/MM/yyyy" };
- yield return new object[] { "en-TK", "dd/MM/yyyy" };
- yield return new object[] { "en-TO", "dd/MM/yyyy" };
- yield return new object[] { "en-TT", "dd/MM/yyyy" };
- yield return new object[] { "en-TV", "dd/MM/yyyy" };
- yield return new object[] { "en-TZ", "dd/MM/yyyy" };
- yield return new object[] { "en-UG", "dd/MM/yyyy" };
- yield return new object[] { "en-UM", "M/d/yyyy" };
- yield return new object[] { "en-US", "M/d/yyyy" };
- yield return new object[] { "en-VC", "dd/MM/yyyy" };
- yield return new object[] { "en-VG", "dd/MM/yyyy" };
- yield return new object[] { "en-VI", "M/d/yyyy" };
- yield return new object[] { "en-VU", "dd/MM/yyyy" };
- yield return new object[] { "en-WS", "dd/MM/yyyy" };
- yield return new object[] { "en-ZA", "yyyy/MM/dd" };
- yield return new object[] { "en-ZM", "dd/MM/yyyy" };
- yield return new object[] { "en-ZW", "d/M/yyyy" };
- yield return new object[] { "es-419", "d/M/yyyy" };
- yield return new object[] { "es-ES", "d/M/yyyy" };
- yield return new object[] { "es-MX", "dd/MM/yyyy" };
- yield return new object[] { "et-EE", "dd.MM.yyyy" };
- yield return new object[] { "fa-IR", "yyyy/M/d" }; // "yyyy/M/d"
- yield return new object[] { "fi-FI", "d.M.yyyy" };
- yield return new object[] { "fil-PH", "M/d/yyyy" };
- yield return new object[] { "fr-BE", "d/MM/yyyy" };
- yield return new object[] { "fr-CA", "yyyy-MM-dd" };
- yield return new object[] { "fr-CH", "dd.MM.yyyy" };
- yield return new object[] { "fr-FR", "dd/MM/yyyy" };
- yield return new object[] { "gu-IN", "d/M/yyyy" };
- yield return new object[] { "he-IL", "d.M.yyyy" };
- yield return new object[] { "hi-IN", "d/M/yyyy" };
- yield return new object[] { "hr-BA", "d. M. yyyy." };
- yield return new object[] { "hr-HR", "dd. MM. yyyy." };
- yield return new object[] { "hu-HU", "yyyy. MM. dd." };
- yield return new object[] { "id-ID", "dd/MM/yyyy" };
- yield return new object[] { "it-CH", "dd.MM.yyyy" };
- yield return new object[] { "it-IT", "dd/MM/yyyy" };
- yield return new object[] { "ja-JP", "yyyy/MM/dd" };
- yield return new object[] { "kn-IN", "d/M/yyyy" };
- yield return new object[] { "ko-KR", "yyyy. M. d." };
- yield return new object[] { "lt-LT", "yyyy-MM-dd" };
- yield return new object[] { "lv-LV", "dd.MM.yyyy" };
- yield return new object[] { "ml-IN", "d/M/yyyy" };
- yield return new object[] { "mr-IN", "d/M/yyyy" };
- yield return new object[] { "ms-BN", "d/MM/yyyy" };
- yield return new object[] { "ms-MY", "d/MM/yyyy" };
- yield return new object[] { "ms-SG", "d/MM/yyyy" };
- yield return new object[] { "nb-NO", "dd.MM.yyyy" };
- yield return new object[] { "no", "dd.MM.yyyy" };
- yield return new object[] { "no-NO", "dd.MM.yyyy" };
- yield return new object[] { "nl-AW", "dd-MM-yyyy" };
- yield return new object[] { "nl-BE", "d/MM/yyyy" };
- yield return new object[] { "nl-NL", "dd-MM-yyyy" };
- yield return new object[] { "pl-PL", "d.MM.yyyy" }; // "dd.MM.yyyy"
- yield return new object[] { "pt-BR", "dd/MM/yyyy" };
- yield return new object[] { "pt-PT", "dd/MM/yyyy" };
- yield return new object[] { "ro-RO", "dd.MM.yyyy" };
- yield return new object[] { "ru-RU", "dd.MM.yyyy" };
- yield return new object[] { "sk-SK", "d. M. yyyy" };
- yield return new object[] { "sl-SI", PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "d. MM. yyyy" : "d. M. yyyy" }; // "d. MM. yyyy"
- yield return new object[] { "sr-Cyrl-RS", "d.M.yyyy." };
- yield return new object[] { "sr-Latn-RS", "d.M.yyyy." };
- yield return new object[] { "sv-AX", "yyyy-MM-dd" };
- yield return new object[] { "sv-SE", "yyyy-MM-dd" };
- yield return new object[] { "sw-CD", "dd/MM/yyyy" };
- yield return new object[] { "sw-KE", "dd/MM/yyyy" };
- yield return new object[] { "sw-TZ", "dd/MM/yyyy" };
- yield return new object[] { "sw-UG", "dd/MM/yyyy" };
- yield return new object[] { "ta-IN", "d/M/yyyy" };
- yield return new object[] { "ta-LK", "d/M/yyyy" };
- yield return new object[] { "ta-MY", "d/M/yyyy" };
- yield return new object[] { "ta-SG", "d/M/yyyy" };
- yield return new object[] { "te-IN", "dd-MM-yyyy" };
- yield return new object[] { "th-TH", "d/M/yyyy" };
- yield return new object[] { "tr-CY", "d.MM.yyyy" };
- yield return new object[] { "tr-TR", "d.MM.yyyy" };
- yield return new object[] { "uk-UA", "dd.MM.yyyy" };
- yield return new object[] { "vi-VN", PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "dd/MM/yyyy" : "d/M/yyyy" }; // "dd/MM/yyyy"
- yield return new object[] { "zh-CN", "yyyy/M/d" };
- yield return new object[] { "zh-Hans-HK", "d/M/yyyy" };
- yield return new object[] { "zh-SG", "dd/MM/yyyy" };
- yield return new object[] { "zh-HK", "d/M/yyyy" };
- yield return new object[] { "zh-TW", "yyyy/M/d" };
- }
-
[ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsIcuGlobalization))]
[MemberData(nameof(ShortDatePattern_Get_TestData_ICU))]
public void ShortDatePattern_Get_ReturnsExpected_ICU(DateTimeFormatInfo format, string expected)
@@ -212,14 +21,6 @@ public void ShortDatePattern_Get_ReturnsExpected_ICU(DateTimeFormatInfo format,
Assert.Equal(expected, format.ShortDatePattern);
}
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
- [MemberData(nameof(ShortDatePattern_Get_TestData_HybridGlobalization))]
- public void ShortDatePattern_Get_ReturnsExpected_HybridGlobalization(string cultureName, string expected)
- {
- var format = new CultureInfo(cultureName).DateTimeFormat;
- Assert.True(expected == format.ShortDatePattern, $"Failed for culture: {cultureName}. Expected: {expected}, Actual: {format.ShortDatePattern}");
- }
-
[Fact]
public void ShortDatePattern_InvariantInfo()
{
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoShortTimePattern.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoShortTimePattern.cs
index d806e19b7502cd..a3d73485f074a3 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoShortTimePattern.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoShortTimePattern.cs
@@ -14,205 +14,6 @@ public void ShortTimePattern_GetInvariantInfo_ReturnsExpected()
Assert.Equal("HH:mm", DateTimeFormatInfo.InvariantInfo.ShortTimePattern);
}
- public static IEnumerable ShortTimePattern_Get_TestData_HybridGlobalization()
- {
- // see the comments on the right to check the non-Hybrid result, if it differs
- yield return new object[] { new CultureInfo("ar-SA").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("am-ET").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("bg-BG").DateTimeFormat, "H:mm" }; // HH:mm
- yield return new object[] { new CultureInfo("bn-BD").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("bn-IN").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("ca-AD").DateTimeFormat, "H:mm" };
- yield return new object[] { new CultureInfo("ca-ES").DateTimeFormat, "H:mm" };
- yield return new object[] { new CultureInfo("cs-CZ").DateTimeFormat, "H:mm" };
- yield return new object[] { new CultureInfo("da-DK").DateTimeFormat, "HH.mm" };
- yield return new object[] { new CultureInfo("de-AT").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("de-BE").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("de-CH").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("de-DE").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("de-IT").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("de-LI").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("de-LU").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("el-CY").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("el-GR").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-AE").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-AG").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-AI").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-AS").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-AT").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-AU").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-BB").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-BE").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-BI").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-BM").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-BS").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-BW").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-BZ").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-CA").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-CC").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-CH").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-CK").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-CM").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-CX").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-CY").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-DE").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-DK").DateTimeFormat, "HH.mm" };
- yield return new object[] { new CultureInfo("en-DM").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-ER").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-FI").DateTimeFormat, "H.mm" };
- yield return new object[] { new CultureInfo("en-FJ").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-FK").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-FM").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-GB").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-GD").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-GG").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-GH").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-GI").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-GM").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-GU").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-GY").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-HK").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-IE").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-IL").DateTimeFormat, "H:mm" };
- yield return new object[] { new CultureInfo("en-IM").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-IN").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-IO").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-JE").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-JM").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-KE").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-KI").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-KN").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-KY").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-LC").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-LR").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-LS").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-MG").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-MH").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-MO").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-MP").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-MS").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-MT").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-MU").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-MW").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-MY").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-NA").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-NF").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-NG").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-NL").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-NR").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-NU").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-NZ").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-PG").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-PH").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-PK").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-PN").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-PR").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-PW").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-RW").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-SB").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-SC").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-SD").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-SE").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-SG").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-SH").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-SI").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-SL").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-SS").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-SX").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-SZ").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-TC").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-TK").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-TO").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-TT").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-TV").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-TZ").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-UG").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-UM").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-US").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-VC").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-VG").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-VI").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-VU").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-WS").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-ZA").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-ZM").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("en-ZW").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("en-US").DateTimeFormat, "h:mm tt" };
- string latinAmericanSpanishPattern = PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "HH:mm" : "h:mm tt"; // "HH:mm"
- yield return new object[] { new CultureInfo("es-419").DateTimeFormat, latinAmericanSpanishPattern };
- yield return new object[] { new CultureInfo("es-ES").DateTimeFormat, "H:mm" };
- yield return new object[] { new CultureInfo("es-MX").DateTimeFormat, latinAmericanSpanishPattern };
- yield return new object[] { new CultureInfo("et-EE").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("fa-IR").DateTimeFormat, "H:mm" };
- yield return new object[] { new CultureInfo("fi-FI").DateTimeFormat, "H.mm" };
- yield return new object[] { new CultureInfo("fil-PH").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("fr-BE").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("fr-CA").DateTimeFormat, "HH 'h' mm 'min'" }; // HH 'h' mm
- yield return new object[] { new CultureInfo("fr-CH").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("fr-FR").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("gu-IN").DateTimeFormat, "hh:mm tt" };
- yield return new object[] { new CultureInfo("he-IL").DateTimeFormat, "H:mm" };
- yield return new object[] { new CultureInfo("hi-IN").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("hr-BA").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("hr-HR").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("hu-HU").DateTimeFormat, "H:mm" };
- yield return new object[] { new CultureInfo("id-ID").DateTimeFormat, "HH.mm" };
- yield return new object[] { new CultureInfo("it-CH").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("it-IT").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("ja-JP").DateTimeFormat, "H:mm" };
- yield return new object[] { new CultureInfo("kn-IN").DateTimeFormat, "hh:mm tt" };
- yield return new object[] { new CultureInfo("ko-KR").DateTimeFormat, "tt h:mm" };
- yield return new object[] { new CultureInfo("lt-LT").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("lv-LV").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("ml-IN").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("mr-IN").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("ms-BN").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("ms-MY").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("ms-SG").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("nb-NO").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("no-NO").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("nl-AW").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("nl-BE").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("nl-NL").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("pl-PL").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("pt-BR").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("pt-PT").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("ro-RO").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("ru-RU").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("sk-SK").DateTimeFormat, "H:mm" };
- yield return new object[] { new CultureInfo("sl-SI").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("sr-Cyrl-RS").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("sr-Latn-RS").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("sv-AX").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("sv-SE").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("sw-CD").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("sw-KE").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("sw-TZ").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("sw-UG").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("ta-IN").DateTimeFormat, "tt h:mm" };
- yield return new object[] { new CultureInfo("ta-LK").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("ta-MY").DateTimeFormat, "tt h:mm" };
- yield return new object[] { new CultureInfo("ta-SG").DateTimeFormat, "tt h:mm" };
- yield return new object[] { new CultureInfo("te-IN").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("th-TH").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("tr-CY").DateTimeFormat, "h:mm tt" };
- yield return new object[] { new CultureInfo("tr-TR").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("uk-UA").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("vi-VN").DateTimeFormat, "HH:mm" };
- yield return new object[] { new CultureInfo("zh-CN").DateTimeFormat, "HH:mm" }; // tth:mm
- yield return new object[] { new CultureInfo("zh-Hans-HK").DateTimeFormat, "tth:mm" };
- yield return new object[] { new CultureInfo("zh-SG").DateTimeFormat, "tth:mm" };
- yield return new object[] { new CultureInfo("zh-HK").DateTimeFormat, "tth:mm" };
- yield return new object[] { new CultureInfo("zh-TW").DateTimeFormat, "tth:mm" };
- }
-
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
- [MemberData(nameof(ShortTimePattern_Get_TestData_HybridGlobalization))]
- public void ShortTimePattern_Get_ReturnsExpected_HybridGlobalization(DateTimeFormatInfo format, string value)
- {
- Assert.Equal(value, format.ShortTimePattern);
- }
-
public static IEnumerable ShortTimePattern_Set_TestData()
{
yield return new object[] { string.Empty };
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoShortestDayNames.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoShortestDayNames.cs
index f99c694d3bb2f5..6e8d620a50102d 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoShortestDayNames.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoShortestDayNames.cs
@@ -28,76 +28,6 @@ public static IEnumerable ShortestDayNames_Set_TestData()
yield return new object[] { new string[] { "", "", "", "", "", "", "" } };
}
- public static IEnumerable ShortestDayNames_Get_TestData_HybridGlobalization()
- {
- yield return new object[] { new CultureInfo("ar-SA").DateTimeFormat, new string[] { "ح", "ن", "ث", "ر", "خ", "ج", "س" } };
- yield return new object[] { new CultureInfo("am-ET").DateTimeFormat, new string[] { "እ", "ሰ", "ማ", "ረ", "ሐ", "ዓ", "ቅ" } };
- yield return new object[] { new CultureInfo("bg-BG").DateTimeFormat, new string[] { "н", "п", "в", "с", "ч", "п", "с" } };
- yield return new object[] { new CultureInfo("bn-IN").DateTimeFormat, new string[] { "র", "সো", "ম", "বু", "বৃ", "শু", "শ" } };
- if (PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS)
- {
- yield return new object[] { new CultureInfo("ca-ES").DateTimeFormat, new string[] { "dg", "dl", "dt", "dc", "dj", "dv", "ds" } };
- yield return new object[] { new CultureInfo("en-AU").DateTimeFormat, new string[] { "Su.", "M.", "Tu.", "W.", "Th.", "F.", "Sa." } };
- }
- else
- {
- yield return new object[] { new CultureInfo("ca-ES").DateTimeFormat, new string[] { "dg.", "dl.", "dt.", "dc.", "dj.", "dv.", "ds." } };
- yield return new object[] { new CultureInfo("en-AU").DateTimeFormat, new string[] { "S", "M", "T", "W", "T", "F", "S" } }; // "Su.", "M.", "Tu.", "W.", "Th.", "F.", "Sa."
- }
-
- yield return new object[] { new CultureInfo("cs-CZ").DateTimeFormat, new string[] { "N", "P", "Ú", "S", "Č", "P", "S" } };
- yield return new object[] { new CultureInfo("da-DK").DateTimeFormat, new string[] { "S", "M", "T", "O", "T", "F", "L" } };
- yield return new object[] { new CultureInfo("de-LU").DateTimeFormat, new string[] { "S", "M", "D", "M", "D", "F", "S" } };
- yield return new object[] { new CultureInfo("el-CY").DateTimeFormat, new string[] { "Κ", "Δ", "Τ", "Τ", "Π", "Π", "Σ" } };
- yield return new object[] { new CultureInfo("en-GB").DateTimeFormat, new string[] { "S", "M", "T", "W", "T", "F", "S" } };
- yield return new object[] { new CultureInfo("es-419").DateTimeFormat, new string[] { "D", "L", "M", "M", "J", "V", "S" } };
- yield return new object[] { new CultureInfo("es-ES").DateTimeFormat, new string[] { "D", "L", "M", "X", "J", "V", "S" } };
- yield return new object[] { new CultureInfo("et-EE").DateTimeFormat, new string[] { "P", "E", "T", "K", "N", "R", "L" } };
- yield return new object[] { new CultureInfo("fa-IR").DateTimeFormat, new string[] { "ی", "د", "س", "چ", "پ", "ج", "ش" } };
- yield return new object[] { new CultureInfo("fi-FI").DateTimeFormat, new string[] { "S", "M", "T", "K", "T", "P", "L" } };
- yield return new object[] { new CultureInfo("fil-PH").DateTimeFormat, new string[] { "Lin", "Lun", "Mar", "Miy", "Huw", "Biy", "Sab" } };
- yield return new object[] { new CultureInfo("fr-CA").DateTimeFormat, new string[] { "D", "L", "M", "M", "J", "V", "S" } };
- yield return new object[] { new CultureInfo("gu-IN").DateTimeFormat, new string[] { "ર", "સો", "મં", "બુ", "ગુ", "શુ", "શ" } };
- yield return new object[] { new CultureInfo("he-IL").DateTimeFormat, new string[] { "א׳", "ב׳", "ג׳", "ד׳", "ה׳", "ו׳", "ש׳" } };
- yield return new object[] { new CultureInfo("hi-IN").DateTimeFormat, new string[] { "र", "सो", "मं", "बु", "गु", "शु", "श" } };
- yield return new object[] { new CultureInfo("hr-BA").DateTimeFormat, new string[] { "N", "P", "U", "S", "Č", "P", "S" } };
- yield return new object[] { new CultureInfo("hr-HR").DateTimeFormat, new string[] { "n", "p", "u", "s", "č", "p", "s" } };
- yield return new object[] { new CultureInfo("hu-HU").DateTimeFormat, new string[] { "V", "H", "K", "Sz", "Cs", "P", "Sz" } };
- yield return new object[] { new CultureInfo("id-ID").DateTimeFormat, new string[] { "M", "S", "S", "R", "K", "J", "S" } };
- yield return new object[] { new CultureInfo("it-CH").DateTimeFormat, new string[] { "D", "L", "M", "M", "G", "V", "S" } };
- yield return new object[] { new CultureInfo("ja-JP").DateTimeFormat, new string[] { "日", "月", "火", "水", "木", "金", "土" } };
- yield return new object[] { new CultureInfo("kn-IN").DateTimeFormat, new string[] { "ಭಾ", "ಸೋ", "ಮಂ", "ಬು", "ಗು", "ಶು", "ಶ" } };
- yield return new object[] { new CultureInfo("ko-KR").DateTimeFormat, new string[] { "일", "월", "화", "수", "목", "금", "토" } };
- yield return new object[] { new CultureInfo("lt-LT").DateTimeFormat, new string[] { "S", "P", "A", "T", "K", "P", "Š" } };
- yield return new object[] { new CultureInfo("lv-LV").DateTimeFormat, new string[] { "S", "P", "O", "T", "C", "P", "S" } };
- yield return new object[] { new CultureInfo("ml-IN").DateTimeFormat, new string[] { "ഞാ", "തി", "ചൊ", "ബു", "വ്യാ", "വെ", "ശ" } };
- yield return new object[] { new CultureInfo("ms-BN").DateTimeFormat, new string[] { "A", "I", "S", "R", "K", "J", "S" } };
- yield return new object[] { new CultureInfo("nb-NO").DateTimeFormat, new string[] { "S", "M", "T", "O", "T", "F", "L" } };
- yield return new object[] { new CultureInfo("nl-NL").DateTimeFormat, new string[] { "Z", "M", "D", "W", "D", "V", "Z" } };
- yield return new object[] { new CultureInfo("pl-PL").DateTimeFormat, new string[] { "N", "P", "W", "Ś", "C", "P", "S" } };
- yield return new object[] { new CultureInfo("pt-PT").DateTimeFormat, new string[] { "D", "S", "T", "Q", "Q", "S", "S" } };
- yield return new object[] { new CultureInfo("ro-RO").DateTimeFormat, new string[] { "D", "L", "M", "M", "J", "V", "S" } };
- yield return new object[] { new CultureInfo("ru-RU").DateTimeFormat, new string[] { "В", "П", "В", "С", "Ч", "П", "С" } };
- yield return new object[] { new CultureInfo("sk-SK").DateTimeFormat, new string[] { "n", "p", "u", "s", "š", "p", "s" } };
- yield return new object[] { new CultureInfo("sl-SI").DateTimeFormat, new string[] { "n", "p", "t", "s", "č", "p", "s" } };
- yield return new object[] { new CultureInfo("sr-Cyrl-RS").DateTimeFormat, new string[] { "н", "п", "у", "с", "ч", "п", "с" } };
- yield return new object[] { new CultureInfo("sw-CD").DateTimeFormat, new string[] { "S", "M", "T", "W", "T", "F", "S" } };
- yield return new object[] { new CultureInfo("ta-IN").DateTimeFormat, new string[] { "ஞா", "தி", "செ", "பு", "வி", "வெ", "ச" } };
- yield return new object[] { new CultureInfo("te-IN").DateTimeFormat, new string[] { "ఆ", "సో", "మ", "బు", "గు", "శు", "శ" } };
- yield return new object[] { new CultureInfo("th-TH").DateTimeFormat, new string[] { "อา", "จ", "อ", "พ", "พฤ", "ศ", "ส" } };
- yield return new object[] { new CultureInfo("tr-CY").DateTimeFormat, new string[] { "P", "P", "S", "Ç", "P", "C", "C" } };
- yield return new object[] { new CultureInfo("uk-UA").DateTimeFormat, new string[] { "Н", "П", "В", "С", "Ч", "П", "С" } };
- yield return new object[] { new CultureInfo("vi-VN").DateTimeFormat, new string[] { "CN", "T2", "T3", "T4", "T5", "T6", "T7" } };
- yield return new object[] { new CultureInfo("zh-CN").DateTimeFormat, new string[] { "日", "一", "二", "三", "四", "五", "六" } };
- }
-
- [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsHybridGlobalizationOnBrowser))]
- [MemberData(nameof(ShortestDayNames_Get_TestData_HybridGlobalization))]
- public void ShortestDayNames_Get_ReturnsExpected_HybridGlobalization(DateTimeFormatInfo format, string[] expected)
- {
- Assert.Equal(expected, format.ShortestDayNames);
- }
-
[Theory]
[MemberData(nameof(ShortestDayNames_Set_TestData))]
public void ShortestDayNames_Set_GetReturnsExpected(string[] value)
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs
index 6e00c34d4ca926..991e05f1f4f908 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoTests.cs
@@ -138,7 +138,7 @@ public void GetShortestDayName_Invoke_ReturnsExpected(string cultureName)
}
}
- [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotHybridGlobalizationOnBrowser))]
+ [Fact]
public void Months_GetHebrew_ReturnsExpected()
{
CultureInfo ci = new CultureInfo("he-IL");
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoYearMonthPattern.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoYearMonthPattern.cs
index 4c4d01b957b40a..53c0028bf3c7bc 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoYearMonthPattern.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/DateTimeFormatInfo/DateTimeFormatInfoYearMonthPattern.cs
@@ -12,30 +12,6 @@ public static IEnumerable YearMonthPattern_Get_TestData()
{
yield return new object[] { DateTimeFormatInfo.InvariantInfo, "yyyy MMMM" };
yield return new object[] { new CultureInfo("fr-FR").DateTimeFormat, "MMMM yyyy" };
- if (PlatformDetection.IsHybridGlobalizationOnBrowser)
- {
- // see the comments on the right to check the non-Hybrid result, if it differs
- yield return new object[] { new CultureInfo("ar-SA").DateTimeFormat, "MMMM yyyy" }; // "MMMM yyyy g"
- yield return new object[] { new CultureInfo("bg-BG").DateTimeFormat, "MMMM yyyy \u0433." }; // ICU: "MMMM yyyy '\u0433'."
- yield return new object[] { new CultureInfo("ca-AD").DateTimeFormat, PlatformDetection.IsFirefox || PlatformDetection.IsNodeJS ? "MMMM de yyyy" : "MMMM del yyyy" }; // ICU: "MMMM 'de' yyyy"
- yield return new object[] { new CultureInfo("es-419").DateTimeFormat, "MMMM de yyyy" }; // ICU: "MMMM 'de' yyyy"
- yield return new object[] { new CultureInfo("es-ES").DateTimeFormat, "MMMM de yyyy" }; // ICU: "MMMM 'de' yyyy"
- yield return new object[] { new CultureInfo("es-MX").DateTimeFormat, "MMMM de yyyy" }; // ICU: "MMMM 'de' yyyy"
- yield return new object[] { new CultureInfo("fa-IR").DateTimeFormat, "yyyy MMMM" };
- yield return new object[] { new CultureInfo("hr-HR").DateTimeFormat, "MMMM yyyy." };
- yield return new object[] { new CultureInfo("hu-HU").DateTimeFormat, "yyyy. MMMM" };
- yield return new object[] { new CultureInfo("ja-JP").DateTimeFormat, "yyyy\u5e74M\u6708" };
- yield return new object[] { new CultureInfo("ko-KR").DateTimeFormat, "yyyy\ub144 MMMM" };
- yield return new object[] { new CultureInfo("lt-LT").DateTimeFormat, "yyyy m. MMMM" }; // ICU: "yyyy 'm'. MMMM"
- yield return new object[] { new CultureInfo("lv-LV").DateTimeFormat, "yyyy. g. MMMM" }; // ICU: "yyyy. 'g'. MMMM"
- yield return new object[] { new CultureInfo("ml-IN").DateTimeFormat, "yyyy MMMM" };
- yield return new object[] { new CultureInfo("pt-PT").DateTimeFormat, "MMMM de yyyy" }; // ICU: "MMMM 'de' yyyy"
- yield return new object[] { new CultureInfo("ru-RU").DateTimeFormat, "MMMM yyyy \u0433." }; // ICU: "MMMM yyyy '\u0433'."
- yield return new object[] { new CultureInfo("sr-Latn-RS").DateTimeFormat, "MMMM yyyy." };
- yield return new object[] { new CultureInfo("vi-VN").DateTimeFormat, "MMMM n\u0103m yyyy" }; // ICU: "MMMM 'n\u0103m' yyyy"
- yield return new object[] { new CultureInfo("zh-CN").DateTimeFormat, "yyyy\u5e74M\u6708" };
- yield return new object[] { new CultureInfo("zh-TW").DateTimeFormat, "yyyy\u5e74M\u6708" };
- }
}
[Theory]
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/Hybrid/System.Globalization.Hybrid.WASM.Tests.csproj b/src/libraries/System.Runtime/tests/System.Globalization.Tests/Hybrid/System.Globalization.Hybrid.WASM.Tests.csproj
deleted file mode 100644
index 8c90eef092f036..00000000000000
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/Hybrid/System.Globalization.Hybrid.WASM.Tests.csproj
+++ /dev/null
@@ -1,61 +0,0 @@
-
-
- $(NetCoreAppCurrent)-browser
- true
- true
- true
- true
-
-
-
- WasmTestOnChrome
- $(TestArchiveRoot)browseronly/
- $(TestArchiveTestsRoot)$(OSPlatformConfig)/
- $(DefineConstants);TARGET_BROWSER
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/libraries/System.Runtime/tests/System.Globalization.Tests/System/Globalization/TextInfoTests.cs b/src/libraries/System.Runtime/tests/System.Globalization.Tests/System/Globalization/TextInfoTests.cs
index 466be98c442d9f..924de536b6efbd 100644
--- a/src/libraries/System.Runtime/tests/System.Globalization.Tests/System/Globalization/TextInfoTests.cs
+++ b/src/libraries/System.Runtime/tests/System.Globalization.Tests/System/Globalization/TextInfoTests.cs
@@ -274,15 +274,7 @@ public static IEnumerable ToLower_TestData()
// we also don't preform.
// Greek Capital Letter Sigma (does not case to U+03C2 with "final sigma" rule).
yield return new object[] { cultureName, "\u03A3", "\u03C3" };
- if (PlatformDetection.IsHybridGlobalizationOnBrowser)
- {
- // JS is using "final sigma" rule correctly - it's costly to unify it with ICU's behavior
- yield return new object[] { cultureName, "O\u03A3", "o\u03C2" };
- }
- else
- {
- yield return new object[] { cultureName, "O\u03A3", "o\u03C3" };
- }
+ yield return new object[] { cultureName, "O\u03A3", "o\u03C3" };
}
foreach (string cultureName in GetTestLocales())
diff --git a/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/FileStream/ReadAsync.cs b/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/FileStream/ReadAsync.cs
index d31149d297c5e0..40220b45ef875a 100644
--- a/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/FileStream/ReadAsync.cs
+++ b/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/FileStream/ReadAsync.cs
@@ -123,7 +123,7 @@ public async Task IncompleteReadCantSetPositionBeyondEndOfFile(FileShare fileSha
await Task.WhenAll(reads);
// but when they are finished, the first buffer should contain valid data:
Assert.Equal(fileSize, reads.First().Result);
- AssertExtensions.SequenceEqual(content, buffers.First().AsSpan(0, fileSize));
+ AssertExtensions.SequenceEqual(content.AsSpan(), buffers.First().AsSpan(0, fileSize));
// and other reads should return 0:
Assert.All(reads.Skip(1), read => Assert.Equal(0, read.Result));
// and the Position must be correct:
diff --git a/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/RandomAccess/WriteGatherAsync.cs b/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/RandomAccess/WriteGatherAsync.cs
index 843cf942f42c7b..8cf7d5233c6d3a 100644
--- a/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/RandomAccess/WriteGatherAsync.cs
+++ b/src/libraries/System.Runtime/tests/System.IO.FileSystem.Tests/RandomAccess/WriteGatherAsync.cs
@@ -1,6 +1,7 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
+using System.Buffers;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
@@ -13,6 +14,7 @@
namespace System.IO.Tests
{
[SkipOnPlatform(TestPlatforms.Browser, "async file IO is not supported on browser")]
+ [Collection(nameof(DisableParallelization))] // don't run in parallel, as some of these tests use a LOT of resources
public class RandomAccess_WriteGatherAsync : RandomAccess_Base
{
protected override ValueTask MethodUnderTest(SafeFileHandle handle, byte[] bytes, long fileOffset)
@@ -151,21 +153,6 @@ public async Task NoInt32OverflowForLargeInputs(bool asyncFile, bool asyncMethod
const int BufferSize = int.MaxValue / 1000;
const long FileSize = (long)BufferCount * BufferSize;
string filePath = GetTestFilePath();
- ReadOnlyMemory writeBuffer = RandomNumberGenerator.GetBytes(BufferSize);
- List> writeBuffers = Enumerable.Repeat(writeBuffer, BufferCount).ToList();
- List> readBuffers = new List>(BufferCount);
-
- try
- {
- for (int i = 0; i < BufferCount; i++)
- {
- readBuffers.Add(new byte[BufferSize]);
- }
- }
- catch (OutOfMemoryException)
- {
- throw new SkipTestException("Not enough memory.");
- }
FileOptions options = asyncFile ? FileOptions.Asynchronous : FileOptions.None; // we need to test both code paths
options |= FileOptions.DeleteOnClose;
@@ -180,29 +167,86 @@ public async Task NoInt32OverflowForLargeInputs(bool asyncFile, bool asyncMethod
throw new SkipTestException("Not enough disk space.");
}
- long fileOffset = 0, bytesRead = 0;
- try
+ using (sfh)
{
- if (asyncMethod)
+ ReadOnlyMemory writeBuffer = RandomNumberGenerator.GetBytes(BufferSize);
+ List> writeBuffers = Enumerable.Repeat(writeBuffer, BufferCount).ToList();
+
+ List memoryManagers = new List(BufferCount);
+ List> readBuffers = new List>(BufferCount);
+
+ try
{
- await RandomAccess.WriteAsync(sfh, writeBuffers, fileOffset);
- bytesRead = await RandomAccess.ReadAsync(sfh, readBuffers, fileOffset);
+ try
+ {
+ for (int i = 0; i < BufferCount; i++)
+ {
+ // We are using native memory here to get OOM as soon as possible.
+ NativeMemoryManager nativeMemoryManager = new(BufferSize);
+ memoryManagers.Add(nativeMemoryManager);
+ readBuffers.Add(nativeMemoryManager.Memory);
+ }
+ }
+ catch (OutOfMemoryException)
+ {
+ throw new SkipTestException("Not enough memory.");
+ }
+
+ await Verify(asyncMethod, FileSize, sfh, writeBuffer, writeBuffers, readBuffers);
}
- else
+ finally
{
- RandomAccess.Write(sfh, writeBuffers, fileOffset);
- bytesRead = RandomAccess.Read(sfh, readBuffers, fileOffset);
+ foreach (IDisposable memoryManager in memoryManagers)
+ {
+ memoryManager.Dispose();
+ }
}
}
- finally
- {
- sfh.Dispose(); // delete the file ASAP to avoid running out of resources in CI
- }
- Assert.Equal(FileSize, bytesRead);
- for (int i = 0; i < BufferCount; i++)
+ static async Task Verify(bool asyncMethod, long FileSize, SafeFileHandle sfh, ReadOnlyMemory writeBuffer, List> writeBuffers, List