-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Add ReadyToRun test project and create CrossModuleInliningInfo section in R2R reflection library #126486
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Add ReadyToRun test project and create CrossModuleInliningInfo section in R2R reflection library #126486
Changes from all commits
Commits
Show all changes
33 commits
Select commit
Hold shift + click to select a range
1606998
Add cross-module R2R reference resolution tests
jtschuster 1493728
Add runtime-async method variants to cross-module resolution tests
jtschuster 70ad8f0
Add R2R validation tool for cross-module resolution tests
jtschuster 1575e66
Extract crossgen2 precommands into shared .targets file
jtschuster ee26040
Refactor crossgen2 orchestration into C# console app
jtschuster 67ffdd6
Output runcrossgen to CORE_ROOT/runcrossgen/
jtschuster d5b2d3a
Use host SDK RID for runcrossgen build-time tool
jtschuster 8029183
WIP: Add ILCompiler.ReadyToRun.Tests project
jtschuster 3e1a6c8
Fix R2R test validation and remove opt-async-methods
jtschuster 183262c
Add runtime-async functional tests for R2R
jtschuster 7bb35e5
Refactor R2R test model: rename DependencyInfo to CompiledAssembly, a…
jtschuster 804ec55
Replace R2RExpectations with Action<ReadyToRunReader> validation call…
jtschuster 25ee0be
Fix R2R test runner: --opt-cross-module args and composite output naming
jtschuster b2e0f5b
Add InliningInfo2 structured parsing and method-targeted assertions
jtschuster c8c6a35
Add 10 new R2R cross-module/async/composite test cases
jtschuster 805f042
Add test source files for new R2R test cases
jtschuster d90a6cd
Fix composite tests: add --optimize flag and cross-assembly inline as…
jtschuster 67e8d19
Fix code review issues: parser bug, deadlock, file handle leak
jtschuster 2ab55e0
Add CrossModuleGenericMultiInliner test for cross-module inliner parsing
jtschuster 03d71ec
Validate resolved inliner names in HasCrossModuleInliners
jtschuster 22e55bd
Remove unused Utility.GetName() from CrossModuleGenericLib test
jtschuster b6d5227
Remove session state and planning files from tracking
jtschuster 61ea4a9
Remove crossmoduleresolution tests from src/tests/readytorun
jtschuster 537cd1b
Fix stale and inaccurate comments across R2R test files
jtschuster 32b6ce8
Use ActiveIssue instead of Fact(Skip) for composite async tests
jtschuster de94dba
Use self-contained crossgen2_inbuild for R2R tests
jtschuster 262a295
Log crossgen2 command line in test output for reproducibility
jtschuster 19b97d2
Merge branch 'main' into RuntimeAsyncComposite
jtschuster 041e4a1
Fix R2R inlining info parser correctness and test build issues
jtschuster 28a7932
Fix SPCL reference path resolution in R2R tests
jtschuster 46dddbd
Add clr.corelib+clr.nativecorelib to CLR_Tools_Tests build
jtschuster b6f6156
Fall back to CoreCLR artifacts dir when SPCL not in runtime pack nati…
jtschuster af54482
InliningInfoSection2 is per assembly in composite mode
jtschuster File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
src/coreclr/tools/aot/ILCompiler.ReadyToRun.Tests/ILCompiler.ReadyToRun.Tests.csproj
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
|
|
||
| <PropertyGroup> | ||
| <AssemblyName>ILCompiler.ReadyToRun.Tests</AssemblyName> | ||
| <TargetFramework>$(NetCoreAppToolCurrent)</TargetFramework> | ||
| <Nullable>enable</Nullable> | ||
| <IsPackable>false</IsPackable> | ||
| <AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||
| <Platforms>x64;x86</Platforms> | ||
| <PlatformTarget>AnyCPU</PlatformTarget> | ||
| <RuntimeIdentifiers>linux-x64;win-x64;osx-x64</RuntimeIdentifiers> | ||
| <Configurations>Debug;Release;Checked</Configurations> | ||
| <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies> | ||
| <TestRunnerAdditionalArguments>-notrait category=failing</TestRunnerAdditionalArguments> | ||
| </PropertyGroup> | ||
|
|
||
| <ItemGroup> | ||
| <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="$(MicrosoftCodeAnalysisCSharpVersion)" /> | ||
| <PackageReference Include="Microsoft.DotNet.XUnitExtensions" Version="$(MicrosoftDotNetXUnitExtensionsVersion)" /> | ||
| </ItemGroup> | ||
|
|
||
| <ItemGroup> | ||
| <ProjectReference Include="../ILCompiler.Reflection.ReadyToRun/ILCompiler.Reflection.ReadyToRun.csproj" /> | ||
| </ItemGroup> | ||
|
|
||
| <!-- Test case source files are embedded as resources so we can compile them with Roslyn at test time. | ||
| Exclude subdirectory sources from compilation since they are compiled in-memory by R2RTestCaseCompiler. --> | ||
| <ItemGroup> | ||
| <Compile Remove="TestCases/*/**/*.cs" /> | ||
| <EmbeddedResource Include="TestCases/**/*.cs" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" /> | ||
| </ItemGroup> | ||
|
|
||
| <!-- Pass build-time paths to test runtime via RuntimeHostConfigurationOption --> | ||
| <ItemGroup> | ||
| <RuntimeHostConfigurationOption Include="R2RTest.Crossgen2Dir"> | ||
| <Value>$(RuntimeBinDir)/$(BuildArchitecture)/crossgen2</Value> | ||
| </RuntimeHostConfigurationOption> | ||
| <RuntimeHostConfigurationOption Include="R2RTest.RuntimePackDir"> | ||
| <Value>$(MicrosoftNetCoreAppRuntimePackRidLibTfmDir)</Value> | ||
| </RuntimeHostConfigurationOption> | ||
| <RuntimeHostConfigurationOption Include="R2RTest.RuntimePackNativeDir"> | ||
| <Value>$(MicrosoftNetCoreAppRuntimePackNativeDir)</Value> | ||
| </RuntimeHostConfigurationOption> | ||
| <RuntimeHostConfigurationOption Include="R2RTest.RefPackDir"> | ||
| <Value>$(MicrosoftNetCoreAppRefPackRefDir)</Value> | ||
| </RuntimeHostConfigurationOption> | ||
| <RuntimeHostConfigurationOption Include="R2RTest.CoreCLRArtifactsDir"> | ||
| <Value>$(CoreCLRArtifactsPath)</Value> | ||
| </RuntimeHostConfigurationOption> | ||
| <RuntimeHostConfigurationOption Include="R2RTest.TargetArchitecture"> | ||
| <Value>$(TargetArchitecture)</Value> | ||
| </RuntimeHostConfigurationOption> | ||
| <RuntimeHostConfigurationOption Include="R2RTest.TargetOS"> | ||
| <Value>$(TargetOS)</Value> | ||
| </RuntimeHostConfigurationOption> | ||
| <RuntimeHostConfigurationOption Include="R2RTest.Configuration"> | ||
| <Value>$(Configuration)</Value> | ||
| </RuntimeHostConfigurationOption> | ||
| </ItemGroup> | ||
|
|
||
| </Project> | ||
27 changes: 27 additions & 0 deletions
27
...reclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCases/CrossModuleInlining/AsyncMethods.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| // Test: Cross-module inlining of async methods | ||
| // Validates that async methods from AsyncInlineableLib are cross-module | ||
| // inlined into this assembly with CHECK_IL_BODY fixups. | ||
| using System; | ||
| using System.Runtime.CompilerServices; | ||
| using System.Threading.Tasks; | ||
|
|
||
| public static class AsyncMethods | ||
| { | ||
| [MethodImpl(MethodImplOptions.NoInlining)] | ||
| public static async Task<int> TestAsyncInline() | ||
| { | ||
| return await AsyncInlineableLib.GetValueAsync(); | ||
| } | ||
|
|
||
| [MethodImpl(MethodImplOptions.NoInlining)] | ||
| public static async Task<string> TestAsyncStringInline() | ||
| { | ||
| return await AsyncInlineableLib.GetStringAsync(); | ||
| } | ||
|
|
||
| [MethodImpl(MethodImplOptions.NoInlining)] | ||
| public static int TestSyncFromAsyncLib() | ||
| { | ||
| return AsyncInlineableLib.GetValueSync(); | ||
| } | ||
| } |
26 changes: 26 additions & 0 deletions
26
...eclr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCases/CrossModuleInlining/BasicInlining.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| // Test: Basic cross-module inlining | ||
| // Validates that crossgen2 with --opt-cross-module produces CHECK_IL_BODY fixups | ||
| // for methods inlined from InlineableLib into this main assembly. | ||
| using System; | ||
| using System.Runtime.CompilerServices; | ||
|
|
||
| public static class BasicInlining | ||
| { | ||
| [MethodImpl(MethodImplOptions.NoInlining)] | ||
| public static int TestGetValue() | ||
| { | ||
| return InlineableLib.GetValue(); | ||
| } | ||
|
|
||
| [MethodImpl(MethodImplOptions.NoInlining)] | ||
| public static string TestGetString() | ||
| { | ||
| return InlineableLib.GetString(); | ||
| } | ||
|
|
||
| [MethodImpl(MethodImplOptions.NoInlining)] | ||
| public static int TestAdd() | ||
| { | ||
| return InlineableLib.Add(10, 32); | ||
| } | ||
| } |
26 changes: 26 additions & 0 deletions
26
...clr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCases/CrossModuleInlining/CompositeAsync.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| // Test: Composite mode with runtime-async methods across assemblies. | ||
| // Validates that async methods produce [ASYNC] variants in composite output. | ||
| using System; | ||
| using System.Runtime.CompilerServices; | ||
| using System.Threading.Tasks; | ||
|
|
||
| public static class CompositeAsyncMain | ||
| { | ||
| [MethodImpl(MethodImplOptions.NoInlining)] | ||
| public static async Task<int> CallCompositeAsync() | ||
| { | ||
| return await AsyncCompositeLib.GetValueAsync(); | ||
| } | ||
|
|
||
| [MethodImpl(MethodImplOptions.NoInlining)] | ||
| public static async Task<string> CallCompositeStringAsync() | ||
| { | ||
| return await AsyncCompositeLib.GetStringAsync(); | ||
| } | ||
|
|
||
| [MethodImpl(MethodImplOptions.NoInlining)] | ||
| public static int CallCompositeSync() | ||
| { | ||
| return AsyncCompositeLib.GetValueSync(); | ||
| } | ||
| } |
20 changes: 20 additions & 0 deletions
20
...clr/tools/aot/ILCompiler.ReadyToRun.Tests/TestCases/CrossModuleInlining/CompositeBasic.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| // Test: Composite mode basic compilation | ||
| // Validates that composite mode R2R compilation with multiple assemblies | ||
| // produces correct manifest references and component assembly entries. | ||
| using System; | ||
| using System.Runtime.CompilerServices; | ||
|
|
||
| public static class CompositeBasic | ||
| { | ||
| [MethodImpl(MethodImplOptions.NoInlining)] | ||
| public static int TestCompositeCall() | ||
| { | ||
| return CompositeLib.GetCompositeValue(); | ||
| } | ||
|
|
||
| [MethodImpl(MethodImplOptions.NoInlining)] | ||
| public static object TestCompositeTypeCreation() | ||
| { | ||
| return new CompositeLib.CompositeType(); | ||
| } | ||
| } |
25 changes: 25 additions & 0 deletions
25
...Compiler.ReadyToRun.Tests/TestCases/CrossModuleInlining/Dependencies/AsyncCompositeLib.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| // Dependency library for composite async tests. | ||
| // Contains runtime-async methods called from another assembly in composite mode. | ||
| using System; | ||
| using System.Runtime.CompilerServices; | ||
| using System.Threading.Tasks; | ||
|
|
||
| public static class AsyncCompositeLib | ||
| { | ||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static async Task<int> GetValueAsync() | ||
| { | ||
| await Task.Yield(); | ||
| return 42; | ||
| } | ||
|
|
||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static async Task<string> GetStringAsync() | ||
| { | ||
| await Task.Yield(); | ||
| return "composite_async"; | ||
| } | ||
|
|
||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static int GetValueSync() => 99; | ||
| } |
15 changes: 15 additions & 0 deletions
15
...ompiler.ReadyToRun.Tests/TestCases/CrossModuleInlining/Dependencies/AsyncInlineableLib.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| using System; | ||
| using System.Runtime.CompilerServices; | ||
| using System.Threading.Tasks; | ||
|
|
||
| public static class AsyncInlineableLib | ||
| { | ||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static async Task<int> GetValueAsync() => 42; | ||
|
|
||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static async Task<string> GetStringAsync() => "Hello from async"; | ||
|
|
||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static int GetValueSync() => 42; | ||
| } |
11 changes: 11 additions & 0 deletions
11
...ot/ILCompiler.ReadyToRun.Tests/TestCases/CrossModuleInlining/Dependencies/CompositeLib.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| using System; | ||
|
|
||
| public static class CompositeLib | ||
| { | ||
| public static int GetCompositeValue() => 100; | ||
|
|
||
| public class CompositeType | ||
| { | ||
| public string Name { get; set; } = "Composite"; | ||
| } | ||
| } |
39 changes: 39 additions & 0 deletions
39
...iler.ReadyToRun.Tests/TestCases/CrossModuleInlining/Dependencies/CrossModuleGenericLib.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| using System.Runtime.CompilerServices; | ||
|
|
||
| /// <summary> | ||
| /// Library with two generic types that each inline the same utility method. | ||
| /// When compiled via CrossModuleCompileable generics, each type's InvokeGetValue() | ||
| /// becomes a distinct cross-module inliner MethodDef for the same inlinee (Utility.GetValue), | ||
| /// producing multiple cross-module inliner entries in the CrossModuleInlineInfo section. | ||
| /// </summary> | ||
| public static class Utility | ||
| { | ||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static int GetValue() => 42; | ||
| } | ||
|
|
||
| public class GenericWrapperA<T> | ||
| { | ||
| private T _value; | ||
|
|
||
| public GenericWrapperA(T value) => _value = value; | ||
|
|
||
| [MethodImpl(MethodImplOptions.NoInlining)] | ||
| public virtual int InvokeGetValue() | ||
| { | ||
| return Utility.GetValue(); | ||
| } | ||
| } | ||
|
|
||
| public class GenericWrapperB<T> | ||
| { | ||
| private T _value; | ||
|
|
||
| public GenericWrapperB(T value) => _value = value; | ||
|
|
||
| [MethodImpl(MethodImplOptions.NoInlining)] | ||
| public virtual int InvokeGetValue() | ||
| { | ||
| return Utility.GetValue(); | ||
| } | ||
| } |
19 changes: 19 additions & 0 deletions
19
...aot/ILCompiler.ReadyToRun.Tests/TestCases/CrossModuleInlining/Dependencies/ExternalLib.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| using System; | ||
|
|
||
| public static class ExternalLib | ||
| { | ||
| public static int ExternalValue => 99; | ||
|
|
||
| public class ExternalType | ||
| { | ||
| public int Value { get; set; } | ||
| } | ||
|
|
||
| public class Outer | ||
| { | ||
| public class Inner | ||
| { | ||
| public static int NestedValue => 77; | ||
| } | ||
| } | ||
| } |
14 changes: 14 additions & 0 deletions
14
...t/ILCompiler.ReadyToRun.Tests/TestCases/CrossModuleInlining/Dependencies/InlineableLib.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| using System; | ||
| using System.Runtime.CompilerServices; | ||
|
|
||
| public static class InlineableLib | ||
| { | ||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static int GetValue() => 42; | ||
|
|
||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static string GetString() => "Hello from InlineableLib"; | ||
|
|
||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static int Add(int a, int b) => a + b; | ||
| } |
14 changes: 14 additions & 0 deletions
14
...er.ReadyToRun.Tests/TestCases/CrossModuleInlining/Dependencies/InlineableLibTransitive.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| using System; | ||
| using System.Runtime.CompilerServices; | ||
|
|
||
| public static class InlineableLibTransitive | ||
| { | ||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static int GetExternalValue() => ExternalLib.ExternalValue; | ||
|
|
||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static int GetNestedValue() => ExternalLib.Outer.Inner.NestedValue; | ||
|
|
||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static ExternalLib.ExternalType CreateExternal() => new ExternalLib.ExternalType { Value = 42 }; | ||
| } |
13 changes: 13 additions & 0 deletions
13
...t/ILCompiler.ReadyToRun.Tests/TestCases/CrossModuleInlining/Dependencies/MultiStepLibA.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| // Dependency library for multi-step compilation tests. | ||
| // Contains sync inlineable methods used in both composite and non-composite steps. | ||
| using System; | ||
| using System.Runtime.CompilerServices; | ||
|
|
||
| public static class MultiStepLibA | ||
| { | ||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static int GetValue() => 42; | ||
|
|
||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static string GetLabel() => "LibA"; | ||
| } |
13 changes: 13 additions & 0 deletions
13
...t/ILCompiler.ReadyToRun.Tests/TestCases/CrossModuleInlining/Dependencies/MultiStepLibB.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| // Second library for multi-step composite compilation. | ||
| // Compiled together with MultiStepLibA as a composite in step 1. | ||
| using System; | ||
| using System.Runtime.CompilerServices; | ||
|
|
||
| public static class MultiStepLibB | ||
| { | ||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static int GetCompositeValue() => MultiStepLibA.GetValue() + 1; | ||
|
|
||
| [MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
| public static string GetCompositeLabel() => MultiStepLibA.GetLabel() + "_B"; | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.