diff options
128 files changed, 2024 insertions, 2136 deletions
diff --git a/.gitignore b/.gitignore index c21764a6f4..55bfda8b3e 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ msbuild.wrn # Cross building rootfs cross/rootfs/ +cross/android-rootfs/ # add x86 as it is ignored in 'Build results' !cross/x86 diff --git a/BuildToolsVersion.txt b/BuildToolsVersion.txt index cac787f94d..7117ae9d2a 100644 --- a/BuildToolsVersion.txt +++ b/BuildToolsVersion.txt @@ -1 +1 @@ -1.0.27-prerelease-01302-03 +1.0.27-prerelease-01306-01 diff --git a/Documentation/building/code-coverage.md b/Documentation/building/code-coverage.md index 403cd8b922..2b19d0f635 100644 --- a/Documentation/building/code-coverage.md +++ b/Documentation/building/code-coverage.md @@ -38,6 +38,7 @@ After it's done the report can be found in the build log, it looks like eg `https://ci.dot.net/job/dotnet_corefx/job/master/job/code_coverage_windows_prtest/16/artifact/bin/tests/coverage` then add index.htm on the end: `https://ci.dot.net/job/dotnet_corefx/job/master/job/code_coverage_windows_prtest/16/artifact/bin/tests/coverage/index.htm` +You can navigate to this from your PR by clicking the "Details" link to the right of the code coverage job listed at the bottom of the PR after having issued the above request to dotnet-bot. In the Jenkins UI for the resulting build, click the "Build Artifacts" link and navigate through the resulting hierarchy to the index.htm file. ## Local Code Coverage Runs @@ -59,11 +60,11 @@ You can also build and test with code coverage for a particular test project rat msbuild /t:BuildAndTest -To do so with code coverage, as with ```build``` append the ```/p:Coverage=true``` argument: +To do so with code coverage, append the ```/p:Coverage=true``` argument: msbuild /t:BuildAndTest /p:Coverage=true -The results for this one library will then also show up in the aforementioned index.htm file. For example, to build, test, and get code coverage results for the System.Diagnostics.Debug library, from the root of my repo I can do: +The results for this one library will then show up in the aforementioned index.htm file. For example, to build, test, and get code coverage results for the System.Diagnostics.Debug library, from the root of the repo one can do: cd src\System.Diagnostics.Debug\tests\ msbuild /t:BuildAndTest /p:Coverage=true @@ -72,22 +73,11 @@ And then once the run completes: ..\..\..\bin\tests\coverage\index.htm -## Code coverage with mscorlib code +## Code coverage with System.Private.CoreLib code -Some of the libraries for which contracts and tests live in the corefx repo are actually implemented in the core runtime library in another repo, e.g. the implementation that backs the System.Runtime contract is in System.Private.Corlib.dll in either the coreclr or corert repo. To run coverage reports for these projects, you need to build mscorlib locally from the coreclr repo. +Some of the libraries for which contracts and tests live in the corefx repo are actually fully or partially implemented in the core runtime library in another repo, e.g. the implementation that backs the System.Runtime contract is in System.Private.CoreLib.dll in either the coreclr or corert repo. To run coverage reports for these projects, you need to build System.Private.CoreLib locally from the coreclr repo. To get coverage of System.Private.CoreLib while running the tests for a particular library: -The following steps can be used manually to produce a coverage report, but a customizable batch file can be found [here](facade-code-coverage.bat). Changing the parameters in the first couple of lines lets you run a coverage report easily for any facade project. +1. Follow the steps outlined at [Testing with Private CoreClr Bits](https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/developer-guide.md#testing-with-private-coreclr-bits). Make sure to include the optional steps listed as being required for code coverage. +2. Add /p:CodeCoverageAssemblies="System.Private.CoreLib" to the previously discussed msbuild command, e.g. msbuild /t:BuildAndTest /p:Coverage=true /p:CodeCoverageAssemblies="System.Private.CoreLib" -1. Build the local test project (`msbuild /T:Build`) -3. Build coreclr locally in Debug or Release (`build.cmd all Debug skiptests`) -2. Navigate to the built test directory in the corefx bin (e.g. `bin/tests/AnyOS.AnyCPU.Debug/System.Runtime/netcoreapp1.0` for `System.Runtime` -4. Delete `coreclr.dll`, `mscorlib.dll`, `mscorlib.ni.dll`, `System.Private.CoreLib.dll` and `System.Private.CoreLib.ni.dll` from that directory -5. Copy all files in the coreclr `bin` directory to the test directory -6. Copy all files in the coreclr `bin/PDB` directory to the test directory -7. Run an OpenCover command with `xunit.console.netcore.exe`. For example: - - <corefx-root>/packages/OpenCover/<opencover-version>/tools/OpenCover.Console.exe -oldStyle -filter:"+[*]* -[*.Tests]* -[xunit.*]*" -excludebyfile:"*\Common\src\System\SR.*" -nodefaultfilters -excludebyattribute:*.ExcludeFromCodeCoverage* -skipautoprops -hideskipped:All -threshold:1 -returntargetcode -register:user -targetdir:<path-to corefx-bin> -target:CoreRun.exe -output:coverage.xml -targetargs:"xunit.console.netcore.exe System.Runtime.Tests -xml testResults.xml -notrait Benchmark=true -notrait category=OuterLoop -notrait category=failing -notrait category=nonwindowstests" - -8. Run a ReportGenerator command with the generated `coverage.xml` file. For example: - - <corefx-root>/packages/ReportGenerator/<opencover-version>/tools/ReportGenerator.exe -reporttypes:Html;Badges -reports:coverage.xml +The resulting code coverage report should now also include details for System.Private.CoreLib. diff --git a/Documentation/building/facade-code-coverage.bat b/Documentation/building/facade-code-coverage.bat deleted file mode 100644 index ef38876b5c..0000000000 --- a/Documentation/building/facade-code-coverage.bat +++ /dev/null @@ -1,82 +0,0 @@ -@echo off -:: Example settings for System.Runtime -SET project=System.Runtime -SET msbuildargs=/T:Build -SET testsubdir=AnyOS.AnyCPU.Debug -SET filter="+[*]* -[*.Tests]* -[*]System.Collections.* -[*]System.Diagnostics.* -[*]System.Globalization.* -[*]System.IO.* -[*]System.Reflection.* -[*]System.Resources.* -[*]System.Runtime.* -[*]System.Security.* -[*]System.StubHelpers.* -[*]System.Threading.* -[*]Microsoft.* -[*]Windows.* -[*]System.App* -[*]System.Text.Decoder* -[*]System.Text.Encoder* -[*]System.Text.*Encoding -[*]System.Text.Internal* -[xunit.*]*" - -:: Update this when OpenCover or ReportGenerator are updated -SET opencoverversion=4.6.519 -SET reportgeneratorversion=2.4.3 - -:: Assumes that the corefx and coreclr repo folders are in the same parent folder -SET root=C:\Users\Hugh\Documents\Github - -SET corefx=%root%\corefx -SET coreclr=%root%\coreclr - -SET packages=%corefx%\packages -SET opencover=%packages%\OpenCover\%opencoverversion%\tools\OpenCover.Console.exe -SET reportgenerator=%packages%\ReportGenerator\%reportgeneratorversion%\tools\ReportGenerator.exe - -SET targetdir=%corefx%\bin\tests\%testsubdir%\%project%.Tests\netcoreapp1.0 - -SET resultsfile=testresults.xml -SET coveragefile=coverage.xml - -SET coveragedir=coverage - -SET originalfolder=%cd% -SET sourcefolder=%corefx%\src\%project%\tests - -SET coreclrbuild=%coreclr%\bin\Product\Windows_NT.x64.Debug -SET coreclrbuild=%coreclr%\bin\Product\Windows_NT.x64.Release - -:: Build the library -cd %sourcefolder% -msbuild %msbuildargs% -cd %originalfolder% - -:: Delete old files (see #8381 for why) -del %targetdir%\mscorlib.dll -del %targetdir%\mscorlib.ni.dll -del %targetdir%\System.Private.CoreLib.dll -del %targetdir%\System.Private.CoreLib.ni.dll -del %targetdir%\coreclr.dll -del %targetdir%\CoreRun.exe -del %targetdir%\CoreConsole.exe -del %targetdir%\clretwrc.dll -del %targetdir%\clrjit.dll -del %targetdir%\dbgshim.dll -del %targetdir%\mscordaccore.dll -del %targetdir%\mscordbi.dll -del %targetdir%\mscorrc.debug.dll -del %targetdir%\mscorrc.dll -del %targetdir%\sos.dll - -:: Copy over our local build files -For %%a in ( -%coreclrbuild%\mscorlib.dll -%coreclrbuild%\PDB\mscorlib.pdb -%coreclrbuild%\System.Private.CoreLib.dll -%coreclrbuild%\PDB\System.Private.CoreLib.pdb -%coreclrbuild%\coreclr.dll -%coreclrbuild%\PDB\coreclr.pdb -%coreclrbuild%\CoreRun.exe -%coreclrbuild%\CoreConsole.exe -%coreclrbuild%\clretwrc.dll -%coreclrbuild%\clrjit.dll -%coreclrbuild%\dbgshim.dll -%coreclrbuild%\mscordaccore.dll -%coreclrbuild%\mscordbi.dll -%coreclrbuild%\mscorrc.debug.dll -%coreclrbuild%\mscorrc.dll -%coreclrbuild%\sos.dll -) do copy /b/v/y "%%~a" "%targetdir%\" - -:: Now, run the actual tests and generate a coverage report -SET corerunargs=%targetdir%\xunit.console.netcore.exe %project%.Tests.dll -xml %resultsfile% -notrait category=OuterLoop -notrait category=failing -notrait category=nonwindowstests - -%opencover% -oldStyle -filter:%filter% -excludebyfile:"*\Common\src\System\SR.*" -nodefaultfilters -excludebyattribute:*.ExcludeFromCodeCoverage* -skipautoprops -hideskipped:All -threshold:1 -returntargetcode -register:user -targetdir:%targetdir% -target:CoreRun.exe -output:%coveragefile% -targetargs:"%corerunargs%" - -%reportgenerator% -targetdir:%coveragedir% -reporttypes:Html;Badges -reports:%coveragefile% -verbosity:Error
\ No newline at end of file diff --git a/Documentation/coding-guidelines/interop-guidelines.md b/Documentation/coding-guidelines/interop-guidelines.md index 161771dc67..cb16b6ef0e 100644 --- a/Documentation/coding-guidelines/interop-guidelines.md +++ b/Documentation/coding-guidelines/interop-guidelines.md @@ -5,39 +5,24 @@ Interop Guidelines We have the following goals related to interop code being used in CoreFX: - Minimize code duplication for interop. - - We should only define a given interop signature in a single place. - This stuff is tricky, and we shouldn't be copy-and-pasting it. + - We should only define a given interop signature in a single place. This stuff is tricky, and we shouldn't be copy-and-pasting it. - Minimize unnecessary IL in assemblies. - - Interop signatures should only be compiled into the assemblies that - actually consume them. Having extra signatures bloats assemblies and - makes it more difficult to do static analysis over assemblies to - understand what they actually use. It also leads to problems when such - static verification is used as a gate, e.g. if a store verifies that - only certain APIs are used by apps in the store. + - Interop signatures should only be compiled into the assemblies that actually consume them. Having extra signatures bloats assemblies and makes it more difficult to do static analysis over assemblies to understand what they actually use. It also leads to problems when such static verification is used as a gate, e.g. if a store verifies that only certain APIs are used by apps in the store. - Keep interop code isolated and consolidated. - - This is both for good hygiene and to help keep platform-specific code - separated from platform-neutral code, which is important for maximizing - reusable code above PAL layers. -- Ensure maximal managed code reuse across different OS flavors which have - the same API but not the same ABI. - - This is the case for UNIX and addressing it is a work-in-progress (see issue - #2137 and section on "shims" below.) + - This is both for good hygiene and to help keep platform-specific code separated from platform-neutral code, which is important for maximizing reusable code above PAL layers. +- Ensure maximal managed code reuse across different OS flavors which have the same API but not the same ABI. + - This is the case for UNIX and addressing it is a work-in-progress (see issue #2137 and section on "shims" below.) ## Approach ### Interop type -- All code related to interop signatures (DllImports, interop structs - used in DllImports, constants that map to native values, etc.) should - live in a partial, static, and internal “Interop” class in the root - namespace, e.g. +- All code related to interop signatures (DllImports, interop structs used in DllImports, constants that map to native values, etc.) should live in a partial, static, and internal “Interop” class in the root namespace, e.g. ```C# internal static partial class Interop { ... } ``` -- Declarations shouldn't be in Interop directly, but rather within a - partial, static, internal nested type named for a given library or set - of libraries, e.g. +- Declarations shouldn't be in Interop directly, but rather within a partial, static, internal nested type named for a given library or set of libraries, e.g. ```C# internal static partial class Interop @@ -50,31 +35,14 @@ internal static partial class Interop internal static partial class mincore { ... } } ``` -- With few exceptions, the only methods that should be defined in these - interop types are DllImports. - - Exceptions are limited to times when most or every consumer of a - particular DllImport will need to wrap its invocation in a helper, e.g. - to provide additional marshaling support, to hide thread-safety issues - in the underlying OS implementation, to do any required manipulation of - safe handles, etc. In such cases, the DllImport should be private - whenever possible rather than internal, with the helper code exposed to - consumers rather than having the DllImport exposed directly. +- With few exceptions, the only methods that should be defined in these interop types are DllImports. + - Exceptions are limited to times when most or every consumer of a particular DllImport will need to wrap its invocation in a helper, e.g. to provide additional marshaling support, to hide thread-safety issues in the underlying OS implementation, to do any required manipulation of safe handles, etc. In such cases, the DllImport should be private whenever possible rather than internal, with the helper code exposed to consumers rather than having the DllImport exposed directly. ### File organization -- The Interop partial class definitions should live in Interop.*.cs - files. These Interop.*.cs files should all live under Common rather than - within a given assembly's folder. - - The only exception to this should be when an assembly P/Invokes to its - own native library that isn't available to or consumed by anyone else, - e.g. System.IO.Compression P/Invoking to clrcompression.dll. In such - cases, System.IO.Compression should have its own Interop folder which - follows a similar scheme as outlined in this proposal, but just for - these private P/Invokes. -- Under Common\src\Interop, we'll have a folder for each target - platform, and within each platform, for each library from which - functionality is being consumed. The Interop.*.cs files will live within - those library folders, e.g. +- The Interop partial class definitions should live in Interop.*.cs files. These Interop.*.cs files should all live under Common rather than within a given assembly's folder. + - The only exception to this should be when an assembly P/Invokes to its own native library that isn't available to or consumed by anyone else, e.g. System.IO.Compression P/Invoking to clrcompression.dll. In such cases, System.IO.Compression should have its own Interop folder which follows a similar scheme as outlined in this proposal, but just for these private P/Invokes. +- Under Common\src\Interop, we'll have a folder for each target platform, and within each platform, for each library from which functionality is being consumed. The Interop.*.cs files will live within those library folders, e.g. ``` \Common\src\Interop @@ -91,15 +59,9 @@ internal static partial class Interop As shown above, platforms may be additive, in that an assembly may use functionality from multiple folders, e.g. System.IO.FileSystem's Linux build will use functionality both from Unix (common across all Unix systems) and from Linux (specific to Linux and not available across non-Linux Unix systems). -- Interop.*.cs files are created in a way such that every assembly - consuming the file will need every DllImport it contains. - - If multiple related DllImports will all be needed by every consumer, - they may be declared in the same file, named for the functionality - grouping, e.g. Interop.IOErrors.cs. - - Otherwise, in the limit (and the expected case for most situations) - each Interop.*.cs file will contain a single DllImport and associated - interop types (e.g. the structs used with that signature) and helper - wrappers, e.g. Interop.strerror.cs. +- Interop.*.cs files are created in a way such that every assembly consuming the file will need every DllImport it contains. + - If multiple related DllImports will all be needed by every consumer, they may be declared in the same file, named for the functionality grouping, e.g. Interop.IOErrors.cs. + - Otherwise, in the limit (and the expected case for most situations) each Interop.*.cs file will contain a single DllImport and associated interop types (e.g. the structs used with that signature) and helper wrappers, e.g. Interop.strerror.cs. ``` \Common\src\Interop @@ -111,14 +73,8 @@ As shown above, platforms may be additive, in that an assembly may use functiona \Interop.OutputDebugString.cs ``` -- If structs/constants will be used on their own without an associated - DllImport, or if they may be used with multiple DllImports not in the - same file, they should be declared in a separate file. -- In the case of multiple overloads of the same DllImport (e.g. some - overloads taking a SafeHandle and others taking an IntPtr, or overloads - taking different kinds of SafeHandles), if they can't all be declared in - the same file (because they won't all be consumed by all consumers), the - file should be qualified with the key differentiator, e.g. +- If structs/constants will be used on their own without an associated DllImport, or if they may be used with multiple DllImports not in the same file, they should be declared in a separate file. +- In the case of multiple overloads of the same DllImport (e.g. some overloads taking a SafeHandle and others taking an IntPtr, or overloads taking different kinds of SafeHandles), if they can't all be declared in the same file (because they won't all be consumed by all consumers), the file should be qualified with the key differentiator, e.g. ``` \Common\src\Interop @@ -128,11 +84,7 @@ As shown above, platforms may be additive, in that an assembly may use functiona \Interop.DuplicateHandle_IntPtr.cs ``` -- The library names used per-platform are stored in internal constants - in the Interop class in a private Libraries class in a per-platform file - named Interop.Libraries.cs. These constants are then used for all - DllImports to that library, rather than having the string duplicated - each time, e.g. +- The library names used per-platform are stored in internal constants in the Interop class in a private Libraries class in a per-platform file named Interop.Libraries.cs. These constants are then used for all DllImports to that library, rather than having the string duplicated each time, e.g. ```C# internal static partial class Interop // contents of Common\src\Interop\Windows\Interop.Libraries.cs @@ -151,9 +103,7 @@ internal static partial class Interop // contents of Common\src\Interop\Windows\ } ``` -(Note that this will likely result in some extra constants defined in -each assembly that uses interop, which minimally violates one of the -goals, but it's very minimal.) +(Note that this will likely result in some extra constants defined in each assembly that uses interop, which minimally violates one of the goals, but it's very minimal.) - .csproj project files then include the interop code they need, e.g. ```XML @@ -170,40 +120,26 @@ goals, but it's very minimal.) ``` ### Build System -When building CoreFx, we use the "OSGroup" property to control what -target platform we are building for. The valid values for this property -are Windows_NT (which is the default value from MSBuild when running on -Windows), Linux and OSX. +When building CoreFx, we use the "OSGroup" property to control what target platform we are building for. The valid values for this property are Windows_NT (which is the default value from MSBuild when running on Windows), Linux and OSX. -The build system sets a few MSBuild properties, depending on the OSGroup -setting: +The build system sets a few MSBuild properties, depending on the OSGroup setting: * TargetsWindows * TargetsLinux * TargetsOSX * TargetsUnix -TargetsUnix is true for both OSX and Linux builds and can be used to -include code that can be used on both Linux and OSX (e.g. it is written -against a POSIX API that is present on both platforms). +TargetsUnix is true for both OSX and Linux builds and can be used to include code that can be used on both Linux and OSX (e.g. it is written against a POSIX API that is present on both platforms). -You should not test the value of the OSGroup property directly, instead -use one of the values above. +You should not test the value of the OSGroup property directly, instead use one of the values above. #### Project Files -Whenever possible, a single .csproj should be used per assembly, -spanning all target platforms, e.g. System.Console.csproj includes -conditional entries for when targeting Windows vs when targeting Linux. -A property can be passed to msbuild to control which flavor is built, -e.g. msbuild /p:OSGroup=OSX System.Console.csproj. +Whenever possible, a single .csproj should be used per assembly, spanning all target platforms, e.g. System.Console.csproj includes conditional entries for when targeting Windows vs when targeting Linux. A property can be passed to msbuild to control which flavor is built, e.g. msbuild /p:OSGroup=OSX System.Console.csproj. ### Constants -- Wherever possible, constants should be defined as "const". Only if the - data type doesn't support this (e.g. IntPtr) should they instead be - static readonly fields. +- Wherever possible, constants should be defined as "const". Only if the data type doesn't support this (e.g. IntPtr) should they instead be static readonly fields. -- Related constants should be grouped under a partial, static, internal - type, e.g. for error codes they'd be grouped under an Errors type: +- Related constants should be grouped under a partial, static, internal type, e.g. for error codes they'd be grouped under an Errors type: ```C# internal static partial class Interop @@ -229,72 +165,53 @@ internal static partial class Interop } ``` -Using enums instead of partial, static classes can lead to needing lots -of casts at call sites and can cause problems if such a type needs to be -split across multiple files (enums can't currently be partial). However, -enums can be valuable in making it clear in a DllImport signature what -values are permissible. Enums may be used in limited circumstances where -these aren't concerns: the full set of values can be represented in the -enum, and the interop signature can be defined to use the enum type -rather than the underlying integral type. +Using enums instead of partial, static classes can lead to needing lots of casts at call sites and can cause problems if such a type needs to be split across multiple files (enums can't currently be partial). However, enums can be valuable in making it clear in a DllImport signature what values are permissible. Enums may be used in limited circumstances where these aren't concerns: the full set of values can be represented in the enum, and the interop signature can be defined to use the enum type rather than the underlying integral type. -## Naming +### Naming -- Interop signatures / structs / constants should be defined using the - same name / capitalization / etc. that's used in the corresponding - native code. - - We should not rename any of these based on managed coding guidelines. - The only exception to this is for the constant grouping type, which - should be named with the most discoverable name possible; if that name - is a concept (e.g. Errors), it can be named using managed naming - guidelines. + Interop signatures / structs / constants should be defined using the same name / capitalization / etc. that's used in the corresponding native code. + - We should not rename any of these based on managed coding guidelines. The only exception to this is for the constant grouping type, which should be named with the most discoverable name possible; if that name is a concept (e.g. Errors), it can be named using managed naming guidelines. + +### Definition + +When defining the P/Invoke signatures and structs, the following guidelines should be followed. More details on P/Invoke behavior and these guidelines can be found here: [P/Invokes](interop-pinvokes) + +- Interop signatures / structs / constants should be defined using the same name / capitalization / etc. that's used in the corresponding native code. +- Avoid using `StringBuilder`, particularly as an output buffer to avoid over allocating. +- Use blittable types in structs where possible (not `string` and `bool`). +- Use `sizeof()` for blittable structs, not `Marshal.SizeOf<MyStruct>()` +- Use C# type keywords that map as closely to the underlying type as possible (e.g. use `uint` when the native type is unsigned, not `int` or `System.UInt`). +- Use `ArrayPool` for buffer pooling. +- Be careful of return string termination when allocating buffers (add room for null where needed). +- Only use `bool` for 32 bit types (matches `BOOL` not `BOOLEAN`). +- Use `[In]` and `[Out]` only when they differ from the implicit behavior. +- Explicitly specify the `CharSet` as `Ansi` or `Unicode` when the signature has a string. +- Use `ExactSpelling` to avoid probing for A/W signature variants. +- Do not set `PreserveSig` to false. ## UNIX shims -Often, various UNIX flavors offer the same API from the point-of-view of compatibility -with C/C++ source code, but they do not have the same ABI. e.g. Fields can be laid out -differently, constants can have different numeric values, exports can -be named differently, etc. There are not only differences between operating systems -(Mac OS X vs. Ubuntu vs. FreeBSD), but also differences related to the underlying -processor architecture (x64 vs. x86 vs. ARM). +Often, various UNIX flavors offer the same API from the point-of-view of compatibility with C/C++ source code, but they do not have the same ABI. e.g. Fields can be laid out differently, constants can have different numeric values, exports can be named differently, etc. There are not only differences between operating systems (Mac OS X vs. Ubuntu vs. FreeBSD), but also differences related to the underlying processor architecture (x64 vs. x86 vs. ARM). -This leaves us with a situation where we can't write portable P/Invoke declarations -that will work on all flavors, and writing separate declarations per flavor is quite -fragile and won't scale. +This leaves us with a situation where we can't write portable P/Invoke declarations that will work on all flavors, and writing separate declarations per flavor is quite fragile and won't scale. -To address this, we're moving to a model where all UNIX interop from corefx starts with -a P/Invoke to a C++ lib written specifically for corefx. These libs -- System.*.Native.so -(aka "shims") -- are intended to be very thin layers over underlying platform libraries. -Generally, they are not there to add any significant abstraction, but to create a -stable ABI such that the same IL assembly can work across UNIX flavors. +To address this, we're moving to a model where all UNIX interop from corefx starts with a P/Invoke to a C++ lib written specifically for corefx. These libs -- System.*.Native.so (aka "shims") -- are intended to be very thin layers over underlying platform libraries. Generally, they are not there to add any significant abstraction, but to create a stable ABI such that the same IL assembly can work across UNIX flavors. Guidelines for shim C++ API: - Keep them as "thin"/1:1 as possible. - We want to write the majority of code in C#. -- Never skip the shim and P/Invoke directly to the underlying platform API. It's -easy to assume something is safe/guaranteed when it isn't. -- Don't cheat and take advantage of coincidental agreement between -one flavor's ABI and the shim's ABI. +- Never skip the shim and P/Invoke directly to the underlying platform API. It's easy to assume something is safe/guaranteed when it isn't. +- Don't cheat and take advantage of coincidental agreement between one flavor's ABI and the shim's ABI. - Use PascalCase in a style closer to Win32 than libc. - - If an export point has a 1:1 correspondence to the platform API, then name - it after the platform API in PascalCase (e.g. stat -> Stat, fstat -> FStat). - - If an export is not 1:1, then spell things out as we typically would in - CoreFX code (i.e. don't use abbreviations unless they come from the underlying - API. - - At first, it seemed that we'd want to use 1:1 names throughout, but it - turns out there are many cases where being strictly 1:1 isn't practical. - - In order to reduce the chance of collisions when linking with CoreRT, all - exports should have a prefix that corresponds to the Libraries' name, e.g. - "SystemNative_" or "CryptoNative_" to make the method name more unique. - See https://github.com/dotnet/corefx/issues/4818. + - If an export point has a 1:1 correspondence to the platform API, then name it after the platform API in PascalCase (e.g. stat -> Stat, fstat -> FStat). + - If an export is not 1:1, then spell things out as we typically would in CoreFX code (i.e. don't use abbreviations unless they come from the underlying API. + - At first, it seemed that we'd want to use 1:1 names throughout, but it turns out there are many cases where being strictly 1:1 isn't practical. + - In order to reduce the chance of collisions when linking with CoreRT, all exports should have a prefix that corresponds to the Libraries' name, e.g. "SystemNative_" or "CryptoNative_" to make the method name more unique. See https://github.com/dotnet/corefx/issues/4818. - Stick to data types which are guaranteed not to vary in size across flavors. - Use int32_t, int64_t, etc. from stdint.h and not int, long, etc. - Use char* for ASCII or UTF-8 strings and uint8_t* for byte buffers. - Note that sizeof(char) == 1 is guaranteed. - - Do not use size_t in shim API. Always pick a fixed size. Often, it is most - convenient to line up with the managed int as int32_t (e.g. scratch buffer - size for read/write), but sometimes we need to handle huge sizes (e.g. - memory mapped files) and therefore use uint64_t. + - Do not use size_t in shim API. Always pick a fixed size. Often, it is most convenient to line up with the managed int as int32_t (e.g. scratch buffer size for read/write), but sometimes we need to handle huge sizes (e.g. memory mapped files) and therefore use uint64_t. - Use int64_t for native off_t values. diff --git a/Documentation/coding-guidelines/interop-pinvokes.md b/Documentation/coding-guidelines/interop-pinvokes.md new file mode 100644 index 0000000000..44f9bb73a7 --- /dev/null +++ b/Documentation/coding-guidelines/interop-pinvokes.md @@ -0,0 +1,228 @@ +P/Invokes +========= + +This document extends the [Interop Guidelines](interop-guidelines.md) to provide more specific guidelines, notes, and resources for defining P/Invokes. + +Attributes +---------- + +**Implicit attributes applied to parameter and return values:** + +| | Implicit Attribute | +|------------------|--------------------| +| parameter | `[In]` | +| `out` parameter | `[Out]` | +| `ref` parameter | `[In],[Out]` | +| return value | `[Out]` | + +**`[DllImport()]` [1] attribute settings:** + +| Setting | Recommendation | Details | +|---------|----------------|---------| +| [`PreserveSig`][2] | keep default | When this is explicitly set to false (the default is true), failed HRESULT return values will be turned into Exceptions (and the return value in the definition becomes null as a result).| +| [`SetLastError`][3] | as per API | Set this to true (default is false) if the API uses GetLastError and use Marshal.GetLastWin32Error to get the value. If the API sets a condition that says it has an error, get the error before making other calls to avoid inadvertently having it overwritten.| +| [`ExactSpelling`][4] | `true` | Set this to true (deafult is false) and gain a slight perf benefit as the framework will avoid looking for an "A" or "W" version. (See NDirectMethodDesc::FindEntryPoint).| +| [`CharSet`][5] | Explicitly use `CharSet.Unicode` or `CharSet.Ansi` when strings are present in the definition | This specifies marshalling behavior of strings and what `ExactSpelling` does when `false`. Be explicit with this one as the documented default is `CharSet.Ansi`. Note that `CharSet.Ansi` is actually UTF8 on Unix (`CharSet.Utf8` is coming). _Most_ of the time Windows uses Unicode while Unix uses UTF8. | + +[1]: https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.aspx "MSDN" +[2]: https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.preservesig.aspx "MSDN" +[3]: https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.setlasterror.aspx "MSDN" +[4]: https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.exactspelling.aspx "MSDN" +[5]: https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.charset.aspx "MSDN" + +Strings +------- + +When the CharSet is Unicode or the argument is explicitly marked as `[MarshalAs(UnmanagedType.LPWSTR)]` _and_ the string is passed by value (not `ref` or `out`) the string will be be pinned and used directly by native code (rather than copied). + +Remember to mark the `[DllImport]` as `Charset.Unicode` unless you explicitly want ANSI treatment of your strings. + +**[AVOID]** `StringBuilder` marshalling *always* creates a native buffer copy (see `ILWSTRBufferMarshaler`). As such it can be extremely inefficient. Take the typical +scenario of calling a Windows API that takes a string: + +1. Create a SB of the desired capacity (allocates managed capacity) **{1}** +2. Invoke + 1. Allocates a native buffer **{2}** + 2. Copies the contents if `[In]` _(the default for a `StringBuilder` parameter)_ + 3. Copies the native buffer into a newly allocated managed array if `[Out]` **{3}** _(also the default for `StringBuilder`)_ +3. `ToString()` allocates yet another managed array **{4}** + +That is *{4}* allocations to get a string out of native code. The best you can do to limit this is to reuse the `StringBuilder` +in another call but this still only saves *1* allocation. It is much better to use and cache a character buffer from `ArrayPool`- you can then get down to just the allocation for the `ToString()` on subsequent calls. + +The other issue with `StringBuilder` is that it always copies the return buffer back up to the first null. If the passed back string isn't terminated or is a double-null-terminated string your P/Invoke is incorrect at best. + +If you *do* use `StringBuilder` one last gotcha is that the capacity does **not** include a hidden null which is always accounted for in interop. It is pretty common for people to get this wrong as most APIs want the size of the buffer *including* the null. This can result in wasted/unnecessary allocations. + +**[USE]** Char arrays from `ArrayPool` or `StringBuffer`. + +[Default Marshalling for Strings](https://msdn.microsoft.com/en-us/library/s9ts558h.aspx "MSDN") + +> ### Windows Specific + +> For `[Out]` strings the CLR will use `CoTaskMemFree` by default to free strings or `SysStringFree` for strings that are marked +as `UnmanagedType.BSTR`. + +> **For most APIs with an output string buffer:** + +> The passed in character count must include the null. If the returned value is less than the passed in character count the call has succeeded and the value is the number of characters *without* the trailing null. Otherwise the count is the required size of the buffer *including* the null character. + +> - Pass in 5, get 4: The string is 4 characters long with a trailing null. +> - Pass in 5, get 6: The string is 5 characters long, need a 6 character buffer to hold the null. + +> [Windows Data Types for Strings](http://msdn.microsoft.com/en-us/library/dd374131.aspx "MSDN") + +Booleans +-------- + +Booleans are easy to mess up. The default marshalling for P/Invoke is as the Windows type `BOOL`, where it is a 4 byte value. `BOOLEAN`, however, is a *single* byte. This can lead to hard to track down bugs as half the return value will be discarded, which will only *potentially* change the result. For `BOOLEAN` attributing `bool` with either `[MarshalAs(UnmanagedType.U1)]` or `[MarshalAs(UnmanagedType.I1)]` will work as `TRUE` is defined as `1` and `FALSE` is defined as `0`. `U1` is technically more correct as `BOOLEAN` is defined as an `unsigned char`. + +`bool` is not a blittable type (see blitting below). As such, when defining structs it is recommended to use `Interop.BOOL.cs` for `BOOL` to get the best performance. + +[Default Marshalling for Boolean Types](https://msdn.microsoft.com/en-us/library/t2t3725f.aspx "MSDN") + +Guids +----- + +Guids are usable directly in signatures. When passed by ref they can either be passed by `ref` or with the `[MarshalAs(UnmanagedType.LPStruct)]` attribute. + +| Guid | By ref Guid | +|------|-------------| +| `KNOWNFOLDERID` | `REFKNOWNFOLDERID` | + +`[MarshalAs(UnmanagedType.LPStruct)]` should _only_ be used for by ref Guids. + +Common Data Types +----------------- + + +|Windows | C | C# | Alternative | +|---------------|-------------------|-------|-------------| +|`BOOL` |`int` |`int` |`bool` +|`BOOLEAN` |`unsigned char` |`byte` |`[MarshalAs(UnmanagedType.U1)] bool` +|`BYTE` |`unsigned char` |`byte` | | +|`CHAR` |`char` |`sbyte` | | +|`UCHAR` |`unsigned char` |`byte` | | +|`SHORT` |`short` |`short` | | +|`CSHORT` |`short` |`short` | | +|`USHORT` |`unsigned short` |`ushort` | | +|`WORD` |`unsigned short` |`ushort` | | +|`ATOM` |`unsigned short` |`ushort` | | +|`INT` |`int` |`int` | | +|`LONG` |`long` |`int` | | +|`ULONG` |`unsigned long` |`uint` | | +|`DWORD` |`unsigned long` |`uint` | | +|`LARGE_INTEGER` |`__int64` |`long` | | +|`LONGLONG` |`__int64` |`long` | | +|`ULONGLONG` |`unsigned __int64` |`ulong` | | +|`ULARGE_INTEGER` |`unsigned __int64` |`ulong` | | +|`UCHAR` |`unsigned char` |`byte` | | +|`HRESULT` |`long` |`int` | | + + +| Signed Pointer Types (`IntPtr`) | Unsigned Pointer Types (`UIntPtr`) | +|----------------------------------|-------------------------------------| +| `HANDLE` | `WPARAM` | +| `HWND` | `UINT_PTR` | +| `HINSTANCE` | `ULONG_PTR` | +| `LPARAM` | `SIZE_T` | +| `LRESULT` | | +| `LONG_PTR` | | +| `INT_PTR` | | + +[Windows Data Types](http://msdn.microsoft.com/en-us/library/aa383751.aspx "MSDN") +[Data Type Ranges](http://msdn.microsoft.com/en-us/library/s3f49ktz.aspx "MSDN") + +Blittable Types +--------------- +Blittable types are types that have the same representation for native code. As such they do not need to be converted to another format to be marshalled to and from native code, and as this improves performance they should be preferred. + +**Blittable types:** + +- `byte`, `sbyte`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`, `single`, `double` +- non-nested one dimensional arrays of blittable types (e.g. `int[]`) +- structs and classes with fixed layout that only have blittable types for instance fields + - fixed layout requires `[StructLayout(LayoutKind.Sequential)]` or `[StructLayout(LayoutKind.Explicit)]` + - structs are `LayoutKind.Sequential` by default, classes are `LayoutKind.Auto` + +**NOT blittable:** + +- `bool` + +**SOMETIMES blittable:** + +- `char`, `string` + +When blittable types are passed by reference they are simply pinned by the marshaller instead of being copied to an intermediate buffer. (Classes are inherently passed by reference, structs are passed by reference when used with `ref` or `out`.) + +`char` is blittable in a one dimensional array **or** if it is part of a type that contains it is explicitly marked with `[StructLayout]` with `CharSet = CharSet.Unicode`. + +```C# +[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] +public struct UnicodeCharStruct +{ + public char c; +} +``` + +`string` is blittable if it isn't contained in another type and it's being passed as an argument that is marked with `[MarshalAs(UnmanagedType.LPWStr)]` or the `[DllImport]` has `CharSet = CharSet.Unicode` set. + +You can see if a type is blittable by attempting to create a pinned `GCHandle`. If the type is not a string or considered blittable `GCHandle.Alloc` will throw an `ArgumentException`. + + +[Blittable and Non-Blittable Types](https://msdn.microsoft.com/en-us/library/75dwhxf7.aspx "MSDN") +[Default Marshalling for Value Types](https://msdn.microsoft.com/en-us/library/0t2cwe11.aspx "MSDN") + +Keeping Managed Objects Alive +----------------------------- +`GC.KeepAlive()` will ensure an object stays in scope until the KeepAlive method is hit. + +[`HandleRef`][6] allows the marshaller to keep an object alive for the duration of a P/Invoke. It can be used instead of `IntPtr` in method signatures. `SafeHandle` effectively replaces this class and should be used instead. + +[6]: https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.handleref.aspx "MSDN" + +[`GCHandle`][7] allows pinning a managed object and getting the native pointer to it. Basic pattern is: + +``` C# +GCHandle handle = GCHandle.Alloc(obj, GCHandleType.Pinned); +IntPtr ptr = handle.AddrOfPinnedObject(); +handle.Free(); +``` + +[7]: https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.gchandle.aspx "MSDN" + +Pinning is not the default for `GCHandle`. The other major pattern is for passing a reference to a managed object through native code back to managed code (via a callback, typically). Here is the pattern: + +``` C# +GCHandle handle = GCHandle.Alloc(obj); +SomeNativeEnumerator(callbackDelegate, GCHandle.ToIntPtr(handle)); + +// In the callback +GCHandle handle = GCHandle.FromIntPtr(param); +object managedObject = handle.Target; + +// After the last callback +handle.Free(); +``` + +Don't forget that `GCHandle` needs to be explicitly freed to avoid memory leaks. + +Structs +------- + +Managed structs are created on the stack and aren't removed until the method returns. By definition then, they are "pinned" (it won't get moved by the GC). You can also simply take the address in unsafe code blocks if native code won't use the pointer past the end of the current method. + +Blittable structs are much more performant as they they can simply be used directly by the marshalling layer. Try to make structs blittable (for example, avoid `bool`). See the "Blittable Types" section above for more details. + +*If* the struct is blittable use `sizeof()` instead of `Marshal.SizeOf<MyStruct>()` for better performance. As mentioned above, you can validate that the type is blittable by attempting to create a pinned `GCHandle`. If the type is not a string or considered blittable `GCHandle.Alloc` will throw an `ArgumentException`. + +Pointers to structs in definitions must either be passed by `ref` or use `unsafe` and `*`. + + +Other References +---------------- + +[MarshalAs Attribute](http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshalasattribute.aspx "MSDN") +[GetLastError and managed code](http://blogs.msdn.com/b/adam_nathan/archive/2003/04/25/56643.aspx "MSDN") +[Copying and Pinning](https://msdn.microsoft.com/en-us/library/23acw07k.aspx "MSDN") +[Marshalling between Managed and Unmanaged Code (MSDN Magazine January 2008)](http://download.microsoft.com/download/3/A/7/3A7FA450-1F33-41F7-9E6D-3AA95B5A6AEA/MSDNMagazineJanuary2008en-us.chm) *This is a .chm download* diff --git a/Documentation/project-docs/developer-guide.md b/Documentation/project-docs/developer-guide.md index 8c859dd875..c1979c2239 100644 --- a/Documentation/project-docs/developer-guide.md +++ b/Documentation/project-docs/developer-guide.md @@ -321,3 +321,7 @@ The CoreFX build and test suite is a work in progress, as are the [building and 5) Run the tests by any means you please - the binary shouldn't get overwritten. If you prefer, you can use a Debug build of System.Private.CoreLib, but if you do you must also use a Debug build of the native portions of the runtime, e.g. coreclr.dll. Tests with a debug runtime will execute much more slowly than with Release runtime bits. + +To collect code coverage that includes types in System.Private.CoreLib.dll, you'll need to follow the above steps, then + +`msbuild /t:rebuildandtest /p:Coverage=true /p:CodeCoverageAssemblies="System.Private.CoreLib"` @@ -12,22 +12,22 @@ The corefx repo contains the library implementation (called "CoreFX") for [.NET | | Inner Loop | Outer Loop | |:---|------:|--------:| -|**CentOS 7.1**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/centos7.1_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/centos7.1_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/centos7.1_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/centos7.1_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_centos7.1_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_centos7.1_debug/)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_centos7.1_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_centos7.1_release/)| -|**Debian 8**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/debian8.4_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/debian8.4_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/debian8.4_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/debian8.4_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/debian8.4_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/debian8.4_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/debian8.4_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/debian8.4_release)| -|**Fedora 23**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/fedora23_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/fedora23_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/fedora23_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/fedora23_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_fedora23_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_fedora23_debug/)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_fedora23_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_fedora23_release/)| -|**Fedora 24**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/fedora24_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/fedora24_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/fedora24_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/fedora24_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_fedora24_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_fedora24_debug/)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_fedora24_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_fedora24_release/)| -|**openSUSE 13.2**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/opensuse13.2_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/opensuse13.2_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/opensuse13.2_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/opensuse13.2_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_opensuse13.2_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_opensuse13.2_debug/)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_opensuse13.2_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_opensuse13.2_release/)| -|**openSUSE 42.1**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/opensuse42.1_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/opensuse42.1_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/opensuse42.1_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/opensuse42.1_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_opensuse42.1_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_opensuse42.1_debug/)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_opensuse42.1_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_opensuse42.1_release/)| -|**OS X 10.11**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/osx_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/osx_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/osx_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/osx_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_osx_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_osx_debug/)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_osx_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_osx_release/)| -|**Red Hat 7.2**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/rhel7.2_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/rhel7.2_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/rhel7.2_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/rhel7.2_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_rhel7.2_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_rhel7.2_debug/)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_rhel7.2_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_rhel7.2_release/)| -|**Ubuntu 14.04**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/ubuntu14.04_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/ubuntu14.04_debug/)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/ubuntu14.04_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/ubuntu14.04_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_ubuntu14.04_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_ubuntu14.04_debug/)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_ubuntu14.04_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_ubuntu14.04_release/)| -|**Ubuntu 16.04**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/ubuntu16.04_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/ubuntu16.04_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/ubuntu16.04_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/ubuntu16.04_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_ubuntu16.04_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_ubuntu16.04_debug/)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_ubuntu16.04_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_ubuntu16.04_release/)| -|**Ubuntu 16.10**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/ubuntu16.10_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/ubuntu16.10_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/ubuntu16.10_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/ubuntu16.10_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_ubuntu16.10_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_ubuntu16.10_debug/)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_ubuntu16.10_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_ubuntu16.10_release/)| -|**PortableLinux**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/portablelinux_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/portablelinux_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/portablelinux_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/portablelinux_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_portablelinux_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_portablelinx_debug/)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_portablelinux_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_portablelinux_release/)| -|**Windows 7**||[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_win7_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_win7_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_win7_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_win7_release)| -|**Windows 8.1**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/windows_nt_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/windows_nt_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/windows_nt_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/windows_nt_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_windows_nt_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_windows_nt_debug)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_windows_nt_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_windows_nt_release)<br/>[![code coverage](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/code_coverage_windows.svg?label=code%20coverage)](https://ci.dot.net/job/dotnet_corefx/job/master/job/code_coverage_windows/Code_Coverage_Report)<br>[![local coverage](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/code_coverage_windows_local.svg?label=local%20code%20coverage)](https://ci.dot.net/job/dotnet_corefx/job/master/job/code_coverage_windows_local/Code_Coverage_Report)| -|**Windows 10**||[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_win10_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_win10_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_win10_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_win10_release)| -|**Windows Nano Server 2016**||[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_winnano16_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_winnano16_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/outerloop_winnano16_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_winnano16_release)| +|**CentOS 7.1**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/centos7.1_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/centos7.1_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/centos7.1_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/centos7.1_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_centos7.1_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_centos7.1_debug/)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_centos7.1_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_centos7.1_release/)| +|**Debian 8**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/debian8.4_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/debian8.4_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/debian8.4_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/debian8.4_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/debian8.4_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/debian8.4_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/debian8.4_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/debian8.4_release)| +|**Fedora 23**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/fedora23_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/fedora23_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/fedora23_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/fedora23_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_fedora23_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_fedora23_debug/)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_fedora23_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_fedora23_release/)| +|**Fedora 24**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/fedora24_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/fedora24_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/fedora24_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/fedora24_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_fedora24_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_fedora24_debug/)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_fedora24_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_fedora24_release/)| +|**openSUSE 13.2**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/opensuse13.2_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/opensuse13.2_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/opensuse13.2_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/opensuse13.2_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_opensuse13.2_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_opensuse13.2_debug/)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_opensuse13.2_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_opensuse13.2_release/)| +|**openSUSE 42.1**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/opensuse42.1_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/opensuse42.1_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/opensuse42.1_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/opensuse42.1_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_opensuse42.1_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_opensuse42.1_debug/)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_opensuse42.1_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_opensuse42.1_release/)| +|**OS X 10.11**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/osx_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/osx_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/osx_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/osx_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_osx_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_osx_debug/)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_osx_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_osx_release/)| +|**Red Hat 7.2**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/rhel7.2_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/rhel7.2_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/rhel7.2_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/rhel7.2_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_rhel7.2_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_rhel7.2_debug/)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_rhel7.2_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_rhel7.2_release/)| +|**Ubuntu 14.04**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/ubuntu14.04_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/ubuntu14.04_debug/)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/ubuntu14.04_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/ubuntu14.04_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_ubuntu14.04_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_ubuntu14.04_debug/)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_ubuntu14.04_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_ubuntu14.04_release/)| +|**Ubuntu 16.04**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/ubuntu16.04_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/ubuntu16.04_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/ubuntu16.04_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/ubuntu16.04_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_ubuntu16.04_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_ubuntu16.04_debug/)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_ubuntu16.04_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_ubuntu16.04_release/)| +|**Ubuntu 16.10**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/ubuntu16.10_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/ubuntu16.10_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/ubuntu16.10_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/ubuntu16.10_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_ubuntu16.10_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_ubuntu16.10_debug/)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_ubuntu16.10_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_ubuntu16.10_release/)| +|**PortableLinux**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/portablelinux_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/portablelinux_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/portablelinux_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/portablelinux_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_portablelinux_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_portablelinx_debug/)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_portablelinux_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_portablelinux_release/)| +|**Windows 7**||[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_win7_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_win7_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_win7_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_win7_release)| +|**Windows 8.1**|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/windows_nt_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/windows_nt_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/windows_nt_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/windows_nt_release)|[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_windows_nt_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_windows_nt_debug)<br/>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_windows_nt_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_windows_nt_release)<br/>[![code coverage](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/code_coverage_windows.svg?label=code%20coverage)](https://ci.dot.net/job/dotnet_corefx/job/master/job/code_coverage_windows/Code_Coverage_Report)<br>[![local coverage](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/code_coverage_windows_local.svg?label=local%20code%20coverage)](https://ci.dot.net/job/dotnet_corefx/job/master/job/code_coverage_windows_local/Code_Coverage_Report)| +|**Windows 10**||[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_win10_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_win10_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_win10_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_win10_release)| +|**Windows Nano Server 2016**||[![x64-debug](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_winnano16_debug.svg?label=x64-debug)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_winnano16_debug)<br>[![x64-release](https://img.shields.io/jenkins/s/https/ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_winnano16_release.svg?label=x64-release)](https://ci.dot.net/job/dotnet_corefx/job/master/job/outerloop_winnano16_release)| ## How to Engage, Contribute and Provide Feedback diff --git a/Tools-Override/FrameworkTargeting.targets b/Tools-Override/FrameworkTargeting.targets index 21f9f35e9a..dcb87fe7ac 100644 --- a/Tools-Override/FrameworkTargeting.targets +++ b/Tools-Override/FrameworkTargeting.targets @@ -1,17 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <PropertyGroup Condition="'$(IncludeDefaultReferences)' == ''"> - <IncludeDefaultReferences Condition="'$(MSBuildProjectExtension)' == '.csproj'">true</IncludeDefaultReferences> - <IncludeDefaultReferences Condition="'$(MSBuildProjectExtension)' == '.vbproj'">true</IncludeDefaultReferences> - </PropertyGroup> - - <ItemGroup> - <!-- netstandard is a default reference whenever building for NETStandard or building an implementation assembly --> - <DefaultReference Condition="$(NuGetTargetMoniker.StartsWith('.NETStandard')) OR '$(IsReferenceAssembly)' != 'true'" - Include="netstandard" /> - </ItemGroup> - <ItemGroup> <TargetingPackDirs Include="$(RefPath)" /> <AdditionalReferencePaths Include="@(TargetingPackDirs)" /> @@ -21,6 +10,8 @@ <ContractOutputPath>$(RefPath)</ContractOutputPath> <FrameworkPathOverride>$(ContractOutputPath)</FrameworkPathOverride> <AssemblySearchPaths>$(AssemblySearchPaths);$(ContractOutputPath);{RawFileName}</AssemblySearchPaths> + <!-- Disable RAR from transitively discovering depdencies for References --> + <_FindDependencies>false</_FindDependencies> </PropertyGroup> <PropertyGroup Condition=" '$(TargetFrameworkIdentifier)' == '' @@ -63,27 +54,32 @@ <NuGetTargetMoniker Condition="'$(NuGetTargetMoniker)' == ''">.NETCoreApp,Version=v1.0</NuGetTargetMoniker> </PropertyGroup> - <Target Name="AddDefaultReferences" - Condition="'$(IncludeDefaultReferences)' =='true'" - BeforeTargets="BeforeResolveReferences"> - <ItemGroup> - <!-- Include default references when specified and they exist --> - <Reference Condition="Exists('$(RefPath)%(Identity).dll')" Include="@(DefaultReference)" /> + <PropertyGroup Condition="'$(IncludeDefaultReferences)' == ''"> + <IncludeDefaultReferences Condition="'$(MSBuildProjectExtension)' == '.csproj'">true</IncludeDefaultReferences> + <IncludeDefaultReferences Condition="'$(MSBuildProjectExtension)' == '.vbproj'">true</IncludeDefaultReferences> + </PropertyGroup> + + <Target Name="SetupDefaultReferences"> + <ItemGroup Condition="'$(IncludeDefaultReferences)' =='true'"> + <!-- netstandard is a default reference whenever building for NETStandard or building an implementation assembly --> + <DefaultReference Condition="$(NuGetTargetMoniker.StartsWith('.NETStandard')) OR '$(IsReferenceAssembly)' != 'true'" + Include="netstandard" /> </ItemGroup> </Target> - <Target Name="MarkReferencePrivateFalse" - BeforeTargets="ResolveAssemblyReferences;AssignProjectConfiguration"> + <Target Name="UpdateReferenceItems" + DependsOnTargets="SetupDefaultReferences" + BeforeTargets="BeforeResolveReferences" + > + <ItemGroup> + <Reference Include="@(DefaultReference)" /> + </ItemGroup> + <ItemGroup> <!-- Simple name references will be resolved from the targeting pack folders and should never be copied to output --> <Reference Condition="'%(Reference.Extension)' != '.dll'"> <Private>false</Private> </Reference> - - <!-- Project references for non-test assemblies should never be copied to the output. --> - <ProjectReference Condition="'$(IsTestProject)' != 'true'"> - <Private>false</Private> - </ProjectReference> </ItemGroup> </Target> @@ -127,6 +123,28 @@ <Import Project="$(MSBuildToolsPath)\Microsoft.VisualBasic.targets" Condition="'$(TargetFrameworkIdentifier)' != '.NETPortable' and '$(MSBuildProjectExtension)' == '.vbproj'" /> + <PropertyGroup> + <ResolveReferencesDependsOn> + AddProjectReferencesDynamically; + $(ResolveReferencesDependsOn); + </ResolveReferencesDependsOn> + <CleanDependsOn> + AddProjectReferencesDynamically; + $(CleanDependsOn); + </CleanDependsOn> + </PropertyGroup> + <!-- + Common targets don't provide a good place to enable adding new ProjectReference items in targets that work + with both clean, build, and rebuild entry point targets. We cannot hook off of AssignProjectConfigurations + because it is conditioned on "'@(ProjectReference)'!=''" which gets evalulated before the BeforeTargets run + so adding ProjectReference as part of a BeforeTarget make still have the AssignProjectConfiguration skipped. + To help with this problem we are creating a new target and correctly hooking it up in the resolve and clean + depends on target chains. + + For information on evaulation of targets ordering see https://msdn.microsoft.com/en-us/library/ee216359.aspx. + --> + <Target Name="AddProjectReferencesDynamically" DependsOnTargets="$(AddProjectReferencesDynamicallyDependsOn)" /> + <PropertyGroup Condition="'$(TargetFrameworkIdentifier)' != '.NETFramework' and '$(OutputType)' == 'exe'"> <!-- RAR thinks all EXEs require binding redirects. That's not the case for CoreCLR --> <AutoUnifyAssemblyReferences>true</AutoUnifyAssemblyReferences> diff --git a/Tools-Override/resolveContract.targets b/Tools-Override/resolveContract.targets index 9a76265298..f8f98711f1 100644 --- a/Tools-Override/resolveContract.targets +++ b/Tools-Override/resolveContract.targets @@ -2,15 +2,14 @@ <Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup Condition="'$(ResolveMatchingContract)' == 'true'"> - <ResolveReferencesDependsOn> + <AddProjectReferencesDynamicallyDependsOn> ResolveMatchingContract; + $(AddProjectReferencesDynamicallyDependsOn); + </AddProjectReferencesDynamicallyDependsOn> + <ResolveReferencesDependsOn> $(ResolveReferencesDependsOn); VerifyMatchingContract </ResolveReferencesDependsOn> - <CleanDependsOn> - ResolveMatchingContract; - $(CleanDependsOn); - </CleanDependsOn> </PropertyGroup> <Target Name="ResolveMatchingContract"> diff --git a/Tools-Override/tests.targets b/Tools-Override/tests.targets index 068a31a252..0e926536ab 100644 --- a/Tools-Override/tests.targets +++ b/Tools-Override/tests.targets @@ -99,6 +99,25 @@ </ItemGroup> </Target> + <Target Name="AddDefaultTestReferences" BeforeTargets="SetupDefaultReferences"> + <ItemGroup Condition="'$(IsTestProject)'=='true' and '$(IncludeDefaultReferences)' == 'true'"> + <TargetingPackExclusions Include="System.Runtime.WindowsRuntime.UI.Xaml" /> <!-- Harmless, but causes PRI targets to run --> + <TargetingPackExclusions Include="@(ReferenceFromRuntime)"/> + + <!-- Whitelisted runtime assemblies that are OK to reference. --> + <ReferenceFromRuntime Include="xunit.core" /> + <ReferenceFromRuntime Include="Xunit.NetCore.Extensions" /> + <ReferenceFromRuntime Include="xunit.assert" /> + <ReferenceFromRuntime Include="xunit.abstractions" /> + <ReferenceFromRuntime Include="xunit.performance.core" /> + + <!-- Reference everything in the targeting pack directory --> + <TargetingPackItems Include="%(TargetingPackDirs.Identity)/*.dll" /> + + <DefaultReference Include="%(TargetingPackItems.Filename)" Exclude="@(TargetingPackExclusions)" /> + </ItemGroup> + </Target> + <!-- Generate the script to run the tests. The script performs two high-level steps: 1. Copies the common test runtime dependencies calculated in DiscoverTestDependencies to the test execution directory. Each copy command no-ops if the file already exists in the test execution diff --git a/buildpipeline/DotNet-CoreFx-Trusted-Linux-Crossbuild.json b/buildpipeline/DotNet-CoreFx-Trusted-Linux-Crossbuild.json index abdc40ea64..81b00467f6 100644 --- a/buildpipeline/DotNet-CoreFx-Trusted-Linux-Crossbuild.json +++ b/buildpipeline/DotNet-CoreFx-Trusted-Linux-Crossbuild.json @@ -4,43 +4,23 @@ "enabled": true, "continueOnError": false, "alwaysRun": false, - "displayName": "Initialize tools", - "timeoutInMinutes": 0, - "task": { - "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", - "versionSpec": "1.*", - "definitionType": "task" - }, - "inputs": { - "filename": "$(Build.SourcesDirectory)/init-tools.sh", - "arguments": "", - "workingFolder": "", - "failOnStandardError": "false" - } - }, - { - "enabled": true, - "continueOnError": false, - "alwaysRun": false, - "displayName": "Docker cleanup", + "displayName": "Delete files from $(Build.SourcesDirectory)", "timeoutInMinutes": 0, "task": { - "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", + "id": "b7e8b412-0437-4065-9371-edc5881de25b", "versionSpec": "1.*", "definitionType": "task" }, "inputs": { - "filename": "$(Build.SourcesDirectory)/Tools/scripts/docker/cleanup-docker.sh", - "arguments": "", - "workingFolder": "", - "failOnStandardError": "false" + "SourceFolder": "$(Build.SourcesDirectory)", + "Contents": "**\n.gitignore" } }, { "enabled": true, "continueOnError": false, "alwaysRun": false, - "displayName": "Clone repository", + "displayName": "git clone", "timeoutInMinutes": 0, "task": { "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", @@ -48,8 +28,8 @@ "definitionType": "task" }, "inputs": { - "filename": "docker", - "arguments": "run --name $(PB_DockerContainerName) $(PB_DockerImageName) git clone $(PB_VsoCorefxGitUrl) $(PB_GitDirectory)", + "filename": "git", + "arguments": "clone $(PB_VsoCorefxGitUrl) corefx", "workingFolder": "", "failOnStandardError": "false" } @@ -58,7 +38,7 @@ "enabled": true, "continueOnError": false, "alwaysRun": false, - "displayName": "Commit changes", + "displayName": "git checkout", "timeoutInMinutes": 0, "task": { "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", @@ -66,17 +46,17 @@ "definitionType": "task" }, "inputs": { - "filename": "docker", - "arguments": "commit $(PB_DockerContainerName) $(PB_DockerContainerName)", - "workingFolder": "", + "filename": "git", + "arguments": "checkout $(SourceVersion)", + "workingFolder": "$(Build.SourcesDirectory)/corefx", "failOnStandardError": "false" } }, { "enabled": true, "continueOnError": false, - "alwaysRun": false, - "displayName": "Remove container", + "alwaysRun": true, + "displayName": "Initialize tools", "timeoutInMinutes": 0, "task": { "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", @@ -84,8 +64,8 @@ "definitionType": "task" }, "inputs": { - "filename": "docker", - "arguments": "rm $(PB_DockerContainerName)", + "filename": "$(Build.SourcesDirectory)/corefx/init-tools.sh", + "arguments": "", "workingFolder": "", "failOnStandardError": "false" } @@ -94,7 +74,7 @@ "enabled": true, "continueOnError": false, "alwaysRun": false, - "displayName": "Run clean.sh", + "displayName": "Docker cleanup", "timeoutInMinutes": 0, "task": { "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", @@ -102,8 +82,8 @@ "definitionType": "task" }, "inputs": { - "filename": "docker", - "arguments": "run -w=\"$(PB_GitDirectory)\" --name $(PB_DockerContainerName) $(PB_DockerContainerName) $(PB_GitDirectory)/clean.sh", + "filename": "$(Build.SourcesDirectory)/corefx/Tools/scripts/docker/cleanup-docker.sh", + "arguments": "", "workingFolder": "", "failOnStandardError": "false" } @@ -112,7 +92,7 @@ "enabled": true, "continueOnError": false, "alwaysRun": false, - "displayName": "Commit changes", + "displayName": "Start detached docker container", "timeoutInMinutes": 0, "task": { "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", @@ -121,7 +101,7 @@ }, "inputs": { "filename": "docker", - "arguments": "commit $(PB_DockerContainerName) $(PB_DockerContainerName)", + "arguments": "run --privileged -d -w $(PB_GitDirectory) --name $(PB_DockerContainerName) $(PB_DockerImageName) sleep 7200", "workingFolder": "", "failOnStandardError": "false" } @@ -130,7 +110,7 @@ "enabled": true, "continueOnError": false, "alwaysRun": false, - "displayName": "Remove container", + "displayName": "Clone repository", "timeoutInMinutes": 0, "task": { "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", @@ -139,7 +119,7 @@ }, "inputs": { "filename": "docker", - "arguments": "rm $(PB_DockerContainerName)", + "arguments": "exec $(PB_DockerContainerName) git clone $(PB_VsoCorefxGitUrl) $(PB_GitDirectory)", "workingFolder": "", "failOnStandardError": "false" } @@ -157,61 +137,7 @@ }, "inputs": { "filename": "docker", - "arguments": "run -w=\"$(PB_GitDirectory)\" --name $(PB_DockerContainerName) $(PB_DockerContainerName) git checkout $(Build.SourceVersion)", - "workingFolder": "", - "failOnStandardError": "false" - } - }, - { - "enabled": true, - "continueOnError": false, - "alwaysRun": false, - "displayName": "Commit changes", - "timeoutInMinutes": 0, - "task": { - "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", - "versionSpec": "1.*", - "definitionType": "task" - }, - "inputs": { - "filename": "docker", - "arguments": "commit $(PB_DockerContainerName) $(PB_DockerContainerName)", - "workingFolder": "", - "failOnStandardError": "false" - } - }, - { - "enabled": true, - "continueOnError": false, - "alwaysRun": false, - "displayName": "Remove container", - "timeoutInMinutes": 0, - "task": { - "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", - "versionSpec": "1.*", - "definitionType": "task" - }, - "inputs": { - "filename": "docker", - "arguments": "rm $(PB_DockerContainerName)", - "workingFolder": "", - "failOnStandardError": "false" - } - }, - { - "enabled": true, - "continueOnError": false, - "alwaysRun": false, - "displayName": "Run build-managed.sh", - "timeoutInMinutes": 0, - "task": { - "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", - "versionSpec": "1.*", - "definitionType": "task" - }, - "inputs": { - "filename": "docker", - "arguments": "run -w=\"$(PB_GitDirectory)\" --name $(PB_DockerContainerName) $(PB_DockerContainerName) $(PB_GitDirectory)/build-managed.sh -OfficialBuildId=$(OfficialBuildId) -- /t:GenerateVersionSourceFile /p:GenerateVersionSourceFile=true", + "arguments": "exec $(PB_DockerContainerName) git checkout $(SourceVersion)", "workingFolder": "", "failOnStandardError": "false" } @@ -220,7 +146,7 @@ "enabled": true, "continueOnError": false, "alwaysRun": false, - "displayName": "Commit changes", + "displayName": "Generate Version Assets", "timeoutInMinutes": 0, "task": { "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", @@ -229,25 +155,7 @@ }, "inputs": { "filename": "docker", - "arguments": "commit $(PB_DockerContainerName) $(PB_DockerContainerName)", - "workingFolder": "", - "failOnStandardError": "false" - } - }, - { - "enabled": true, - "continueOnError": false, - "alwaysRun": false, - "displayName": "Remove container", - "timeoutInMinutes": 0, - "task": { - "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", - "versionSpec": "1.*", - "definitionType": "task" - }, - "inputs": { - "filename": "docker", - "arguments": "rm $(PB_DockerContainerName)", + "arguments": "exec $(PB_DockerContainerName) $(PB_GitDirectory)/build-managed.sh -OfficialBuildId=$(OfficialBuildId) -- /t:GenerateVersionSourceFile /p:GenerateVersionSourceFile=true", "workingFolder": "", "failOnStandardError": "false" } @@ -265,43 +173,7 @@ }, "inputs": { "filename": "docker", - "arguments": "run -w=\"$(PB_GitDirectory)\" --name $(PB_DockerContainerName) $(PB_DockerContainerName) $(PB_GitDirectory)/sync.sh -p -- /p:ArchGroup=$(PB_Architecture)", - "workingFolder": "", - "failOnStandardError": "false" - } - }, - { - "enabled": true, - "continueOnError": false, - "alwaysRun": false, - "displayName": "Commit changes", - "timeoutInMinutes": 0, - "task": { - "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", - "versionSpec": "1.*", - "definitionType": "task" - }, - "inputs": { - "filename": "docker", - "arguments": "commit $(PB_DockerContainerName) $(PB_DockerContainerName)", - "workingFolder": "", - "failOnStandardError": "false" - } - }, - { - "enabled": true, - "continueOnError": false, - "alwaysRun": false, - "displayName": "Remove container", - "timeoutInMinutes": 0, - "task": { - "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", - "versionSpec": "1.*", - "definitionType": "task" - }, - "inputs": { - "filename": "docker", - "arguments": "rm $(PB_DockerContainerName)", + "arguments": "exec $(PB_DockerContainerName) $(PB_GitDirectory)/sync.sh -p -- /p:ArchGroup=$(PB_Architecture)", "workingFolder": "", "failOnStandardError": "false" } @@ -319,43 +191,7 @@ }, "inputs": { "filename": "sudo", - "arguments": "docker run --privileged -w=$(PB_GitDirectory) --name $(PB_DockerContainerName) $(PB_DockerContainerName) $(PB_GitDirectory)/cross/build-rootfs.sh $(PB_Architecture) $(CrossToolsetVersion) $(SkipUnmount)", - "workingFolder": "", - "failOnStandardError": "false" - } - }, - { - "enabled": true, - "continueOnError": false, - "alwaysRun": false, - "displayName": "Commit changes", - "timeoutInMinutes": 0, - "task": { - "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", - "versionSpec": "1.*", - "definitionType": "task" - }, - "inputs": { - "filename": "docker", - "arguments": "commit $(PB_DockerContainerName) $(PB_DockerContainerName)", - "workingFolder": "", - "failOnStandardError": "false" - } - }, - { - "enabled": true, - "continueOnError": false, - "alwaysRun": false, - "displayName": "Remove container", - "timeoutInMinutes": 0, - "task": { - "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", - "versionSpec": "1.*", - "definitionType": "task" - }, - "inputs": { - "filename": "docker", - "arguments": "rm $(PB_DockerContainerName)", + "arguments": "docker exec --privileged $(PB_DockerContainerName) $(PB_GitDirectory)/cross/build-rootfs.sh $(PB_Architecture) $(CrossToolsetVersion) $(SkipUnmount)", "workingFolder": "", "failOnStandardError": "false" } @@ -373,7 +209,7 @@ }, "inputs": { "filename": "docker", - "arguments": "run -w=\"$(PB_GitDirectory)\" --name $(PB_DockerContainerName) $(PB_DockerContainerName) $(PB_GitDirectory)/build.sh -buildArch=$(PB_Architecture) -$(PB_ConfigurationGroup)", + "arguments": "exec $(PB_DockerContainerName) $(PB_GitDirectory)/build.sh -buildArch=$(PB_Architecture) -$(PB_ConfigurationGroup)", "workingFolder": "", "failOnStandardError": "false" } @@ -382,7 +218,7 @@ "enabled": true, "continueOnError": false, "alwaysRun": false, - "displayName": "Commit changes", + "displayName": "Cleanup RootFS", "timeoutInMinutes": 0, "task": { "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", @@ -390,8 +226,8 @@ "definitionType": "task" }, "inputs": { - "filename": "docker", - "arguments": "commit $(PB_DockerContainerName) $(PB_DockerContainerName)", + "filename": "sudo", + "arguments": "docker exec --privileged $(PB_DockerContainerName) git clean -xdf $(PB_GitDirectory)/cross/", "workingFolder": "", "failOnStandardError": "false" } @@ -400,7 +236,7 @@ "enabled": true, "continueOnError": false, "alwaysRun": false, - "displayName": "Remove container", + "displayName": "Run publish-packages.sh", "timeoutInMinutes": 0, "task": { "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", @@ -409,7 +245,7 @@ }, "inputs": { "filename": "docker", - "arguments": "rm $(PB_DockerContainerName)", + "arguments": "exec $(PB_DockerContainerName) $(PB_GitDirectory)/publish-packages.sh -AzureAccount=$(PB_CloudDropAccountName) -AzureToken=$(CloudDropAccessToken) -Container=$(PB_Label) -verbose -- /p:OverwriteOnPublish=true", "workingFolder": "", "failOnStandardError": "false" } @@ -418,25 +254,23 @@ "enabled": true, "continueOnError": false, "alwaysRun": false, - "displayName": "Cleanup RootFS", + "displayName": "Delete files from $(PB_DockerCopyDest)", "timeoutInMinutes": 0, "task": { - "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", + "id": "b7e8b412-0437-4065-9371-edc5881de25b", "versionSpec": "1.*", "definitionType": "task" }, "inputs": { - "filename": "docker", - "arguments": "run --privileged -w=\"$(PB_GitDirectory)\" --name $(PB_DockerContainerName) $(PB_DockerContainerName) git clean -xdf $(PB_GitDirectory)/cross/", - "workingFolder": "", - "failOnStandardError": "false" + "SourceFolder": "$(PB_DockerCopyDest)", + "Contents": "*" } }, { "enabled": true, - "continueOnError": false, - "alwaysRun": false, - "displayName": "Commit Changes", + "continueOnError": true, + "alwaysRun": true, + "displayName": "Expose docker repo for publishing", "timeoutInMinutes": 0, "task": { "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", @@ -445,7 +279,7 @@ }, "inputs": { "filename": "docker", - "arguments": "commit $(PB_DockerContainerName) $(PB_DockerContainerName)", + "arguments": "cp $(PB_DockerContainerName):$(PB_GitDirectory) $(PB_DockerCopyDest)", "workingFolder": "", "failOnStandardError": "false" } @@ -454,7 +288,7 @@ "enabled": true, "continueOnError": false, "alwaysRun": false, - "displayName": "Remove Container", + "displayName": "Run docker", "timeoutInMinutes": 0, "task": { "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", @@ -463,7 +297,7 @@ }, "inputs": { "filename": "docker", - "arguments": "rm $(PB_DockerContainerName)", + "arguments": "stop $(PB_DockerContainerName)", "workingFolder": "", "failOnStandardError": "false" } @@ -472,7 +306,7 @@ "enabled": true, "continueOnError": false, "alwaysRun": false, - "displayName": "Run publish-packages.sh", + "displayName": "Remove container", "timeoutInMinutes": 0, "task": { "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", @@ -481,61 +315,28 @@ }, "inputs": { "filename": "docker", - "arguments": "run -w=\"$(PB_GitDirectory)\" --name $(PB_DockerContainerName) $(PB_DockerContainerName) $(PB_GitDirectory)/publish-packages.sh -AzureAccount=$(PB_CloudDropAccountName) -AzureToken=$(CloudDropAccessToken) -Container=$(PB_Label) -verbose -- /p:OverwriteOnPublish=true", + "arguments": "rm $(PB_DockerContainerName)", "workingFolder": "", "failOnStandardError": "false" } }, { "enabled": true, - "continueOnError": false, - "alwaysRun": false, - "displayName": "Delete files from $(PB_DockerCopyDest)", - "timeoutInMinutes": 0, - "task": { - "id": "b7e8b412-0437-4065-9371-edc5881de25b", - "versionSpec": "1.*", - "definitionType": "task" - }, - "inputs": { - "SourceFolder": "$(PB_DockerCopyDest)", - "Contents": "*" - } - }, - { - "enabled": true, "continueOnError": true, "alwaysRun": true, - "displayName": "Expose docker repo for publishing", - "timeoutInMinutes": 0, - "task": { - "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", - "versionSpec": "1.*", - "definitionType": "task" - }, - "inputs": { - "filename": "docker", - "arguments": "cp $(PB_DockerContainerName):$(PB_GitDirectory) $(PB_DockerCopyDest)", - "workingFolder": "", - "failOnStandardError": "false" - } - }, - { - "enabled": true, - "continueOnError": false, - "alwaysRun": false, - "displayName": "Remove container", + "displayName": "Copy Publish Artifact: BuildLogs", "timeoutInMinutes": 0, "task": { - "id": "d9bafed4-0b18-4f58-968d-86655b4d2ce9", + "id": "1d341bb0-2106-458c-8422-d00bcea6512a", "versionSpec": "1.*", "definitionType": "task" }, "inputs": { - "filename": "docker", - "arguments": "rm $(PB_DockerContainerName)", - "workingFolder": "", - "failOnStandardError": "false" + "CopyRoot": "$(PB_DockerCopyDest)/corefx", + "Contents": "**/*.log", + "ArtifactName": "BuildLogs", + "ArtifactType": "Container", + "TargetPath": "\\\\my\\share\\$(Build.DefinitionName)\\$(Build.BuildNumber)" } }, { @@ -555,25 +356,6 @@ "workingFolder": "", "failOnStandardError": "false" } - }, - { - "enabled": true, - "continueOnError": true, - "alwaysRun": true, - "displayName": "Copy Publish Artifact: BuildLogs", - "timeoutInMinutes": 0, - "task": { - "id": "1d341bb0-2106-458c-8422-d00bcea6512a", - "versionSpec": "1.*", - "definitionType": "task" - }, - "inputs": { - "CopyRoot": "$(PB_DockerCopyDest)/corefx", - "Contents": "**/*.log", - "ArtifactName": "BuildLogs", - "ArtifactType": "Container", - "TargetPath": "\\\\my\\share\\$(Build.DefinitionName)\\$(Build.BuildNumber)" - } } ], "options": [ @@ -723,15 +505,15 @@ }, "path": "\\", "type": "build", - "id": 5192, + "id": 5247, "name": "DotNet-CoreFx-Trusted-Linux-Crossbuild", - "url": "https://devdiv.visualstudio.com/DefaultCollection/0bdbc590-a062-4c3f-b0f6-9383f67865ee/_apis/build/Definitions/5192", + "url": "https://devdiv.visualstudio.com/DefaultCollection/0bdbc590-a062-4c3f-b0f6-9383f67865ee/_apis/build/Definitions/5247", "project": { "id": "0bdbc590-a062-4c3f-b0f6-9383f67865ee", "name": "DevDiv", "description": "Visual Studio and DevDiv team project for git source code repositories. Work items will be added for Adams, Dev14 work items are tracked in vstfdevdiv. ", "url": "https://devdiv.visualstudio.com/DefaultCollection/_apis/projects/0bdbc590-a062-4c3f-b0f6-9383f67865ee", "state": "wellFormed", - "revision": 418097483 + "revision": 418097503 } }
\ No newline at end of file diff --git a/buildvertical.targets b/buildvertical.targets index 3c841f0a7e..891061899d 100644 --- a/buildvertical.targets +++ b/buildvertical.targets @@ -27,7 +27,7 @@ <_projectBuildConfigurations> <AdditionalProperties>Configuration=%(Identity);%(_projectBuildConfigurations.AdditionalProperties)</AdditionalProperties> </_projectBuildConfigurations> - + <!-- transform back to project --> <_projectWithConfiguration Include="@(_projectBuildConfigurations->'%(OriginalItemSpec)')" /> </ItemGroup> @@ -83,7 +83,7 @@ <!-- Runs in a leaf project (csproj) to determine best configuration for ProjectReferences --> <Target Name="AnnotateProjectReference" - BeforeTargets="BeforeResolveReferences" + BeforeTargets="AssignProjectConfiguration" Condition="'@(ProjectReference)' != ''" Inputs="%(ProjectReference.Identity)" Outputs="unused"> @@ -116,6 +116,11 @@ <ProjectReference> <AdditionalProperties>Configuration=$(_projectReferenceConfiguration);%(ProjectReference.AdditionalProperties)</AdditionalProperties> </ProjectReference> + + <!-- Project references for non-test assemblies should never be copied to the output. --> + <ProjectReference Condition="'$(IsTestProject)' != 'true'"> + <Private>false</Private> + </ProjectReference> </ItemGroup> </Target> diff --git a/cross/build-android-rootfs.sh b/cross/build-android-rootfs.sh new file mode 100755 index 0000000000..452d4e8592 --- /dev/null +++ b/cross/build-android-rootfs.sh @@ -0,0 +1,108 @@ +#!/usr/bin/env bash + +usage() +{ + echo "Creates a toolchain and sysroot used for cross-compiling for Android." + echo. + echo "Usage: $0 [BuildArch] [ApiLevel]" + echo. + echo "BuildArch is the target architecture of Android. Currently only arm64 is supported." + echo "ApiLevel is the target Android API level. API levels usually match to Android releases. See https://source.android.com/source/build-numbers.html" + echo. + echo "By default, the toolchain and sysroot will be generated in cross/android-rootfs/toolchain/[BuildArch]. You can change this behavior" + echo "by setting the TOOLCHAIN_DIR environment variable" + echo. + echo "By default, the NDK will be downloaded into the cross/android-rootfs/android-ndk-r13b directory. If you already have an NDK installation," + echo "you can set the NDK_DIR environment variable to have this script use that installation of the NDK." + exit 1 +} + +__ApiLevel=21 # The minimum platform for arm64 is API level 21 +__BuildArch=arm64 +__AndroidArch=aarch64 + +for i in "$@" + do + lowerI="$(echo $i | awk '{print tolower($0)}')" + case $lowerI in + -?|-h|--help) + usage + exit 1 + ;; + arm64) + __BuildArch=arm64 + __AndroidArch=aarch64 + ;; + *[0-9]) + __ApiLevel=$i + ;; + *) + __UnprocessedBuildArgs="$__UnprocessedBuildArgs $i" + ;; + esac +done + +# Obtain the location of the bash script to figure out where the root of the repo is. +__CrossDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +__Android_Cross_Dir="$__CrossDir/android-rootfs" +__NDK_Dir="$__Android_Cross_Dir/android-ndk-r13b" +__libunwind_Dir="$__Android_Cross_Dir/libunwind" +__ToolchainDir="$__Android_Cross_Dir/toolchain/$__BuildArch" + +if [[ -n "$TOOLCHAIN_DIR" ]]; then + __ToolchainDir=$TOOLCHAIN_DIR +fi + +if [[ -n "$NDK_DIR" ]]; then + __NDK_Dir=$NDK_DIR +fi + +echo "Target API level: $__ApiLevel" +echo "Target architecture: $__BuildArch" +echo "NDK location: $__NDK_Dir" +echo "Target Toolchain location: $__ToolchainDir" + +# Download the NDK if required +if [ ! -d $__NDK_Dir ]; then + echo Downloading the NDK into $__NDK_Dir + mkdir -p $__NDK_Dir + wget -nv -nc --show-progress https://dl.google.com/android/repository/android-ndk-r13b-linux-x86_64.zip -O $__Android_Cross_Dir/android-ndk-r13b-linux-x86_64.zip + unzip -q $__Android_Cross_Dir/android-ndk-r13b-linux-x86_64.zip -d $__Android_Cross_Dir +fi + +# Create the RootFS for both arm64 as well as aarch +rm -rf $__Android_Cross_Dir/toolchain + +echo Generating the $__BuildArch toolchain +$__NDK_Dir/build/tools/make_standalone_toolchain.py --arch $__BuildArch --api $__ApiLevel --install-dir $__ToolchainDir + +# Install the required packages into the toolchain +rm -rf $__Android_Cross_Dir/deb/ +rm -rf $__Android_Cross_Dir/tmp + +mkdir -p $__Android_Cross_Dir/deb/ +mkdir -p $__Android_Cross_Dir/tmp/$arch/ +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/libcurl-dev_7.52.1_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/libcurl-dev_7.52.1_$__AndroidArch.deb +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/libcurl_7.52.1_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/libcurl_7.52.1_$__AndroidArch.deb +wget -nv -nc https://github.com/qmfrederik/dotnet-alpine-arm/raw/master/krb5-dev_1.15_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/krb5-dev_1.15_$__AndroidArch.deb +wget -nv -nc https://github.com/qmfrederik/dotnet-alpine-arm/raw/master/krb5_1.15_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/krb5_1.15_$__AndroidArch.deb +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/openssl-dev_1.0.2k_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/openssl-dev_1.0.2k_$__AndroidArch.deb +wget -nv -nc http://termux.net/dists/stable/main/binary-$__AndroidArch/openssl_1.0.2k_$__AndroidArch.deb -O $__Android_Cross_Dir/deb/openssl_1.0.2k_$__AndroidArch.deb + +echo Unpacking Termux packages +dpkg -x $__Android_Cross_Dir/deb/libcurl-dev_7.52.1_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/libcurl_7.52.1_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/krb5-dev_1.15_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/krb5_1.15_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/openssl-dev_1.0.2k_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ +dpkg -x $__Android_Cross_Dir/deb/openssl_1.0.2k_$__AndroidArch.deb $__Android_Cross_Dir/tmp/$__AndroidArch/ + +cp -R $__Android_Cross_Dir/tmp/$__AndroidArch/data/data/com.termux/files/usr/* $__ToolchainDir/sysroot/usr/ + +# ifaddrs.h is not available natively Android, but a version of it is available +# See https://github.com/termux/termux-packages/issues/338 for context +wget -nv -nc https://raw.githubusercontent.com/qnnnnez/android-ifaddrs/master/include/ifaddrs_single.h -O $__ToolchainDir/sysroot/usr/include/ifaddrs.h + +echo Now run: +echo CONFIG_DIR=\`realpath cross/android/arm64\` ROOTFS_DIR=\`realpath $__ToolchainDir/sysroot\` ./build-native.sh -debug -buildArch=arm64 -- verbose cross diff --git a/dependencies.props b/dependencies.props index 46f522ada8..d40f6b0fff 100644 --- a/dependencies.props +++ b/dependencies.props @@ -17,22 +17,24 @@ These ref versions are pulled from https://github.com/dotnet/versions. --> <PropertyGroup> - <CoreFxCurrentRef>85185417fa53abb10ebb38326604e19fb8b4d105</CoreFxCurrentRef> - <CoreClrCurrentRef>bcd06bf0e441fa9c018bf722f08bbaece884a8f9</CoreClrCurrentRef> + <CoreFxCurrentRef>8c02c8b91856b5b8f6e5d7f1707f6b2f0de67644</CoreFxCurrentRef> + <CoreClrCurrentRef>d7b3774e789985c90bbdba7cbfd8de421e2ec4fc</CoreClrCurrentRef> <ExternalCurrentRef>6ebb1923d44306ebc37fe819f95f54e547a38c46</ExternalCurrentRef> - <ProjectNTfsCurrentRef>8bff607695d15009cc3c94456500d5383a3487ae</ProjectNTfsCurrentRef> - <SniCurrentRef>99a2e18954382a654e66aed649af70c1c61a47c3</SniCurrentRef> + <ProjectNTfsCurrentRef>d7b3774e789985c90bbdba7cbfd8de421e2ec4fc</ProjectNTfsCurrentRef> + <SniCurrentRef>d7b3774e789985c90bbdba7cbfd8de421e2ec4fc</SniCurrentRef> + <StandardCurrentRef>d7b3774e789985c90bbdba7cbfd8de421e2ec4fc</StandardCurrentRef> </PropertyGroup> <!-- Auto-upgraded properties for each build info dependency. --> <PropertyGroup> - <CoreFxExpectedPrerelease>beta-25006-01</CoreFxExpectedPrerelease> - <CoreClrExpectedPrerelease>beta-25006-03</CoreClrExpectedPrerelease> + <CoreFxExpectedPrerelease>beta-25007-02</CoreFxExpectedPrerelease> + <CoreClrExpectedPrerelease>beta-25007-01</CoreClrExpectedPrerelease> <ExternalExpectedPrerelease>beta-25005-00</ExternalExpectedPrerelease> - <ProjectNTfsExpectedPrerelease>beta-25006-00</ProjectNTfsExpectedPrerelease> - <StandardExpectedPrerelease>beta-25003-02</StandardExpectedPrerelease> + <ProjectNTfsExpectedPrerelease>beta-25007-00</ProjectNTfsExpectedPrerelease> + <NETStandardPackageVersion>2.0.0-beta-25006-01</NETStandardPackageVersion> + <NETStandardPackageId>NETStandard.Library</NETStandardPackageId> <!-- Use the SNI runtime package --> - <SniPackageVersion>4.4.0-beta-24926-02</SniPackageVersion> + <SniPackageVersion>4.4.0-beta-25007-01</SniPackageVersion> </PropertyGroup> <!-- Full package version strings that are used in other parts of the build. --> @@ -65,6 +67,10 @@ <BuildInfoPath>$(BaseDotNetBuildInfo)sni/$(DependencyBranch)</BuildInfoPath> <CurrentRef>$(SniCurrentRef)</CurrentRef> </RemoteDependencyBuildInfo> + <RemoteDependencyBuildInfo Include="Standard"> + <BuildInfoPath>$(BaseDotNetBuildInfo)standard/$(DependencyBranch)</BuildInfoPath> + <CurrentRef>$(StandardCurrentRef)</CurrentRef> + </RemoteDependencyBuildInfo> <RemoteDependencyBuildInfo Condition="'$(DisableProjectNTfsAutoUpgrade)' != 'true'" Include="ProjectNTfs"> <BuildInfoPath>$(BaseDotNetBuildInfo)projectn-tfs/$(DependencyBranch)</BuildInfoPath> <CurrentRef>$(ProjectNTfsCurrentRef)</CurrentRef> @@ -89,6 +95,11 @@ <ElementName>ExternalExpectedPrerelease</ElementName> <BuildInfoName>External</BuildInfoName> </XmlUpdateStep> + <XmlUpdateStep Include="Standard"> + <Path>$(MSBuildThisFileFullPath)</Path> + <ElementName>NETStandardPackageVersion</ElementName> + <PackageId>$(NETStandardPackageId)</PackageId> + </XmlUpdateStep> <XmlUpdateStep Condition="'$(DisableProjectNTfsAutoUpgrade)' != 'true'" Include="ProjectNTfs"> <Path>$(MSBuildThisFileFullPath)</Path> <ElementName>ProjectNTfsExpectedPrerelease</ElementName> @@ -54,8 +54,6 @@ <BuildToolsTargetsDesktop Condition="'$(RunningOnCore)' != 'true'">true</BuildToolsTargetsDesktop> </PropertyGroup> - <Import Project="$(MSBuildThisFileDirectory)targetingpacks.props" /> - <!-- Enable the analyzers for this repo --> <PropertyGroup> <EnableDotnetAnalyzers Condition="'$(EnableDotnetAnalyzers)'==''">true</EnableDotnetAnalyzers> diff --git a/external/netstandard/netstandard.depproj b/external/netstandard/netstandard.depproj index 4553750dec..4db52b05eb 100644 --- a/external/netstandard/netstandard.depproj +++ b/external/netstandard/netstandard.depproj @@ -14,7 +14,7 @@ <_NETStandardTFMFolder Condition="'$(NuGetTargetMoniker)' == '.NETStandard,Version=v2.0'">netstandard2.0</_NETStandardTFMFolder> <_NETStandardTFMFolder Condition="'$(IsNetFx)' == 'true'">net461</_NETStandardTFMFolder> </PropertyGroup> - + <ItemGroup> <!-- for all configurations this project provides refs for that configuration --> <BinplaceConfiguration Include="$(Configuration)"> @@ -23,19 +23,17 @@ <RuntimePath>$(RuntimePath)</RuntimePath> </BinplaceConfiguration> </ItemGroup> - + <Target Name="AddNETStandardRefs" AfterTargets="ResolveReferences" Condition="'$(_NETStandardTFMFolder)' != ''"> <PropertyGroup> - <_NETStandardPackageId>NETStandard.Library</_NETStandardPackageId> - <_NETStandardPackageVersion>2.0.0-$(StandardExpectedPrerelease)</_NETStandardPackageVersion> - <_NETStandardRefFolder>$(PackagesDir)$(_NETStandardPackageId)\$(_NETStandardPackageVersion)\build\$(_NETStandardTFMFolder)\ref</_NETStandardRefFolder> + <_NETStandardRefFolder>$(PackagesDir)$(NETStandardPackageId)\$(NETStandardPackageVersion)\build\$(_NETStandardTFMFolder)\ref</_NETStandardRefFolder> </PropertyGroup> <ItemGroup> <Reference Include="$(_NETStandardRefFolder)\*.dll"> <Private>False</Private> - <NuGetPackageId>NETStandard.Library</NuGetPackageId> - <NuGetPackageVersion>$(_NETStandardPackageVersion)</NuGetPackageVersion> + <NuGetPackageId>$(NETStandardPackageId)</NuGetPackageId> + <NuGetPackageVersion>$(NETStandardPackageVersion)</NuGetPackageVersion> </Reference> </ItemGroup> </Target> diff --git a/external/netstandard/netstandard1.x/project.json.template b/external/netstandard/netstandard1.x/project.json.template index ae43c47a0f..08b678e4b4 100644 --- a/external/netstandard/netstandard1.x/project.json.template +++ b/external/netstandard/netstandard1.x/project.json.template @@ -2,7 +2,7 @@ "frameworks": { "{TFM}": { "dependencies": { - "NETStandard.Library": "2.0.0-beta-24928-01", + "NETStandard.Library": "2.0.0-beta-25006-01", "System.Diagnostics.Contracts": "4.3.0", "System.Diagnostics.Debug": "4.3.0", "System.Dynamic.Runtime": "4.3.0", diff --git a/external/netstandard/project.json.template b/external/netstandard/project.json.template index 544d1afd26..281c6c6e7f 100644 --- a/external/netstandard/project.json.template +++ b/external/netstandard/project.json.template @@ -2,7 +2,7 @@ "frameworks": { "{TFM}": { "dependencies": { - "NETStandard.Library": "2.0.0-beta-25003-02" + "NETStandard.Library": "2.0.0-beta-25006-01" } } } diff --git a/external/runtime/NETNative/project.json.template b/external/runtime/NETNative/project.json.template index c6e5cf38a0..9b5e51c290 100644 --- a/external/runtime/NETNative/project.json.template +++ b/external/runtime/NETNative/project.json.template @@ -2,7 +2,7 @@ "frameworks": { "{TFM}": { "dependencies": { - "Microsoft.TargetingPack.Private.NETNative": "1.1.0-beta-25006-00" + "Microsoft.TargetingPack.Private.NETNative": "1.1.0-beta-25007-00" } } }, diff --git a/external/runtime/project.json.template b/external/runtime/project.json.template index 42d7b34be4..dae248fd78 100644 --- a/external/runtime/project.json.template +++ b/external/runtime/project.json.template @@ -2,9 +2,9 @@ "frameworks": { "{TFM}": { "dependencies": { - "Microsoft.NETCore.Platforms": "2.0.0-beta-25006-01", - "Microsoft.NETCore.Runtime.CoreCLR": "2.0.0-beta-25006-03", - "Microsoft.NETCore.TestHost": "2.0.0-beta-25006-03", + "Microsoft.NETCore.Platforms": "2.0.0-beta-25007-02", + "Microsoft.NETCore.Runtime.CoreCLR": "2.0.0-beta-25007-01", + "Microsoft.NETCore.TestHost": "2.0.0-beta-25007-01", "runtime.native.System.Data.SqlClient.sni": "4.4.0-beta-24913-02", "Microsoft.NETCore.DotNetHost": "1.2.0-beta-001259-00", "Microsoft.NETCore.DotNetHostPolicy": "1.2.0-beta-001259-00" diff --git a/referenceFromRuntime.targets b/referenceFromRuntime.targets index 9f0bc48d24..df0b90a15e 100644 --- a/referenceFromRuntime.targets +++ b/referenceFromRuntime.targets @@ -9,8 +9,8 @@ </ItemGroup> </Target> - <Target Name="AddRuntimeProjectReference" - BeforeTargets="AnnotateProjectReference" + <Target Name="AddRuntimeProjectReference" + BeforeTargets="AddProjectReferencesDynamically" Condition="'$(IsTestProject)'!='true' AND '@(ReferenceFromRuntime)' != ''"> <Error Condition="'$(IsReferenceAssembly)' != 'true' AND '$(RuntimeProjectFile)' == ''" Text="RuntimeProjectFile must be specified when using ReferenceFromRuntime from source projects." /> <Error Condition="'$(IsReferenceAssembly)' == 'true'" Text="ReferenceFromRuntime may not be used from reference assemblies." /> @@ -22,8 +22,8 @@ </ProjectReference> </ItemGroup> </Target> - - <Target Name="FilterReferenceFromRuntime" + + <Target Name="FilterReferenceFromRuntime" AfterTargets="ResolveProjectReferences" Condition="'$(IsTestProject)'!='true' AND '@(ReferenceFromRuntime)' != ''"> <ItemGroup> diff --git a/src/Common/src/System/Numerics/Hashing/HashHelpers.cs b/src/Common/src/System/Numerics/Hashing/HashHelpers.cs index 166c49fe02..841eb04d87 100644 --- a/src/Common/src/System/Numerics/Hashing/HashHelpers.cs +++ b/src/Common/src/System/Numerics/Hashing/HashHelpers.cs @@ -10,11 +10,13 @@ namespace System.Numerics.Hashing public static int Combine(int h1, int h2) { - // RyuJIT optimizes this to use the ROL instruction - // Related GitHub pull request: dotnet/coreclr#1830 - uint rol5 = ((uint)h1 << 5) | ((uint)h1 >> 27); - return ((int)rol5 + h1) ^ h2; + unchecked + { + // RyuJIT optimizes this to use the ROL instruction + // Related GitHub pull request: dotnet/coreclr#1830 + uint rol5 = ((uint)h1 << 5) | ((uint)h1 >> 27); + return ((int)rol5 + h1) ^ h2; + } } } -} - +}
\ No newline at end of file diff --git a/src/Common/tests/System/Collections/ICollection.Generic.Tests.cs b/src/Common/tests/System/Collections/ICollection.Generic.Tests.cs index 3d2e37508c..7dda8a1591 100644 --- a/src/Common/tests/System/Collections/ICollection.Generic.Tests.cs +++ b/src/Common/tests/System/Collections/ICollection.Generic.Tests.cs @@ -141,7 +141,7 @@ namespace System.Collections.Tests [Theory] [MemberData(nameof(ValidCollectionSizes))] - public void ICollection_Generic_Add_DefaultValue(int count) + public virtual void ICollection_Generic_Add_DefaultValue(int count) { if (DefaultValueAllowed && !IsReadOnly && !AddRemoveClear_ThrowsNotSupported) { @@ -374,7 +374,7 @@ namespace System.Collections.Tests [Theory] [MemberData(nameof(ValidCollectionSizes))] - public void ICollection_Generic_Contains_DefaultValueOnCollectionContainingDefaultValue(int count) + public virtual void ICollection_Generic_Contains_DefaultValueOnCollectionContainingDefaultValue(int count) { if (DefaultValueAllowed && !IsReadOnly && !AddRemoveClear_ThrowsNotSupported) { @@ -549,7 +549,7 @@ namespace System.Collections.Tests [Theory] [MemberData(nameof(ValidCollectionSizes))] - public void ICollection_Generic_Remove_DefaultValueContainedInCollection(int count) + public virtual void ICollection_Generic_Remove_DefaultValueContainedInCollection(int count) { if (!IsReadOnly && !AddRemoveClear_ThrowsNotSupported && DefaultValueAllowed && !Enumerable.Contains(InvalidValues, default(T))) { diff --git a/src/Common/tests/System/Diagnostics/RemoteExecutorConsoleApp/RemoteExecutorConsoleApp.csproj b/src/Common/tests/System/Diagnostics/RemoteExecutorConsoleApp/RemoteExecutorConsoleApp.csproj index 32918bb7fd..1228952a9f 100644 --- a/src/Common/tests/System/Diagnostics/RemoteExecutorConsoleApp/RemoteExecutorConsoleApp.csproj +++ b/src/Common/tests/System/Diagnostics/RemoteExecutorConsoleApp/RemoteExecutorConsoleApp.csproj @@ -8,7 +8,6 @@ <AssemblyName>RemoteExecutorConsoleApp</AssemblyName> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> <CopyNuGetImplementations>false</CopyNuGetImplementations> - <NoWarn>0436</NoWarn> </PropertyGroup> <!-- Default configurations to help VS understand the configurations --> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" /> diff --git a/src/Common/tests/System/Xml/BaseLibManaged/BaseLibManaged.csproj b/src/Common/tests/System/Xml/BaseLibManaged/BaseLibManaged.csproj index 227d43fd62..2462b3e3e7 100644 --- a/src/Common/tests/System/Xml/BaseLibManaged/BaseLibManaged.csproj +++ b/src/Common/tests/System/Xml/BaseLibManaged/BaseLibManaged.csproj @@ -4,7 +4,6 @@ <PropertyGroup> <ProjectGuid>{42F10363-C2A2-42B5-B7B9-1B5DBB0BC71E}</ProjectGuid> <RootNamespace>WebData.BaseLib</RootNamespace> - <NoWarn>0436</NoWarn> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'"> </PropertyGroup> diff --git a/src/Common/tests/System/Xml/ModuleCore/ModuleCore.csproj b/src/Common/tests/System/Xml/ModuleCore/ModuleCore.csproj index 29e1c2e49f..fa46d46471 100644 --- a/src/Common/tests/System/Xml/ModuleCore/ModuleCore.csproj +++ b/src/Common/tests/System/Xml/ModuleCore/ModuleCore.csproj @@ -3,7 +3,6 @@ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> <PropertyGroup> <ProjectGuid>{3CF0CC76-4CE0-460A-BA37-657CFED39AB0}</ProjectGuid> - <NoWarn>0436</NoWarn> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Release|AnyCPU'" /> diff --git a/src/Common/tests/System/Xml/XmlCoreTest/XmlCoreTest.csproj b/src/Common/tests/System/Xml/XmlCoreTest/XmlCoreTest.csproj index 111689c529..50efac961d 100644 --- a/src/Common/tests/System/Xml/XmlCoreTest/XmlCoreTest.csproj +++ b/src/Common/tests/System/Xml/XmlCoreTest/XmlCoreTest.csproj @@ -5,7 +5,6 @@ <ProjectGuid>{89701565-F68B-46D9-BD78-95B0F052C50B}</ProjectGuid> <AssemblyName>XmlCoreTest</AssemblyName> <RootNamespace>XmlCoreTest.Common</RootNamespace> - <NoWarn>0436</NoWarn> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Release|AnyCPU'" /> @@ -31,8 +30,5 @@ <ProjectReference Include="..\ModuleCore\ModuleCore.csproj" /> <ProjectReference Include="..\XmlDiff\XmlDiff.csproj" /> </ItemGroup> - <ItemGroup> - <None Include="project.json" /> - </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> </Project>
\ No newline at end of file diff --git a/src/Common/tests/System/Xml/XmlDiff/XmlDiff.csproj b/src/Common/tests/System/Xml/XmlDiff/XmlDiff.csproj index e9bdc7e149..e3c605d987 100644 --- a/src/Common/tests/System/Xml/XmlDiff/XmlDiff.csproj +++ b/src/Common/tests/System/Xml/XmlDiff/XmlDiff.csproj @@ -5,7 +5,6 @@ <ProjectGuid>{466D87DF-BDEC-4E6C-BACD-317D79B8EDBE}</ProjectGuid> <AssemblyName>XmlDiff</AssemblyName> <RootNamespace>System.Xml.XmlDiff</RootNamespace> - <NoWarn>0436</NoWarn> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Release|AnyCPU'" /> @@ -23,8 +22,5 @@ <ItemGroup> <ProjectReference Include="..\ModuleCore\ModuleCore.csproj" /> </ItemGroup> - <ItemGroup> - <None Include="project.json" /> - </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> </Project>
\ No newline at end of file diff --git a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Syntax/NameTable.cs b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Syntax/NameTable.cs index 0018816ba3..29e844062a 100644 --- a/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Syntax/NameTable.cs +++ b/src/Microsoft.CSharp/src/Microsoft/CSharp/RuntimeBinder/Syntax/NameTable.cs @@ -75,17 +75,22 @@ namespace Microsoft.CSharp.RuntimeBinder.Syntax private int ComputeHashCode(string key) { - int len = key.Length; - int hashCode = len + _hashCodeRandomizer; - // use key.Length to eliminate the range check - for (int i = 0; i < key.Length; i++) + int hashCode, len = key.Length; + + unchecked { - hashCode += (hashCode << 7) ^ key[i]; + hashCode = len + _hashCodeRandomizer; + // use key.Length to eliminate the range check + for (int i = 0; i < key.Length; i++) + { + hashCode += (hashCode << 7) ^ key[i]; + } + // mix it a bit more + hashCode -= hashCode >> 17; + hashCode -= hashCode >> 11; + hashCode -= hashCode >> 5; } - // mix it a bit more - hashCode -= hashCode >> 17; - hashCode -= hashCode >> 11; - hashCode -= hashCode >> 5; + return hashCode; } diff --git a/src/Native/Unix/Common/pal_config.h.in b/src/Native/Unix/Common/pal_config.h.in index e07db8fe3b..15637f6bcf 100644 --- a/src/Native/Unix/Common/pal_config.h.in +++ b/src/Native/Unix/Common/pal_config.h.in @@ -66,6 +66,13 @@ #cmakedefine01 HAVE_CRT_EXTERNS_H #cmakedefine01 HAVE_GETDOMAINNAME #cmakedefine01 HAVE_UNAME +#cmakedefine01 HAVE_FUTIMES +#cmakedefine01 HAVE_FUTIMENS +#cmakedefine01 HAVE_MKSTEMPS +#cmakedefine01 HAVE_MKSTEMP +#cmakedefine01 IPV6MR_INTERFACE_UNSIGNED +#cmakedefine01 BIND_ADDRLEN_UNSIGNED +#cmakedefine01 INOTIFY_RM_WATCH_WD_UNSIGNED // Mac OS X has stat64, but it is deprecated since plain stat now // provides the same 64-bit aware struct when targeting OS X > 10.5 diff --git a/src/Native/Unix/System.Native/CMakeLists.txt b/src/Native/Unix/System.Native/CMakeLists.txt index 2e8f87370b..256bd644e1 100644 --- a/src/Native/Unix/System.Native/CMakeLists.txt +++ b/src/Native/Unix/System.Native/CMakeLists.txt @@ -42,7 +42,7 @@ add_library(System.Native-Static SET_TARGET_PROPERTIES(System.Native-Static PROPERTIES PREFIX "") SET_TARGET_PROPERTIES(System.Native-Static PROPERTIES OUTPUT_NAME System.Native CLEAN_DIRECT_OUTPUT 1) -if (CMAKE_SYSTEM_NAME STREQUAL Linux) +if (CMAKE_SYSTEM_NAME STREQUAL Linux AND NOT CLR_CMAKE_PLATFORM_ANDROID) target_link_libraries(System.Native rt) endif () diff --git a/src/Native/Unix/System.Native/pal_io.cpp b/src/Native/Unix/System.Native/pal_io.cpp index 14eb5b45dc..91eddc761d 100644 --- a/src/Native/Unix/System.Native/pal_io.cpp +++ b/src/Native/Unix/System.Native/pal_io.cpp @@ -584,7 +584,45 @@ extern "C" int32_t SystemNative_Link(const char* source, const char* linkTarget) extern "C" intptr_t SystemNative_MksTemps(char* pathTemplate, int32_t suffixLength) { intptr_t result; +#if HAVE_MKSTEMPS while (CheckInterrupted(result = mkstemps(pathTemplate, suffixLength))); +#elif HAVE_MKSTEMP + // mkstemps is not available bionic/Android, but mkstemp is + // mkstemp doesn't allow the suffix that msktemps does allow, so we'll need to + // remove that before passing pathTemplate to mkstemp + + int32_t pathTemplateLength = static_cast<int32_t>(strlen(pathTemplate)); + + // pathTemplate must include at least XXXXXX (6 characters) which are not part of + // the suffix + if (suffixLength < 0 || suffixLength > pathTemplateLength - 6) + { + errno = EINVAL; + return -1; + } + + // Make mkstemp ignore the suffix by setting the first char of the suffix to \0, + // if there is a suffix + int32_t firstSuffixIndex = 0; + char firstSuffixChar = 0; + + if (suffixLength > 0) + { + firstSuffixIndex = pathTemplateLength - suffixLength; + firstSuffixChar = pathTemplate[firstSuffixIndex]; + pathTemplate[firstSuffixIndex] = 0; + } + + while (CheckInterrupted(result = mkstemp(pathTemplate))); + + // Reset the first char of the suffix back to its original value, if there is a suffix + if (suffixLength > 0) + { + pathTemplate[firstSuffixIndex] = firstSuffixChar; + } +#else +#error "Cannot find mkstemps nor mkstemp on this platform" +#endif return result; } @@ -1086,15 +1124,28 @@ extern "C" int32_t SystemNative_CopyFile(intptr_t sourceFd, intptr_t destination // Now that the data from the file has been copied, copy over metadata // from the source file. First copy the file times. + // If futimes nor futimes are available on this platform, file times will + // not be copied over. while (CheckInterrupted(ret = fstat_(inFd, &sourceStat))); if (ret == 0) { +#if HAVE_FUTIMES struct timeval origTimes[2]; origTimes[0].tv_sec = sourceStat.st_atime; origTimes[0].tv_usec = 0; origTimes[1].tv_sec = sourceStat.st_mtime; origTimes[1].tv_usec = 0; while (CheckInterrupted(ret = futimes(outFd, origTimes))); +#elif HAVE_FUTIMENS + // futimes is not a POSIX function, and not available on Android, + // but futimens is + struct timespec origTimes[2]; + origTimes[0].tv_sec = sourceStat.st_atime; + origTimes[0].tv_nsec = 0; + origTimes[1].tv_sec = sourceStat.st_mtime; + origTimes[1].tv_nsec = 0; + while (CheckInterrupted(ret = futimens(outFd, origTimes))); +#endif } if (ret != 0) { @@ -1142,7 +1193,13 @@ extern "C" int32_t SystemNative_INotifyRemoveWatch(intptr_t fd, int32_t wd) assert(wd >= 0); #if HAVE_INOTIFY - return inotify_rm_watch(ToFileDescriptor(fd), wd); + return inotify_rm_watch( + ToFileDescriptor(fd), +#if INOTIFY_RM_WATCH_WD_UNSIGNED + static_cast<uint32_t>(wd)); +#else + wd); +#endif #else (void)fd, (void)wd; errno = ENOTSUP; diff --git a/src/Native/Unix/System.Native/pal_mount.cpp b/src/Native/Unix/System.Native/pal_mount.cpp index 53b249af7f..ee62ba9e6e 100644 --- a/src/Native/Unix/System.Native/pal_mount.cpp +++ b/src/Native/Unix/System.Native/pal_mount.cpp @@ -16,6 +16,11 @@ #include <sys/statfs.h> #include <mntent.h> #define STRING_BUFFER_SIZE 8192 + +// Android does not define MNTOPT_RO +#ifndef MNTOPT_RO +#define MNTOPT_RO "r" +#endif #endif static int32_t GetMountInfo(MountPointFound onFound) diff --git a/src/Native/Unix/System.Native/pal_networking.cpp b/src/Native/Unix/System.Native/pal_networking.cpp index bf02245ea3..3a36068cb8 100644 --- a/src/Native/Unix/System.Native/pal_networking.cpp +++ b/src/Native/Unix/System.Native/pal_networking.cpp @@ -1525,8 +1525,14 @@ extern "C" Error SystemNative_SetIPv6MulticastOption(intptr_t socket, int32_t mu ipv6_mreq opt; memset(&opt, 0, sizeof(ipv6_mreq)); - opt.ipv6mr_interface = static_cast<unsigned int>(option->InterfaceIndex); - + + opt.ipv6mr_interface = +#if IPV6MR_INTERFACE_UNSIGNED + static_cast<unsigned int>(option->InterfaceIndex); +#else + option->InterfaceIndex; +#endif + ConvertByteArrayToIn6Addr(opt.ipv6mr_multiaddr, &option->Address.Address[0], NUM_BYTES_IN_IPV6_ADDRESS); int err = setsockopt(fd, IPPROTO_IP, optionName, &opt, sizeof(opt)); @@ -1784,7 +1790,15 @@ extern "C" Error SystemNative_Bind(intptr_t socket, uint8_t* socketAddress, int3 int fd = ToFileDescriptor(socket); - int err = bind(fd, reinterpret_cast<sockaddr*>(socketAddress), static_cast<socklen_t>(socketAddressLen)); + int err = bind( + fd, + reinterpret_cast<sockaddr*>(socketAddress), +#if BIND_ADDRLEN_UNSIGNED + static_cast<socklen_t>(socketAddressLen)); +#else + socketAddressLen); +#endif + return err == 0 ? PAL_SUCCESS : SystemNative_ConvertErrorPlatformToPal(errno); } diff --git a/src/Native/Unix/configure.cmake b/src/Native/Unix/configure.cmake index a8e3761350..ac1f693594 100644 --- a/src/Native/Unix/configure.cmake +++ b/src/Native/Unix/configure.cmake @@ -294,6 +294,10 @@ set(HAVE_THREAD_SAFE_GETHOSTBYNAME_AND_GETHOSTBYADDR 0) if (CMAKE_SYSTEM_NAME STREQUAL Linux) set(CMAKE_REQUIRED_LIBRARIES rt) set(HAVE_SUPPORT_FOR_DUAL_MODE_IPV4_PACKET_INFO 1) + + if (CLR_CMAKE_PLATFORM_ANDROID) + set(HAVE_THREAD_SAFE_GETHOSTBYNAME_AND_GETHOSTBYADDR 1) + endif() elseif (CMAKE_SYSTEM_NAME STREQUAL Darwin) set(HAVE_THREAD_SAFE_GETHOSTBYNAME_AND_GETHOSTBYADDR 1) endif () @@ -321,6 +325,65 @@ check_function_exists( mach_timebase_info HAVE_MACH_TIMEBASE_INFO) +check_function_exists( + futimes + HAVE_FUTIMES) + +check_function_exists( + futimens + HAVE_FUTIMENS) + +set (PREVIOUS_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) +set (CMAKE_REQUIRED_FLAGS "-Werror -Wsign-conversion") + +check_cxx_source_compiles( + " + #include <sys/socket.h> + + int main() + { + int fd; + sockaddr* addr; + socklen_t addrLen; + + int err = bind(fd, addr, addrLen); + return 0; + } + " + BIND_ADDRLEN_UNSIGNED +) + +check_cxx_source_compiles( + " + #include <netinet/in.h> + #include <netinet/tcp.h> + + int main() + { + ipv6_mreq opt; + unsigned int index = 0; + opt.ipv6mr_interface = index; + return 0; + } + " + IPV6MR_INTERFACE_UNSIGNED +) + +check_cxx_source_compiles( + " + #include <sys/inotify.h> + + int main() + { + intptr_t fd; + uint32_t wd; + return inotify_rm_watch(fd, wd); + } + " + INOTIFY_RM_WATCH_WD_UNSIGNED) + +set (CMAKE_REQUIRED_FLAGS ${PREVIOUS_CMAKE_REQUIRED_FLAGS}) + check_cxx_source_runs( " #include <sys/mman.h> @@ -362,6 +425,38 @@ check_prototype_definition( check_cxx_source_compiles( " + #include <stdlib.h> + #include <unistd.h> + #include <string.h> + + int main() + { + char* path = strdup(\"abc\"); + return mkstemps(path, 3); + } + " + HAVE_MKSTEMPS) + +check_cxx_source_compiles( + " + #include <stdlib.h> + #include <unistd.h> + #include <string.h> + + int main() + { + char* path = strdup(\"abc\"); + return mkstemp(path); + } + " + HAVE_MKSTEMP) + +if (NOT HAVE_MKSTEMPS AND NOT HAVE_MKSTEMP) + message(FATAL_ERROR "Cannot find mkstemp nor mkstemp on this platform.") +endif() + +check_cxx_source_compiles( + " #include <sys/types.h> #include <sys/socketvar.h> #include <netinet/ip.h> @@ -372,8 +467,11 @@ check_cxx_source_compiles( HAVE_TCP_VAR_H ) +# If sys/cdefs is not included on Android, this check will fail because +# __BEGIN_DECLS is not defined check_cxx_source_compiles( " + #include <sys/cdefs.h> #include <netinet/tcp.h> int main() { int x = TCP_ESTABLISHED; return x; } " diff --git a/src/System.Buffers/src/System.Buffers.csproj b/src/System.Buffers/src/System.Buffers.csproj index 6d98b7b944..b67005178a 100644 --- a/src/System.Buffers/src/System.Buffers.csproj +++ b/src/System.Buffers/src/System.Buffers.csproj @@ -4,7 +4,7 @@ <PropertyGroup> <ProjectGuid>{2ADDB484-6F57-4D71-A3FE-A57EC6329A2B}</ProjectGuid> <AllowUnsafeBlocks>true</AllowUnsafeBlocks> - <DocumentationFile>$(OutputPath)$(AssemblyName).xml</DocumentationFile> + <DocumentationFile>$(OutputPath)$(MSBuildProjectName).xml</DocumentationFile> <UseOpenKey Condition="'$(UseOpenKey)'==''">true</UseOpenKey> <IsPartialFacadeAssembly Condition="'$(TargetGroup)' != 'netstandard' and '$(TargetGroup)' != 'netstandard1.1'">true</IsPartialFacadeAssembly> <ExcludeResourcesImport Condition="'$(IsPartialFacadeAssembly)'=='true'">true</ExcludeResourcesImport> diff --git a/src/System.CodeDom/src/Microsoft/CSharp/CSharpCodeGenerator.cs b/src/System.CodeDom/src/Microsoft/CSharp/CSharpCodeGenerator.cs index 242a60a2e8..e180cb5c5a 100644 --- a/src/System.CodeDom/src/Microsoft/CSharp/CSharpCodeGenerator.cs +++ b/src/System.CodeDom/src/Microsoft/CSharp/CSharpCodeGenerator.cs @@ -1213,7 +1213,7 @@ namespace Microsoft.CSharp string name = e.Name; if (e.PrivateImplementationType != null) { - name = GetBaseTypeOutput(e.PrivateImplementationType) + "." + name; + name = GetBaseTypeOutput(e.PrivateImplementationType, preferBuiltInTypes: false) + "." + name; } OutputTypeNamePair(e.Type, name); Output.WriteLine(';'); @@ -1472,7 +1472,7 @@ namespace Microsoft.CSharp Output.Write(' '); if (e.PrivateImplementationType != null) { - Output.Write(GetBaseTypeOutput(e.PrivateImplementationType)); + Output.Write(GetBaseTypeOutput(e.PrivateImplementationType, preferBuiltInTypes: false)); Output.Write('.'); } OutputIdentifier(e.Name); @@ -1558,7 +1558,7 @@ namespace Microsoft.CSharp if (e.PrivateImplementationType != null && !IsCurrentInterface) { - Output.Write(GetBaseTypeOutput(e.PrivateImplementationType)); + Output.Write(GetBaseTypeOutput(e.PrivateImplementationType, preferBuiltInTypes: false)); Output.Write('.'); } @@ -2803,68 +2803,56 @@ namespace Microsoft.CSharp } // returns the type name without any array declaration. - private string GetBaseTypeOutput(CodeTypeReference typeRef) + private string GetBaseTypeOutput(CodeTypeReference typeRef, bool preferBuiltInTypes = true) { string s = typeRef.BaseType; - if (s.Length == 0) - { - s = "void"; - return s; - } - string lowerCaseString = s.ToLower(CultureInfo.InvariantCulture).Trim(); + if (preferBuiltInTypes) + { + if (s.Length == 0) + { + return "void"; + } + + string lowerCaseString = s.ToLower(CultureInfo.InvariantCulture).Trim(); + + switch (lowerCaseString) + { + case "system.int16": + return "short"; + case "system.int32": + return "int"; + case "system.int64": + return "long"; + case "system.string": + return "string"; + case "system.object": + return "object"; + case "system.boolean": + return "bool"; + case "system.void": + return "void"; + case "system.char": + return "char"; + case "system.byte": + return "byte"; + case "system.uint16": + return "ushort"; + case "system.uint32": + return "uint"; + case "system.uint64": + return "ulong"; + case "system.sbyte": + return "sbyte"; + case "system.single": + return "float"; + case "system.double": + return "double"; + case "system.decimal": + return "decimal"; + } + } - switch (lowerCaseString) - { - case "system.int16": - s = "short"; - break; - case "system.int32": - s = "int"; - break; - case "system.int64": - s = "long"; - break; - case "system.string": - s = "string"; - break; - case "system.object": - s = "object"; - break; - case "system.boolean": - s = "bool"; - break; - case "system.void": - s = "void"; - break; - case "system.char": - s = "char"; - break; - case "system.byte": - s = "byte"; - break; - case "system.uint16": - s = "ushort"; - break; - case "system.uint32": - s = "uint"; - break; - case "system.uint64": - s = "ulong"; - break; - case "system.sbyte": - s = "sbyte"; - break; - case "system.single": - s = "float"; - break; - case "system.double": - s = "double"; - break; - case "system.decimal": - s = "decimal"; - break; - default: // replace + with . for nested classes. // var sb = new StringBuilder(s.Length + 10); @@ -2919,8 +2907,6 @@ namespace Microsoft.CSharp sb.Append(CreateEscapedIdentifier(baseType.Substring(lastIndex))); return sb.ToString(); - } - return s; } private string GetTypeArgumentsOutput(CodeTypeReferenceCollection typeArguments) diff --git a/src/System.CodeDom/src/Microsoft/VisualBasic/VBCodeGenerator.cs b/src/System.CodeDom/src/Microsoft/VisualBasic/VBCodeGenerator.cs index 60f5a4f18d..a03d0b02be 100644 --- a/src/System.CodeDom/src/Microsoft/VisualBasic/VBCodeGenerator.cs +++ b/src/System.CodeDom/src/Microsoft/VisualBasic/VBCodeGenerator.cs @@ -1434,7 +1434,7 @@ namespace Microsoft.VisualBasic string eventName = e.Name; if (e.PrivateImplementationType != null) { - string impl = GetBaseTypeOutput(e.PrivateImplementationType); + string impl = GetBaseTypeOutput(e.PrivateImplementationType, preferBuiltInTypes: false); impl = impl.Replace('.', '_'); e.Name = impl + "_" + e.Name; } @@ -1561,7 +1561,7 @@ namespace Microsoft.VisualBasic string methodName = e.Name; if (e.PrivateImplementationType != null) { - string impl = GetBaseTypeOutput(e.PrivateImplementationType); + string impl = GetBaseTypeOutput(e.PrivateImplementationType, preferBuiltInTypes: false); impl = impl.Replace('.', '_'); e.Name = impl + "_" + e.Name; } @@ -1714,7 +1714,7 @@ namespace Microsoft.VisualBasic string propName = e.Name; if (e.PrivateImplementationType != null) { - string impl = GetBaseTypeOutput(e.PrivateImplementationType); + string impl = GetBaseTypeOutput(e.PrivateImplementationType, preferBuiltInTypes: false); impl = impl.Replace('.', '_'); e.Name = impl + "_" + e.Name; } @@ -2399,80 +2399,56 @@ namespace Microsoft.VisualBasic return name; } - private string GetBaseTypeOutput(CodeTypeReference typeRef) + private string GetBaseTypeOutput(CodeTypeReference typeRef, bool preferBuiltInTypes = true) { string baseType = typeRef.BaseType; - if (baseType.Length == 0) - { - return "Void"; - } - else if (string.Equals(baseType, "System.Byte", StringComparison.OrdinalIgnoreCase)) - { - return "Byte"; - } - else if (string.Equals(baseType, "System.SByte", StringComparison.OrdinalIgnoreCase)) - { - return "SByte"; - } - else if (string.Equals(baseType, "System.Int16", StringComparison.OrdinalIgnoreCase)) - { - return "Short"; - } - else if (string.Equals(baseType, "System.Int32", StringComparison.OrdinalIgnoreCase)) - { - return "Integer"; - } - else if (string.Equals(baseType, "System.Int64", StringComparison.OrdinalIgnoreCase)) - { - return "Long"; - } - else if (string.Equals(baseType, "System.UInt16", StringComparison.OrdinalIgnoreCase)) - { - return "UShort"; - } - else if (string.Equals(baseType, "System.UInt32", StringComparison.OrdinalIgnoreCase)) - { - return "UInteger"; - } - else if (string.Equals(baseType, "System.UInt64", StringComparison.OrdinalIgnoreCase)) - { - return "ULong"; - } - else if (string.Equals(baseType, "System.String", StringComparison.OrdinalIgnoreCase)) - { - return "String"; - } - else if (string.Equals(baseType, "System.DateTime", StringComparison.OrdinalIgnoreCase)) - { - return "Date"; - } - else if (string.Equals(baseType, "System.Decimal", StringComparison.OrdinalIgnoreCase)) - { - return "Decimal"; - } - else if (string.Equals(baseType, "System.Single", StringComparison.OrdinalIgnoreCase)) - { - return "Single"; - } - else if (string.Equals(baseType, "System.Double", StringComparison.OrdinalIgnoreCase)) - { - return "Double"; - } - else if (string.Equals(baseType, "System.Boolean", StringComparison.OrdinalIgnoreCase)) - { - return "Boolean"; - } - else if (string.Equals(baseType, "System.Char", StringComparison.OrdinalIgnoreCase)) - { - return "Char"; - } - else if (string.Equals(baseType, "System.Object", StringComparison.OrdinalIgnoreCase)) - { - return "Object"; + if (preferBuiltInTypes) + { + if (baseType.Length == 0) + { + return "Void"; + } + + string lowerCaseString = baseType.ToLowerInvariant(); + + switch (lowerCaseString) + { + case "system.byte": + return "Byte"; + case "system.sbyte": + return "SByte"; + case "system.int16": + return "Short"; + case "system.int32": + return "Integer"; + case "system.int64": + return "Long"; + case "system.uint16": + return "UShort"; + case "system.uint32": + return "UInteger"; + case "system.uint64": + return "ULong"; + case "system.string": + return "String"; + case "system.datetime": + return "Date"; + case "system.decimal": + return "Decimal"; + case "system.single": + return "Single"; + case "system.double": + return "Double"; + case "system.boolean": + return "Boolean"; + case "system.char": + return "Char"; + case "system.object": + return "Object"; + } } - else - { + var sb = new StringBuilder(baseType.Length + 10); if ((typeRef.Options & CodeTypeReferenceOptions.GlobalReference) != 0) { @@ -2525,7 +2501,6 @@ namespace Microsoft.VisualBasic } return sb.ToString(); - } } private string GetTypeOutputWithoutArrayPostFix(CodeTypeReference typeRef) diff --git a/src/System.CodeDom/tests/CSharpCodeGenerationTests.cs b/src/System.CodeDom/tests/CSharpCodeGenerationTests.cs index bc36ebccaf..38777f60e4 100644 --- a/src/System.CodeDom/tests/CSharpCodeGenerationTests.cs +++ b/src/System.CodeDom/tests/CSharpCodeGenerationTests.cs @@ -448,6 +448,32 @@ namespace System.CodeDom.Tests }"); } + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, ".NET Framework outputs C# keywords rather than type names")] + [Theory] + [InlineData(typeof(byte), "void System.Byte.MyMethod() { }")] + [InlineData(typeof(short), "void System.Int16.MyMethod() { }")] + [InlineData(typeof(ushort), "void System.UInt16.MyMethod() { }")] + [InlineData(typeof(int), "void System.Int32.MyMethod() { }")] + [InlineData(typeof(uint), "void System.UInt32.MyMethod() { }")] + [InlineData(typeof(long), "void System.Int64.MyMethod() { }")] + [InlineData(typeof(ulong), "void System.UInt64.MyMethod() { }")] + [InlineData(typeof(string), "void System.String.MyMethod() { }")] + [InlineData(typeof(object), "void System.Object.MyMethod() { }")] + [InlineData(typeof(bool), "void System.Boolean.MyMethod() { }")] + [InlineData(typeof(void), "void System.Void.MyMethod() { }")] + [InlineData(typeof(char), "void System.Char.MyMethod() { }")] + [InlineData(typeof(float), "void System.Single.MyMethod() { }")] + [InlineData(typeof(double), "void System.Double.MyMethod() { }")] + [InlineData(typeof(decimal), "void System.Decimal.MyMethod() { }")] + public void ExplicitImplementation(Type type, string expectedResult) + { + AssertEqual(new CodeMemberMethod() + { + Name = "MyMethod", + PrivateImplementationType = new CodeTypeReference(type) + }, expectedResult); + } + [Fact] public void Arrays_SingleDimensional_PrimitiveTypes() { diff --git a/src/System.CodeDom/tests/VBCodeGenerationTests.cs b/src/System.CodeDom/tests/VBCodeGenerationTests.cs index 43e752c1b9..619694b8ba 100644 --- a/src/System.CodeDom/tests/VBCodeGenerationTests.cs +++ b/src/System.CodeDom/tests/VBCodeGenerationTests.cs @@ -416,6 +416,32 @@ namespace System.CodeDom.Tests End Namespace"); } + [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, ".NET Framework outputs C# keywords rather than type names")] + [Theory] + [InlineData(typeof(byte), "Sub System_[Byte]_MyMethod() Implements Byte.MyMethod End Sub")] + [InlineData(typeof(short), "Sub System_Int16_MyMethod() Implements Short.MyMethod End Sub")] + [InlineData(typeof(ushort), "Sub System_UInt16_MyMethod() Implements UShort.MyMethod End Sub")] + [InlineData(typeof(int), "Sub System_Int32_MyMethod() Implements Integer.MyMethod End Sub")] + [InlineData(typeof(uint), "Sub System_UInt32_MyMethod() Implements UInteger.MyMethod End Sub")] + [InlineData(typeof(long), "Sub System_Int64_MyMethod() Implements Long.MyMethod End Sub")] + [InlineData(typeof(ulong), "Sub System_UInt64_MyMethod() Implements ULong.MyMethod End Sub")] + [InlineData(typeof(string), "Sub System_[String]_MyMethod() Implements String.MyMethod End Sub")] + [InlineData(typeof(object), "Sub System_[Object]_MyMethod() Implements Object.MyMethod End Sub")] + [InlineData(typeof(bool), "Sub System_[Boolean]_MyMethod() Implements Boolean.MyMethod End Sub")] + [InlineData(typeof(void), "Sub System_Void_MyMethod() Implements System.Void.MyMethod End Sub")] + [InlineData(typeof(char), "Sub System_[Char]_MyMethod() Implements Char.MyMethod End Sub")] + [InlineData(typeof(float), "Sub System_[Single]_MyMethod() Implements Single.MyMethod End Sub")] + [InlineData(typeof(double), "Sub System_[Double]_MyMethod() Implements Double.MyMethod End Sub")] + [InlineData(typeof(decimal), "Sub System_[Decimal]_MyMethod() Implements Decimal.MyMethod End Sub")] + public void ExplicitImplementation_BuiltIns_UsesTypeNamesForBetterCompilerHandling(Type type, string expectedResult) + { + AssertEqual(new CodeMemberMethod() + { + Name = "MyMethod", + PrivateImplementationType = new CodeTypeReference(type) + }, expectedResult); + } + [Fact] public void Arrays_SingleDimensional_PrimitiveTypes() { diff --git a/src/System.Collections.Immutable/src/System.Collections.Immutable.csproj b/src/System.Collections.Immutable/src/System.Collections.Immutable.csproj index 0b0dc67bbf..f13f641d9d 100644 --- a/src/System.Collections.Immutable/src/System.Collections.Immutable.csproj +++ b/src/System.Collections.Immutable/src/System.Collections.Immutable.csproj @@ -6,9 +6,8 @@ <ProjectGuid>{1DD0FF15-6234-4BD6-850A-317F05479554}</ProjectGuid> <AppDesignerFolder>Properties</AppDesignerFolder> <RootNamespace>System.Collections.Immutable</RootNamespace> - <AssemblyName>System.Collections.Immutable</AssemblyName> <FileAlignment>512</FileAlignment> - <DocumentationFile>$(OutputPath)System.Collections.Immutable.xml</DocumentationFile> + <DocumentationFile>$(OutputPath)$(MSBuildProjectName).xml</DocumentationFile> <GenerateAppxPackageOnBuild>False</GenerateAppxPackageOnBuild> <PackageTargetFramework Condition="'$(TargetGroup)' == 'netstandard1.0'">netstandard1.0;portable-net45+win8+wp8+wpa81</PackageTargetFramework> </PropertyGroup> @@ -46,6 +45,7 @@ <Compile Include="System\Collections\Immutable\ImmutableArray_1.Builder.DebuggerProxy.cs" /> <Compile Include="System\Collections\Immutable\ImmutableArray_1.Enumerator.cs" /> <Compile Include="System\Collections\Immutable\ImmutableArray_1.cs" /> + <Compile Include="System\Collections\Immutable\ImmutableArray_1.Minimal.cs" /> <Compile Include="System\Collections\Immutable\ImmutableDictionary.cs" /> <Compile Include="System\Collections\Immutable\ImmutableDictionary_2.Builder.cs" /> <Compile Include="System\Collections\Immutable\ImmutableDictionary_2.Comparers.cs" /> @@ -56,6 +56,7 @@ <Compile Include="System\Collections\Immutable\ImmutableDictionary_2.MutationResult.cs" /> <Compile Include="System\Collections\Immutable\ImmutableDictionary_2.cs" /> <Compile Include="System\Collections\Immutable\ImmutableExtensions.cs" /> + <Compile Include="System\Collections\Immutable\ImmutableExtensions.Minimal.cs" /> <Compile Include="System\Collections\Immutable\ImmutableHashSet.cs" /> <Compile Include="System\Collections\Immutable\ImmutableHashSet_1.Builder.cs" /> <Compile Include="System\Collections\Immutable\ImmutableHashSet_1.DebuggerProxy.cs" /> diff --git a/src/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Minimal.cs b/src/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Minimal.cs new file mode 100644 index 0000000000..b5a30ae825 --- /dev/null +++ b/src/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.Minimal.cs @@ -0,0 +1,426 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.Contracts; +using System.Globalization; +using System.Linq; +using System.Runtime.Versioning; + +namespace System.Collections.Immutable +{ + /// <summary> + /// A readonly array with O(1) indexable lookup time. + /// </summary> + /// <typeparam name="T">The type of element stored by the array.</typeparam> + /// <devremarks> + /// This type has a documented contract of being exactly one reference-type field in size. + /// Our own <see cref="ImmutableInterlocked"/> class depends on it, as well as others externally. + /// IMPORTANT NOTICE FOR MAINTAINERS AND REVIEWERS: + /// This type should be thread-safe. As a struct, it cannot protect its own fields + /// from being changed from one thread while its members are executing on other threads + /// because structs can change *in place* simply by reassigning the field containing + /// this struct. Therefore it is extremely important that + /// ** Every member should only dereference <c>this</c> ONCE. ** + /// If a member needs to reference the array field, that counts as a dereference of <c>this</c>. + /// Calling other instance members (properties or methods) also counts as dereferencing <c>this</c>. + /// Any member that needs to use <c>this</c> more than once must instead + /// assign <c>this</c> to a local variable and use that for the rest of the code instead. + /// This effectively copies the one field in the struct to a local variable so that + /// it is insulated from other threads. + /// </devremarks> + [DebuggerDisplay("{DebuggerDisplay,nq}")] + [NonVersionable] // Applies to field layout + public partial struct ImmutableArray<T> : IEnumerable<T>, IEquatable<ImmutableArray<T>>, IImmutableArray + { + /// <summary> + /// An empty (initialized) instance of <see cref="ImmutableArray{T}"/>. + /// </summary> + public static readonly ImmutableArray<T> Empty = new ImmutableArray<T>(new T[0]); + + /// <summary> + /// The backing field for this instance. References to this value should never be shared with outside code. + /// </summary> + /// <remarks> + /// This would be private, but we make it internal so that our own extension methods can access it. + /// </remarks> + [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] + internal T[] array; + + /// <summary> + /// Initializes a new instance of the <see cref="ImmutableArray{T}"/> struct + /// *without making a defensive copy*. + /// </summary> + /// <param name="items">The array to use. May be null for "default" arrays.</param> + internal ImmutableArray(T[] items) + { + this.array = items; + } + + #region Operators + + /// <summary> + /// Checks equality between two instances. + /// </summary> + /// <param name="left">The instance to the left of the operator.</param> + /// <param name="right">The instance to the right of the operator.</param> + /// <returns><c>true</c> if the values' underlying arrays are reference equal; <c>false</c> otherwise.</returns> + [NonVersionable] + public static bool operator ==(ImmutableArray<T> left, ImmutableArray<T> right) + { + return left.Equals(right); + } + + /// <summary> + /// Checks inequality between two instances. + /// </summary> + /// <param name="left">The instance to the left of the operator.</param> + /// <param name="right">The instance to the right of the operator.</param> + /// <returns><c>true</c> if the values' underlying arrays are reference not equal; <c>false</c> otherwise.</returns> + [NonVersionable] + public static bool operator !=(ImmutableArray<T> left, ImmutableArray<T> right) + { + return !left.Equals(right); + } + + /// <summary> + /// Checks equality between two instances. + /// </summary> + /// <param name="left">The instance to the left of the operator.</param> + /// <param name="right">The instance to the right of the operator.</param> + /// <returns><c>true</c> if the values' underlying arrays are reference equal; <c>false</c> otherwise.</returns> + public static bool operator ==(ImmutableArray<T>? left, ImmutableArray<T>? right) + { + return left.GetValueOrDefault().Equals(right.GetValueOrDefault()); + } + + /// <summary> + /// Checks inequality between two instances. + /// </summary> + /// <param name="left">The instance to the left of the operator.</param> + /// <param name="right">The instance to the right of the operator.</param> + /// <returns><c>true</c> if the values' underlying arrays are reference not equal; <c>false</c> otherwise.</returns> + public static bool operator !=(ImmutableArray<T>? left, ImmutableArray<T>? right) + { + return !left.GetValueOrDefault().Equals(right.GetValueOrDefault()); + } + + #endregion + + /// <summary> + /// Gets the element at the specified index in the read-only list. + /// </summary> + /// <param name="index">The zero-based index of the element to get.</param> + /// <returns>The element at the specified index in the read-only list.</returns> + public T this[int index] + { + [NonVersionable] + get + { + // We intentionally do not check this.array != null, and throw NullReferenceException + // if this is called while uninitialized. + // The reason for this is perf. + // Length and the indexer must be absolutely trivially implemented for the JIT optimization + // of removing array bounds checking to work. + return this.array[index]; + } + } + + /// <summary> + /// Gets a value indicating whether this collection is empty. + /// </summary> + [DebuggerBrowsable(DebuggerBrowsableState.Never)] + public bool IsEmpty + { + [NonVersionable] + get { return this.Length == 0; } + } + + /// <summary> + /// Gets the number of elements in the array. + /// </summary> + [DebuggerBrowsable(DebuggerBrowsableState.Never)] + public int Length + { + [NonVersionable] + get + { + // We intentionally do not check this.array != null, and throw NullReferenceException + // if this is called while uninitialized. + // The reason for this is perf. + // Length and the indexer must be absolutely trivially implemented for the JIT optimization + // of removing array bounds checking to work. + return this.array.Length; + } + } + + /// <summary> + /// Gets a value indicating whether this struct was initialized without an actual array instance. + /// </summary> + [DebuggerBrowsable(DebuggerBrowsableState.Never)] + public bool IsDefault + { + get { return this.array == null; } + } + + /// <summary> + /// Gets a value indicating whether this struct is empty or uninitialized. + /// </summary> + [DebuggerBrowsable(DebuggerBrowsableState.Never)] + public bool IsDefaultOrEmpty + { + get + { + var self = this; + return self.array == null || self.array.Length == 0; + } + } + + /// <summary> + /// Gets an untyped reference to the array. + /// </summary> + [DebuggerBrowsable(DebuggerBrowsableState.Never)] + Array IImmutableArray.Array + { + get { return this.array; } + } + + /// <summary> + /// Gets the string to display in the debugger watches window for this instance. + /// </summary> + [DebuggerBrowsable(DebuggerBrowsableState.Never)] + private string DebuggerDisplay + { + get + { + var self = this; + return self.IsDefault ? "Uninitialized" : String.Format(CultureInfo.CurrentCulture, "Length = {0}", self.Length); + } + } + + /// <summary> + /// Copies the contents of this array to the specified array. + /// </summary> + /// <param name="destination">The array to copy to.</param> + [Pure] + public void CopyTo(T[] destination) + { + var self = this; + self.ThrowNullRefIfNotInitialized(); + Array.Copy(self.array, 0, destination, 0, self.Length); + } + + /// <summary> + /// Copies the contents of this array to the specified array. + /// </summary> + /// <param name="destination">The array to copy to.</param> + /// <param name="destinationIndex">The index into the destination array to which the first copied element is written.</param> + [Pure] + public void CopyTo(T[] destination, int destinationIndex) + { + var self = this; + self.ThrowNullRefIfNotInitialized(); + Array.Copy(self.array, 0, destination, destinationIndex, self.Length); + } + + /// <summary> + /// Copies the contents of this array to the specified array. + /// </summary> + /// <param name="sourceIndex">The index into this collection of the first element to copy.</param> + /// <param name="destination">The array to copy to.</param> + /// <param name="destinationIndex">The index into the destination array to which the first copied element is written.</param> + /// <param name="length">The number of elements to copy.</param> + [Pure] + public void CopyTo(int sourceIndex, T[] destination, int destinationIndex, int length) + { + var self = this; + self.ThrowNullRefIfNotInitialized(); + Array.Copy(self.array, sourceIndex, destination, destinationIndex, length); + } + + /// <summary> + /// Returns a builder that is populated with the same contents as this array. + /// </summary> + /// <returns>The new builder.</returns> + [Pure] + public ImmutableArray<T>.Builder ToBuilder() + { + var self = this; + if (self.Length == 0) + { + return new Builder(); // allow the builder to create itself with a reasonable default capacity + } + + var builder = new Builder(self.Length); + builder.AddRange(self); + return builder; + } + + /// <summary> + /// Returns an enumerator for the contents of the array. + /// </summary> + /// <returns>An enumerator.</returns> + [Pure] + public Enumerator GetEnumerator() + { + var self = this; + self.ThrowNullRefIfNotInitialized(); + return new Enumerator(self.array); + } + + /// <summary> + /// Returns a hash code for this instance. + /// </summary> + /// <returns> + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + /// </returns> + [Pure] + public override int GetHashCode() + { + var self = this; + return self.array == null ? 0 : self.array.GetHashCode(); + } + + /// <summary> + /// Determines whether the specified <see cref="Object"/> is equal to this instance. + /// </summary> + /// <param name="obj">The <see cref="Object"/> to compare with this instance.</param> + /// <returns> + /// <c>true</c> if the specified <see cref="Object"/> is equal to this instance; otherwise, <c>false</c>. + /// </returns> + [Pure] + public override bool Equals(object obj) + { + IImmutableArray other = obj as IImmutableArray; + if (other != null) + { + return this.array == other.Array; + } + + return false; + } + + /// <summary> + /// Indicates whether the current object is equal to another object of the same type. + /// </summary> + /// <param name="other">An object to compare with this object.</param> + /// <returns> + /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false. + /// </returns> + [Pure] + [NonVersionable] + public bool Equals(ImmutableArray<T> other) + { + return this.array == other.array; + } + + /// <summary> + /// Initializes a new instance of the <see cref="ImmutableArray{T}"/> struct based on the contents + /// of an existing instance, allowing a covariant static cast to efficiently reuse the existing array. + /// </summary> + /// <param name="items">The array to initialize the array with. No copy is made.</param> + /// <remarks> + /// Covariant upcasts from this method may be reversed by calling the + /// <see cref="ImmutableArray{T}.As{TOther}"/> or <see cref="ImmutableArray{T}.CastArray{TOther}"/>method. + /// </remarks> + [Pure] + public static ImmutableArray<T> CastUp<TDerived>(ImmutableArray<TDerived> items) + where TDerived : class, T + { + return new ImmutableArray<T>(items.array); + } + + /// <summary> + /// Initializes a new instance of the <see cref="ImmutableArray{T}"/> struct by casting the underlying + /// array to an array of type <typeparam name="TOther"/>. + /// </summary> + /// <exception cref="InvalidCastException">Thrown if the cast is illegal.</exception> + [Pure] + public ImmutableArray<TOther> CastArray<TOther>() where TOther : class + { + return new ImmutableArray<TOther>((TOther[])(object)array); + } + + /// <summary> + /// Creates an immutable array for this array, cast to a different element type. + /// </summary> + /// <typeparam name="TOther">The type of array element to return.</typeparam> + /// <returns> + /// A struct typed for the base element type. If the cast fails, an instance + /// is returned whose <see cref="IsDefault"/> property returns <c>true</c>. + /// </returns> + /// <remarks> + /// Arrays of derived elements types can be cast to arrays of base element types + /// without reallocating the array. + /// These upcasts can be reversed via this same method, casting an array of base + /// element types to their derived types. However, downcasting is only successful + /// when it reverses a prior upcasting operation. + /// </remarks> + [Pure] + public ImmutableArray<TOther> As<TOther>() where TOther : class + { + return new ImmutableArray<TOther>(this.array as TOther[]); + } + + /// <summary> + /// Returns an enumerator for the contents of the array. + /// </summary> + /// <returns>An enumerator.</returns> + /// <exception cref="InvalidOperationException">Thrown if the <see cref="IsDefault"/> property returns true.</exception> + [Pure] + IEnumerator<T> IEnumerable<T>.GetEnumerator() + { + var self = this; + self.ThrowInvalidOperationIfNotInitialized(); + return EnumeratorObject.Create(self.array); + } + + /// <summary> + /// Returns an enumerator for the contents of the array. + /// </summary> + /// <returns>An enumerator.</returns> + /// <exception cref="InvalidOperationException">Thrown if the <see cref="IsDefault"/> property returns true.</exception> + [Pure] + IEnumerator IEnumerable.GetEnumerator() + { + var self = this; + self.ThrowInvalidOperationIfNotInitialized(); + return EnumeratorObject.Create(self.array); + } + + /// <summary> + /// Throws a null reference exception if the array field is null. + /// </summary> + internal void ThrowNullRefIfNotInitialized() + { + // Force NullReferenceException if array is null by touching its Length. + // This way of checking has a nice property of requiring very little code + // and not having any conditions/branches. + // In a faulting scenario we are relying on hardware to generate the fault. + // And in the non-faulting scenario (most common) the check is virtually free since + // if we are going to do anything with the array, we will need Length anyways + // so touching it, and potentially causing a cache miss, is not going to be an + // extra expense. + var unused = this.array.Length; + } + + /// <summary> + /// Throws an <see cref="InvalidOperationException"/> if the <see cref="array"/> field is null, i.e. the + /// <see cref="IsDefault"/> property returns true. The + /// <see cref="InvalidOperationException"/> message specifies that the operation cannot be performed + /// on a default instance of <see cref="ImmutableArray{T}"/>. + /// + /// This is intended for explicitly implemented interface method and property implementations. + /// </summary> + private void ThrowInvalidOperationIfNotInitialized() + { + if (this.IsDefault) + { + throw new InvalidOperationException(SR.InvalidOperationOnDefaultArray); + } + } + } +} diff --git a/src/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.cs b/src/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.cs index c6585b17da..48981cfc7f 100644 --- a/src/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.cs +++ b/src/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableArray_1.cs @@ -12,124 +12,9 @@ using System.Runtime.Versioning; namespace System.Collections.Immutable { - /// <summary> - /// A readonly array with O(1) indexable lookup time. - /// </summary> - /// <typeparam name="T">The type of element stored by the array.</typeparam> - /// <devremarks> - /// This type has a documented contract of being exactly one reference-type field in size. - /// Our own <see cref="ImmutableInterlocked"/> class depends on it, as well as others externally. - /// IMPORTANT NOTICE FOR MAINTAINERS AND REVIEWERS: - /// This type should be thread-safe. As a struct, it cannot protect its own fields - /// from being changed from one thread while its members are executing on other threads - /// because structs can change *in place* simply by reassigning the field containing - /// this struct. Therefore it is extremely important that - /// ** Every member should only dereference <c>this</c> ONCE. ** - /// If a member needs to reference the array field, that counts as a dereference of <c>this</c>. - /// Calling other instance members (properties or methods) also counts as dereferencing <c>this</c>. - /// Any member that needs to use <c>this</c> more than once must instead - /// assign <c>this</c> to a local variable and use that for the rest of the code instead. - /// This effectively copies the one field in the struct to a local variable so that - /// it is insulated from other threads. - /// </devremarks> - [DebuggerDisplay("{DebuggerDisplay,nq}")] - [NonVersionable] // Applies to field layout - public partial struct ImmutableArray<T> : IReadOnlyList<T>, IList<T>, IEquatable<ImmutableArray<T>>, IImmutableList<T>, IList, IImmutableArray, IStructuralComparable, IStructuralEquatable + public partial struct ImmutableArray<T> : IReadOnlyList<T>, IList<T>, IEquatable<ImmutableArray<T>>, IList, IImmutableArray, IStructuralComparable, IStructuralEquatable, IImmutableList<T> { /// <summary> - /// An empty (initialized) instance of <see cref="ImmutableArray{T}"/>. - /// </summary> - public static readonly ImmutableArray<T> Empty = new ImmutableArray<T>(new T[0]); - - /// <summary> - /// The backing field for this instance. References to this value should never be shared with outside code. - /// </summary> - /// <remarks> - /// This would be private, but we make it internal so that our own extension methods can access it. - /// </remarks> - [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] - internal T[] array; - - /// <summary> - /// Initializes a new instance of the <see cref="ImmutableArray{T}"/> struct - /// *without making a defensive copy*. - /// </summary> - /// <param name="items">The array to use. May be null for "default" arrays.</param> - internal ImmutableArray(T[] items) - { - this.array = items; - } - - #region Operators - - /// <summary> - /// Checks equality between two instances. - /// </summary> - /// <param name="left">The instance to the left of the operator.</param> - /// <param name="right">The instance to the right of the operator.</param> - /// <returns><c>true</c> if the values' underlying arrays are reference equal; <c>false</c> otherwise.</returns> - [NonVersionable] - public static bool operator ==(ImmutableArray<T> left, ImmutableArray<T> right) - { - return left.Equals(right); - } - - /// <summary> - /// Checks inequality between two instances. - /// </summary> - /// <param name="left">The instance to the left of the operator.</param> - /// <param name="right">The instance to the right of the operator.</param> - /// <returns><c>true</c> if the values' underlying arrays are reference not equal; <c>false</c> otherwise.</returns> - [NonVersionable] - public static bool operator !=(ImmutableArray<T> left, ImmutableArray<T> right) - { - return !left.Equals(right); - } - - /// <summary> - /// Checks equality between two instances. - /// </summary> - /// <param name="left">The instance to the left of the operator.</param> - /// <param name="right">The instance to the right of the operator.</param> - /// <returns><c>true</c> if the values' underlying arrays are reference equal; <c>false</c> otherwise.</returns> - public static bool operator ==(ImmutableArray<T>? left, ImmutableArray<T>? right) - { - return left.GetValueOrDefault().Equals(right.GetValueOrDefault()); - } - - /// <summary> - /// Checks inequality between two instances. - /// </summary> - /// <param name="left">The instance to the left of the operator.</param> - /// <param name="right">The instance to the right of the operator.</param> - /// <returns><c>true</c> if the values' underlying arrays are reference not equal; <c>false</c> otherwise.</returns> - public static bool operator !=(ImmutableArray<T>? left, ImmutableArray<T>? right) - { - return !left.GetValueOrDefault().Equals(right.GetValueOrDefault()); - } - - #endregion - - /// <summary> - /// Gets the element at the specified index in the read-only list. - /// </summary> - /// <param name="index">The zero-based index of the element to get.</param> - /// <returns>The element at the specified index in the read-only list.</returns> - public T this[int index] - { - [NonVersionable] - get - { - // We intentionally do not check this.array != null, and throw NullReferenceException - // if this is called while uninitialized. - // The reason for this is perf. - // Length and the indexer must be absolutely trivially implemented for the JIT optimization - // of removing array bounds checking to work. - return this.array[index]; - } - } - - /// <summary> /// Gets or sets the element at the specified index in the read-only list. /// </summary> /// <param name="index">The zero-based index of the element to get.</param> @@ -160,34 +45,6 @@ namespace System.Collections.Immutable } /// <summary> - /// Gets a value indicating whether this collection is empty. - /// </summary> - [DebuggerBrowsable(DebuggerBrowsableState.Never)] - public bool IsEmpty - { - [NonVersionable] - get { return this.Length == 0; } - } - - /// <summary> - /// Gets the number of elements in the array. - /// </summary> - [DebuggerBrowsable(DebuggerBrowsableState.Never)] - public int Length - { - [NonVersionable] - get - { - // We intentionally do not check this.array != null, and throw NullReferenceException - // if this is called while uninitialized. - // The reason for this is perf. - // Length and the indexer must be absolutely trivially implemented for the JIT optimization - // of removing array bounds checking to work. - return this.array.Length; - } - } - - /// <summary> /// Gets the number of array in the collection. /// </summary> /// <exception cref="InvalidOperationException">Thrown if the <see cref="IsDefault"/> property returns true.</exception> @@ -236,50 +93,6 @@ namespace System.Collections.Immutable } /// <summary> - /// Gets a value indicating whether this struct was initialized without an actual array instance. - /// </summary> - [DebuggerBrowsable(DebuggerBrowsableState.Never)] - public bool IsDefault - { - get { return this.array == null; } - } - - /// <summary> - /// Gets a value indicating whether this struct is empty or uninitialized. - /// </summary> - [DebuggerBrowsable(DebuggerBrowsableState.Never)] - public bool IsDefaultOrEmpty - { - get - { - var self = this; - return self.array == null || self.array.Length == 0; - } - } - - /// <summary> - /// Gets an untyped reference to the array. - /// </summary> - [DebuggerBrowsable(DebuggerBrowsableState.Never)] - Array IImmutableArray.Array - { - get { return this.array; } - } - - /// <summary> - /// Gets the string to display in the debugger watches window for this instance. - /// </summary> - [DebuggerBrowsable(DebuggerBrowsableState.Never)] - private string DebuggerDisplay - { - get - { - var self = this; - return self.IsDefault ? "Uninitialized" : String.Format(CultureInfo.CurrentCulture, "Length = {0}", self.Length); - } - } - - /// <summary> /// Searches the array for the specified item. /// </summary> /// <param name="item">The item to search for.</param> @@ -476,46 +289,6 @@ namespace System.Collections.Immutable } /// <summary> - /// Copies the contents of this array to the specified array. - /// </summary> - /// <param name="destination">The array to copy to.</param> - [Pure] - public void CopyTo(T[] destination) - { - var self = this; - self.ThrowNullRefIfNotInitialized(); - Array.Copy(self.array, 0, destination, 0, self.Length); - } - - /// <summary> - /// Copies the contents of this array to the specified array. - /// </summary> - /// <param name="destination">The array to copy to.</param> - /// <param name="destinationIndex">The index into the destination array to which the first copied element is written.</param> - [Pure] - public void CopyTo(T[] destination, int destinationIndex) - { - var self = this; - self.ThrowNullRefIfNotInitialized(); - Array.Copy(self.array, 0, destination, destinationIndex, self.Length); - } - - /// <summary> - /// Copies the contents of this array to the specified array. - /// </summary> - /// <param name="sourceIndex">The index into this collection of the first element to copy.</param> - /// <param name="destination">The array to copy to.</param> - /// <param name="destinationIndex">The index into the destination array to which the first copied element is written.</param> - /// <param name="length">The number of elements to copy.</param> - [Pure] - public void CopyTo(int sourceIndex, T[] destination, int destinationIndex, int length) - { - var self = this; - self.ThrowNullRefIfNotInitialized(); - Array.Copy(self.array, sourceIndex, destination, destinationIndex, length); - } - - /// <summary> /// Returns a new array with the specified value inserted at the specified position. /// </summary> /// <param name="index">The 0-based index into the array at which the new item should be added.</param> @@ -1030,131 +803,6 @@ namespace System.Collections.Immutable return self; } - - /// <summary> - /// Returns a builder that is populated with the same contents as this array. - /// </summary> - /// <returns>The new builder.</returns> - [Pure] - public ImmutableArray<T>.Builder ToBuilder() - { - var self = this; - if (self.Length == 0) - { - return new Builder(); // allow the builder to create itself with a reasonable default capacity - } - - var builder = new Builder(self.Length); - builder.AddRange(self); - return builder; - } - - /// <summary> - /// Returns an enumerator for the contents of the array. - /// </summary> - /// <returns>An enumerator.</returns> - [Pure] - public Enumerator GetEnumerator() - { - var self = this; - self.ThrowNullRefIfNotInitialized(); - return new Enumerator(self.array); - } - - /// <summary> - /// Returns a hash code for this instance. - /// </summary> - /// <returns> - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// </returns> - [Pure] - public override int GetHashCode() - { - var self = this; - return self.array == null ? 0 : self.array.GetHashCode(); - } - - /// <summary> - /// Determines whether the specified <see cref="Object"/> is equal to this instance. - /// </summary> - /// <param name="obj">The <see cref="Object"/> to compare with this instance.</param> - /// <returns> - /// <c>true</c> if the specified <see cref="Object"/> is equal to this instance; otherwise, <c>false</c>. - /// </returns> - [Pure] - public override bool Equals(object obj) - { - IImmutableArray other = obj as IImmutableArray; - if (other != null) - { - return this.array == other.Array; - } - - return false; - } - - /// <summary> - /// Indicates whether the current object is equal to another object of the same type. - /// </summary> - /// <param name="other">An object to compare with this object.</param> - /// <returns> - /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false. - /// </returns> - [Pure] - [NonVersionable] - public bool Equals(ImmutableArray<T> other) - { - return this.array == other.array; - } - - /// <summary> - /// Initializes a new instance of the <see cref="ImmutableArray{T}"/> struct based on the contents - /// of an existing instance, allowing a covariant static cast to efficiently reuse the existing array. - /// </summary> - /// <param name="items">The array to initialize the array with. No copy is made.</param> - /// <remarks> - /// Covariant upcasts from this method may be reversed by calling the - /// <see cref="ImmutableArray{T}.As{TOther}"/> or <see cref="ImmutableArray{T}.CastArray{TOther}"/>method. - /// </remarks> - [Pure] - public static ImmutableArray<T> CastUp<TDerived>(ImmutableArray<TDerived> items) - where TDerived : class, T - { - return new ImmutableArray<T>(items.array); - } - - /// <summary> - /// Initializes a new instance of the <see cref="ImmutableArray{T}"/> struct by casting the underlying - /// array to an array of type <typeparam name="TOther"/>. - /// </summary> - /// <exception cref="InvalidCastException">Thrown if the cast is illegal.</exception> - [Pure] - public ImmutableArray<TOther> CastArray<TOther>() where TOther : class - { - return new ImmutableArray<TOther>((TOther[])(object)array); - } - - /// <summary> - /// Creates an immutable array for this array, cast to a different element type. - /// </summary> - /// <typeparam name="TOther">The type of array element to return.</typeparam> - /// <returns> - /// A struct typed for the base element type. If the cast fails, an instance - /// is returned whose <see cref="IsDefault"/> property returns <c>true</c>. - /// </returns> - /// <remarks> - /// Arrays of derived elements types can be cast to arrays of base element types - /// without reallocating the array. - /// These upcasts can be reversed via this same method, casting an array of base - /// element types to their derived types. However, downcasting is only successful - /// when it reverses a prior upcasting operation. - /// </remarks> - [Pure] - public ImmutableArray<TOther> As<TOther>() where TOther : class - { - return new ImmutableArray<TOther>(this.array as TOther[]); - } - /// <summary> /// Filters the elements of this array to those assignable to the specified type. /// </summary> @@ -1208,32 +856,6 @@ namespace System.Collections.Immutable } /// <summary> - /// Returns an enumerator for the contents of the array. - /// </summary> - /// <returns>An enumerator.</returns> - /// <exception cref="InvalidOperationException">Thrown if the <see cref="IsDefault"/> property returns true.</exception> - [Pure] - IEnumerator<T> IEnumerable<T>.GetEnumerator() - { - var self = this; - self.ThrowInvalidOperationIfNotInitialized(); - return EnumeratorObject.Create(self.array); - } - - /// <summary> - /// Returns an enumerator for the contents of the array. - /// </summary> - /// <returns>An enumerator.</returns> - /// <exception cref="InvalidOperationException">Thrown if the <see cref="IsDefault"/> property returns true.</exception> - [Pure] - IEnumerator IEnumerable.GetEnumerator() - { - var self = this; - self.ThrowInvalidOperationIfNotInitialized(); - return EnumeratorObject.Create(self.array); - } - - /// <summary> /// See <see cref="IImmutableList{T}"/> /// </summary> [ExcludeFromCodeCoverage] @@ -1643,37 +1265,6 @@ namespace System.Collections.Immutable #endregion - /// <summary> - /// Throws a null reference exception if the array field is null. - /// </summary> - internal void ThrowNullRefIfNotInitialized() - { - // Force NullReferenceException if array is null by touching its Length. - // This way of checking has a nice property of requiring very little code - // and not having any conditions/branches. - // In a faulting scenario we are relying on hardware to generate the fault. - // And in the non-faulting scenario (most common) the check is virtually free since - // if we are going to do anything with the array, we will need Length anyways - // so touching it, and potentially causing a cache miss, is not going to be an - // extra expense. - var unused = this.array.Length; - } - - /// <summary> - /// Throws an <see cref="InvalidOperationException"/> if the <see cref="array"/> field is null, i.e. the - /// <see cref="IsDefault"/> property returns true. The - /// <see cref="InvalidOperationException"/> message specifies that the operation cannot be performed - /// on a default instance of <see cref="ImmutableArray{T}"/>. - /// - /// This is intended for explicitly implemented interface method and property implementations. - /// </summary> - private void ThrowInvalidOperationIfNotInitialized() - { - if (this.IsDefault) - { - throw new InvalidOperationException(SR.InvalidOperationOnDefaultArray); - } - } /// <summary> /// Returns an array with items at the specified indices removed. diff --git a/src/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableExtensions.Minimal.cs b/src/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableExtensions.Minimal.cs new file mode 100644 index 0000000000..2887d99fd3 --- /dev/null +++ b/src/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableExtensions.Minimal.cs @@ -0,0 +1,181 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; +using System.Diagnostics.Contracts; +using System.Linq; +using System.Reflection; + +namespace System.Collections.Immutable +{ + internal static partial class ImmutableExtensions + { + /// <summary> + /// Tries to divine the number of elements in a sequence without actually enumerating each element. + /// </summary> + /// <typeparam name="T">The type of elements in the sequence.</typeparam> + /// <param name="sequence">The enumerable source.</param> + /// <param name="count">Receives the number of elements in the enumeration, if it could be determined.</param> + /// <returns><c>true</c> if the count could be determined; <c>false</c> otherwise.</returns> + internal static bool TryGetCount<T>(this IEnumerable<T> sequence, out int count) + { + return TryGetCount<T>((IEnumerable)sequence, out count); + } + + /// <summary> + /// Tries to divine the number of elements in a sequence without actually enumerating each element. + /// </summary> + /// <typeparam name="T">The type of elements in the sequence.</typeparam> + /// <param name="sequence">The enumerable source.</param> + /// <param name="count">Receives the number of elements in the enumeration, if it could be determined.</param> + /// <returns><c>true</c> if the count could be determined; <c>false</c> otherwise.</returns> + internal static bool TryGetCount<T>(this IEnumerable sequence, out int count) + { + var collection = sequence as ICollection; + if (collection != null) + { + count = collection.Count; + return true; + } + + var collectionOfT = sequence as ICollection<T>; + if (collectionOfT != null) + { + count = collectionOfT.Count; + return true; + } + + var readOnlyCollection = sequence as IReadOnlyCollection<T>; + if (readOnlyCollection != null) + { + count = readOnlyCollection.Count; + return true; + } + + count = 0; + return false; + } + + /// <summary> + /// Gets the number of elements in the specified sequence, + /// while guaranteeing that the sequence is only enumerated once + /// in total by this method and the caller. + /// </summary> + /// <typeparam name="T">The type of element in the collection.</typeparam> + /// <param name="sequence">The sequence.</param> + /// <returns>The number of elements in the sequence.</returns> + internal static int GetCount<T>(ref IEnumerable<T> sequence) + { + int count; + if (!sequence.TryGetCount(out count)) + { + // We cannot predict the length of the sequence. We must walk the entire sequence + // to find the count. But avoid our caller also having to enumerate by capturing + // the enumeration in a snapshot and passing that back to the caller. + var list = sequence.ToList(); + count = list.Count; + sequence = list; + } + + return count; + } + + /// <summary> + /// Tries to copy the elements in the sequence to the specified array, + /// if the sequence is a well-known collection type. Otherwise, does + /// nothing and returns <c>false</c>. + /// </summary> + /// <typeparam name="T">The type of element in the sequence.</typeparam> + /// <param name="sequence">The sequence to copy.</param> + /// <param name="array">The array to copy the elements to.</param> + /// <param name="arrayIndex">The index in the array to start copying.</param> + /// <returns><c>true</c> if the elements were successfully copied; <c>false</c> otherwise.</returns> + /// <remarks> + /// <para> + /// The reason we don't copy anything other than for well-known types is that a malicious interface + /// implementation of <see cref="ICollection{T}"/> could hold on to the array when its <see cref="ICollection{T}.CopyTo"/> + /// method is called. If the array it holds onto underlies an <see cref="ImmutableArray{T}"/>, it could violate + /// immutability by modifying the array. + /// </para> + /// </remarks> + internal static bool TryCopyTo<T>(this IEnumerable<T> sequence, T[] array, int arrayIndex) + { + Debug.Assert(sequence != null); + Debug.Assert(array != null); + Debug.Assert(arrayIndex >= 0 && arrayIndex <= array.Length); + + // IList is the GCD of what the following types implement. + var listInterface = sequence as IList<T>; + if (listInterface != null) + { + var list = sequence as List<T>; + if (list != null) + { + list.CopyTo(array, arrayIndex); + return true; + } + + // Array.Copy can throw an ArrayTypeMismatchException if the underlying type of + // the destination array is not typeof(T[]), but is assignment-compatible with T[]. + // See https://github.com/dotnet/corefx/issues/2241 for more info. + if (sequence.GetType() == typeof(T[])) + { + var sourceArray = (T[])sequence; + Array.Copy(sourceArray, 0, array, arrayIndex, sourceArray.Length); + return true; + } + + if (sequence is ImmutableArray<T>) + { + var immutable = (ImmutableArray<T>)sequence; + Array.Copy(immutable.array, 0, array, arrayIndex, immutable.Length); + return true; + } + } + + return false; + } + + /// <summary> + /// Gets a copy of a sequence as an array. + /// </summary> + /// <typeparam name="T">The type of element.</typeparam> + /// <param name="sequence">The sequence to be copied.</param> + /// <param name="count">The number of elements in the sequence.</param> + /// <returns>The array.</returns> + /// <remarks> + /// This is more efficient than the <see cref="Enumerable.ToArray{TSource}"/> extension method + /// because that only tries to cast the sequence to <see cref="ICollection{T}"/> to determine + /// the count before it falls back to reallocating arrays as it enumerates. + /// </remarks> + internal static T[] ToArray<T>(this IEnumerable<T> sequence, int count) + { + Requires.NotNull(sequence, nameof(sequence)); + Requires.Range(count >= 0, nameof(count)); + + if (count == 0) + { + return ImmutableArray<T>.Empty.array; + } + + T[] array = new T[count]; + + if (!sequence.TryCopyTo(array, 0)) + { + int i = 0; + foreach (var item in sequence) + { + Requires.Argument(i < count); + array[i++] = item; + } + + Requires.Argument(i == count); + } + + return array; + } + } +} diff --git a/src/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableExtensions.cs b/src/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableExtensions.cs index 783192bbd5..4f0a711ca7 100644 --- a/src/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableExtensions.cs +++ b/src/System.Collections.Immutable/src/System/Collections/Immutable/ImmutableExtensions.cs @@ -14,172 +14,8 @@ namespace System.Collections.Immutable /// <summary> /// Extension methods for immutable types. /// </summary> - internal static class ImmutableExtensions + internal static partial class ImmutableExtensions { - /// <summary> - /// Tries to divine the number of elements in a sequence without actually enumerating each element. - /// </summary> - /// <typeparam name="T">The type of elements in the sequence.</typeparam> - /// <param name="sequence">The enumerable source.</param> - /// <param name="count">Receives the number of elements in the enumeration, if it could be determined.</param> - /// <returns><c>true</c> if the count could be determined; <c>false</c> otherwise.</returns> - internal static bool TryGetCount<T>(this IEnumerable<T> sequence, out int count) - { - return TryGetCount<T>((IEnumerable)sequence, out count); - } - - /// <summary> - /// Tries to divine the number of elements in a sequence without actually enumerating each element. - /// </summary> - /// <typeparam name="T">The type of elements in the sequence.</typeparam> - /// <param name="sequence">The enumerable source.</param> - /// <param name="count">Receives the number of elements in the enumeration, if it could be determined.</param> - /// <returns><c>true</c> if the count could be determined; <c>false</c> otherwise.</returns> - internal static bool TryGetCount<T>(this IEnumerable sequence, out int count) - { - var collection = sequence as ICollection; - if (collection != null) - { - count = collection.Count; - return true; - } - - var collectionOfT = sequence as ICollection<T>; - if (collectionOfT != null) - { - count = collectionOfT.Count; - return true; - } - - var readOnlyCollection = sequence as IReadOnlyCollection<T>; - if (readOnlyCollection != null) - { - count = readOnlyCollection.Count; - return true; - } - - count = 0; - return false; - } - - /// <summary> - /// Gets the number of elements in the specified sequence, - /// while guaranteeing that the sequence is only enumerated once - /// in total by this method and the caller. - /// </summary> - /// <typeparam name="T">The type of element in the collection.</typeparam> - /// <param name="sequence">The sequence.</param> - /// <returns>The number of elements in the sequence.</returns> - internal static int GetCount<T>(ref IEnumerable<T> sequence) - { - int count; - if (!sequence.TryGetCount(out count)) - { - // We cannot predict the length of the sequence. We must walk the entire sequence - // to find the count. But avoid our caller also having to enumerate by capturing - // the enumeration in a snapshot and passing that back to the caller. - var list = sequence.ToList(); - count = list.Count; - sequence = list; - } - - return count; - } - - /// <summary> - /// Tries to copy the elements in the sequence to the specified array, - /// if the sequence is a well-known collection type. Otherwise, does - /// nothing and returns <c>false</c>. - /// </summary> - /// <typeparam name="T">The type of element in the sequence.</typeparam> - /// <param name="sequence">The sequence to copy.</param> - /// <param name="array">The array to copy the elements to.</param> - /// <param name="arrayIndex">The index in the array to start copying.</param> - /// <returns><c>true</c> if the elements were successfully copied; <c>false</c> otherwise.</returns> - /// <remarks> - /// <para> - /// The reason we don't copy anything other than for well-known types is that a malicious interface - /// implementation of <see cref="ICollection{T}"/> could hold on to the array when its <see cref="ICollection{T}.CopyTo"/> - /// method is called. If the array it holds onto underlies an <see cref="ImmutableArray{T}"/>, it could violate - /// immutability by modifying the array. - /// </para> - /// </remarks> - internal static bool TryCopyTo<T>(this IEnumerable<T> sequence, T[] array, int arrayIndex) - { - Debug.Assert(sequence != null); - Debug.Assert(array != null); - Debug.Assert(arrayIndex >= 0 && arrayIndex <= array.Length); - - // IList is the GCD of what the following types implement. - var listInterface = sequence as IList<T>; - if (listInterface != null) - { - var list = sequence as List<T>; - if (list != null) - { - list.CopyTo(array, arrayIndex); - return true; - } - - // Array.Copy can throw an ArrayTypeMismatchException if the underlying type of - // the destination array is not typeof(T[]), but is assignment-compatible with T[]. - // See https://github.com/dotnet/corefx/issues/2241 for more info. - if (sequence.GetType() == typeof(T[])) - { - var sourceArray = (T[])sequence; - Array.Copy(sourceArray, 0, array, arrayIndex, sourceArray.Length); - return true; - } - - if (sequence is ImmutableArray<T>) - { - var immutable = (ImmutableArray<T>)sequence; - Array.Copy(immutable.array, 0, array, arrayIndex, immutable.Length); - return true; - } - } - - return false; - } - - /// <summary> - /// Gets a copy of a sequence as an array. - /// </summary> - /// <typeparam name="T">The type of element.</typeparam> - /// <param name="sequence">The sequence to be copied.</param> - /// <param name="count">The number of elements in the sequence.</param> - /// <returns>The array.</returns> - /// <remarks> - /// This is more efficient than the <see cref="Enumerable.ToArray{TSource}"/> extension method - /// because that only tries to cast the sequence to <see cref="ICollection{T}"/> to determine - /// the count before it falls back to reallocating arrays as it enumerates. - /// </remarks> - internal static T[] ToArray<T>(this IEnumerable<T> sequence, int count) - { - Requires.NotNull(sequence, nameof(sequence)); - Requires.Range(count >= 0, nameof(count)); - - if (count == 0) - { - return ImmutableArray<T>.Empty.array; - } - - T[] array = new T[count]; - - if (!sequence.TryCopyTo(array, 0)) - { - int i = 0; - foreach (var item in sequence) - { - Requires.Argument(i < count); - array[i++] = item; - } - - Requires.Argument(i == count); - } - - return array; - } #if EqualsStructurally diff --git a/src/System.Collections/src/System.Collections.csproj b/src/System.Collections/src/System.Collections.csproj index 4aa0a05cae..8047db6726 100644 --- a/src/System.Collections/src/System.Collections.csproj +++ b/src/System.Collections/src/System.Collections.csproj @@ -6,8 +6,6 @@ <AssemblyName>System.Collections</AssemblyName> <AllowUnsafeBlocks>true</AllowUnsafeBlocks> <IsPartialFacadeAssembly>true</IsPartialFacadeAssembly> - <!-- 436 is thrown because BitArray conflict with corelib --> - <NoWarn>0436</NoWarn> </PropertyGroup> <!-- Default configurations to help VS understand the options --> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Unix-Debug|AnyCPU'" /> diff --git a/src/System.Collections/src/System/Collections/BitArray.cs b/src/System.Collections/src/System/Collections/BitArray.cs index 819bf18a2d..75bc51996e 100644 --- a/src/System.Collections/src/System/Collections/BitArray.cs +++ b/src/System.Collections/src/System/Collections/BitArray.cs @@ -527,7 +527,7 @@ namespace System.Collections Array.Copy(m_array, 0, intArray, index, GetArrayLength(m_length, BitsPerInt32) - 1); // the last int needs to be masked - intArray[index + last] = m_array[last] & ((1 << extraBits) - 1); + intArray[index + last] = m_array[last] & unchecked((1 << extraBits) - 1); } } else if (array is byte[]) diff --git a/src/System.Collections/tests/Generic/SortedSet/SortedSet.Generic.Tests.cs b/src/System.Collections/tests/Generic/SortedSet/SortedSet.Generic.Tests.cs index 4a8532fbf6..2d255fc7ab 100644 --- a/src/System.Collections/tests/Generic/SortedSet/SortedSet.Generic.Tests.cs +++ b/src/System.Collections/tests/Generic/SortedSet/SortedSet.Generic.Tests.cs @@ -83,14 +83,19 @@ namespace System.Collections.Tests [MemberData(nameof(ValidCollectionSizes))] public void SortedSet_Generic_MaxAndMin(int setLength) { + SortedSet<T> set = (SortedSet<T>)GenericISetFactory(setLength); if (setLength > 0) { - SortedSet<T> set = (SortedSet<T>)GenericISetFactory(setLength); List<T> expected = set.ToList(); expected.Sort(GetIComparer()); Assert.Equal(expected[0], set.Min); Assert.Equal(expected[setLength - 1], set.Max); } + else + { + Assert.Equal(default(T), set.Min); + Assert.Equal(default(T), set.Max); + } } #endregion @@ -197,6 +202,13 @@ namespace System.Collections.Tests Assert.Equal(setLength, set.Count); } + [Fact] + public void SortedSet_Generic_RemoveWhere_NullPredicate_ThrowsArgumentNullException() + { + SortedSet<T> set = (SortedSet<T>)GenericISetFactory(); + Assert.Throws<ArgumentNullException>("match", () => set.RemoveWhere(null)); + } + #endregion #region Enumeration and Ordering diff --git a/src/System.Collections/tests/Generic/SortedSet/SortedSet.TreeSubSet.Tests.cs b/src/System.Collections/tests/Generic/SortedSet/SortedSet.TreeSubSet.Tests.cs new file mode 100644 index 0000000000..196ab3cc97 --- /dev/null +++ b/src/System.Collections/tests/Generic/SortedSet/SortedSet.TreeSubSet.Tests.cs @@ -0,0 +1,80 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Linq; +using Xunit; + +namespace System.Collections.Tests +{ + public class SortedSet_TreeSubset_Int_Tests : SortedSet_TreeSubset_Tests<int> + { + protected override int Min => int.MinValue; + protected override int Max => int.MaxValue; + + protected override bool DefaultValueAllowed => true; + + protected override int CreateT(int seed) + { + Random rand = new Random(seed); + return rand.Next(); + } + } + + public class SortedSet_TreeSubset_String_Tests : SortedSet_TreeSubset_Tests<string> + { + protected override string Min => 0.ToString().PadLeft(10); + protected override string Max => int.MaxValue.ToString().PadLeft(10); + private int _current = 1; + + protected override string CreateT(int seed) + { + return _current++.ToString().PadLeft(10); + } + + public override void ICollection_Generic_Remove_DefaultValueContainedInCollection(int count) + { + if (!IsReadOnly && !AddRemoveClear_ThrowsNotSupported && DefaultValueAllowed && !Enumerable.Contains(InvalidValues, default(string))) + { + int seed = count * 21; + ICollection<string> collection = GenericICollectionFactory(count); + Assert.Throws<ArgumentOutOfRangeException>("item", () => collection.Remove(default(string))); + } + } + + public override void ICollection_Generic_Contains_DefaultValueOnCollectionContainingDefaultValue(int count) + { + if (DefaultValueAllowed && !IsReadOnly && !AddRemoveClear_ThrowsNotSupported) + { + ICollection<string> collection = GenericICollectionFactory(count); + Assert.Throws<ArgumentOutOfRangeException>("item", () => collection.Add(default(string))); + } + } + } + + public abstract class SortedSet_TreeSubset_Tests<T> : SortedSet_Generic_Tests<T> + { + protected abstract T Min { get; } + protected abstract T Max { get; } + private SortedSet<T> OriginalSet { get; set; } + + protected override ISet<T> GenericISetFactory() + { + OriginalSet = new SortedSet<T>(); + return OriginalSet.GetViewBetween(Min, Max); + } + + public override void ICollection_Generic_Add_DefaultValue(int count) + { + // Adding an item to a TreeSubset does nothing - it updates the parent. + if (DefaultValueAllowed && !IsReadOnly && !AddRemoveClear_ThrowsNotSupported) + { + ICollection<T> collection = GenericICollectionFactory(count); + collection.Add(default(T)); + Assert.Equal(count, collection.Count); + Assert.Equal(count + 1, OriginalSet.Count); + } + } + } +} diff --git a/src/System.Collections/tests/System.Collections.Tests.csproj b/src/System.Collections/tests/System.Collections.Tests.csproj index 6ba7cbcb58..ba2001458b 100644 --- a/src/System.Collections/tests/System.Collections.Tests.csproj +++ b/src/System.Collections/tests/System.Collections.Tests.csproj @@ -67,6 +67,7 @@ <Link>Common\System\ObjectCloner.cs</Link> </Compile> <!-- Generic tests --> + <Compile Include="Generic\SortedSet\SortedSet.TreeSubSet.Tests.cs" /> <Compile Include="StructuralComparisonsTests.cs" /> <Compile Include="BitArray\BitArray_CtorTests.cs" /> <Compile Include="BitArray\BitArray_GetSetTests.cs" /> diff --git a/src/System.Composition/demos/Microsoft.Composition.Demos.ExtendedCollectionImports/Microsoft.Composition.Demos.ExtendedCollectionImports.csproj b/src/System.Composition/demos/Microsoft.Composition.Demos.ExtendedCollectionImports/Microsoft.Composition.Demos.ExtendedCollectionImports.csproj index e25ebe862b..635ebdcae3 100644 --- a/src/System.Composition/demos/Microsoft.Composition.Demos.ExtendedCollectionImports/Microsoft.Composition.Demos.ExtendedCollectionImports.csproj +++ b/src/System.Composition/demos/Microsoft.Composition.Demos.ExtendedCollectionImports/Microsoft.Composition.Demos.ExtendedCollectionImports.csproj @@ -6,7 +6,6 @@ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> <PropertyGroup> <ProjectGuid>{44C7E52C-3873-4C64-875C-8A23A8376D60}</ProjectGuid> - <NoWarn>0436</NoWarn> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Release|AnyCPU'" /> diff --git a/src/System.Composition/scenarios/TestLibrary/TestClass.cs b/src/System.Composition/scenarios/TestLibrary/TestClass.cs index bfe6392fc2..1028071213 100644 --- a/src/System.Composition/scenarios/TestLibrary/TestClass.cs +++ b/src/System.Composition/scenarios/TestLibrary/TestClass.cs @@ -10,7 +10,6 @@ using System.Composition; namespace TestLibrary { [Export] - [CLSCompliant(false)] public class ClassWithDependecy { public TestDependency _dep; @@ -22,7 +21,6 @@ namespace TestLibrary } [Export] - [CLSCompliant(false)] public class ClassWithDependecyAndSameBaseType { public IDependency _dep; diff --git a/src/System.Composition/scenarios/TestLibrary/TestLibrary.csproj b/src/System.Composition/scenarios/TestLibrary/TestLibrary.csproj index 611d4f165a..b393d2adad 100644 --- a/src/System.Composition/scenarios/TestLibrary/TestLibrary.csproj +++ b/src/System.Composition/scenarios/TestLibrary/TestLibrary.csproj @@ -6,7 +6,6 @@ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> <PropertyGroup> <ProjectGuid>{DA6841A5-0344-4CC7-98B0-89CBEE18DEE3}</ProjectGuid> - <NoWarn>0436,3021</NoWarn> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Debug|AnyCPU'" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Release|AnyCPU'" /> diff --git a/src/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj b/src/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj index 64778030fa..1c93fe47e9 100644 --- a/src/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj +++ b/src/System.Configuration.ConfigurationManager/tests/System.Configuration.ConfigurationManager.Tests.csproj @@ -90,6 +90,7 @@ <Compile Include="System\Configuration\TempConfig.cs" /> <Compile Include="System\Configuration\TestData.cs" /> <Compile Include="System\Configuration\TypeUtilTests.cs" /> + <Compile Include="System\Configuration\UriSectionTests.cs" /> <Compile Include="System\Configuration\ValidatiorUtilsTests.cs" /> </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> diff --git a/src/System.Configuration.ConfigurationManager/tests/System/Configuration/UriSectionTests.cs b/src/System.Configuration.ConfigurationManager/tests/System/Configuration/UriSectionTests.cs new file mode 100644 index 0000000000..d63ea2ebb8 --- /dev/null +++ b/src/System.Configuration.ConfigurationManager/tests/System/Configuration/UriSectionTests.cs @@ -0,0 +1,53 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Configuration; +using Xunit; + +namespace System.ConfigurationTests +{ + public class UriSectionTests + { + public static string UriSectionConfiguration = +@"<?xml version='1.0' encoding='utf-8' ?> +<configuration> + <configSections> + <section name='uri' type='System.Configuration.UriSection, System' /> + </configSections> + <uri> + <idn enabled='All' /> + <iriParsing enabled='true' /> + <schemeSettings> + <add name='ftp' genericUriParserOptions='DontCompressPath' /> + </schemeSettings> + </uri> +</configuration>"; + + [Fact] + public void UriSectionIdnIriParsing() + { + using (var temp = new TempConfig(UriSectionConfiguration)) + { + var config = ConfigurationManager.OpenExeConfiguration(temp.ExePath); + UriSection uriSection = (UriSection)config.GetSection("uri"); + Assert.Equal(UriIdnScope.All, uriSection.Idn.Enabled); + Assert.Equal(true, uriSection.IriParsing.Enabled); + } + } + + [Fact] + public void UriSectionSchemeSettings() + { + using (var temp = new TempConfig(UriSectionConfiguration)) + { + var config = ConfigurationManager.OpenExeConfiguration(temp.ExePath); + UriSection uriSection = (UriSection)config.GetSection("uri"); + Assert.Equal(1, uriSection.SchemeSettings.Count); + SchemeSettingElement schemeSettingElement = uriSection.SchemeSettings[0]; + Assert.Equal("ftp", schemeSettingElement.Name); + Assert.Equal(GenericUriParserOptions.DontCompressPath, schemeSettingElement.GenericUriParserOptions); + } + } + } +}
\ No newline at end of file diff --git a/src/System.Data.Common/src/System/Data/RbTree.cs b/src/System.Data.Common/src/System/Data/RbTree.cs index dd7549911c..230f4c514e 100644 --- a/src/System.Data.Common/src/System/Data/RbTree.cs +++ b/src/System.Data.Common/src/System/Data/RbTree.cs @@ -1991,10 +1991,10 @@ namespace System.Data segmentPos = _nextFreeSlotLine; while (segmentPos < _slotMap.Length) { - if (((uint)_slotMap[segmentPos]) < 0xFFFFFFFF) + if (unchecked((uint)_slotMap[segmentPos]) < 0xFFFFFFFF) { freeSlotId = 0; - freeSlot = (~(_slotMap[segmentPos])) & (_slotMap[segmentPos] + 1); + freeSlot = (~(_slotMap[segmentPos])) & unchecked(_slotMap[segmentPos] + 1); // avoid string concat to allow debug code to run faster Debug.Assert((_slotMap[segmentPos] & freeSlot) == 0, "Slot position segment[segmentPos ]: [freeSlot] is in use. Expected to be empty"); @@ -2006,7 +2006,7 @@ namespace System.Data tree._inUseNodeCount++; // convert freeSlotPos to int value giving number of 0's to its right i.e. freeSlotId - freeSlotId = GetIntValueFromBitMap((uint)freeSlot); + freeSlotId = GetIntValueFromBitMap(unchecked((uint)freeSlot)); _nextFreeSlotLine = segmentPos; freeSlotId = (segmentPos * TreePage.slotLineSize) + freeSlotId; diff --git a/src/System.Data.Common/src/System/Data/SQLTypes/SQLByte.cs b/src/System.Data.Common/src/System/Data/SQLTypes/SQLByte.cs index bd0d1fe420..68fcdc33e7 100644 --- a/src/System.Data.Common/src/System/Data/SQLTypes/SQLByte.cs +++ b/src/System.Data.Common/src/System/Data/SQLTypes/SQLByte.cs @@ -84,7 +84,7 @@ namespace System.Data.SqlTypes // Unary operators public static SqlByte operator ~(SqlByte x) { - return x.IsNull ? Null : new SqlByte((byte)~x._value); + return x.IsNull ? Null : new SqlByte(unchecked((byte)~x._value)); } diff --git a/src/System.Data.Common/src/System/Data/SQLTypes/SQLDecimal.cs b/src/System.Data.Common/src/System/Data/SQLTypes/SQLDecimal.cs index 1304d66db1..20f83d398e 100644 --- a/src/System.Data.Common/src/System/Data/SQLTypes/SQLDecimal.cs +++ b/src/System.Data.Common/src/System/Data/SQLTypes/SQLDecimal.cs @@ -488,12 +488,16 @@ namespace System.Data.SqlTypes // m_data2 = *pInt++; // mid part int[] bits = decimal.GetBits(value); + uint sgnscl; - uint sgnscl = (uint)bits[3]; - _data1 = (uint)bits[0]; - _data2 = (uint)bits[1]; - _data3 = (uint)bits[2]; - _data4 = s_uiZero; + unchecked + { + sgnscl = (uint)bits[3]; + _data1 = (uint)bits[0]; + _data2 = (uint)bits[1]; + _data3 = (uint)bits[2]; + _data4 = s_uiZero; + } // set the sign bit _bStatus |= ((sgnscl & 0x80000000) == 0x80000000) ? s_bNegative : (byte)0; @@ -523,7 +527,7 @@ namespace System.Data.SqlTypes // set the null bit _bStatus = s_bNotNull; - uint uiValue = (uint)value; + uint uiValue = unchecked((uint)value); // set the sign bit if (value < 0) @@ -548,7 +552,7 @@ namespace System.Data.SqlTypes // set the null bit _bStatus = s_bNotNull; - ulong dwl = (ulong)value; + ulong dwl = unchecked((ulong)value); // set the sign bit if (value < 0) @@ -861,7 +865,11 @@ namespace System.Data.SqlTypes { if (IsNull) throw new SqlNullValueException(); - return new int[4] { (int)_data1, (int)_data2, (int)_data3, (int)_data4 }; + + unchecked + { + return new int[4] { (int)_data1, (int)_data2, (int)_data3, (int)_data4 }; + } } } @@ -1135,7 +1143,10 @@ namespace System.Data.SqlTypes if ((int)_data4 != 0 || _bScale > 28) throw new OverflowException(SQLResource.s_conversionOverflowMessage); - return new decimal((int)_data1, (int)_data2, (int)_data3, !IsPositive, _bScale); + unchecked + { + return new decimal((int)_data1, (int)_data2, (int)_data3, !IsPositive, _bScale); + } } // Implicit conversion from Decimal to SqlDecimal @@ -1272,7 +1283,7 @@ namespace System.Data.SqlTypes if (iulData < culOp2) dwlAccum += rglData2[iulData]; - rglData1[iulData] = (uint)dwlAccum; // equiv to mod x_lInt32Base + rglData1[iulData] = unchecked((uint)dwlAccum); // equiv to mod x_lInt32Base dwlAccum >>= 32; // equiv to div x_lInt32Base } @@ -1317,7 +1328,7 @@ namespace System.Data.SqlTypes if (iulData < culOp2) dwlAccum -= rglData2[iulData]; - rglData1[iulData] = (uint)dwlAccum; // equiv to mod BaseUI4 + rglData1[iulData] = unchecked((uint)dwlAccum); // equiv to mod BaseUI4 if (rglData1[iulData] != 0) iulLastNonZero = iulData; dwlAccum >>= 32; // equiv to /= BaseUI4 @@ -1474,7 +1485,7 @@ namespace System.Data.SqlTypes dwlNextAccum = 0; // Update result and accum - rgulRes[idRes++] = (uint)(dwlAccum);// & x_ulInt32BaseForMod); // equiv to mod x_lInt32Base + rgulRes[idRes++] = unchecked((uint)dwlAccum);// & x_ulInt32BaseForMod); // equiv to mod x_lInt32Base dwlAccum = (dwlAccum >> 32) + dwlNextAccum; // equiv to div BaseUI4 + dwlNAccum // dwlNextAccum can't overflow next iteration @@ -2137,8 +2148,8 @@ namespace System.Data.SqlTypes dwlNextAccum = s_ulInt32Base; // how much to add to dwlAccum after div x_dwlBaseUI4 else dwlNextAccum = 0; - rguiData[iData] = (uint)dwlAccum; // equivalent to mod x_dwlBaseUI4 - dwlAccum = (dwlAccum >> 32) + dwlNextAccum; // equivalent to div x_dwlBaseUI4 + rguiData[iData] = unchecked((uint)dwlAccum); // equivalent to mod x_dwlBaseUI4 + dwlAccum = (dwlAccum >> 32) + dwlNextAccum; // equivalent to div x_dwlBaseUI4 } // If any carry, diff --git a/src/System.Data.Common/src/System/Data/SQLTypes/SQLInt16.cs b/src/System.Data.Common/src/System/Data/SQLTypes/SQLInt16.cs index 813fc41232..780bc216f1 100644 --- a/src/System.Data.Common/src/System/Data/SQLTypes/SQLInt16.cs +++ b/src/System.Data.Common/src/System/Data/SQLTypes/SQLInt16.cs @@ -173,7 +173,7 @@ namespace System.Data.SqlTypes public static SqlInt16 operator |(SqlInt16 x, SqlInt16 y) { - return (x.IsNull || y.IsNull) ? Null : new SqlInt16((short)((ushort)x._value | (ushort)y._value)); + return (x.IsNull || y.IsNull) ? Null : new SqlInt16(unchecked((short)((ushort)x._value | (ushort)y._value))); } public static SqlInt16 operator ^(SqlInt16 x, SqlInt16 y) diff --git a/src/System.Data.Common/src/System/Data/SQLTypes/SQLMoney.cs b/src/System.Data.Common/src/System/Data/SQLTypes/SQLMoney.cs index 60244ab530..0f28570582 100644 --- a/src/System.Data.Common/src/System/Data/SQLTypes/SQLMoney.cs +++ b/src/System.Data.Common/src/System/Data/SQLTypes/SQLMoney.cs @@ -137,7 +137,7 @@ namespace System.Data.SqlTypes if (_value < 0) { fNegative = true; - value = -_value; + value = unchecked(-_value); } return new decimal(unchecked((int)value), unchecked((int)(value >> 32)), 0, fNegative, (byte)s_iMoneyScale); diff --git a/src/System.Data.SqlClient/tests/StressTests/System.Data.StressFramework/System.Data.StressFramework.csproj b/src/System.Data.SqlClient/tests/StressTests/System.Data.StressFramework/System.Data.StressFramework.csproj index 2e47a6ff89..af80e9993b 100644 --- a/src/System.Data.SqlClient/tests/StressTests/System.Data.StressFramework/System.Data.StressFramework.csproj +++ b/src/System.Data.SqlClient/tests/StressTests/System.Data.StressFramework/System.Data.StressFramework.csproj @@ -22,7 +22,6 @@ <Compile Include="TrackedRandom.cs" /> </ItemGroup> <ItemGroup> - <None Include="project.json" /> <None Include="StressTest.config"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </None> diff --git a/src/System.Data.SqlClient/tests/Tools/TDS/TDS.Servers/TDS.Servers.csproj b/src/System.Data.SqlClient/tests/Tools/TDS/TDS.Servers/TDS.Servers.csproj index aa37c9dfc3..b219d3e406 100644 --- a/src/System.Data.SqlClient/tests/Tools/TDS/TDS.Servers/TDS.Servers.csproj +++ b/src/System.Data.SqlClient/tests/Tools/TDS/TDS.Servers/TDS.Servers.csproj @@ -24,7 +24,6 @@ <Compile Include="RoutingTDSServerArguments.cs" /> <Compile Include="ServerNameFilterType.cs" /> <Compile Include="TDSServerArguments.cs" /> - <None Include="project.json" /> <None Include="TdsServerCertificate.pfx"> <CopyToOutputDirectory>Always</CopyToOutputDirectory> </None> diff --git a/src/System.Data.SqlClient/tests/Tools/TDS/TDS/TDS.csproj b/src/System.Data.SqlClient/tests/Tools/TDS/TDS/TDS.csproj index 8a393e195d..9cae0448df 100644 --- a/src/System.Data.SqlClient/tests/Tools/TDS/TDS/TDS.csproj +++ b/src/System.Data.SqlClient/tests/Tools/TDS/TDS/TDS.csproj @@ -105,7 +105,6 @@ <Compile Include="TDSUtilities.cs" /> <Compile Include="TDSVersion.cs" /> <Compile Include="TransactionIsolationLevelType.cs" /> - <None Include="project.json" /> </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> </Project>
\ No newline at end of file diff --git a/src/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj b/src/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj index 09b862bd7b..bef2163241 100644 --- a/src/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj +++ b/src/System.Diagnostics.DiagnosticSource/src/System.Diagnostics.DiagnosticSource.csproj @@ -3,8 +3,7 @@ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> <PropertyGroup> <ProjectGuid>{F24D3391-2928-4E83-AADE-B34423498750}</ProjectGuid> - <AssemblyName>System.Diagnostics.DiagnosticSource</AssemblyName> - <DocumentationFile>$(OutputPath)$(AssemblyName).xml</DocumentationFile> + <DocumentationFile>$(OutputPath)$(MSBuildProjectName).xml</DocumentationFile> <UseOpenKey Condition="'$(UseOpenKey)'==''">true</UseOpenKey> <!-- duplicate in net46 folder so older nuget clients can consume --> <PackageTargetFramework Condition="'$(TargetGroup)' == 'netstandard1.3'">netstandard1.3;net46</PackageTargetFramework> diff --git a/src/System.Diagnostics.FileVersionInfo/tests/System.Diagnostics.FileVersionInfo.TestAssembly/System.Diagnostics.FileVersionInfo.TestAssembly.csproj b/src/System.Diagnostics.FileVersionInfo/tests/System.Diagnostics.FileVersionInfo.TestAssembly/System.Diagnostics.FileVersionInfo.TestAssembly.csproj index 9beb0abe55..926656bf3d 100644 --- a/src/System.Diagnostics.FileVersionInfo/tests/System.Diagnostics.FileVersionInfo.TestAssembly/System.Diagnostics.FileVersionInfo.TestAssembly.csproj +++ b/src/System.Diagnostics.FileVersionInfo/tests/System.Diagnostics.FileVersionInfo.TestAssembly/System.Diagnostics.FileVersionInfo.TestAssembly.csproj @@ -21,8 +21,5 @@ <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" /> <Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" /> </ItemGroup> - <ItemGroup> - <None Include="project.json" /> - </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> </Project>
\ No newline at end of file diff --git a/src/System.Diagnostics.Process/src/System/Diagnostics/ProcessManager.Windows.cs b/src/System.Diagnostics.Process/src/System/Diagnostics/ProcessManager.Windows.cs index f391fc505e..3a04511b18 100644 --- a/src/System.Diagnostics.Process/src/System/Diagnostics/ProcessManager.Windows.cs +++ b/src/System.Diagnostics.Process/src/System/Diagnostics/ProcessManager.Windows.cs @@ -904,13 +904,13 @@ namespace System.Diagnostics bufferSize, out requiredSize); - if ((uint)status == Interop.NtDll.STATUS_INFO_LENGTH_MISMATCH) + if (unchecked((uint)status) == Interop.NtDll.STATUS_INFO_LENGTH_MISMATCH) { if (bufferHandle.IsAllocated) bufferHandle.Free(); buffer = null; bufferSize = GetNewBufferSize(bufferSize, requiredSize); } - } while ((uint)status == Interop.NtDll.STATUS_INFO_LENGTH_MISMATCH); + } while (unchecked((uint)status) == Interop.NtDll.STATUS_INFO_LENGTH_MISMATCH); if (status < 0) { // see definition of NT_SUCCESS(Status) in SDK diff --git a/src/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj b/src/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj index 6b146b3bfd..0de299e824 100644 --- a/src/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj +++ b/src/System.DirectoryServices.Protocols/src/System.DirectoryServices.Protocols.csproj @@ -52,8 +52,5 @@ <Compile Include="System\DirectoryServices\Protocols\ldap\SafeHandles.cs" /> <Compile Include="System\DirectoryServices\Protocols\ldap\Wldap32UnsafeMethods.cs" /> </ItemGroup> - <ItemGroup> - <None Include="project.json" /> - </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> </Project>
\ No newline at end of file diff --git a/src/System.DirectoryServices/src/System.DirectoryServices.csproj b/src/System.DirectoryServices/src/System.DirectoryServices.csproj index 18803888c5..afd8ecc933 100644 --- a/src/System.DirectoryServices/src/System.DirectoryServices.csproj +++ b/src/System.DirectoryServices/src/System.DirectoryServices.csproj @@ -136,8 +136,5 @@ <Compile Include="Interop\SafeNativeMethods.cs" /> <Compile Include="Interop\UnsafeNativeMethods.cs" /> </ItemGroup> - <ItemGroup> - <None Include="project.json" /> - </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> </Project>
\ No newline at end of file diff --git a/src/System.Drawing.Primitives/src/System/Drawing/Point.cs b/src/System.Drawing.Primitives/src/System/Drawing/Point.cs index eb1de2208d..28b5a84c95 100644 --- a/src/System.Drawing.Primitives/src/System/Drawing/Point.cs +++ b/src/System.Drawing.Primitives/src/System/Drawing/Point.cs @@ -134,32 +134,32 @@ namespace System.Drawing /// Translates a <see cref='System.Drawing.Point'/> by a given <see cref='System.Drawing.Size'/> . /// </para> /// </summary> - public static Point Add(Point pt, Size sz) => new Point(pt.X + sz.Width, pt.Y + sz.Height); + public static Point Add(Point pt, Size sz) => new Point(unchecked(pt.X + sz.Width), unchecked(pt.Y + sz.Height)); /// <summary> /// <para> /// Translates a <see cref='System.Drawing.Point'/> by the negative of a given <see cref='System.Drawing.Size'/> . /// </para> /// </summary> - public static Point Subtract(Point pt, Size sz) => new Point(pt.X - sz.Width, pt.Y - sz.Height); + public static Point Subtract(Point pt, Size sz) => new Point(unchecked(pt.X - sz.Width), unchecked(pt.Y - sz.Height)); /// <summary> /// Converts a PointF to a Point by performing a ceiling operation on /// all the coordinates. /// </summary> - public static Point Ceiling(PointF value) => new Point((int)Math.Ceiling(value.X), (int)Math.Ceiling(value.Y)); + public static Point Ceiling(PointF value) => new Point(unchecked((int)Math.Ceiling(value.X)), unchecked((int)Math.Ceiling(value.Y))); /// <summary> /// Converts a PointF to a Point by performing a truncate operation on /// all the coordinates. /// </summary> - public static Point Truncate(PointF value) => new Point((int)value.X, (int)value.Y); + public static Point Truncate(PointF value) => new Point(unchecked((int)value.X), unchecked((int)value.Y)); /// <summary> /// Converts a PointF to a Point by performing a round operation on /// all the coordinates. /// </summary> - public static Point Round(PointF value) => new Point((int)Math.Round(value.X), (int)Math.Round(value.Y)); + public static Point Round(PointF value) => new Point(unchecked((int)Math.Round(value.X)), unchecked((int)Math.Round(value.Y))); /// <summary> /// <para> @@ -183,8 +183,11 @@ namespace System.Drawing /// </summary> public void Offset(int dx, int dy) { - X += dx; - Y += dy; + unchecked + { + X += dx; + Y += dy; + } } /// <summary> @@ -201,8 +204,8 @@ namespace System.Drawing /// </summary> public override string ToString() => "{X=" + X.ToString() + ",Y=" + Y.ToString() + "}"; - private static short HighInt16(int n) => (short)((n >> 16) & 0xffff); + private static short HighInt16(int n) => unchecked((short)((n >> 16) & 0xffff)); - private static short LowInt16(int n) => (short)(n & 0xffff); + private static short LowInt16(int n) => unchecked((short)(n & 0xffff)); } } diff --git a/src/System.Drawing.Primitives/src/System/Drawing/Rectangle.cs b/src/System.Drawing.Primitives/src/System/Drawing/Rectangle.cs index 8b3327d748..296796e14c 100644 --- a/src/System.Drawing.Primitives/src/System/Drawing/Rectangle.cs +++ b/src/System.Drawing.Primitives/src/System/Drawing/Rectangle.cs @@ -55,7 +55,7 @@ namespace System.Drawing /// the specified location and size. /// </summary> public static Rectangle FromLTRB(int left, int top, int right, int bottom) => - new Rectangle(left, top, right - left, bottom - top); + new Rectangle(left, top, unchecked(right - left), unchecked(bottom - top)); /// <summary> /// <para> @@ -148,7 +148,7 @@ namespace System.Drawing /// rectangular region defined by this <see cref='System.Drawing.Rectangle'/>. /// </para> /// </summary> - public int Right => X + Width; + public int Right => unchecked(X + Width); /// <summary> /// <para> @@ -156,7 +156,7 @@ namespace System.Drawing /// rectangular region defined by this <see cref='System.Drawing.Rectangle'/>. /// </para> /// </summary> - public int Bottom => Y + Height; + public int Bottom => unchecked(Y + Height); /// <summary> /// <para> @@ -197,34 +197,49 @@ namespace System.Drawing /// Converts a RectangleF to a Rectangle by performing a ceiling operation on /// all the coordinates. /// </summary> - public static Rectangle Ceiling(RectangleF value) => - new Rectangle( - (int)Math.Ceiling(value.X), - (int)Math.Ceiling(value.Y), - (int)Math.Ceiling(value.Width), - (int)Math.Ceiling(value.Height)); + public static Rectangle Ceiling(RectangleF value) + { + unchecked + { + return new Rectangle( + (int)Math.Ceiling(value.X), + (int)Math.Ceiling(value.Y), + (int)Math.Ceiling(value.Width), + (int)Math.Ceiling(value.Height)); + } + } /// <summary> /// Converts a RectangleF to a Rectangle by performing a truncate operation on /// all the coordinates. /// </summary> - public static Rectangle Truncate(RectangleF value) => - new Rectangle( - (int)value.X, - (int)value.Y, - (int)value.Width, - (int)value.Height); + public static Rectangle Truncate(RectangleF value) + { + unchecked + { + return new Rectangle( + (int)value.X, + (int)value.Y, + (int)value.Width, + (int)value.Height); + } + } /// <summary> /// Converts a RectangleF to a Rectangle by performing a round operation on /// all the coordinates. /// </summary> - public static Rectangle Round(RectangleF value) => - new Rectangle( - (int)Math.Round(value.X), - (int)Math.Round(value.Y), - (int)Math.Round(value.Width), - (int)Math.Round(value.Height)); + public static Rectangle Round(RectangleF value) + { + unchecked + { + return new Rectangle( + (int)Math.Round(value.X), + (int)Math.Round(value.Y), + (int)Math.Round(value.Width), + (int)Math.Round(value.Height)); + } + } /// <summary> /// <para> @@ -267,10 +282,14 @@ namespace System.Drawing /// </summary> public void Inflate(int width, int height) { - X -= width; - Y -= height; - Width += 2 * width; - Height += 2 * height; + unchecked + { + X -= width; + Y -= height; + + Width += 2 * width; + Height += 2 * height; + } } /// <summary> @@ -359,8 +378,11 @@ namespace System.Drawing /// </summary> public void Offset(int x, int y) { - X += x; - Y += y; + unchecked + { + X += x; + Y += y; + } } /// <summary> diff --git a/src/System.Drawing.Primitives/src/System/Drawing/Size.cs b/src/System.Drawing.Primitives/src/System/Drawing/Size.cs index 22a8a0a5f4..267a801f11 100644 --- a/src/System.Drawing.Primitives/src/System/Drawing/Size.cs +++ b/src/System.Drawing.Primitives/src/System/Drawing/Size.cs @@ -132,32 +132,36 @@ namespace System.Drawing /// Performs vector addition of two <see cref='System.Drawing.Size'/> objects. /// </para> /// </summary> - public static Size Add(Size sz1, Size sz2) => new Size(sz1.Width + sz2.Width, sz1.Height + sz2.Height); + public static Size Add(Size sz1, Size sz2) => + new Size(unchecked(sz1.Width + sz2.Width), unchecked(sz1.Height + sz2.Height)); /// <summary> /// Converts a SizeF to a Size by performing a ceiling operation on /// all the coordinates. /// </summary> - public static Size Ceiling(SizeF value) => new Size((int)Math.Ceiling(value.Width), (int)Math.Ceiling(value.Height)); + public static Size Ceiling(SizeF value) => + new Size(unchecked((int)Math.Ceiling(value.Width)), unchecked((int)Math.Ceiling(value.Height))); /// <summary> /// <para> /// Contracts a <see cref='System.Drawing.Size'/> by another <see cref='System.Drawing.Size'/> . /// </para> /// </summary> - public static Size Subtract(Size sz1, Size sz2) => new Size(sz1.Width - sz2.Width, sz1.Height - sz2.Height); + public static Size Subtract(Size sz1, Size sz2) => + new Size(unchecked(sz1.Width - sz2.Width), unchecked(sz1.Height - sz2.Height)); /// <summary> /// Converts a SizeF to a Size by performing a truncate operation on /// all the coordinates. /// </summary> - public static Size Truncate(SizeF value) => new Size((int)value.Width, (int)value.Height); + public static Size Truncate(SizeF value) => new Size(unchecked((int)value.Width), unchecked((int)value.Height)); /// <summary> /// Converts a SizeF to a Size by performing a round operation on /// all the coordinates. /// </summary> - public static Size Round(SizeF value) => new Size((int)Math.Round(value.Width), (int)Math.Round(value.Height)); + public static Size Round(SizeF value) => + new Size(unchecked((int)Math.Round(value.Width)), unchecked((int)Math.Round(value.Height))); /// <summary> /// <para> diff --git a/src/System.Drawing.Primitives/tests/PointTests.cs b/src/System.Drawing.Primitives/tests/PointTests.cs index 0f38a0ca64..520cd7c491 100644 --- a/src/System.Drawing.Primitives/tests/PointTests.cs +++ b/src/System.Drawing.Primitives/tests/PointTests.cs @@ -35,7 +35,7 @@ namespace System.Drawing.PrimitivesTests public void SingleIntConstructorTest(int x) { Point p1 = new Point(x); - Point p2 = new Point((short)(x & 0xFFFF), (short)((x >> 16) & 0xFFFF)); + Point p2 = new Point(unchecked((short)(x & 0xFFFF)), unchecked((short)((x >> 16) & 0xFFFF))); Assert.Equal(p1, p2); } @@ -98,11 +98,14 @@ namespace System.Drawing.PrimitivesTests [InlineData(0, 0)] public void ArithmeticTest(int x, int y) { - Point p = new Point(x, y); + Point addExpected, subExpected, p = new Point(x, y); Size s = new Size(y, x); - Point addExpected = new Point(x + y, y + x); - Point subExpected = new Point(x - y, y - x); + unchecked + { + addExpected = new Point(x + y, y + x); + subExpected = new Point(x - y, y - x); + } Assert.Equal(addExpected, p + s); Assert.Equal(subExpected, p - s); @@ -118,9 +121,14 @@ namespace System.Drawing.PrimitivesTests public void PointFMathematicalTest(float x, float y) { PointF pf = new PointF(x, y); - Point pCeiling = new Point((int)Math.Ceiling(x), (int)Math.Ceiling(y)); - Point pTruncate = new Point((int)x, (int)y); - Point pRound = new Point((int)Math.Round(x), (int)Math.Round(y)); + Point pCeiling, pTruncate, pRound; + + unchecked + { + pCeiling = new Point((int)Math.Ceiling(x), (int)Math.Ceiling(y)); + pTruncate = new Point((int)x, (int)y); + pRound = new Point((int)Math.Round(x), (int)Math.Round(y)); + } Assert.Equal(pCeiling, Point.Ceiling(pf)); Assert.Equal(pRound, Point.Round(pf)); @@ -139,7 +147,7 @@ namespace System.Drawing.PrimitivesTests p1.Offset(p2); - Assert.Equal(p2.X + p2.Y, p1.X); + Assert.Equal(unchecked(p2.X + p2.Y), p1.X); Assert.Equal(p1.X, p1.Y); p2.Offset(x, y); diff --git a/src/System.Drawing.Primitives/tests/RectangleTests.cs b/src/System.Drawing.Primitives/tests/RectangleTests.cs index b5bf6a0805..c04cdab224 100644 --- a/src/System.Drawing.Primitives/tests/RectangleTests.cs +++ b/src/System.Drawing.Primitives/tests/RectangleTests.cs @@ -35,7 +35,7 @@ namespace System.Drawing.PrimitivesTest [InlineData(0, int.MinValue, 0, int.MaxValue)] public void FromLTRBTest(int left, int top, int right, int bottom) { - Rectangle rect1 = new Rectangle(left, top, right - left, bottom - top); + Rectangle rect1 = new Rectangle(left, top, unchecked(right - left), unchecked(bottom - top)); Rectangle rect2 = Rectangle.FromLTRB(left, top, right, bottom); Assert.Equal(rect1, rect2); @@ -77,8 +77,8 @@ namespace System.Drawing.PrimitivesTest Assert.Equal(height, rect.Height); Assert.Equal(x, rect.Left); Assert.Equal(y, rect.Top); - Assert.Equal(x + width, rect.Right); - Assert.Equal(y + height, rect.Bottom); + Assert.Equal(unchecked(x + width), rect.Right); + Assert.Equal(unchecked(y + height), rect.Bottom); Point p = new Point(width, height); Size s = new Size(x, y); @@ -94,8 +94,8 @@ namespace System.Drawing.PrimitivesTest Assert.Equal(y, rect.Height); Assert.Equal(width, rect.Left); Assert.Equal(height, rect.Top); - Assert.Equal(x + width, rect.Right); - Assert.Equal(y + height, rect.Bottom); + Assert.Equal(unchecked(x + width), rect.Right); + Assert.Equal(unchecked(y + height), rect.Bottom); } [Theory] @@ -168,11 +168,16 @@ namespace System.Drawing.PrimitivesTest public void RectangleFConversionTest(float x, float y, float width, float height) { RectangleF rect = new RectangleF(x, y, width, height); - Rectangle rCeiling = new Rectangle((int)Math.Ceiling(x), (int)Math.Ceiling(y), - (int)Math.Ceiling(width), (int)Math.Ceiling(height)); - Rectangle rTruncate = new Rectangle((int)x, (int)y, (int)width, (int)height); - Rectangle rRound = new Rectangle((int)Math.Round(x), (int)Math.Round(y), - (int)Math.Round(width), (int)Math.Round(height)); + Rectangle rCeiling, rTruncate, rRound; + + unchecked + { + rCeiling = new Rectangle((int)Math.Ceiling(x), (int)Math.Ceiling(y), + (int)Math.Ceiling(width), (int)Math.Ceiling(height)); + rTruncate = new Rectangle((int)x, (int)y, (int)width, (int)height); + rRound = new Rectangle((int)Math.Round(x), (int)Math.Round(y), + (int)Math.Round(width), (int)Math.Round(height)); + } Assert.Equal(rCeiling, Rectangle.Ceiling(rect)); Assert.Equal(rTruncate, Rectangle.Truncate(rect)); @@ -184,7 +189,7 @@ namespace System.Drawing.PrimitivesTest [InlineData(0, int.MinValue, int.MaxValue, 0)] public void ContainsTest(int x, int y, int width, int height) { - Rectangle rect = new Rectangle(2 * x - width, 2 * y - height, width, height); + Rectangle rect = new Rectangle(unchecked(2 * x - width), unchecked(2 * y - height), width, height); Point p = new Point(x, y); Rectangle r = new Rectangle(x, y, width / 2, height / 2); @@ -199,8 +204,11 @@ namespace System.Drawing.PrimitivesTest [InlineData(0, int.MinValue, int.MaxValue, 0)] public void InflateTest(int x, int y, int width, int height) { - Rectangle rect = new Rectangle(x, y, width, height); - Rectangle inflatedRect = new Rectangle(x - width, y - height, width + 2 * width, height + 2 * height); + Rectangle inflatedRect, rect = new Rectangle(x, y, width, height); + unchecked + { + inflatedRect = new Rectangle(x - width, y - height, width + 2 * width, height + 2 * height); + } Assert.Equal(inflatedRect, Rectangle.Inflate(rect, width, height)); @@ -208,7 +216,10 @@ namespace System.Drawing.PrimitivesTest Assert.Equal(inflatedRect, rect); Size s = new Size(x, y); - inflatedRect = new Rectangle(rect.X - x, rect.Y - y, rect.Width + 2 * x, rect.Height + 2 * y); + unchecked + { + inflatedRect = new Rectangle(rect.X - x, rect.Y - y, rect.Width + 2 * x, rect.Height + 2 * y); + } rect.Inflate(s); Assert.Equal(inflatedRect, rect); diff --git a/src/System.Drawing.Primitives/tests/SizeFTests.cs b/src/System.Drawing.Primitives/tests/SizeFTests.cs index 4d5278b249..0caa768e26 100644 --- a/src/System.Drawing.Primitives/tests/SizeFTests.cs +++ b/src/System.Drawing.Primitives/tests/SizeFTests.cs @@ -130,7 +130,7 @@ namespace System.Drawing.PrimitivesTest { SizeF s1 = new SizeF(width, height); PointF p1 = (PointF)s1; - Size s2 = new Size((int)width, (int)height); + Size s2 = new Size(unchecked((int)width), unchecked((int)height)); Assert.Equal(new PointF(width, height), p1); Assert.Equal(p1, s1.ToPointF()); diff --git a/src/System.Drawing.Primitives/tests/SizeTests.cs b/src/System.Drawing.Primitives/tests/SizeTests.cs index 8eeefaf873..84460e1f2a 100644 --- a/src/System.Drawing.Primitives/tests/SizeTests.cs +++ b/src/System.Drawing.Primitives/tests/SizeTests.cs @@ -94,9 +94,13 @@ namespace System.Drawing.PrimitivesTests { Size sz1 = new Size(width, height); Size sz2 = new Size(height, width); + Size addExpected, subExpected; - Size addExpected = new Size(width + height, height + width); - Size subExpected = new Size(width - height, height - width); + unchecked + { + addExpected = new Size(width + height, height + width); + subExpected = new Size(width - height, height - width); + } Assert.Equal(addExpected, sz1 + sz2); Assert.Equal(subExpected, sz1 - sz2); @@ -112,9 +116,14 @@ namespace System.Drawing.PrimitivesTests public void PointFMathematicalTest(float width, float height) { SizeF szF = new SizeF(width, height); - Size pCeiling = new Size((int)Math.Ceiling(width), (int)Math.Ceiling(height)); - Size pTruncate = new Size((int)width, (int)height); - Size pRound = new Size((int)Math.Round(width), (int)Math.Round(height)); + Size pCeiling, pTruncate, pRound; + + unchecked + { + pCeiling = new Size((int)Math.Ceiling(width), (int)Math.Ceiling(height)); + pTruncate = new Size((int)width, (int)height); + pRound = new Size((int)Math.Round(width), (int)Math.Round(height)); + } Assert.Equal(pCeiling, Size.Ceiling(szF)); Assert.Equal(pRound, Size.Round(szF)); @@ -129,7 +138,7 @@ namespace System.Drawing.PrimitivesTests public void EqualityTest(int width, int height) { Size p1 = new Size(width, height); - Size p2 = new Size(width - 1, height - 1); + Size p2 = new Size(unchecked(width - 1), unchecked(height - 1)); Size p3 = new Size(width, height); Assert.True(p1 == p3); diff --git a/src/System.Globalization/tests/Performance/System.Globalization.Performance.Tests.csproj b/src/System.Globalization/tests/Performance/System.Globalization.Performance.Tests.csproj index d59d5e64dc..72819ad3be 100644 --- a/src/System.Globalization/tests/Performance/System.Globalization.Performance.Tests.csproj +++ b/src/System.Globalization/tests/Performance/System.Globalization.Performance.Tests.csproj @@ -3,7 +3,6 @@ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> <PropertyGroup> <IncludePerformanceTests>true</IncludePerformanceTests> - <DefineConstants Condition="'$(TargetGroup)' == 'net46'">$(DefineConstants);net46</DefineConstants> <ProjectGuid>{0BA6851E-0E75-453D-9D2A-CEB94E4DE975}</ProjectGuid> </PropertyGroup> <!-- Default configurations to help VS understand the configurations --> @@ -17,12 +16,6 @@ <Link>Common\System\PerfUtils.cs</Link> </Compile> </ItemGroup> - <ItemGroup Condition="'$(TargetGroup)' == 'net46'"> - <TargetingPackReference Include="System" /> - <TargetingPackReference Include="System.Threading.Tasks" /> - <TargetingPackReference Include="System.Core" /> - <TargetingPackReference Include="System.Runtime" /> - </ItemGroup> <ItemGroup> <EmbeddedResource Include="$(CommonTestPath)\Data\UnicodeData.8.0.txt"> <Link>CharUnicodeInfo\UnicodeData8.0.txt</Link> diff --git a/src/System.IO.Compression/src/System/IO/Compression/Crc32Helper.cs b/src/System.IO.Compression/src/System/IO/Compression/Crc32Helper.cs index 47fdac1b38..0e0ca4bcb3 100644 --- a/src/System.IO.Compression/src/System/IO/Compression/Crc32Helper.cs +++ b/src/System.IO.Compression/src/System/IO/Compression/Crc32Helper.cs @@ -493,7 +493,7 @@ namespace System.IO.Compression for (int i = 0; i < runningLength / 8; i++) { - crc32 ^= (uint)(buffer[offset] | buffer[offset + 1] << 8 | buffer[offset + 2] << 16 | buffer[offset + 3] << 24); + crc32 ^= unchecked((uint)(buffer[offset] | buffer[offset + 1] << 8 | buffer[offset + 2] << 16 | buffer[offset + 3] << 24)); offset += 4; term1 = s_crcTable_7[crc32 & 0x000000FF] ^ s_crcTable_6[(crc32 >> 8) & 0x000000FF]; @@ -503,7 +503,7 @@ namespace System.IO.Compression s_crcTable_4[(term2 >> 8) & 0x000000FF]; - term3 = (uint)(buffer[offset] | buffer[offset + 1] << 8 | buffer[offset + 2] << 16 | buffer[offset + 3] << 24); + term3 = unchecked((uint)(buffer[offset] | buffer[offset + 1] << 8 | buffer[offset + 2] << 16 | buffer[offset + 3] << 24)); offset += 4; term1 = s_crcTable_3[term3 & 0x000000FF] ^ s_crcTable_2[(term3 >> 8) & 0x000000FF]; diff --git a/src/System.IO.MemoryMappedFiles/tests/MemoryMappedFile.CrossProcess.cs b/src/System.IO.MemoryMappedFiles/tests/MemoryMappedFile.CrossProcess.cs index 887b072aff..22f06c5762 100644 --- a/src/System.IO.MemoryMappedFiles/tests/MemoryMappedFile.CrossProcess.cs +++ b/src/System.IO.MemoryMappedFiles/tests/MemoryMappedFile.CrossProcess.cs @@ -22,7 +22,7 @@ namespace System.IO.MemoryMappedFiles.Tests long capacity = acc.Capacity; for (int i = 0; i < capacity; i++) { - acc.Write(i, (byte)i); + acc.Write(i, unchecked((byte)i)); } acc.Flush(); diff --git a/src/System.IO/src/System.IO.csproj b/src/System.IO/src/System.IO.csproj index d506b6a44b..de605ab761 100644 --- a/src/System.IO/src/System.IO.csproj +++ b/src/System.IO/src/System.IO.csproj @@ -6,7 +6,6 @@ <ProjectGuid>{07390899-C8F6-4e83-A3A9-6867B8CB46A0}</ProjectGuid> <IsPartialFacadeAssembly>true</IsPartialFacadeAssembly> <DefineConstants Condition="'$(TargetGroup)' == 'netcoreapp' OR '$(TargetGroup)' == 'uap'">$(DefineConstants);netcoreapp17</DefineConstants> - <NoWarn>CS0436</NoWarn> </PropertyGroup> <!-- Default configurations to help VS understand the options --> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Debug|AnyCPU'" /> diff --git a/src/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/ILGen.cs b/src/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/ILGen.cs index feb6aaf475..effbd8f1eb 100644 --- a/src/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/ILGen.cs +++ b/src/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/ILGen.cs @@ -431,7 +431,7 @@ namespace System.Linq.Expressions.Compiler internal static void EmitUInt(this ILGenerator il, uint value) { - il.EmitInt((int)value); + il.EmitInt(unchecked((int)value)); il.Emit(OpCodes.Conv_U4); } @@ -450,7 +450,7 @@ namespace System.Linq.Expressions.Compiler internal static void EmitULong(this ILGenerator il, ulong value) { - il.Emit(OpCodes.Ldc_I8, (long)value); + il.Emit(OpCodes.Ldc_I8, unchecked((long)value)); il.Emit(OpCodes.Conv_U8); } @@ -1127,7 +1127,7 @@ namespace System.Linq.Expressions.Compiler il.EmitInt(bits[1]); il.EmitInt(bits[2]); il.EmitBoolean((bits[3] & 0x80000000) != 0); - il.EmitByte((byte)(bits[3] >> 16)); + il.EmitByte(unchecked((byte)(bits[3] >> 16))); il.EmitNew(Decimal_Ctor_Int32_Int32_Int32_Bool_Byte); } diff --git a/src/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Binary.cs b/src/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Binary.cs index 3364b45292..7d4e502dd6 100644 --- a/src/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Binary.cs +++ b/src/System.Linq.Expressions/src/System/Linq/Expressions/Compiler/LambdaCompiler.Binary.cs @@ -544,20 +544,25 @@ namespace System.Linq.Expressions.Compiler _ilg.Emit(OpCodes.Stloc, locLeft); // test for null - // use short circuiting + // don't use short circuiting if (leftIsNullable) { _ilg.Emit(OpCodes.Ldloca, locLeft); _ilg.EmitHasValue(leftType); - _ilg.Emit(OpCodes.Brfalse_S, labIfNull); } + if (rightIsNullable) { _ilg.Emit(OpCodes.Ldloca, locRight); _ilg.EmitHasValue(rightType); - _ilg.Emit(OpCodes.Brfalse_S, labIfNull); + if (leftIsNullable) + { + _ilg.Emit(OpCodes.And); + } } + _ilg.Emit(OpCodes.Brfalse_S, labIfNull); + // do op on values if (leftIsNullable) { diff --git a/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/DivInstruction.cs b/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/DivInstruction.cs index 3aaaaaba79..f90587910f 100644 --- a/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/DivInstruction.cs +++ b/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/DivInstruction.cs @@ -30,7 +30,7 @@ namespace System.Linq.Expressions.Interpreter } else { - frame.Data[frame.StackIndex - 2] = (short)((short)l / (short)r); + frame.Data[frame.StackIndex - 2] = unchecked((short)((short)l / (short)r)); } frame.StackIndex--; return 1; diff --git a/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LeftShiftInstruction.cs b/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LeftShiftInstruction.cs index 24b4c25196..96d9451869 100644 --- a/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LeftShiftInstruction.cs +++ b/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LeftShiftInstruction.cs @@ -29,7 +29,7 @@ namespace System.Linq.Expressions.Interpreter } else { - frame.Push((sbyte)((sbyte)value << (int)shift)); + frame.Push(unchecked((sbyte)((sbyte)value << (int)shift))); } return 1; } @@ -47,7 +47,7 @@ namespace System.Linq.Expressions.Interpreter } else { - frame.Push((short)((short)value << (int)shift)); + frame.Push(unchecked((short)((short)value << (int)shift))); } return 1; } @@ -101,7 +101,7 @@ namespace System.Linq.Expressions.Interpreter } else { - frame.Push((byte)((byte)value << (int)shift)); + frame.Push(unchecked((byte)((byte)value << (int)shift))); } return 1; } @@ -119,7 +119,7 @@ namespace System.Linq.Expressions.Interpreter } else { - frame.Push((ushort)((ushort)value << (int)shift)); + frame.Push(unchecked((ushort)((ushort)value << (int)shift))); } return 1; } diff --git a/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/NotInstruction.cs b/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/NotInstruction.cs index e2fc2037d6..cd61d79e88 100644 --- a/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/NotInstruction.cs +++ b/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/NotInstruction.cs @@ -129,7 +129,7 @@ namespace System.Linq.Expressions.Interpreter } else { - frame.Push((ushort)(~(ushort)value)); + frame.Push(unchecked((ushort)(~(ushort)value))); } return 1; } @@ -146,7 +146,7 @@ namespace System.Linq.Expressions.Interpreter } else { - frame.Push((byte)(~(byte)value)); + frame.Push(unchecked((byte)(~(byte)value))); } return 1; } diff --git a/src/System.Linq.Expressions/tests/System.Linq.Expressions.Tests.csproj b/src/System.Linq.Expressions/tests/System.Linq.Expressions.Tests.csproj index 59cefeb5fb..e9c670df12 100644 --- a/src/System.Linq.Expressions/tests/System.Linq.Expressions.Tests.csproj +++ b/src/System.Linq.Expressions/tests/System.Linq.Expressions.Tests.csproj @@ -253,5 +253,8 @@ <Compile Include="ILReader\LocalsSignatureParser.cs" /> <Compile Include="ILReader\SigParser.cs" /> </ItemGroup> + <ItemGroup> + <ReferenceFromRuntime Include="xunit.execution.dotnet" /> + </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> </Project>
\ No newline at end of file diff --git a/src/System.Linq.Expressions/tests/TestExtensions/TestOrderer.cs b/src/System.Linq.Expressions/tests/TestExtensions/TestOrderer.cs index 35985108d8..5168d7733a 100644 --- a/src/System.Linq.Expressions/tests/TestExtensions/TestOrderer.cs +++ b/src/System.Linq.Expressions/tests/TestExtensions/TestOrderer.cs @@ -16,7 +16,7 @@ namespace System.Linq.Expressions.Tests Dictionary<int, List<TTestCase>> queue = new Dictionary<int, List<TTestCase>>(); foreach (TTestCase testCase in testCases) { - Xunit.Abstractions.IAttributeInfo orderAttribute = ReflectionAbstractionExtensions.GetCustomAttributes(testCase.TestMethod.Method, typeof(TestOrderAttribute)).FirstOrDefault(); + Xunit.Abstractions.IAttributeInfo orderAttribute = testCase.TestMethod.Method.GetCustomAttributes(typeof(TestOrderAttribute)).FirstOrDefault(); int order; if (orderAttribute == null || (order = orderAttribute.GetConstructorArguments().Cast<int>().First()) == 0) { diff --git a/src/System.Memory/src/System.Memory.csproj b/src/System.Memory/src/System.Memory.csproj index 6c784837ea..74c329c4e9 100644 --- a/src/System.Memory/src/System.Memory.csproj +++ b/src/System.Memory/src/System.Memory.csproj @@ -3,10 +3,9 @@ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> <PropertyGroup> <ProjectGuid>{4BBC8F69-D03E-4432-AA8A-D458FA5B235A}</ProjectGuid> - <AssemblyName>System.Memory</AssemblyName> <AllowUnsafeBlocks>true</AllowUnsafeBlocks> <CLSCompliant>false</CLSCompliant> - <DocumentationFile>$(OutputPath)$(AssemblyName).xml</DocumentationFile> + <DocumentationFile>$(OutputPath)$(MSBuildProjectName).xml</DocumentationFile> <IsPartialFacadeAssembly Condition="'$(TargetGroup)' == 'netcoreapp' OR '$(TargetGroup)' == 'uap'">true</IsPartialFacadeAssembly> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Windows_NT-Debug|AnyCPU'" /> diff --git a/src/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs b/src/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs index 0e069ad23d..0d763499f2 100644 --- a/src/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs +++ b/src/System.Net.Sockets/tests/FunctionalTests/DualModeSocketTest.cs @@ -104,19 +104,13 @@ namespace System.Net.Sockets.Tests [Fact] public void ConnectV4IPAddressToV6Host_Fails() { - Assert.ThrowsAny<SocketException>(() => - { - DualModeConnect_IPAddressToHost_Helper(IPAddress.Loopback, IPAddress.IPv6Loopback, false); - }); + DualModeConnect_IPAddressToHost_Fails_Helper(IPAddress.Loopback, IPAddress.IPv6Loopback); } [Fact] public void ConnectV6IPAddressToV4Host_Fails() { - Assert.ThrowsAny<SocketException>(() => - { - DualModeConnect_IPAddressToHost_Helper(IPAddress.IPv6Loopback, IPAddress.Loopback, false); - }); + DualModeConnect_IPAddressToHost_Fails_Helper(IPAddress.IPv6Loopback, IPAddress.Loopback); } [Fact] @@ -141,6 +135,20 @@ namespace System.Net.Sockets.Tests Assert.True(socket.Connected); } } + + private void DualModeConnect_IPAddressToHost_Fails_Helper(IPAddress connectTo, IPAddress listenOn) + { + Assert.ThrowsAny<SocketException>(() => + { + DualModeConnect_IPAddressToHost_Helper(connectTo, listenOn, false); + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // On Unix, socket assignment is random (not incremental) and there is a small chance the + // listening socket was created in another test currently running. Try the test one more time. + DualModeConnect_IPAddressToHost_Helper(connectTo, listenOn, false); + } + }); + } } [Trait("IPv4", "true")] @@ -186,19 +194,13 @@ namespace System.Net.Sockets.Tests [Fact] public void ConnectV4IPEndPointToV6Host_Fails() { - Assert.ThrowsAny<SocketException>(() => - { - DualModeConnect_IPEndPointToHost_Helper(IPAddress.Loopback, IPAddress.IPv6Loopback, false); - }); + DualModeConnect_IPEndPointToHost_Fails_Helper(IPAddress.Loopback, IPAddress.IPv6Loopback); } [Fact] public void ConnectV6IPEndPointToV4Host_Fails() { - Assert.ThrowsAny<SocketException>(() => - { - DualModeConnect_IPEndPointToHost_Helper(IPAddress.IPv6Loopback, IPAddress.Loopback, false); - }); + DualModeConnect_IPEndPointToHost_Fails_Helper(IPAddress.IPv6Loopback, IPAddress.Loopback); } [Fact] @@ -223,6 +225,20 @@ namespace System.Net.Sockets.Tests Assert.True(socket.Connected); } } + + private void DualModeConnect_IPEndPointToHost_Fails_Helper(IPAddress connectTo, IPAddress listenOn) + { + Assert.ThrowsAny<SocketException>(() => + { + DualModeConnect_IPEndPointToHost_Helper(connectTo, listenOn, false); + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // On Unix, socket assignment is random (not incremental) and there is a small chance the + // listening socket was created in another test currently running. Try the test one more time. + DualModeConnect_IPEndPointToHost_Helper(connectTo, listenOn, false); + } + }); + } } [Trait("IPv4", "true")] @@ -339,19 +355,13 @@ namespace System.Net.Sockets.Tests [Fact] public void BeginConnectV4IPAddressToV6Host_Fails() { - Assert.ThrowsAny<SocketException>(() => - { - DualModeBeginConnect_IPAddressToHost_Helper(IPAddress.Loopback, IPAddress.IPv6Loopback, false); - }); + DualModeBeginConnect_IPAddressToHost_Fails_Helper(IPAddress.Loopback, IPAddress.IPv6Loopback); } [Fact] public void BeginConnectV6IPAddressToV4Host_Fails() { - Assert.ThrowsAny<SocketException>(() => - { - DualModeBeginConnect_IPAddressToHost_Helper(IPAddress.IPv6Loopback, IPAddress.Loopback, false); - }); + DualModeBeginConnect_IPAddressToHost_Fails_Helper(IPAddress.IPv6Loopback, IPAddress.Loopback); } [Fact] @@ -377,6 +387,20 @@ namespace System.Net.Sockets.Tests Assert.True(socket.Connected); } } + + private void DualModeBeginConnect_IPAddressToHost_Fails_Helper(IPAddress connectTo, IPAddress listenOn) + { + Assert.ThrowsAny<SocketException>(() => + { + DualModeBeginConnect_IPAddressToHost_Helper(connectTo, listenOn, false); + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // On Unix, socket assignment is random (not incremental) and there is a small chance the + // listening socket was created in another test currently running. Try the test one more time. + DualModeBeginConnect_IPAddressToHost_Helper(connectTo, listenOn, false); + } + }); + } } [Trait("IPv4", "true")] @@ -513,19 +537,13 @@ namespace System.Net.Sockets.Tests [ConditionalFact(nameof(PlatformDetection) + "." + nameof(PlatformDetection.IsNotWindowsSubsystemForLinux))] // https://github.com/Microsoft/BashOnWindows/issues/982 public void ConnectAsyncV4IPEndPointToV6Host_Fails() { - Assert.Throws<SocketException>(() => - { - DualModeConnectAsync_IPEndPointToHost_Helper(IPAddress.Loopback, IPAddress.IPv6Loopback, false); - }); + DualModeConnectAsync_IPEndPointToHost_Fails_Helper(IPAddress.Loopback, IPAddress.IPv6Loopback); } [ConditionalFact(nameof(PlatformDetection) + "." + nameof(PlatformDetection.IsNotWindowsSubsystemForLinux))] // https://github.com/Microsoft/BashOnWindows/issues/982 public void ConnectAsyncV6IPEndPointToV4Host_Fails() { - Assert.Throws<SocketException>(() => - { - DualModeConnectAsync_IPEndPointToHost_Helper(IPAddress.IPv6Loopback, IPAddress.Loopback, false); - }); + DualModeConnectAsync_IPEndPointToHost_Fails_Helper(IPAddress.IPv6Loopback, IPAddress.Loopback); } [Fact] @@ -563,6 +581,20 @@ namespace System.Net.Sockets.Tests } } + private void DualModeConnectAsync_IPEndPointToHost_Fails_Helper(IPAddress connectTo, IPAddress listenOn) + { + Assert.ThrowsAny<SocketException>(() => + { + DualModeConnectAsync_IPEndPointToHost_Helper(connectTo, listenOn, false); + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + // On Unix, socket assignment is random (not incremental) and there is a small chance the + // listening socket was created in another test currently running. Try the test one more time. + DualModeConnectAsync_IPEndPointToHost_Helper(connectTo, listenOn, false); + } + }); + } + [Theory] [MemberData(nameof(DualMode_Connect_IPAddress_DualMode_Data))] [PlatformSpecific(TestPlatforms.Windows)] diff --git a/src/System.Numerics.Vectors/src/System.Numerics.Vectors.csproj b/src/System.Numerics.Vectors/src/System.Numerics.Vectors.csproj index b5eeb2a070..54e0e83f73 100644 --- a/src/System.Numerics.Vectors/src/System.Numerics.Vectors.csproj +++ b/src/System.Numerics.Vectors/src/System.Numerics.Vectors.csproj @@ -4,8 +4,7 @@ <PropertyGroup> <ProjectGuid>{53134B0C-0D57-481B-B84E-D1991E8D54FF}</ProjectGuid> <RootNamespace>System.Numerics</RootNamespace> - <AssemblyName>System.Numerics.Vectors</AssemblyName> - <DocumentationFile>$(OutputPath)System.Numerics.Vectors.xml</DocumentationFile> + <DocumentationFile>$(OutputPath)$(MSBuildProjectName).xml</DocumentationFile> <AllowUnsafeBlocks>true</AllowUnsafeBlocks> <IsPartialFacadeAssembly Condition="'$(TargetGroup)'=='netfx'">true</IsPartialFacadeAssembly> <PackageTargetFramework Condition="'$(TargetGroup)' == 'netcoreapp'">netcoreapp;portable-net45+win8+wp8+wpa81</PackageTargetFramework> diff --git a/src/System.Private.Uri/src/System.Private.Uri.csproj b/src/System.Private.Uri/src/System.Private.Uri.csproj index f55edc3b97..907ccccfb6 100644 --- a/src/System.Private.Uri/src/System.Private.Uri.csproj +++ b/src/System.Private.Uri/src/System.Private.Uri.csproj @@ -5,8 +5,6 @@ <ProjectGuid>{4AC5343E-6E31-4BA5-A795-0493AE7E9008}</ProjectGuid> <AssemblyName>System.Private.Uri</AssemblyName> <AllowUnsafeBlocks>true</AllowUnsafeBlocks> - <!-- Suppress warnings for type conflicts between SafeFileHandle in partial facade and mscorlib --> - <NoWarn>0436</NoWarn> <SkipCommonResourcesIncludes Condition="'$(TargetGroup)'=='uapaot' or '$(TargetGroup)' == 'netcoreapp1.2corert'">true</SkipCommonResourcesIncludes> <DefineConstants Condition="'$(TargetGroup)'=='netcoreapp' OR '$(TargetGroup)'=='uap'">$(DefineConstants);netstandard10</DefineConstants> </PropertyGroup> diff --git a/src/System.Private.Uri/src/System/Uri.cs b/src/System.Private.Uri/src/System/Uri.cs index d59e26bffc..d4015681b3 100644 --- a/src/System.Private.Uri/src/System/Uri.cs +++ b/src/System.Private.Uri/src/System/Uri.cs @@ -2690,9 +2690,9 @@ namespace System private string GetEscapedParts(UriComponents uriParts) { // Which Uri parts are not escaped canonically ? - // Notice that public UriPart and private Flags must me in Sync so below code can work + // Notice that public UriPart and private Flags must be in Sync so below code can work // - ushort nonCanonical = (ushort)(((ushort)_flags & ((ushort)Flags.CannotDisplayCanonical << 7)) >> 6); + ushort nonCanonical = unchecked((ushort)(((ushort)_flags & ((ushort)Flags.CannotDisplayCanonical << 7)) >> 6)); if (InFact(Flags.SchemeNotCanonical)) { nonCanonical |= (ushort)Flags.SchemeNotCanonical; @@ -2712,7 +2712,7 @@ namespace System } } - if (((ushort)uriParts & nonCanonical) == 0) + if ((unchecked((ushort)uriParts) & nonCanonical) == 0) { string ret = GetUriPartsFromUserString(uriParts); if ((object)ret != null) @@ -2745,7 +2745,7 @@ namespace System } } - if (((ushort)uriParts & nonCanonical) == 0) + if ((unchecked((ushort)uriParts) & nonCanonical) == 0) { string ret = GetUriPartsFromUserString(uriParts); if ((object)ret != null) diff --git a/src/System.Private.Xml.Linq/tests/XDocument.Common/XDocument.Common.csproj b/src/System.Private.Xml.Linq/tests/XDocument.Common/XDocument.Common.csproj index 74a37a3119..cd7a7880f1 100644 --- a/src/System.Private.Xml.Linq/tests/XDocument.Common/XDocument.Common.csproj +++ b/src/System.Private.Xml.Linq/tests/XDocument.Common/XDocument.Common.csproj @@ -5,7 +5,6 @@ <ProjectGuid>{52666206-B6C9-49FA-A1D7-D0A0C68807B0}</ProjectGuid> <AssemblyName>XDocument.Common</AssemblyName> <RootNamespace>CoreXml.Test.XLinq</RootNamespace> - <NoWarn>0436</NoWarn> </PropertyGroup> <!-- Default configurations to help VS understand the configurations --> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" /> diff --git a/src/System.Private.Xml.Linq/tests/XDocument.Test.ModuleCore/XDocument.Test.ModuleCore.csproj b/src/System.Private.Xml.Linq/tests/XDocument.Test.ModuleCore/XDocument.Test.ModuleCore.csproj index cb9252a91c..c4df68c3b5 100644 --- a/src/System.Private.Xml.Linq/tests/XDocument.Test.ModuleCore/XDocument.Test.ModuleCore.csproj +++ b/src/System.Private.Xml.Linq/tests/XDocument.Test.ModuleCore/XDocument.Test.ModuleCore.csproj @@ -3,7 +3,6 @@ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> <PropertyGroup> <ProjectGuid>{979510CE-9042-4F8D-9C74-EE03B89194CC}</ProjectGuid> - <NoWarn>0436</NoWarn> </PropertyGroup> <!-- Default configurations to help VS understand the configurations --> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" /> diff --git a/src/System.Private.Xml/src/System/Xml/Schema/XsdDateTime.cs b/src/System.Private.Xml/src/System/Xml/Schema/XsdDateTime.cs index 2ccb65ea7c..b87cd3b2b2 100644 --- a/src/System.Private.Xml/src/System/Xml/Schema/XsdDateTime.cs +++ b/src/System.Private.Xml/src/System/Xml/Schema/XsdDateTime.cs @@ -987,7 +987,7 @@ namespace System.Xml.Schema while (++start < _length) { int d = _text[start] - '0'; - if (9u < (uint)d) + if (9u < unchecked((uint)d)) { // d < 0 || 9 < d break; } diff --git a/src/System.Private.Xml/tests/XmlReaderLib/System.Xml.RW.XmlReaderLib.csproj b/src/System.Private.Xml/tests/XmlReaderLib/System.Xml.RW.XmlReaderLib.csproj index 70be57865e..456772fe64 100644 --- a/src/System.Private.Xml/tests/XmlReaderLib/System.Xml.RW.XmlReaderLib.csproj +++ b/src/System.Private.Xml/tests/XmlReaderLib/System.Xml.RW.XmlReaderLib.csproj @@ -4,7 +4,6 @@ <PropertyGroup> <ProjectGuid>{F05DE950-CA99-42A8-B44D-E7DAA5C3C783}</ProjectGuid> <RootNamespace>XmlReaderTest.Common</RootNamespace> - <NoWarn>0436</NoWarn> </PropertyGroup> <!-- Default configurations to help VS understand the configurations --> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> diff --git a/src/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj b/src/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj index e2744b459d..a3d54a4730 100644 --- a/src/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj +++ b/src/System.Reflection.Metadata/src/System.Reflection.Metadata.csproj @@ -3,8 +3,7 @@ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> <PropertyGroup> <ProjectGuid>{F3E433C8-352F-4944-BF7F-765CE435370D}</ProjectGuid> - <AssemblyName>System.Reflection.Metadata</AssemblyName> - <DocumentationFile>$(OutputPath)System.Reflection.Metadata.xml</DocumentationFile> + <DocumentationFile>$(OutputPath)$(MSBuildProjectName).xml</DocumentationFile> <RootNamespace>System.Reflection.Metadata</RootNamespace> <FileAlignment>512</FileAlignment> <AllowUnsafeBlocks>true</AllowUnsafeBlocks> diff --git a/src/System.Reflection/tests/CoreCLR/System.Reflection.CoreCLR.Tests.csproj b/src/System.Reflection/tests/CoreCLR/System.Reflection.CoreCLR.Tests.csproj index 137d675983..33a2d4aabd 100644 --- a/src/System.Reflection/tests/CoreCLR/System.Reflection.CoreCLR.Tests.csproj +++ b/src/System.Reflection/tests/CoreCLR/System.Reflection.CoreCLR.Tests.csproj @@ -10,9 +10,6 @@ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> </PropertyGroup> <ItemGroup> - <None Include="project.json" /> - </ItemGroup> - <ItemGroup> <Compile Include="AssemblyTests.CoreCLR.cs" /> </ItemGroup> <ItemGroup> diff --git a/src/System.Reflection/tests/TestExe/System.Reflection.TestExe.csproj b/src/System.Reflection/tests/TestExe/System.Reflection.TestExe.csproj index 77e9804a1b..3fc1f8ebbd 100644 --- a/src/System.Reflection/tests/TestExe/System.Reflection.TestExe.csproj +++ b/src/System.Reflection/tests/TestExe/System.Reflection.TestExe.csproj @@ -4,7 +4,6 @@ <PropertyGroup> <ProjectGuid>{8C19B991-41E9-4B38-9602-E19375397F1D}</ProjectGuid> <OutputType>Exe</OutputType> - <NoWarn>0436</NoWarn> </PropertyGroup> <!-- Default configurations to help VS understand the configurations --> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" /> @@ -15,8 +14,5 @@ <Link>Common\System\Diagnostics\CodeAnalysis\ExcludeFromCodeCoverageAssemblyAttribute.cs</Link> </Compile> </ItemGroup> - <ItemGroup> - <None Include="project.json" /> - </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> </Project>
\ No newline at end of file diff --git a/src/System.Resources.ResourceManager/src/System.Resources.ResourceManager.csproj b/src/System.Resources.ResourceManager/src/System.Resources.ResourceManager.csproj index cefe71aaaa..08e199e95b 100644 --- a/src/System.Resources.ResourceManager/src/System.Resources.ResourceManager.csproj +++ b/src/System.Resources.ResourceManager/src/System.Resources.ResourceManager.csproj @@ -29,7 +29,6 @@ <Compile Include="$(CommonPath)\System\SR.Core.cs"> <Link>Common\System\SR.Core.cs</Link> </Compile> - <TargetingPackReference Include="System.Private.CoreLib.WinRTInterop" /> <Reference Include="mscorlib" /> <Reference Include="Windows" /> <Reference Include="System.Resources.Reader" /> diff --git a/src/System.Runtime.Extensions/src/System/BitConverter.cs b/src/System.Runtime.Extensions/src/System/BitConverter.cs index 8b03ffe081..9dd8a4135a 100644 --- a/src/System.Runtime.Extensions/src/System/BitConverter.cs +++ b/src/System.Runtime.Extensions/src/System/BitConverter.cs @@ -236,13 +236,13 @@ namespace System { int i1 = (*pbyte) | (*(pbyte + 1) << 8) | (*(pbyte + 2) << 16) | (*(pbyte + 3) << 24); int i2 = (*(pbyte + 4)) | (*(pbyte + 5) << 8) | (*(pbyte + 6) << 16) | (*(pbyte + 7) << 24); - return (uint)i1 | ((long)i2 << 32); + return unchecked((uint)i1) | ((long)i2 << 32); } else { int i1 = (*pbyte << 24) | (*(pbyte + 1) << 16) | (*(pbyte + 2) << 8) | (*(pbyte + 3)); int i2 = (*(pbyte + 4) << 24) | (*(pbyte + 5) << 16) | (*(pbyte + 6) << 8) | (*(pbyte + 7)); - return (uint)i2 | ((long)i1 << 32); + return unchecked((uint)i2) | ((long)i1 << 32); } } } diff --git a/src/System.Runtime.Extensions/tests/AssemblyResolveTests/AssemblyResolveTests.csproj b/src/System.Runtime.Extensions/tests/AssemblyResolveTests/AssemblyResolveTests.csproj index 96103be4cd..bca454c68a 100644 --- a/src/System.Runtime.Extensions/tests/AssemblyResolveTests/AssemblyResolveTests.csproj +++ b/src/System.Runtime.Extensions/tests/AssemblyResolveTests/AssemblyResolveTests.csproj @@ -4,7 +4,6 @@ <PropertyGroup> <ProjectGuid>ad83807c-8be5-4f27-85df-9793613233e1</ProjectGuid> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> - <NoWarn>0436</NoWarn> </PropertyGroup> <!-- Default configurations to help VS understand the configurations --> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" /> diff --git a/src/System.Runtime.Extensions/tests/TestApp/TestApp.csproj b/src/System.Runtime.Extensions/tests/TestApp/TestApp.csproj index b19a5c2adc..9b30e2e22e 100644 --- a/src/System.Runtime.Extensions/tests/TestApp/TestApp.csproj +++ b/src/System.Runtime.Extensions/tests/TestApp/TestApp.csproj @@ -5,7 +5,6 @@ <ProjectGuid>{24BCEC6B-B9D2-47BC-9D66-725BD6B526FA}</ProjectGuid> <OutputType>Exe</OutputType> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> - <NoWarn>0436</NoWarn> </PropertyGroup> <!-- Default configurations to help VS understand the configurations --> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" /> @@ -19,8 +18,5 @@ <Link>Common\System\Diagnostics\CodeAnalysis\ExcludeFromCodeCoverageAssemblyAttribute.cs</Link> </Compile> </ItemGroup> - <ItemGroup> - <None Include="project.json" /> - </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> </Project>
\ No newline at end of file diff --git a/src/System.Runtime.Extensions/tests/TestAppOutsideOfTPA/TestAppOutsideOfTPA.csproj b/src/System.Runtime.Extensions/tests/TestAppOutsideOfTPA/TestAppOutsideOfTPA.csproj index aa9e8c1998..3a416dcd4a 100644 --- a/src/System.Runtime.Extensions/tests/TestAppOutsideOfTPA/TestAppOutsideOfTPA.csproj +++ b/src/System.Runtime.Extensions/tests/TestAppOutsideOfTPA/TestAppOutsideOfTPA.csproj @@ -5,7 +5,6 @@ <ProjectGuid>{C44B33E3-F89F-40B9-B353-D380C1524988}</ProjectGuid> <OutputType>Exe</OutputType> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> - <NoWarn>0436</NoWarn> </PropertyGroup> <!-- Default configurations to help VS understand the configurations --> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" /> diff --git a/src/System.Runtime.Extensions/tests/VoidMainWithExitCodeApp/VoidMainWithExitCodeApp.csproj b/src/System.Runtime.Extensions/tests/VoidMainWithExitCodeApp/VoidMainWithExitCodeApp.csproj index 90f54284b8..56c6550e0c 100644 --- a/src/System.Runtime.Extensions/tests/VoidMainWithExitCodeApp/VoidMainWithExitCodeApp.csproj +++ b/src/System.Runtime.Extensions/tests/VoidMainWithExitCodeApp/VoidMainWithExitCodeApp.csproj @@ -5,7 +5,6 @@ <ProjectGuid>{9F312D76-9AF1-4E90-B3B0-815A1EC6C346}</ProjectGuid> <OutputType>Exe</OutputType> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> - <NoWarn>0436</NoWarn> </PropertyGroup> <!-- Default configurations to help VS understand the configurations --> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" /> diff --git a/src/System.Runtime.Loader/tests/DefaultContext/System.Runtime.Loader.DefaultContext.Tests.csproj b/src/System.Runtime.Loader/tests/DefaultContext/System.Runtime.Loader.DefaultContext.Tests.csproj index 2c8a4bdeef..38c67574ee 100644 --- a/src/System.Runtime.Loader/tests/DefaultContext/System.Runtime.Loader.DefaultContext.Tests.csproj +++ b/src/System.Runtime.Loader/tests/DefaultContext/System.Runtime.Loader.DefaultContext.Tests.csproj @@ -11,9 +11,6 @@ <Compile Include="DefaultLoadContextTest.cs" /> </ItemGroup> <ItemGroup> - <None Include="project.json" /> - </ItemGroup> - <ItemGroup> <ProjectReference Include="../System.Runtime.Loader.Noop.Assembly/System.Runtime.Loader.Noop.Assembly.csproj"> <ReferenceOutputAssembly>false</ReferenceOutputAssembly> <OutputItemType>content</OutputItemType> diff --git a/src/System.Runtime.Loader/tests/System.Runtime.Loader.Noop.Assembly/System.Runtime.Loader.Noop.Assembly.csproj b/src/System.Runtime.Loader/tests/System.Runtime.Loader.Noop.Assembly/System.Runtime.Loader.Noop.Assembly.csproj index d027519f8a..602ec55b12 100644 --- a/src/System.Runtime.Loader/tests/System.Runtime.Loader.Noop.Assembly/System.Runtime.Loader.Noop.Assembly.csproj +++ b/src/System.Runtime.Loader/tests/System.Runtime.Loader.Noop.Assembly/System.Runtime.Loader.Noop.Assembly.csproj @@ -5,15 +5,11 @@ <ProjectGuid>{396D6EBF-60BD-4DAF-8783-FB403E070A57}</ProjectGuid> <!-- Test expects an un-signed assembly --> <SkipSigning>true</SkipSigning> - <NoWarn>0436</NoWarn> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'" /> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|AnyCPU'" /> <ItemGroup> <Compile Include="TestClass.cs" /> </ItemGroup> - <ItemGroup> - <None Include="project.json" /> - </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> </Project>
\ No newline at end of file diff --git a/src/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj b/src/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj index 5c6933452c..92b556f3aa 100644 --- a/src/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj +++ b/src/System.Runtime.Loader/tests/System.Runtime.Loader.Tests.csproj @@ -16,9 +16,6 @@ <Compile Include="ResourceAssemblyLoadContext.cs" /> </ItemGroup> <ItemGroup> - <None Include="project.json" /> - </ItemGroup> - <ItemGroup> <EmbeddedResource Include="System.Runtime.Loader.Test.Assembly.dll" /> </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> diff --git a/src/System.Runtime.Serialization.Formatters/tests/System.Runtime.Serialization.Formatters.Tests.csproj b/src/System.Runtime.Serialization.Formatters/tests/System.Runtime.Serialization.Formatters.Tests.csproj index 62af51f7ff..510ccdaa99 100644 --- a/src/System.Runtime.Serialization.Formatters/tests/System.Runtime.Serialization.Formatters.Tests.csproj +++ b/src/System.Runtime.Serialization.Formatters/tests/System.Runtime.Serialization.Formatters.Tests.csproj @@ -29,9 +29,6 @@ </Compile> </ItemGroup> <ItemGroup> - <None Include="project.json" /> - </ItemGroup> - <ItemGroup> <ProjectReference Include="$(CommonTestPath)\System\Diagnostics\RemoteExecutorConsoleApp\RemoteExecutorConsoleApp.csproj"> <Project>{69e46a6f-9966-45a5-8945-2559fe337827}</Project> <Name>RemoteExecutorConsoleApp</Name> diff --git a/src/System.Runtime.Serialization.Json/tests/Performance/System.Runtime.Serialization.Json.Performance.Tests.csproj b/src/System.Runtime.Serialization.Json/tests/Performance/System.Runtime.Serialization.Json.Performance.Tests.csproj index 83e7f2739b..4ba345169a 100644 --- a/src/System.Runtime.Serialization.Json/tests/Performance/System.Runtime.Serialization.Json.Performance.Tests.csproj +++ b/src/System.Runtime.Serialization.Json/tests/Performance/System.Runtime.Serialization.Json.Performance.Tests.csproj @@ -16,7 +16,7 @@ <Compile Include="JsonNetPerformanceTest.cs" /> </ItemGroup> <ItemGroup> - <None Include="project.json" /> + <ReferenceFromRuntime Include="Newtonsoft.Json" /> </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> -</Project>
\ No newline at end of file +</Project> diff --git a/src/System.Runtime.Serialization.Xml/ref/System.Runtime.Serialization.Xml.csproj b/src/System.Runtime.Serialization.Xml/ref/System.Runtime.Serialization.Xml.csproj index e03da2bed7..8506313073 100644 --- a/src/System.Runtime.Serialization.Xml/ref/System.Runtime.Serialization.Xml.csproj +++ b/src/System.Runtime.Serialization.Xml/ref/System.Runtime.Serialization.Xml.csproj @@ -2,7 +2,6 @@ <Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> <PropertyGroup> - <NoWarn Condition="'$(TargetGroup)' == 'netfx'">$(NoWarn);0436</NoWarn> <ProjectGuid>{025743B4-6E1E-4602-BE7F-1E479CC8EEBE}</ProjectGuid> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netcoreapp-Debug|AnyCPU'" /> diff --git a/src/System.Runtime.WindowsRuntime/src/Resources/Strings.resx b/src/System.Runtime.WindowsRuntime/src/Resources/Strings.resx index 520ebf7c70..5c7c933542 100644 --- a/src/System.Runtime.WindowsRuntime/src/Resources/Strings.resx +++ b/src/System.Runtime.WindowsRuntime/src/Resources/Strings.resx @@ -282,60 +282,9 @@ <data name="NotSupported_UnwritableStream" xml:space="preserve"> <value>Stream does not support writing.</value> </data> - <data name="ArgumentNull_Buffer" xml:space="preserve"> - <value>Buffer cannot be null.</value> - </data> - <data name="ArgumentOutOfRange_NegFileSize" xml:space="preserve"> - <value>Length must be non-negative.</value> - </data> - <data name="NotSupported_CannotWriteToBufferedStreamIfReadBufferCannotBeFlushed" xml:space="preserve"> - <value>Cannot write to a BufferedStream while the read buffer is not empty if the underlying stream is not seekable. Ensure that the stream underlying this BufferedStream can seek or avoid interleaving read and write operations on this BufferedStream.</value> - </data> - <data name="Argument_InvalidSafeBufferOffLen" xml:space="preserve"> - <value>Offset and length were greater than the size of the SafeBuffer.</value> - </data> - <data name="InvalidOperation_CalledTwice" xml:space="preserve"> - <value>The method cannot be called twice on the same instance.</value> - </data> - <data name="ArgumentOutOfRange_LengthGreaterThanCapacity" xml:space="preserve"> - <value>The length cannot be greater than the capacity.</value> - </data> - <data name="ArgumentOutOfRange_UnmanagedMemStreamWrapAround" xml:space="preserve"> - <value>The UnmanagedMemoryStream capacity would wrap around the high end of the address space.</value> - </data> - <data name="ArgumentOutOfRange_Enum" xml:space="preserve"> - <value>Enum value was out of legal range.</value> - </data> - <data name="NotSupported_UmsSafeBuffer" xml:space="preserve"> - <value>This operation is not supported for an UnmanagedMemoryStream created from a SafeBuffer.</value> - </data> - <data name="IndexOutOfRange_UMSPosition" xml:space="preserve"> - <value>Unmanaged memory stream position was beyond the capacity of the stream.</value> - </data> - <data name="IO_SeekBeforeBegin" xml:space="preserve"> - <value>An attempt was made to move the position before the beginning of the stream.</value> - </data> <data name="Argument_InvalidSeekOrigin" xml:space="preserve"> <value>Invalid seek origin.</value> </data> - <data name="IO_FixedCapacity" xml:space="preserve"> - <value>Unable to expand length of this stream beyond its capacity.</value> - </data> - <data name="IO_StreamTooLong" xml:space="preserve"> - <value>Stream was too long.</value> - </data> - <data name="Arg_BufferTooSmall" xml:space="preserve"> - <value>Not enough space available in the buffer.</value> - </data> - <data name="ArgumentOutOfRange_NeedNonNegNum" xml:space="preserve"> - <value>Non-negative number required.</value> - </data> - <data name="Argument_InvalidOffLen" xml:space="preserve"> - <value>Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.</value> - </data> - <data name="ArgumentOutOfRange_StreamLength" xml:space="preserve"> - <value>Stream length must be non-negative and less than 2^31 - 1 - origin.</value> - </data> <data name="DirectUI_Empty" xml:space="preserve"> <value>Empty.</value> </data> diff --git a/src/System.Runtime.WindowsRuntime/src/System.Runtime.WindowsRuntime.csproj b/src/System.Runtime.WindowsRuntime/src/System.Runtime.WindowsRuntime.csproj index 7f397c51b8..59873e3598 100644 --- a/src/System.Runtime.WindowsRuntime/src/System.Runtime.WindowsRuntime.csproj +++ b/src/System.Runtime.WindowsRuntime/src/System.Runtime.WindowsRuntime.csproj @@ -28,10 +28,9 @@ <Reference Include="Windows" /> <!-- Needed for the compiler to resolve IObservableMap.MapChanged. --> <ProjectReference Include="..\..\System.Runtime\src\System.Runtime.csproj" /> - <Reference Include="System.Runtime.Extensions"> + <ProjectReference Include="..\..\System.Runtime.Extensions\src\System.Runtime.Extensions.csproj"> <Aliases>System_Runtime_Extensions</Aliases> - </Reference> - <ProjectReference Include="..\..\System.Diagnostics.Debug\src\System.Diagnostics.Debug.csproj" /> + </ProjectReference> <ProjectReference Include="..\..\System.Diagnostics.Debug\src\System.Diagnostics.Debug.csproj" /> <ProjectReference Include="..\..\System.Diagnostics.Tools\src\System.Diagnostics.Tools.csproj" /> <ProjectReference Include="..\..\System.Runtime.InteropServices.WindowsRuntime\src\System.Runtime.InteropServices.WindowsRuntime.csproj" /> <ProjectReference Include="..\..\System.ObjectModel\src\System.ObjectModel.csproj" /> @@ -58,8 +57,9 @@ <ProjectReference Include="..\..\System.Runtime\src\System.Runtime.csproj"> <TargetGroup>uapaot</TargetGroup> </ProjectReference> - <ProjectReference Include="..\..\System.Runtime.Extensions\ref\System.Runtime.Extensions.csproj"> + <ProjectReference Include="..\..\System.Runtime.Extensions\src\System.Runtime.Extensions.csproj"> <Aliases>System_Runtime_Extensions</Aliases> + <TargetGroup>uapaot</TargetGroup> </ProjectReference> <ProjectReference Include="..\..\System.Resources.ResourceManager\src\System.Resources.ResourceManager.csproj"> <TargetGroup>uapaot</TargetGroup> @@ -81,7 +81,6 @@ </ItemGroup> <ItemGroup Condition="'$(TargetGroup)'=='uapaot'"> <Compile Include="System\IO\StreamOperationAsyncResult.CoreRT.cs" /> - <Compile Include="System\IO\UnmanagedMemoryStreamInternal.cs" /> <Compile Include="System\Threading\Tasks\AsyncInfoToTaskBridge.CoreRT.cs" /> <Compile Include="System\WindowsRuntimeSystemExtensions.CoreRT.cs" /> </ItemGroup> diff --git a/src/System.Runtime.WindowsRuntime/src/System/IO/NetFxToWinRtStreamAdapter.cs b/src/System.Runtime.WindowsRuntime/src/System/IO/NetFxToWinRtStreamAdapter.cs index b64bd327cf..52ac810801 100644 --- a/src/System.Runtime.WindowsRuntime/src/System/IO/NetFxToWinRtStreamAdapter.cs +++ b/src/System.Runtime.WindowsRuntime/src/System/IO/NetFxToWinRtStreamAdapter.cs @@ -2,10 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -extern alias System_Runtime_Extensions; - using System.Diagnostics; using System.Diagnostics.Contracts; +using System.IO; using System.Runtime.InteropServices.WindowsRuntime; using System.Runtime.InteropServices; using System.Runtime.WindowsRuntime.Internal; @@ -14,8 +13,6 @@ using System.Threading; using Windows.Foundation; using Windows.Storage.Streams; -using MemoryStream = System_Runtime_Extensions::System.IO.MemoryStream; - namespace System.IO { /// <summary> diff --git a/src/System.Runtime.WindowsRuntime/src/System/IO/StreamOperationsImplementation.cs b/src/System.Runtime.WindowsRuntime/src/System/IO/StreamOperationsImplementation.cs index b5658619b7..1664c81929 100644 --- a/src/System.Runtime.WindowsRuntime/src/System/IO/StreamOperationsImplementation.cs +++ b/src/System.Runtime.WindowsRuntime/src/System/IO/StreamOperationsImplementation.cs @@ -2,10 +2,9 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -extern alias System_Runtime_Extensions; - using System.Diagnostics; using System.Diagnostics.Contracts; +using System.IO; using System.Runtime.InteropServices.WindowsRuntime; using System.Runtime.InteropServices; using System.Threading.Tasks; @@ -13,10 +12,6 @@ using System.Threading; using Windows.Foundation; using Windows.Storage.Streams; -// Type aliases cannot match existing typenames. In this file our code is in System.IO, which would -// create two MemoryStream definitions that are in scope if we defined as MemoryStream. -using SREMemoryStream = System_Runtime_Extensions::System.IO.MemoryStream; - namespace System.IO { /// <summary>Depending on the concrete type of the stream managed by a <c>NetFxToWinRtStreamAdapter</c>, @@ -33,7 +28,7 @@ namespace System.IO internal static IAsyncOperationWithProgress<IBuffer, UInt32> ReadAsync_MemoryStream(Stream stream, IBuffer buffer, UInt32 count) { Debug.Assert(stream != null); - Debug.Assert(stream is SREMemoryStream); + Debug.Assert(stream is MemoryStream); Debug.Assert(stream.CanRead); Debug.Assert(stream.CanSeek); Debug.Assert(buffer != null); @@ -48,7 +43,7 @@ namespace System.IO // The user specified buffer will not have any data put into it: buffer.Length = 0; - SREMemoryStream memStream = stream as SREMemoryStream; + MemoryStream memStream = stream as MemoryStream; Debug.Assert(memStream != null); try diff --git a/src/System.Runtime.WindowsRuntime/src/System/IO/UnmanagedMemoryStreamInternal.cs b/src/System.Runtime.WindowsRuntime/src/System/IO/UnmanagedMemoryStreamInternal.cs deleted file mode 100644 index a1c96c62d7..0000000000 --- a/src/System.Runtime.WindowsRuntime/src/System/IO/UnmanagedMemoryStreamInternal.cs +++ /dev/null @@ -1,450 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System; -using System.Diagnostics; -using System.Diagnostics.Contracts; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Runtime.WindowsRuntime.Internal; -using System.Runtime; -using System.Security; -using System.Threading; - -namespace System.IO -{ - [Flags] - internal enum FileAccess - { - // Specifies read access to the file. Data can be read from the file and - // the file pointer can be moved. Combine with WRITE for read-write access. - Read = 1, - - // Specifies write access to the file. Data can be written to the file and - // the file pointer can be moved. Combine with READ for read-write access. - Write = 2, - - // Specifies read and write access to the file. Data can be written to the - // file and the file pointer can be moved. Data can also be read from the - // file. - ReadWrite = 3, - } - - /* - * This class is used to access a contiguous block of memory, likely outside - * the GC heap (or pinned in place in the GC heap, but a MemoryStream may - * make more sense in those cases). It's great if you have a pointer and - * a length for a section of memory mapped in by someone else and you don't - * want to copy this into the GC heap. UnmanagedMemoryStream assumes these - * two things: - * - * 1) All the memory in the specified block is readable or writable, - * depending on the values you pass to the constructor. - * 2) The lifetime of the block of memory is at least as long as the lifetime - * of the UnmanagedMemoryStream. - * 3) You clean up the memory when appropriate. The UnmanagedMemoryStream - * currently will do NOTHING to free this memory. - * 4) All calls to Write and WriteByte may not be threadsafe currently. - * - * It may become necessary to add in some sort of - * DeallocationMode enum, specifying whether we unmap a section of memory, - * call free, run a user-provided delegate to free the memory, etc etc. - * We'll suggest user write a subclass of UnmanagedMemoryStream that uses - * a SafeHandle subclass to hold onto the memory. - * Check for problems when using this in the negative parts of a - * process's address space. We may need to use unsigned longs internally - * and change the overflow detection logic. - */ - internal class UnmanagedMemoryStream : Stream - { - private unsafe byte* _mem; - private long _length; - private long _capacity; - private long _position; - private FileAccess _access; - internal bool _isOpen; - - // Needed for subclasses that need to map a file, etc. - protected UnmanagedMemoryStream() - { - unsafe - { - _mem = null; - } - _isOpen = false; - } - - public unsafe UnmanagedMemoryStream(byte* pointer, long length) - { - Initialize(pointer, length, length, FileAccess.Read, false); - } - - public unsafe UnmanagedMemoryStream(byte* pointer, long length, long capacity, FileAccess access) - { - Initialize(pointer, length, capacity, access, false); - } - - // We must create one of these without doing a security check. This - // class is created while security is trying to start up. Plus, doing - // a Demand from Assembly.GetManifestResourceStream isn't useful. - internal unsafe UnmanagedMemoryStream(byte* pointer, long length, long capacity, FileAccess access, bool skipSecurityCheck) - { - Initialize(pointer, length, capacity, access, skipSecurityCheck); - } - - protected unsafe void Initialize(byte* pointer, long length, long capacity, FileAccess access) - { - Initialize(pointer, length, capacity, access, false); - } - - internal unsafe void Initialize(byte* pointer, long length, long capacity, FileAccess access, bool skipSecurityCheck) - { - if (pointer == null) - throw new ArgumentNullException(nameof(pointer)); - if (length < 0 || capacity < 0) - throw new ArgumentOutOfRangeException((length < 0) ? nameof(length): nameof(capacity), SR.ArgumentOutOfRange_NeedNonNegNum); - if (length > capacity) - throw new ArgumentOutOfRangeException(nameof(length), SR.ArgumentOutOfRange_LengthGreaterThanCapacity); - Contract.EndContractBlock(); - // Check for wraparound. - if (((byte*)((long)pointer + capacity)) < pointer) - throw new ArgumentOutOfRangeException(nameof(capacity), SR.ArgumentOutOfRange_UnmanagedMemStreamWrapAround); - if (access < FileAccess.Read || access > FileAccess.ReadWrite) - throw new ArgumentOutOfRangeException(nameof(access), SR.ArgumentOutOfRange_Enum); - if (_isOpen) - throw new InvalidOperationException(SR.InvalidOperation_CalledTwice); - - _mem = pointer; - _length = length; - _capacity = capacity; - _access = access; - _isOpen = true; - } - - public override bool CanRead - { - [Pure] - get - { return _isOpen && (_access & FileAccess.Read) != 0; } - } - - public override bool CanSeek - { - [Pure] - get - { return _isOpen; } - } - - public override bool CanWrite - { - [Pure] - get - { return _isOpen && (_access & FileAccess.Write) != 0; } - } - - [System.Security.SecuritySafeCritical] // auto-generated - protected override void Dispose(bool disposing) - { - _isOpen = false; - unsafe { _mem = null; } - - // Stream allocates WaitHandles for async calls. So for correctness - // call base.Dispose(disposing) for better perf, avoiding waiting - // for the finalizers to run on those types. - base.Dispose(disposing); - } - - public override void Flush() - { - if (!_isOpen) throw new ObjectDisposedException(null, SR.ObjectDisposed_StreamClosed); - } - - public override long Length - { - get - { - if (!_isOpen) throw new ObjectDisposedException(null, SR.ObjectDisposed_StreamClosed); - return Interlocked.Read(ref _length); - } - } - - public long Capacity - { - get - { - if (!_isOpen) throw new ObjectDisposedException(null, SR.ObjectDisposed_StreamClosed); - return _capacity; - } - } - - public override long Position - { - get - { - if (!CanSeek) throw new ObjectDisposedException(null, SR.ObjectDisposed_StreamClosed); - Contract.EndContractBlock(); - return Interlocked.Read(ref _position); - } - [System.Security.SecuritySafeCritical] // auto-generated - set - { - if (value < 0) - throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); - if (!CanSeek) throw new ObjectDisposedException(null, SR.ObjectDisposed_StreamClosed); - -#if WIN32 - unsafe - { - // On 32 bit machines, ensure we don't wrap around. - if (value > (long)Int32.MaxValue || _mem + value < _mem) - throw new ArgumentOutOfRangeException(nameof(value), SR.ArgumentOutOfRange_StreamLength); - } -#endif - Interlocked.Exchange(ref _position, value); - } - } - - public unsafe byte* PositionPointer - { - get - { - // Use a temp to avoid a race - long pos = Interlocked.Read(ref _position); - if (pos > _capacity) - throw new IndexOutOfRangeException(SR.IndexOutOfRange_UMSPosition); - byte* ptr = _mem + pos; - if (!_isOpen) throw new ObjectDisposedException(null, SR.ObjectDisposed_StreamClosed); - return ptr; - } - set - { - if (!_isOpen) throw new ObjectDisposedException(null, SR.ObjectDisposed_StreamClosed); - - if (value < _mem) - throw new IOException(SR.IO_SeekBeforeBegin); - - Interlocked.Exchange(ref _position, value - _mem); - } - } - - internal unsafe byte* Pointer - { - get - { - return _mem; - } - } - - [System.Security.SecuritySafeCritical] // auto-generated - public override int Read([In, Out] byte[] buffer, int offset, int count) - { - if (buffer == null) - throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer); - if (offset < 0) - throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum); - if (count < 0) - throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum); - if (buffer.Length - offset < count) - throw new ArgumentException(SR.Argument_InvalidOffLen); - Contract.EndContractBlock(); - - if (!_isOpen) throw new ObjectDisposedException(null, SR.ObjectDisposed_StreamClosed); - if (!CanRead) throw new NotSupportedException(SR.NotSupported_UnreadableStream); - - // Use a local variable to avoid a race where another thread - // changes our position after we decide we can read some bytes. - long pos = Interlocked.Read(ref _position); - long len = Interlocked.Read(ref _length); - long n = len - pos; - if (n > count) - n = count; - if (n <= 0) - return 0; - - int nInt = (int)n; // Safe because n <= count, which is an Int32 - Debug.Assert(pos + nInt >= 0, "_position + n >= 0"); // len is less than 2^63 -1. - - unsafe - { - Marshal.Copy((IntPtr)(_mem + pos), buffer, offset, nInt); - } - Interlocked.Exchange(ref _position, pos + n); - return nInt; - } - - [System.Security.SecuritySafeCritical] // auto-generated - public override int ReadByte() - { - if (!_isOpen) throw new ObjectDisposedException(null, SR.ObjectDisposed_StreamClosed); - if (!CanRead) throw new NotSupportedException(SR.NotSupported_UnreadableStream); - - long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition - long len = Interlocked.Read(ref _length); - if (pos >= len) - return -1; - Interlocked.Exchange(ref _position, pos + 1); - int result; - unsafe - { - result = _mem[pos]; - } - return result; - } - - public override long Seek(long offset, SeekOrigin loc) - { - if (!_isOpen) throw new ObjectDisposedException(null, SR.ObjectDisposed_StreamClosed); - switch (loc) - { - case SeekOrigin.Begin: - if (offset < 0) - throw new IOException(SR.IO_SeekBeforeBegin); - Interlocked.Exchange(ref _position, offset); - break; - - case SeekOrigin.Current: - long pos = Interlocked.Read(ref _position); - if (offset + pos < 0) - throw new IOException(SR.IO_SeekBeforeBegin); - Interlocked.Exchange(ref _position, offset + pos); - break; - - case SeekOrigin.End: - long len = Interlocked.Read(ref _length); - if (len + offset < 0) - throw new IOException(SR.IO_SeekBeforeBegin); - Interlocked.Exchange(ref _position, len + offset); - break; - - default: - throw new ArgumentException(SR.Argument_InvalidSeekOrigin); - } - - long finalPos = Interlocked.Read(ref _position); - Debug.Assert(finalPos >= 0, "_position >= 0"); - return finalPos; - } - - [System.Security.SecuritySafeCritical] // auto-generated - public override void SetLength(long value) - { - if (value < 0) - throw new ArgumentOutOfRangeException("length", SR.ArgumentOutOfRange_NeedNonNegNum); - Contract.EndContractBlock(); - if (!_isOpen) throw new ObjectDisposedException(null, SR.ObjectDisposed_StreamClosed); - if (!CanWrite) throw new NotSupportedException(SR.NotSupported_UnwritableStream); - - if (value > _capacity) - throw new IOException(SR.IO_FixedCapacity); - - long pos = Interlocked.Read(ref _position); - long len = Interlocked.Read(ref _length); - if (value > len) - { - unsafe - { - Helpers.ZeroMemory(_mem + len, value - len); - } - } - Interlocked.Exchange(ref _length, value); - if (pos > value) - { - Interlocked.Exchange(ref _position, value); - } - } - - [System.Security.SecuritySafeCritical] // auto-generated - public override void Write(byte[] buffer, int offset, int count) - { - if (buffer == null) - throw new ArgumentNullException(nameof(buffer), SR.ArgumentNull_Buffer); - if (offset < 0) - throw new ArgumentOutOfRangeException(nameof(offset), SR.ArgumentOutOfRange_NeedNonNegNum); - if (count < 0) - throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum); - if (buffer.Length - offset < count) - throw new ArgumentException(SR.Argument_InvalidOffLen); - Contract.EndContractBlock(); - - if (!_isOpen) throw new ObjectDisposedException(null, SR.ObjectDisposed_StreamClosed); - if (!CanWrite) throw new NotSupportedException(SR.NotSupported_UnwritableStream); - - long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition - long len = Interlocked.Read(ref _length); - long n = pos + count; - // Check for overflow - if (n < 0) - throw new IOException(SR.IO_StreamTooLong); - - if (n > _capacity) - { - throw new NotSupportedException(SR.IO_FixedCapacity); - } - - // Check to see whether we are now expanding the stream and must - // zero any memory in the middle. - if (pos > len) - { - unsafe - { - Helpers.ZeroMemory(_mem + len, pos - len); - } - } - - // set length after zeroing memory to avoid race condition of accessing unzeroed memory - if (n > len) - { - Interlocked.Exchange(ref _length, n); - } - - unsafe - { - Marshal.Copy(buffer, offset, (IntPtr)(_mem + pos), count); - } - - Interlocked.Exchange(ref _position, n); - return; - } - - [System.Security.SecuritySafeCritical] // auto-generated - public override void WriteByte(byte value) - { - if (!_isOpen) throw new ObjectDisposedException(null, SR.ObjectDisposed_StreamClosed); - if (!CanWrite) throw new NotSupportedException(SR.NotSupported_UnwritableStream); - - long pos = Interlocked.Read(ref _position); // Use a local to avoid a race condition - long len = Interlocked.Read(ref _length); - long n = pos + 1; - if (pos >= len) - { - // Check for overflow - if (n < 0) - throw new IOException(SR.IO_StreamTooLong); - - if (n > _capacity) - throw new NotSupportedException(SR.IO_FixedCapacity); - - // Check to see whether we are now expanding the stream and must - // zero any memory in the middle. - if (pos > len) - { - unsafe - { - Helpers.ZeroMemory(_mem + len, pos - len); - } - } - - // set length after zeroing memory to avoid race condition of accessing unzeroed memory - Interlocked.Exchange(ref _length, n); - } - - unsafe - { - _mem[pos] = value; - } - Interlocked.Exchange(ref _position, n); - } - } -} diff --git a/src/System.Runtime.WindowsRuntime/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeBufferExtensions.cs b/src/System.Runtime.WindowsRuntime/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeBufferExtensions.cs index dc19e8a45f..cfec66b647 100644 --- a/src/System.Runtime.WindowsRuntime/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeBufferExtensions.cs +++ b/src/System.Runtime.WindowsRuntime/src/System/Runtime/InteropServices/WindowsRuntime/WindowsRuntimeBufferExtensions.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -extern alias System_Runtime_Extensions; - using System.Diagnostics.Contracts; using System.Diagnostics; using System.IO; @@ -11,8 +9,6 @@ using System.Runtime.WindowsRuntime.Internal; using Windows.Foundation; using Windows.Storage.Streams; -using MemoryStream = System_Runtime_Extensions::System.IO.MemoryStream; - namespace System.Runtime.InteropServices.WindowsRuntime { /// <summary> diff --git a/src/System.Runtime/ref/System.Runtime.csproj b/src/System.Runtime/ref/System.Runtime.csproj index 4be931b6b9..349f7efa20 100644 --- a/src/System.Runtime/ref/System.Runtime.csproj +++ b/src/System.Runtime/ref/System.Runtime.csproj @@ -14,8 +14,5 @@ <Compile Include="System.Runtime.cs" /> <Compile Include="System.Runtime.Manual.cs" /> </ItemGroup> - <ItemGroup> - <None Include="project.json" /> - </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> </Project>
\ No newline at end of file diff --git a/src/System.Runtime/tests/System/ActivatorTests.cs b/src/System.Runtime/tests/System/ActivatorTests.cs index 5a40391038..4e8420835b 100644 --- a/src/System.Runtime/tests/System/ActivatorTests.cs +++ b/src/System.Runtime/tests/System/ActivatorTests.cs @@ -85,8 +85,10 @@ namespace System.Tests // out of Activator.CreateInstance. Accidental or not, we'll inherit that behavior on .NET Native.) Assert.Throws<InvalidCastException>(() => Activator.CreateInstance(typeof(Choice1), new object[] { new VarIntArgs(), 1, (short)2 })); - Assert.ThrowsAny<MissingMemberException>(() => Activator.CreateInstance<TypeWithoutDefaultCtor>()); // Type has no default constructor - Assert.Throws<TargetInvocationException>(() => Activator.CreateInstance<TypeWithDefaultCtorThatThrows>()); // Type has a default constructor throws an exception + Assert.ThrowsAny<MissingMemberException>(() => Activator.CreateInstance(typeof(TypeWithoutDefaultCtor))); // Type has no default constructor + Assert.Throws<TargetInvocationException>(() => Activator.CreateInstance(typeof(TypeWithDefaultCtorThatThrows))); // Type has a default constructor throws an exception + Assert.ThrowsAny<MissingMemberException>(() => Activator.CreateInstance(typeof(AbstractTypeWithDefaultCtor))); // Type is abstract + Assert.ThrowsAny<MissingMemberException>(() => Activator.CreateInstance(typeof(IInterfaceType))); // Type is an interface // Type is not a valid RuntimeType Assert.Throws<ArgumentException>("type", () => Activator.CreateInstance(Helpers.NonRuntimeType())); @@ -109,6 +111,23 @@ namespace System.Tests Assert.ThrowsAny<MissingMemberException>(() => Activator.CreateInstance<TypeWithoutDefaultCtor>()); // Type has no default constructor Assert.Throws<TargetInvocationException>(() => Activator.CreateInstance<TypeWithDefaultCtorThatThrows>()); // Type has a default constructor that throws + Assert.ThrowsAny<MissingMemberException>(() => Activator.CreateInstance<AbstractTypeWithDefaultCtor>()); // Type is abstract + Assert.ThrowsAny<MissingMemberException>(() => Activator.CreateInstance<IInterfaceType>()); // Type is an interface + } + + [Fact] + public static void TestActivatorOnNonActivatableFinalizableTypes() + { + // On runtimes where the generic Activator is implemented with special codegen intrinsics, we might allocate + // an uninitialized instance of the object before we realize there's no default constructor to run. + // Make sure this has no observable side effects. + Assert.ThrowsAny<MissingMemberException>(() => { Activator.CreateInstance<TypeWithPrivateDefaultCtorAndFinalizer>(); }); + + GC.Collect(); + GC.WaitForPendingFinalizers(); + GC.Collect(); + + Assert.False(TypeWithPrivateDefaultCtorAndFinalizer.WasCreated); } class PrivateType @@ -193,6 +212,27 @@ namespace System.Tests public class VarIntArgs { } + public class TypeWithPrivateDefaultCtorAndFinalizer + { + public static bool WasCreated { get; private set; } + + private TypeWithPrivateDefaultCtorAndFinalizer() { } + + ~TypeWithPrivateDefaultCtorAndFinalizer() + { + WasCreated = true; + } + } + + private interface IInterfaceType + { + } + + public abstract class AbstractTypeWithDefaultCtor + { + public AbstractTypeWithDefaultCtor() { } + } + public struct StructTypeWithoutReflectionMetadata { } public class TypeWithoutDefaultCtor diff --git a/src/System.Runtime/tests/TestAssembly/TestAssembly.csproj b/src/System.Runtime/tests/TestAssembly/TestAssembly.csproj index e2f985b940..b185e3f2e8 100644 --- a/src/System.Runtime/tests/TestAssembly/TestAssembly.csproj +++ b/src/System.Runtime/tests/TestAssembly/TestAssembly.csproj @@ -4,7 +4,6 @@ <PropertyGroup> <ProjectGuid>{2EF7D710-A7BD-4BB3-8EF6-3F0298CD4986}</ProjectGuid> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> - <NoWarn>0436</NoWarn> </PropertyGroup> <!-- Default configurations to help VS understand the configurations --> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" /> @@ -18,8 +17,5 @@ <Link>Common\System\Diagnostics\CodeAnalysis\ExcludeFromCodeCoverageAssemblyAttribute.cs</Link> </Compile> </ItemGroup> - <ItemGroup> - <None Include="project.json" /> - </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> </Project>
\ No newline at end of file diff --git a/src/System.Runtime/tests/TestLoadAssembly/TestLoadAssembly.csproj b/src/System.Runtime/tests/TestLoadAssembly/TestLoadAssembly.csproj index 2a5f962b9d..7a13ac873d 100644 --- a/src/System.Runtime/tests/TestLoadAssembly/TestLoadAssembly.csproj +++ b/src/System.Runtime/tests/TestLoadAssembly/TestLoadAssembly.csproj @@ -5,7 +5,6 @@ <ProjectGuid>{71DE1A1F-F8E2-452A-9D54-0385F6099DD3}</ProjectGuid> <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> <AssemblyVersion>1.0.0.0</AssemblyVersion> - <NoWarn>0436</NoWarn> </PropertyGroup> <!-- Default configurations to help VS understand the configurations --> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Debug|AnyCPU'" /> @@ -13,8 +12,5 @@ <ItemGroup> <Compile Include="TestLoadAssembly.cs" /> </ItemGroup> - <ItemGroup> - <None Include="project.json" /> - </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> </Project>
\ No newline at end of file diff --git a/src/System.Security.Cryptography.Csp/tests/System.Security.Cryptography.Csp.Tests.csproj b/src/System.Security.Cryptography.Csp/tests/System.Security.Cryptography.Csp.Tests.csproj index bc35d71dff..890efc49e8 100644 --- a/src/System.Security.Cryptography.Csp/tests/System.Security.Cryptography.Csp.Tests.csproj +++ b/src/System.Security.Cryptography.Csp/tests/System.Security.Cryptography.Csp.Tests.csproj @@ -107,8 +107,5 @@ <Link>CommonTest\System\Security\Cryptography\AlgorithmImplementations\RSA\RSAXml.cs</Link> </Compile> </ItemGroup> - <ItemGroup> - <None Include="project.json" /> - </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> </Project>
\ No newline at end of file diff --git a/src/System.Text.Encodings.Web/src/System.Text.Encodings.Web.csproj b/src/System.Text.Encodings.Web/src/System.Text.Encodings.Web.csproj index 276aafe4f9..646a5bd9bb 100644 --- a/src/System.Text.Encodings.Web/src/System.Text.Encodings.Web.csproj +++ b/src/System.Text.Encodings.Web/src/System.Text.Encodings.Web.csproj @@ -4,10 +4,9 @@ <PropertyGroup> <ProjectGuid>{B7EDBF00-765A-48E8-B593-CD668288E274}</ProjectGuid> <RootNamespace>System.Text.Encodings.Web</RootNamespace> - <AssemblyName>System.Text.Encodings.Web</AssemblyName> <AllowUnsafeBlocks>true</AllowUnsafeBlocks> <UseOpenKey Condition="'$(UseOpenKey)'==''">true</UseOpenKey> - <DocumentationFile>$(OutputPath)$(AssemblyName).xml</DocumentationFile> + <DocumentationFile>$(OutputPath)$(MSBuildProjectName).xml</DocumentationFile> </PropertyGroup> <!-- Default configurations to help VS understand the configurations --> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='netstandard1.0-Debug|AnyCPU'" /> diff --git a/src/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj b/src/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj index 8882d7ff9e..387a90baa9 100644 --- a/src/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj +++ b/src/System.Threading.Tasks.Dataflow/src/System.Threading.Tasks.Dataflow.csproj @@ -4,8 +4,7 @@ <PropertyGroup> <ProjectGuid>{2E2F7224-7C72-4A81-9625-A5241F8D836D}</ProjectGuid> <RootNamespace>System.Threading.Tasks.Dataflow</RootNamespace> - <AssemblyName>System.Threading.Tasks.Dataflow</AssemblyName> - <DocumentationFile>$(OutputPath)System.Threading.Tasks.Dataflow.XML</DocumentationFile> + <DocumentationFile>$(OutputPath)$(MSBuildProjectName).xml</DocumentationFile> <DefineConstants Condition="'$(TargetGroup)' == 'netstandard1.1' OR '$(TargetGroup)' == 'netstandard'">$(DefineConstants);CONCURRENT_COLLECTIONS;FEATURE_TRACING</DefineConstants> <PackageTargetFramework Condition="'$(TargetGroup)' == 'netstandard1.1'">netstandard1.1;portable-net45+win8+wpa81</PackageTargetFramework> </PropertyGroup> diff --git a/src/System.Threading.Tasks.Extensions/src/System.Threading.Tasks.Extensions.csproj b/src/System.Threading.Tasks.Extensions/src/System.Threading.Tasks.Extensions.csproj index 1c62c86b8a..3baaf495e6 100644 --- a/src/System.Threading.Tasks.Extensions/src/System.Threading.Tasks.Extensions.csproj +++ b/src/System.Threading.Tasks.Extensions/src/System.Threading.Tasks.Extensions.csproj @@ -3,8 +3,7 @@ <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" /> <PropertyGroup> <ProjectGuid>{DE90AD0B-649D-4062-B8D9-9658DE140532}</ProjectGuid> - <AssemblyName>System.Threading.Tasks.Extensions</AssemblyName> - <DocumentationFile>$(OutputPath)$(AssemblyName).xml</DocumentationFile> + <DocumentationFile>$(OutputPath)$(MSBuildProjectName).xml</DocumentationFile> <UseOpenKey Condition="'$(UseOpenKey)'==''">true</UseOpenKey> <PackageTargetFramework Condition="'$(TargetGroup)' == 'netstandard1.0'">netstandard1.0;portable-net45+win8+wp8+wpa81</PackageTargetFramework> </PropertyGroup> diff --git a/src/System.Threading.Thread/tests/System.Threading.Thread.Tests.csproj b/src/System.Threading.Thread/tests/System.Threading.Thread.Tests.csproj index af2aba9722..d05f9b23f9 100644 --- a/src/System.Threading.Thread/tests/System.Threading.Thread.Tests.csproj +++ b/src/System.Threading.Thread/tests/System.Threading.Thread.Tests.csproj @@ -19,8 +19,5 @@ <Link>CommonTest\System\Threading\ThreadPoolHelpers.cs</Link> </Compile> </ItemGroup> - <ItemGroup> - <None Include="project.json" /> - </ItemGroup> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" /> </Project> diff --git a/src/System.ValueTuple/src/System.ValueTuple.csproj b/src/System.ValueTuple/src/System.ValueTuple.csproj index 98245c2b25..2548407245 100644 --- a/src/System.ValueTuple/src/System.ValueTuple.csproj +++ b/src/System.ValueTuple/src/System.ValueTuple.csproj @@ -4,7 +4,7 @@ <PropertyGroup> <!-- rev'ed to 4.0.1.0 even though 4.0.0.0 never shipped so that we can drop pre-release down to beta --> <ProjectGuid>{4C2655DB-BD9E-4C86-83A6-744ECDDBDF29}</ProjectGuid> - <DocumentationFile>$(OutputPath)$(AssemblyName).xml</DocumentationFile> + <DocumentationFile>$(OutputPath)$(MSBuildProjectName).xml</DocumentationFile> <UseOpenKey Condition="'$(UseOpenKey)'==''">true</UseOpenKey> <IsPartialFacadeAssembly Condition="'$(TargetGroup)' == 'netcoreapp' OR '$(TargetGroup)' == 'uap'">true</IsPartialFacadeAssembly> <RunApiCompat Condition="'$(TargetGroup)' != 'netcoreapp' AND '$(TargetGroup)' != 'uap'">false</RunApiCompat> diff --git a/targetingpacks.props b/targetingpacks.props deleted file mode 100644 index 9f4df8b4e7..0000000000 --- a/targetingpacks.props +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - - <!-- Adds test references to the targeting pack and runtime assemblies. --> - <Target Name="AddTestTargetingPackReferences" BeforeTargets="ResolveAssemblyReferences"> - <ItemGroup Condition="'$(IsTestProject)'=='true'"> - <TargetingPackExclusions Include="System.Private.CoreLib" /> - <TargetingPackExclusions Include="System.Runtime.WindowsRuntime.UI.Xaml" /> <!-- Harmless, but causes PRI targets to run --> - <TargetingPackExclusions Include="@(ReferenceFromRuntime)"/> - - <!-- Whitelisted runtime assemblies that are OK to reference. --> - <ReferenceFromRuntime Include="xunit.core" /> - <ReferenceFromRuntime Include="Xunit.NetCore.Extensions" /> - <ReferenceFromRuntime Include="xunit.assert" /> - <ReferenceFromRuntime Include="xunit.abstractions" /> - <ReferenceFromRuntime Include="xunit.performance.core" /> - <ReferenceFromRuntime Include="xunit.execution.dotnet" Condition="'$(_bc_TargetGroup)'!='netfx'"/> - <ReferenceFromRuntime Include="Newtonsoft.Json" Condition="'$(SkipIncludeNewtonsoftJson)'!='true'" /> - - <!-- Add Reference's to all files in the targeting pack folder, and to whitelisted items from the group above in the runtime folder. --> - <TargetingPackItems Include="%(TargetingPackDirs.Identity)/*" Condition="'$(NoTargetingPackReferences)' != 'true'" /> - </ItemGroup> - - <ItemGroup> - <Reference Include="%(TargetingPackItems.Filename)" Exclude="@(TargetingPackExclusions)"> <!-- TODO: System.Private.CoreLib shouldn't even be in the targeting pack. --> - <Private>false</Private> - </Reference> - </ItemGroup> - </Target> -</Project> |