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

Treat decompiled sources separately from metadata sources #27940

Merged
merged 5 commits into from
Jun 29, 2018

Conversation

sharwell
Copy link
Member

Fixes #25244
Fixes #25255
Fixes #25731
Fixes #26329
Fixes #27187

Ask Mode template not completed

Customer scenario

What does the customer do to get into this situation, and why do we think this
is common enough to address for this release. (Granted, sometimes this will be
obvious "Open project, VS crashes" but in general, I need to understand how
common a scenario is)

Bugs this fixes

(either VSO or GitHub links)

Workarounds, if any

Also, why we think they are insufficient for RC vs. RC2, RC3, or RTW

Risk

This is generally a measure our how central the affected code is to adjacent
scenarios and thus how likely your fix is to destabilize a broader area of code

Performance impact

(with a brief justification for that assessment (e.g. "Low perf impact because no extra allocations/no complexity changes" vs. "Low")

Is this a regression from a previous update?

Root cause analysis

How did we miss it? What tests are we adding to guard against it in the future?

How was the bug found?

(E.g. customer reported it vs. ad hoc testing)

Test documentation updated?

If this is a new non-compiler feature or a significant improvement to an existing feature, update https://github.com/dotnet/roslyn/wiki/Manual-Testing once you know which release it is targeting.

@sharwell sharwell requested a review from a team as a code owner June 17, 2018 19:24
@sharwell sharwell added this to the 15.8 milestone Jun 17, 2018
Copy link
Member

@jasonmalinowski jasonmalinowski left a comment

Choose a reason for hiding this comment

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

I believe we're now losing Mutexes which might cause files to be deleted under the process which might end badly. Everything else looks reasonable than that bit though.

{
var guidString = Guid.NewGuid().ToString("N");
_rootTemporaryPathWithGuid = Path.Combine(_rootTemporaryPath, guidString);
rootTemporaryPathWithGuid = Path.Combine(_rootTemporaryPath, guidString);
_mutex = new Mutex(initiallyOwned: true, name: CreateMutexName(guidString));
Copy link
Member

Choose a reason for hiding this comment

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

This now may be overwriting a previous Mutex created by our process; I'm guessing if the Mutex GCs then another process might clean up things under us? I believe the right fix here is to preserve a single folder, and just maybe add another layer of folders inside of it, i.e. MetadataAsSource-{guid}\Decompiled vs. MetadataAsSource-{guid}\Metadata. Or, hold onto two mutexes, but I think going back to a single directory is easier, and also scales if/when we create a third type of something to go in here...

Copy link
Member Author

Choose a reason for hiding this comment

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

Two mutexes is easy with the current pattern. Yay ref locals!

this.Workspace = sourceProject.Solution.Workspace;
this.LanguageName = sourceProject.Language;
if (allowDecompilation && sourceProject.Language != LanguageNames.CSharp)
Copy link
Member

Choose a reason for hiding this comment

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

If you just move this after this.LanguageName =, then I think you can reduce this all back to _parseOptions = Workspace.Services.GetLanguageServices(this.LanguageName).GetRequriedService().ParseOptions;. Basically, you've already figured out once that if it's decompiled it's always C#; no reason to do it twice.

@sharwell sharwell force-pushed the separate-decompiled-sources branch from dcaa384 to f1ed8a7 Compare June 20, 2018 19:02
@sharwell
Copy link
Member Author

@jasonmalinowski Updated based on review feedback. Planning to rebase this back to 2 commits once the review completes.

{
if (_rootTemporaryPathWithGuid == null)
ref string rootTemporaryPathWithGuid = ref (allowDecompilation ? ref _rootDecompiledTemporaryPathWithGuid : ref _rootMetadataTemporaryPathWithGuid);
ref Mutex mutex = ref (allowDecompilation ? ref _decompiledMutex : ref _metadataMutex);
Copy link
Member

Choose a reason for hiding this comment

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

i personally hate this :) but i guess i will have to grow to live with these sorts of patterns :)

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I admire your desire to play with new things, but if we just went back to a single mutex/folder and generated the paths differently, it's just two lines with no fancy tricks whatsoever.

"If you write your code as cleverly as possible..."

else
{
_parseOptions = Workspace.Services.GetLanguageServices(LanguageName).GetRequiredService<ISyntaxTreeFactoryService>().GetDefaultParseOptionsWithLatestLanguageVersion();
}
Copy link
Member

Choose a reason for hiding this comment

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

nit: consider ?:

Copy link
Member Author

Choose a reason for hiding this comment

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

Opted against it here. The two branches seem different enough that I like to keep it obvious.

Copy link
Member

Choose a reason for hiding this comment

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

Why still having the branches at all? When would the source project's parse options be different than the default parse options for the language in an observable way?

I'm not saying there's not a reason for this....I just can't tell what it is. I can't read your mind (not sure if good thing or bad thing?) but do we need a comment here?

Copy link
Member

@jasonmalinowski jasonmalinowski left a comment

Choose a reason for hiding this comment

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

Would really like us to stop doing the fancy ref tricks when simpler code would do.

else
{
_parseOptions = Workspace.Services.GetLanguageServices(LanguageName).GetRequiredService<ISyntaxTreeFactoryService>().GetDefaultParseOptionsWithLatestLanguageVersion();
}
Copy link
Member

Choose a reason for hiding this comment

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

Why still having the branches at all? When would the source project's parse options be different than the default parse options for the language in an observable way?

I'm not saying there's not a reason for this....I just can't tell what it is. I can't read your mind (not sure if good thing or bad thing?) but do we need a comment here?

@sharwell
Copy link
Member Author

@jasonmalinowski main feedback should be addressed now.

this.References = sourceProject.MetadataReferences.ToImmutableArray();
this.AssemblyIdentity = topLevelNamedType.ContainingAssembly.Identity;

var extension = sourceProject.Language == LanguageNames.CSharp ? ".cs" : ".vb";
var extension = LanguageName == LanguageNames.CSharp ? ".cs" : ".vb";

var directoryName = Guid.NewGuid().ToString("N");
this.TemporaryFilePath = Path.Combine(rootPath, directoryName, topLevelNamedType.Name + extension);
Copy link
Member

Choose a reason for hiding this comment

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

Doesn't this still need to have some differentiation for the decompiled vs. not?

Copy link
Member Author

Choose a reason for hiding this comment

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

It does. Two levels of directory names are used when the keys don't match; this one will still get one unique GUID in the path where before it was getting two.

@sharwell sharwell changed the base branch from master to dev15.8-preview4 June 26, 2018 22:39
@jasonmalinowski
Copy link
Member

@jinujoseph I see this is assigned to me now, who is doing the work to take this for QB approval?

@sharwell sharwell changed the base branch from dev15.8-preview4 to master June 28, 2018 17:44
@jinujoseph
Copy link
Contributor

jinujoseph commented Jun 28, 2018

approved to merge for 15.8.Preview5 (once green)

@jasonmalinowski jasonmalinowski merged commit 4bf5381 into dotnet:master Jun 29, 2018
@sharwell sharwell deleted the separate-decompiled-sources branch June 29, 2018 09:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment