Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dir.props
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@

<!-- Default Test platform to deploy the netstandard compiled tests to -->
<PropertyGroup>
<TestTFM Condition="'$(TestTFM)'=='' AND '$(TargetGroup)'=='netstandard1.7'">netcoreapp1.1</TestTFM>
<TestTFM Condition="'$(TestTFM)'=='' and ('$(TargetGroup)'=='netstandard1.7' or '$(TargetGroup)'=='netcoreapp1.1')">netcoreapp1.1</TestTFM>
<TestTFM Condition="'$(TestTFM)'==''">netcoreapp1.0</TestTFM>
<!-- we default FilterToTestTFM to netcoreapp1.1 if it is not explicity defined -->
<FilterToTestTFM Condition="'$(FilterToTestTFM)'==''">netcoreapp1.1</FilterToTestTFM>
Expand Down
13 changes: 0 additions & 13 deletions dir.targets
Original file line number Diff line number Diff line change
Expand Up @@ -58,19 +58,6 @@
</SupplementalTestData>
</ItemGroup>

<!-- ToDo: Remove this target and the following ItemGroup once the mapping between netstandard1.7 and netcoreapp1.1 is supported. Issue https://github.com/dotnet/corefx/issues/11321 -->
<Target Name="RemoveUnwantedTestMonikers" Condition="'$(TargetGroup)'=='netstandard1.7'" BeforeTargets="CopyTestToTestDirectory">
<ItemGroup>
<TestNugetTargetMoniker Remove=".NETCoreApp,Version=v1.1" />
</ItemGroup>
</Target>

<ItemGroup Condition="'$(TargetGroup)'=='netstandard1.7'">
<TestNugetTargetMoniker Include="$(NugetTargetMoniker)">
<Folder>netcoreapp1.1</Folder>
</TestNugetTargetMoniker>
</ItemGroup>

<ItemGroup Condition="'$(NuGetTargetMoniker)'=='.NETStandard,Version=v1.7'">
<!-- Temporarily suppress the message until we get a nuget version that knows about the mapping between netstandard1.7 and uap10.1 -->
<SuppressPackageTargetFrameworkCompatibility Include="uap10.1" />
Expand Down
3 changes: 2 additions & 1 deletion src/Common/src/System/IO/PathInternal.Unix.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ internal static partial class PathInternal

internal static readonly int MaxComponentLength = Interop.Sys.MaxName;

internal const string ParentDirectoryPrefix = @"../";

/// <summary>Returns a value indicating if the given path contains invalid characters.</summary>
internal static bool HasIllegalCharacters(string path)
{
Expand All @@ -25,7 +27,6 @@ internal static bool HasIllegalCharacters(string path)

internal static int GetRootLength(string path)
{
PathInternal.CheckInvalidPathChars(path);
return path.Length > 0 && IsDirectorySeparator(path[0]) ? 1 : 0;
}

Expand Down
2 changes: 2 additions & 0 deletions src/Common/src/System/IO/PathInternal.Windows.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ internal static partial class PathInternal
internal const string UncExtendedPrefixToInsert = @"?\UNC\";
internal const string UncExtendedPathPrefix = @"\\?\UNC\";
internal const string DevicePathPrefix = @"\\.\";
internal const string ParentDirectoryPrefix = @"..\";

internal const int MaxShortPath = 260;
internal const int MaxShortDirectoryPath = 248;
internal const int MaxLongPath = short.MaxValue;
Expand Down
87 changes: 83 additions & 4 deletions src/Common/src/System/IO/PathInternal.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal static void CheckInvalidPathChars(string path)
if (path == null)
throw new ArgumentNullException(nameof(path));

if (PathInternal.HasIllegalCharacters(path))
if (HasIllegalCharacters(path))
throw new ArgumentException(SR.Argument_InvalidPathChars, nameof(path));
}

Expand Down Expand Up @@ -98,16 +98,95 @@ internal static StringBuilder TrimEnd(this StringBuilder builder, params char[]
internal static int FindFileNameIndex(string path)
{
Debug.Assert(path != null);
PathInternal.CheckInvalidPathChars(path);
CheckInvalidPathChars(path);

for (int i = path.Length - 1; i >= 0; i--)
{
char ch = path[i];
if (IsDirectoryOrVolumeSeparator(ch))
return i + 1;
}

return 0; // the whole path is the filename
}

/// <summary>
/// Returns true if the path ends in a directory separator.
/// </summary>
internal static bool EndsInDirectorySeparator(string path) =>
!string.IsNullOrEmpty(path) && IsDirectorySeparator(path[path.Length - 1]);

/// <summary>
/// Get the common path length from the start of the string.
/// </summary>
internal static int GetCommonPathLength(string first, string second, bool ignoreCase)
{
int commonChars = EqualStartingCharacterCount(first, second, ignoreCase: ignoreCase);

// If nothing matches
if (commonChars == 0)
return commonChars;

// Or we're a full string and equal length or match to a separator
if (commonChars == first.Length
&& (commonChars == second.Length || IsDirectorySeparator(second[commonChars])))
return commonChars;

if (commonChars == second.Length && IsDirectorySeparator(first[commonChars]))
return commonChars;

// It's possible we matched somewhere in the middle of a segment e.g. C:\Foodie and C:\Foobar.
while (commonChars > 0 && !IsDirectorySeparator(first[commonChars - 1]))
commonChars--;

return commonChars;
}

/// <summary>
/// Gets the count of common characters from the left optionally ignoring case
/// </summary>
unsafe internal static int EqualStartingCharacterCount(string first, string second, bool ignoreCase)
Copy link
Copy Markdown
Contributor

@jamesqo jamesqo Sep 13, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to substitute this function with string.Compare or string.CompareOrdinal instead? The builtin string functions will typically be faster than hand-rolled pointer arithmetic. For example, CompareOrdinal compares 4 chars at a time and uses loop unrolling.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we had the same concept exposed, sure. I can't do it with string without calling compare repeatedly.

{
if (string.IsNullOrEmpty(first) || string.IsNullOrEmpty(second)) return 0;

int commonChars = 0;

fixed (char* f = first)
fixed (char* s = second)
{
char* l = f;
char* r = s;
char* leftEnd = l + first.Length;
char* rightEnd = r + second.Length;

while (l != leftEnd && r != rightEnd
&& (*l == *r || (ignoreCase && char.ToUpperInvariant((*l)) == char.ToUpperInvariant((*r)))))
{
commonChars++;
l++;
r++;
}
}

return commonChars;
}

/// <summary>
/// Returns true if the two paths have the same root
/// </summary>
internal static bool AreRootsEqual(string first, string second, StringComparison comparisonType)
{
int firstRootLength = GetRootLength(first);
int secondRootLength = GetRootLength(second);

return firstRootLength == secondRootLength
&& string.Compare(
strA: first,
indexA: 0,
strB: second,
indexB: 0,
length: firstRootLength,
comparisonType: comparisonType) == 0;
}
}
}
57 changes: 57 additions & 0 deletions src/Common/tests/Tests/System/IO/PathInternal.Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,62 @@ public void StartsWithOrdinal_PositiveCases(string source, string value, bool ex
Assert.Equal(expected, PathInternal.StartsWithOrdinal(source, value));
Assert.Equal(expected, PathInternal.StartsWithOrdinal(new StringBuilder(source), value));
}

[Theory,
InlineData("", "", true, 0)
InlineData("", "", false, 0)
InlineData("a", "", true, 0)
InlineData("a", "", false, 0)
InlineData("", "b", true, 0)
InlineData("", "b", false, 0)
InlineData("\0", "\0", true, 1)
InlineData("\0", "\0", false, 1)
InlineData("ABcd", "ABCD", true, 4)
InlineData("ABCD", "ABcd", true, 4)
InlineData("ABcd", "ABCD", false, 2)
InlineData("ABCD", "ABcd", false, 2)
InlineData("AB\0cd", "AB\0CD", true, 5)
InlineData("AB\0CD", "AB\0cd", true, 5)
InlineData("AB\0cd", "AB\0CD", false, 3)
InlineData("AB\0CD", "AB\0cd", false, 3)
InlineData("ABc\0", "ABC\0", true, 4)
InlineData("ABC\0", "ABc\0", true, 4)
InlineData("ABc\0", "ABC\0", false, 2)
InlineData("ABC\0", "ABc\0", false, 2)
InlineData("ABcdxyzl", "ABCDpdq", true, 4)
InlineData("ABCDxyz", "ABcdpdql", true, 4)
InlineData("ABcdxyz", "ABCDpdq", false, 2)
InlineData("ABCDxyzoo", "ABcdpdq", false, 2)
]
public void EqualStartingCharacterCount(string first, string second, bool ignoreCase, int expected)
{
Assert.Equal(expected, PathInternal.EqualStartingCharacterCount(first, second, ignoreCase));
}


[Theory,
InlineData(@"", @"", true, 0)
InlineData(@"", @"", false, 0)
InlineData(@"a", @"A", true, 1)
InlineData(@"A", @"a", true, 1)
InlineData(@"a", @"A", false, 0)
InlineData(@"A", @"a", false, 0)
InlineData(@"foo", @"foobar", true, 0)
InlineData(@"foo", @"foobar", false, 0)
InlineData(@"foo", @"foo/bar", true, 3)
InlineData(@"foo", @"foo/bar", false, 3)
InlineData(@"foo/", @"foo/bar", true, 4)
InlineData(@"foo/", @"foo/bar", false, 4)
InlineData(@"foo/bar", @"foo/bar", true, 7)
InlineData(@"foo/bar", @"foo/bar", false, 7)
InlineData(@"foo/bar", @"foo/BAR", true, 7)
InlineData(@"foo/bar", @"foo/BAR", false, 4)
InlineData(@"foo/bar", @"foo/barb", true, 4)
InlineData(@"foo/bar", @"foo/barb", false, 4)
]
public void GetCommonPathLength(string first, string second, bool ignoreCase, int expected)
{
Assert.Equal(expected, PathInternal.GetCommonPathLength(first, second, ignoreCase));
}
}
}
15 changes: 15 additions & 0 deletions src/Common/tests/Tests/System/IO/PathInternal.Windows.Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,19 @@ public void FindFileNameIndexTests(string path, int expected)
{
Assert.Equal(expected, PathInternal.FindFileNameIndex(path));
}

[Theory,
InlineData(@"", @"", StringComparison.OrdinalIgnoreCase, true)
InlineData(@"", @"", StringComparison.Ordinal, true)
InlineData(@"A", @"a", StringComparison.OrdinalIgnoreCase, true)
InlineData(@"A", @"a", StringComparison.Ordinal, true)
InlineData(@"C:\", @"c:\", StringComparison.OrdinalIgnoreCase, true)
InlineData(@"C:\", @"c:\", StringComparison.Ordinal, false)
]
[PlatformSpecific(PlatformID.Windows)]
public void AreRootsEqual(string first, string second, StringComparison comparisonType, bool expected)
{
Assert.Equal(expected, PathInternal.AreRootsEqual(first, second, comparisonType));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,5 @@
<ItemGroup>
<None Include="project.json" />
</ItemGroup>
<!-- ToDo: Remove this target once the infrastructure for testing in netcoreapp1.1 is ready -->
<Target Name="RemoveUnwantedTestMonikers" Condition="'$(TargetGroup)'=='netstandard1.7'" BeforeTargets="CopyTestToTestDirectory">
<ItemGroup>
<TestNugetTargetMoniker Remove=".NETCoreApp,Version=v1.1" />
</ItemGroup>
</Target>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,5 @@
<ItemGroup>
<None Include="project.json" />
</ItemGroup>
<!-- ToDo: Remove this target once the infrastructure for testing in netcoreapp1.1 is ready -->
<Target Name="RemoveUnwantedTestMonikers" Condition="'$(TargetGroup)'=='netstandard1.7'" BeforeTargets="CopyTestToTestDirectory">
<ItemGroup>
<TestNugetTargetMoniker Remove=".NETCoreApp,Version=v1.1" />
</ItemGroup>
</Target>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,5 @@
<ItemGroup>
<None Include="project.json" />
</ItemGroup>
<!-- ToDo: Remove this target once the infrastructure for testing in netcoreapp1.1 is ready -->
<Target Name="RemoveUnwantedTestMonikers" Condition="'$(TargetGroup)'=='netstandard1.7'" BeforeTargets="CopyTestToTestDirectory">
<ItemGroup>
<TestNugetTargetMoniker Remove=".NETCoreApp,Version=v1.1" />
</ItemGroup>
</Target>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
6 changes: 0 additions & 6 deletions src/System.Collections/tests/System.Collections.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -164,11 +164,5 @@
<ItemGroup>
<None Include="project.json" />
</ItemGroup>
<!-- ToDo: Remove this target once the infrastructure for testing in netcoreapp1.1 is ready -->
<Target Name="RemoveUnwantedTestMonikers" Condition="'$(TargetGroup)'=='netstandard1.7'" BeforeTargets="CopyTestToTestDirectory">
<ItemGroup>
<TestNugetTargetMoniker Remove=".NETCoreApp,Version=v1.1" />
</ItemGroup>
</Target>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
2 changes: 2 additions & 0 deletions src/System.Runtime.Extensions/System.Runtime.Extensions.sln
Original file line number Diff line number Diff line change
Expand Up @@ -139,5 +139,7 @@ Global
{845D2B72-D8A4-42E5-9BE9-17639EC4FC1A} = {1962877E-782F-499B-8468-F0F2A0692E96}
{E73B023E-609E-4281-866A-3AECB1AB5D48} = {8C66E70A-65C3-443E-A23A-18A1C12972B0}
{6C314C9B-3D28-4B05-9B4C-B57A00A9B3B9} = {4253F45C-FA2F-4743-9FC8-20666C416A68}
{373D255D-4749-4F26-A24A-A083E77B4471} = {4253F45C-FA2F-4743-9FC8-20666C416A68}
{9F312D76-9AF1-4E90-B3B0-815A1EC6C346} = {4253F45C-FA2F-4743-9FC8-20666C416A68}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<ProjectReference Include="..\ref\4.1.0\System.Runtime.Extensions.depproj">
<SupportedFramework>netcoreapp1.0;net462</SupportedFramework>
</ProjectReference>
<ProjectReference Include="..\ref\System.Runtime.Extensions.csproj">
<ProjectReference Include="..\ref\System.Runtime.Extensions.builds">
<SupportedFramework>netcoreapp1.1;net463;$(AllXamarinFrameworks)</SupportedFramework>
</ProjectReference>
<ProjectReference Include="..\src\System.Runtime.Extensions.csproj">
Expand Down
11 changes: 11 additions & 0 deletions src/System.Runtime.Extensions/ref/System.Runtime.Extensions.builds
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<ItemGroup>
<Project Include="System.Runtime.Extensions.csproj" />
<Project Include="System.Runtime.Extensions.csproj">
<TargetGroup>netcoreapp1.1</TargetGroup>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ericstj should we have a different AssemblyVersion for the netcoreapp1.1 contract?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No: we have similar precedent on desktop where more surface area is visible via facades.

</Project>
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.traversal.targets))\dir.traversal.targets" />
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,9 @@ public static partial class Path
public static string GetTempPath() { return default(string); }
public static bool HasExtension(string path) { return default(bool); }
public static bool IsPathRooted(string path) { return default(bool); }
#if netcoreapp11
public static string GetRelativePath(string relativeTo, string path) { return default(string); }
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New APIs should only be exposed in netcoreapp and not netstandard.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How will this work? Do we need to have two "prerelease" contract versions, one for the next version of netstandard, and one for the next version of necoreapp?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ericstj has a PR out #11272 which shows how to add these specifically for .NET Core. We will be handling things that are part of netstandard differently moving forward and the APIs will be added in a different place from where we actually build .NET Core so these projects will essentially be converted to .NET Core refs only.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I can just make the same changes then?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Presumably yes but I'm not sure if all the kinks have been worked out yet.

#endif
}
}
namespace System.Net
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.props))\dir.props" />
<PropertyGroup>
<OutputType>Library</OutputType>
<NuGetTargetMoniker>.NETStandard,Version=v1.7</NuGetTargetMoniker>
<NuGetTargetMoniker Condition="'$(TargetGroup)' == ''">.NETStandard,Version=v1.7</NuGetTargetMoniker>
<DefineConstants Condition="'$(TargetGroup)' == 'netcoreapp1.1'">$(DefineConstants);netcoreapp11</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Compile Include="System.Runtime.Extensions.cs" />
Expand Down
9 changes: 3 additions & 6 deletions src/System.Runtime.Extensions/ref/project.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
{
"dependencies": {
"System.Runtime": "4.0.20"
"System.Runtime": "4.3.0-beta-24516-03"
},
"frameworks": {
"netstandard1.7": {
"imports": [
"dotnet5.8"
]
}
"netstandard1.7": { },
"netcoreapp1.1": { }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,8 @@
<Link>Common\Interop\Windows\mincore\Interop.LookupAccountNameW.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup Condition=" '$(TargetsWindows)' == 'true' And '$(CoreClrOrCorRt)' == 'true'"> <!-- Microsoft.Win32.Registry, needed for some Environment env var support -->
<ItemGroup Condition=" '$(TargetsWindows)' == 'true' And '$(CoreClrOrCorRt)' == 'true'">
<!-- Microsoft.Win32.Registry, needed for some Environment env var support -->
<Compile Include="..\..\Microsoft.Win32.Registry\src\Microsoft\Win32\Registry.cs">
<Link>Microsoft.Win32.Registry\src\Microsoft\Win32\Registry.cs</Link>
</Compile>
Expand Down Expand Up @@ -371,7 +372,8 @@
<TargetingPackReference Include="System.Private.CoreLib" />
<TargetingPackReference Include="System.Private.CoreLib.InteropServices" />
<TargetingPackReference Include="System.Private.Interop" />
<TargetingPackReference Include="System.Private.Reflection" /> <!-- can remove once we remove the Environment reflection workaround -->
<!-- can remove once we remove the Environment reflection workaround -->
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: reformatting here may have changed meaning of the comment.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved this above, thanks

<TargetingPackReference Include="System.Private.Reflection" />
<TargetingPackReference Include="System.Private.Threading" />
<ProjectReference Include="$(SourceDir)/mscorlib.WinRT-Facade/mscorlib.WinRT-Facade.csproj" Condition="'$(TargetGroup)' == 'netcore50aot'" />
<ProjectReference Include="..\..\System.Runtime\src\redist\System.Runtime.depproj">
Expand Down
Loading