Skip to content

Use newer Roslyn APIs in the language service#8499

Merged
drewnoakes merged 6 commits intodotnet:mainfrom
drewnoakes:update-lang-svc-api
Oct 13, 2022
Merged

Use newer Roslyn APIs in the language service#8499
drewnoakes merged 6 commits intodotnet:mainfrom
drewnoakes:update-lang-svc-api

Conversation

@drewnoakes
Copy link
Member

@drewnoakes drewnoakes commented Sep 17, 2022

@tmat and I designed a new API for the interaction between the .NET Project System and Roslyn when creating instances of IWorkspaceProjectContext.

This new API:

  • Allows Roslyn to (generally) request additional properties from the project system, without requiring a corresponding change in the project system.

  • Avoids having to create a wasteful batched update immediately after constructing the workspace.

This PR updates the API we use.

Bumping that package pulled the thread on a whole bunch of other package upgrades, including analyzer changes that lead to .editorconfig changes, some naming guideline changes, and some suppressions.

Microsoft Reviewers: Open in CodeFlow

@drewnoakes drewnoakes added Feature-Language-Service Populating the Roslyn workspace with references, source files, analyzers, etc Tenet-Performance This issue affects the "Performance" tenet. Performance-Scenario-Solution-Open This issue affects solution open performance. labels Sep 17, 2022
@drewnoakes drewnoakes added this to the 17.4 milestone Sep 17, 2022
@drewnoakes drewnoakes requested a review from a team as a code owner September 17, 2022 03:16
Comment on lines -214 to +234
snapshot.Properties.TryGetValue(ConfigurationGeneral.TargetPathProperty, out string? binOutputPath);
snapshot.Properties.TryGetValue(ConfigurationGeneral.MSBuildProjectFullPathProperty, out string? projectFilePath);
snapshot.Properties.TryGetValue(ConfigurationGeneral.AssemblyNameProperty, out string? assemblyName);
snapshot.Properties.TryGetValue(ConfigurationGeneral.CommandLineArgsForDesignTimeEvaluationProperty, out string? commandLineArgsForDesignTimeEvaluation);

if (string.IsNullOrEmpty(languageName) || string.IsNullOrEmpty(binOutputPath) || string.IsNullOrEmpty(projectFilePath))
if (string.IsNullOrEmpty(languageName) || string.IsNullOrEmpty(projectFilePath))
Copy link
Member Author

Choose a reason for hiding this comment

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

We no longer pull these properties out on our side. Roslyn will obtain them via an object we provide.


try
{
EvaluationDataAdapter evaluationData = new(snapshot.Properties);
Copy link
Member Author

Choose a reason for hiding this comment

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

This object allows Roslyn to call us back for any property that's in ConfigurationGeneral. In future we may also allow requesting arbitrary project properties.

Comment on lines 235 to 262
_context = await _workspaceProjectContextFactory.Value.CreateProjectContextAsync(
languageName,
_contextId,
projectFilePath,
_projectGuid,
_contextId,
languageName,
evaluationData,
hostObject,
binOutputPath,
assemblyName,
cancellationToken);
Copy link
Member Author

Choose a reason for hiding this comment

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

Calling the new overload.

Comment on lines -247 to -273

// Update additional properties within a batch to avoid thread pool starvation.
// https://github.com/dotnet/project-system/issues/8027
_context.StartBatch();

try
{
_context.LastDesignTimeBuildSucceeded = false; // By default, turn off diagnostics until the first design time build succeeds for this project.

// Pass along any early approximation we have of the command line options
#pragma warning disable CS0618 // This was obsoleted in favor of the one that takes an array, but here just the string is easier; we'll un-Obsolete this API
_context.SetOptions(commandLineArgsForDesignTimeEvaluation ?? "");
#pragma warning restore CS0618 // Type or member is obsolete
}
finally
{
await _context.EndBatchAsync();
}
Copy link
Member Author

Choose a reason for hiding this comment

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

This whole post-construction update is no longer needed.

Comment on lines +140 to +142
#pragma warning disable CS0618 // Type or member is obsolete
Renamer.RenameDocumentActionSet documentAction = await Renamer.RenameDocumentAsync(oldDocument, null!, documentFolders);
#pragma warning restore CS0618 // Type or member is obsolete
Copy link
Member Author

Choose a reason for hiding this comment

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

Roslyn has deprecated a bunch of these rename APIs.

@ocallesp do we have a work item tracking the update of this? If not, could you file one please?

Copy link
Member Author

Choose a reason for hiding this comment

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

I filed #8591

@drewnoakes
Copy link
Member Author

I struggled making the package references and versions work here. It builds on my machine, though I half expect it to fail in CI. I'm not convinced the approach here is right, and it seems like some of the packages we need are incorrectly authored or missing from the feeds we source them from. I will revisit this next soon.

await _context.EndBatchAsync();
}
}
catch (Exception ex)
Copy link
Member

Choose a reason for hiding this comment

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

Exception

Roslyn throws InvalidProjectPropertyValueException if a property that is required isn't present or has invalid value, in case you want to handle it in a different way.

Copy link

@jacdavis jacdavis left a comment

Choose a reason for hiding this comment

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

:shipit:

@drewnoakes drewnoakes force-pushed the update-lang-svc-api branch 2 times, most recently from 66cb773 to bd63af1 Compare October 11, 2022 22:47
@drewnoakes drewnoakes force-pushed the update-lang-svc-api branch 2 times, most recently from 9920029 to b9a7494 Compare October 12, 2022 01:59
This new API:

- allows Roslyn to request additional properties in future, without requiring a corresponding change in the Project System.

- avoids having to create a wasteful batched update immediately after constructing the workspace
@drewnoakes drewnoakes modified the milestones: 17.4, 17.5 Oct 13, 2022
@drewnoakes drewnoakes merged commit f5a4241 into dotnet:main Oct 13, 2022
@drewnoakes drewnoakes deleted the update-lang-svc-api branch October 13, 2022 09:55
drewnoakes added a commit to drewnoakes/project-system that referenced this pull request Oct 19, 2022
Historically, the set of project properties we passed to Roslyn when initialising an `IWorkspaceProjectContext` was hard-coded in the project system. We changed this recently in dotnet#8499, and introduced a means for Roslyn to request whatever properties they wanted, allowing Roslyn to make changes without requiring a synchronised change in the project system.

With that change, we serviced property value requests using `ProjectRuleSource` data. This limited Roslyn to only those properties present in our `ConfigurationGeneral` XAML rule file.

This commit uses a `ProjectInstance` to service such requests instead. This means that Roslyn can add new projects in their own props/targets, and not need the project system to make any changes in order to provide those values.

Motivated by a bug exposed through dotnet/roslyn#64749 which added required property `OutputAssemblyForDesignTimeEvaluation` which did not exist in our rules, leading to runtime errors.
drewnoakes added a commit to drewnoakes/project-system that referenced this pull request Oct 19, 2022
Historically, the set of project properties we passed to Roslyn when initialising an `IWorkspaceProjectContext` was hard-coded in the project system. We changed this recently in dotnet#8499, and introduced a means for Roslyn to request whatever properties they wanted, allowing Roslyn to make changes without requiring a synchronised change in the project system.

With that change, we serviced property value requests using `ProjectRuleSource` data. This limited Roslyn to only those properties present in our `ConfigurationGeneral` XAML rule file.

This commit uses a `ProjectInstance` to service such requests instead. This means that Roslyn can add new projects in their own props/targets, and not need the project system to make any changes in order to provide those values.

Motivated by a bug exposed through dotnet/roslyn#64749 which added required property `OutputAssemblyForDesignTimeEvaluation` which did not exist in our rules, leading to runtime errors.
drewnoakes added a commit to drewnoakes/project-system that referenced this pull request Oct 27, 2022
Historically, the set of project properties we passed to Roslyn when initialising an `IWorkspaceProjectContext` was hard-coded in the project system. We changed this recently in dotnet#8499, and introduced a means for Roslyn to request whatever properties they wanted, allowing Roslyn to make changes without requiring a synchronised change in the project system.

With that change, we serviced property value requests using `ProjectRuleSource` data. This limited Roslyn to only those properties present in our `ConfigurationGeneral` XAML rule file.

This commit uses a `ProjectInstance` to service such requests instead. This means that Roslyn can add new projects in their own props/targets, and not need the project system to make any changes in order to provide those values.

Motivated by a bug exposed through dotnet/roslyn#64749 which added required property `OutputAssemblyForDesignTimeEvaluation` which did not exist in our rules, leading to runtime errors.
haileymck pushed a commit to haileymck/project-system that referenced this pull request Nov 8, 2022
Historically, the set of project properties we passed to Roslyn when initialising an `IWorkspaceProjectContext` was hard-coded in the project system. We changed this recently in dotnet#8499, and introduced a means for Roslyn to request whatever properties they wanted, allowing Roslyn to make changes without requiring a synchronised change in the project system.

With that change, we serviced property value requests using `ProjectRuleSource` data. This limited Roslyn to only those properties present in our `ConfigurationGeneral` XAML rule file.

This commit uses a `ProjectInstance` to service such requests instead. This means that Roslyn can add new projects in their own props/targets, and not need the project system to make any changes in order to provide those values.

Motivated by a bug exposed through dotnet/roslyn#64749 which added required property `OutputAssemblyForDesignTimeEvaluation` which did not exist in our rules, leading to runtime errors.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature-Language-Service Populating the Roslyn workspace with references, source files, analyzers, etc Performance-Scenario-Solution-Open This issue affects solution open performance. Tenet-Performance This issue affects the "Performance" tenet.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants