Skip to content

Ensure we match equivalent paths when retrieving analyzer options in global configs#56588

Merged
chsienki merged 11 commits intodotnet:release/dev17.0from
chsienki:editor_config_double_dot
Oct 1, 2021
Merged

Ensure we match equivalent paths when retrieving analyzer options in global configs#56588
chsienki merged 11 commits intodotnet:release/dev17.0from
chsienki:editor_config_double_dot

Conversation

@chsienki
Copy link
Copy Markdown
Member

Fixes #47786

@chsienki
Copy link
Copy Markdown
Member Author

@dotnet/roslyn-compiler for review please :)

@RikkiGibson

This comment has been minimized.

@chsienki chsienki force-pushed the editor_config_double_dot branch from 1059699 to 96d4078 Compare September 22, 2021 22:37
@chsienki
Copy link
Copy Markdown
Member Author

chsienki commented Sep 22, 2021

Rebased onto rel/dev17.0

@chsienki chsienki force-pushed the editor_config_double_dot branch from 96d4078 to e1e4212 Compare September 28, 2021 19:47
@chsienki chsienki requested a review from a team as a code owner September 28, 2021 19:47
@chsienki chsienki changed the base branch from main to release/dev17.0 September 28, 2021 19:48
@chsienki
Copy link
Copy Markdown
Member Author

@RikkiGibson @dotnet/roslyn-compiler. I've changed the approach for this PR. At this point we don't treat analyzer config paths as their system representations, so its incorrect to use system functions on them. Instead, we now just extract out the '..' and '.' ourselves, which is simple because we know the path has to be in a certain format.

Appreciate a couple of re-reviews on this.

Correctly handle windows paths
Add extra comments
var parts = GetPathParts(p);

// On windows we need to skip the volume specifier, but remember it for re-joining later
var volumeSpecifier = (!IsUnixLikePlatform) ? string.Empty : p.Substring(0, 2);
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.

2

Are we guaranteed there are two characters in p?

// GetPathParts also removes any instances of '.'
var parts = GetPathParts(p);

// On windows we need to skip the volume specifier, but remember it for re-joining later
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.

volume specifier

Are we testing volume specifiers? Consider having a unit test that calls ExpandNormalizedFullPathWithRelativeParts() directly.

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.

Yes, the test explicitly adds the volume for windows. Makes sense to add a direct test too though.

var volumeSpecifier = (!IsUnixLikePlatform) ? string.Empty : p.Substring(0, 2);

// Skip the root directory
var toSkip = IsUnixLikePlatform ? 1 : 2;
Copy link
Copy Markdown
Contributor

@cston cston Sep 30, 2021

Choose a reason for hiding this comment

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

IsUnixLikePlatform ? 1 : 2

Are we guaranteed there are at least two parts on Windows? What if the path is a UNC path?

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.

It actually would work with UNC paths, but not entirely correctly. Instead i've just made it bail if we see them, as this is supposed to be best effort.

[InlineData("././../.././dir1/dir2/file.cs", false)]
[InlineData("./dir1/../file.cs", false)]
[InlineData("../dir1/dir2.cs", false)]
public void EquivalentSourcePathNames(string sourcePath, bool shouldMatch)
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.

public

Consider testing ExpandNormalizedFullPathWithRelativeParts() directly and test UNC paths on Windows.

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.

Done. Explicitly excluding UNC paths. Its essentially a best effort, so if we can't expand it we'll just return the original string. Added tests for relative, device specified and UNC and called out in the remarks what we do.

[InlineData("./dir1/dir2/file.cs", false)]
[InlineData("././../.././dir1/dir2/file.cs", false)]
[InlineData("./dir1/../file.cs", false)]
[InlineData("../dir1/dir2.cs", false)]
Copy link
Copy Markdown
Member

@RikkiGibson RikkiGibson Sep 30, 2021

Choose a reason for hiding this comment

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

Instead of 'shouldMatch', should we just include a 'string expected' in this data? For example, the expected result of normalizing ./dir1/../file.cs is file.cs (I hope--otherwise I misread the implementation or didn't look closely enough at GetParts, etc.)

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.

I ended up doing that on the direct test, so we can get decent coverage.

Add tests for method directly.
}

[ConditionalTheory(typeof(WindowsOnly))]
[InlineData("x:\\a\\b\\file.cs", "x:/a/b/file.cs")]
Copy link
Copy Markdown
Contributor

@cston cston Sep 30, 2021

Choose a reason for hiding this comment

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

\

Consider using verbatim strings for each of these values, to avoid the need to escape backslashes so it's more obvious what we're testing in each case. #Closed

[InlineData("\\\\.\\C:\\a\\..\\b.cs", "\\\\.\\C:\\a\\..\\b.cs")]
[InlineData("\\\\?\\C:\\a\\b.cs", "\\\\?\\C:\\a\\b.cs")]
[InlineData("\\\\.\\Volume{00000000-0000-0000-0000-000000000000}\\a\\b.cs", "\\\\.\\Volume{00000000-0000-0000-0000-000000000000}\\a\\b.cs")]
public void TestExpandAbsolutePathWithRelativeParts_Windows(string input, string expected) => TestExpandAbsolutePathWithRelativeParts(input, expected);
Copy link
Copy Markdown
Contributor

@cston cston Sep 30, 2021

Choose a reason for hiding this comment

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

public

Please test:

  • "\" (a single backslash)
  • "\\" (two backslashes)
  • "\\server" (no file name)
  • "x:" (no file name)
  • "x:\" (no file name) #Closed

[InlineData("../a/../b/c", "../a/../b/c")]
[InlineData("foo", "foo")]
[InlineData("", "")]
public void TestExpandAbsolutePathWithRelativeParts(string input, string expected)
Copy link
Copy Markdown
Contributor

@cston cston Sep 30, 2021

Choose a reason for hiding this comment

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

public

Please test:

  • "/"
  • ".."
  • "."
  • "../"
  • "./" #Closed

@chsienki chsienki requested a review from a team as a code owner September 30, 2021 20:49
@chsienki chsienki merged commit dc717fa into dotnet:release/dev17.0 Oct 1, 2021
@chsienki chsienki deleted the editor_config_double_dot branch October 1, 2021 17:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Generators] The AnalyzerConfigOptionsProvider.GetOptions does not use the proper file path

4 participants