Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prefer more specific path map key #49670

Merged
merged 2 commits into from
Dec 10, 2020
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
Original file line number Diff line number Diff line change
Expand Up @@ -1482,6 +1482,8 @@ internal sealed override CommandLineArguments CommonParse(IEnumerable<string> ar
new CSharpRequiredLanguageVersion(MessageID.IDS_FeatureNullableReferenceTypes.RequiredVersion())), Location.None));
}

pathMap = SortPathMap(pathMap);

return new CSharpCommandLineArguments
{
IsScriptRunner = IsScriptCommandLineParser,
Expand Down
6 changes: 6 additions & 0 deletions src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10740,6 +10740,12 @@ public void PathMapParser()
parsedArgs.Errors.Verify();
Assert.Equal(KeyValuePairUtil.Create("a =,b" + s, "1,= 2" + s), parsedArgs.PathMap[0]);
Assert.Equal(KeyValuePairUtil.Create("x =,y" + s, "3 4" + s), parsedArgs.PathMap[1]);

parsedArgs = DefaultParse(new[] { @"/pathmap:C:\temp\=/_1/,C:\temp\a\=/_2/,C:\temp\a\b\=/_3/", "a.cs", @"a\b.cs", @"a\b\c.cs" }, WorkingDirectory);
parsedArgs.Errors.Verify();
Assert.Equal(KeyValuePairUtil.Create(@"C:\temp\a\b\", "/_3/"), parsedArgs.PathMap[0]);
Assert.Equal(KeyValuePairUtil.Create(@"C:\temp\a\", "/_2/"), parsedArgs.PathMap[1]);
Assert.Equal(KeyValuePairUtil.Create(@"C:\temp\", "/_1/"), parsedArgs.PathMap[2]);
}

[Theory]
Expand Down
8 changes: 8 additions & 0 deletions src/Compilers/Core/Portable/CommandLine/CommandLineParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1195,5 +1195,13 @@ internal static ImmutableDictionary<string, string> ParseFeatures(List<string> f
CompilerOptionParseUtilities.ParseFeatures(builder, features);
return builder.ToImmutable();
}

/// <summary>
/// Sort so that more specific keys precede less specific.
/// When mapping a path we find the first key in the array that is a prefix of the path.
/// If multiple keys are prefixes of the path we want to use the longest (more specific) one for the mapping.
/// </summary>
internal static ImmutableArray<KeyValuePair<string, string>> SortPathMap(ImmutableArray<KeyValuePair<string, string>> pathMap)
=> pathMap.Sort((x, y) => -x.Key.Length.CompareTo(y.Key.Length));
}
}
4 changes: 1 addition & 3 deletions src/Compilers/Core/Portable/SourceFileResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,13 @@ public SourceFileResolver(
{
var pathMapBuilder = ArrayBuilder<KeyValuePair<string, string>>.GetInstance(pathMap.Length);

foreach (var kv in pathMap)
foreach (var (key, value) in pathMap)
{
var key = kv.Key;
if (key == null || key.Length == 0)
{
throw new ArgumentException(CodeAnalysisResources.EmptyKeyInPathMap, nameof(pathMap));
}

var value = kv.Value;
if (value == null)
{
throw new ArgumentException(CodeAnalysisResources.NullValueInPathMap, nameof(pathMap));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1440,6 +1440,8 @@ lVbRuntimePlus:
' If the script is passed without the `\i` option simply execute the script (`vbi script.vbx`).
interactiveMode = interactiveMode Or (IsScriptCommandLineParser AndAlso sourceFiles.Count = 0)

pathMap = SortPathMap(pathMap)

Return New VisualBasicCommandLineArguments With
{
.IsScriptRunner = IsScriptCommandLineParser,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3483,6 +3483,12 @@ print Goodbye, World"
parsedArgs.Errors.Verify()
Assert.Equal(KeyValuePairUtil.Create("a =,b" & s, "1,= 2" & s), parsedArgs.PathMap(0))
Assert.Equal(KeyValuePairUtil.Create("x =,y" & s, "3 4" & s), parsedArgs.PathMap(1))

parsedArgs = DefaultParse({"/pathmap:C:\temp\=/_1/,C:\temp\a\=/_2/,C:\temp\a\b\=/_3/", "a.cs", "a\b.cs", "a\b\c.cs"}, _baseDirectory)
parsedArgs.Errors.Verify()
Assert.Equal(KeyValuePairUtil.Create("C:\temp\a\b\", "/_3/"), parsedArgs.PathMap(0))
Assert.Equal(KeyValuePairUtil.Create("C:\temp\a\", "/_2/"), parsedArgs.PathMap(1))
Assert.Equal(KeyValuePairUtil.Create("C:\temp\", "/_1/"), parsedArgs.PathMap(2))
End Sub

' PathMapKeepsCrossPlatformRoot and PathMapInconsistentSlashes should be in an
Expand Down