Skip to content

Commit

Permalink
Merge pull request dotnet#60855 from jasonmalinowski/provide-parse-op…
Browse files Browse the repository at this point in the history
…tions-immediately

Provide parse options to the language service more quickly
  • Loading branch information
jasonmalinowski authored Jul 13, 2022
2 parents 1dd7719 + 29ed5ea commit 8d0ca82
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 3 deletions.
22 changes: 22 additions & 0 deletions src/Compilers/Core/MSBuildTask/Microsoft.CSharp.Core.targets
Original file line number Diff line number Diff line change
Expand Up @@ -165,4 +165,26 @@

<CallTarget Targets="$(TargetsTriggeredByCompilation)" Condition="'$(TargetsTriggeredByCompilation)' != ''" />
</Target>

<!-- When we load a project in Visual Studio, the project system first does an evaluation pass of the
project, and hands the resulting list of <Compile> items to the language service. It then does an
execution pass executing CoreCompile passing SkipCompilerExecution=true and ProvideCommandLineArgs=true,
that resulting command line string is where we get our compiler switches. The execution pass is much
slower than the evaluation pass, so there's a window of time where we have a list of files, but not
any options yet.
Because there's a gap, that means there's a time where we are parsing source files with the default
parse options. We'll then have to reparse them a second time which isn't great. It also means any
cache lookups we do won't have the right options either, so the cache lookups might miss.
To help this, we'll have a property for the evaluation pass which is an "approximation" of the
options that would come out of CoreCompile, but only the ones that matter for parsing. It's acceptable
for this to be imperfect: once the execution pass is complete we'll use those options instead,
so any behaviors here that don't match the real command line generation will only be temporary, and
probably won't be any worse than having no options at all. -->

<PropertyGroup>
<CommandLineArgsForDesignTimeEvaluation>-langversion:$(LangVersion)</CommandLineArgsForDesignTimeEvaluation>
<CommandLineArgsForDesignTimeEvaluation Condition="'$(DefineConstants)' != ''">$(CommandLineArgsForDesignTimeEvaluation) -define:$(DefineConstants)</CommandLineArgsForDesignTimeEvaluation>
</PropertyGroup>
</Project>
22 changes: 22 additions & 0 deletions src/Compilers/Core/MSBuildTask/Microsoft.VisualBasic.Core.targets
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,26 @@

<CallTarget Targets="$(TargetsTriggeredByCompilation)" Condition="'$(TargetsTriggeredByCompilation)' != ''" />
</Target>

<!-- When we load a project in Visual Studio, the project system first does an evaluation pass of the
project, and hands the resulting list of <Compile> items to the language service. It then does an
execution pass executing CoreCompile passing SkipCompilerExecution=true and ProvideCommandLineArgs=true,
that resulting command line string is where we get our compiler switches. The execution pass is much
slower than the evaluation pass, so there's a window of time where we have a list of files, but not
any options yet.
Because there's a gap, that means there's a time where we are parsing source files with the default
parse options. We'll then have to reparse them a second time which isn't great. It also means any
cache lookups we do won't have the right options either, so the cache lookups might miss.
To help this, we'll have a property for the evaluation pass which is an "approximation" of the
options that would come out of CoreCompile, but only the ones that matter for parsing. It's acceptable
for this to be imperfect: once the execution pass is complete we'll use those options instead,
so any behaviors here that don't match the real command line generation will only be temporary, and
probably won't be any worse than having no options at all. -->

<PropertyGroup>
<CommandLineArgsForDesignTimeEvaluation>-langversion:$(LangVersion)</CommandLineArgsForDesignTimeEvaluation>
<CommandLineArgsForDesignTimeEvaluation Condition="'$(FinalDefineConstants)' != ''">$(CommandLineArgsForDesignTimeEvaluation) -define:$(FinalDefineConstants)</CommandLineArgsForDesignTimeEvaluation>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ internal interface IWorkspaceProjectContext : IDisposable

// Options.

[Obsolete("To avoid contributing to the large object heap, use SetOptions(ImmutableArray<string>). This API will be removed in the future.")]
void SetOptions(string commandLineForOptions);
void SetOptions(ImmutableArray<string> arguments);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ private bool ReparseCommandLineIfChanged_NoLock(ImmutableArray<string> arguments
return true;
}

[Obsolete("To avoid contributing to the large object heap, use SetOptions(ImmutableArray<string>). This API will be removed in the future.")]
public void SetCommandLine(string commandLine)
{
if (commandLine == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ internal string? CompilationOutputAssemblyFilePath

public ProjectId Id => _visualStudioProject.Id;

[Obsolete("To avoid contributing to the large object heap, use SetOptions(ImmutableArray<string>). This API will be removed in the future.")]
public void SetOptions(string commandLineForOptions)
=> _visualStudioProjectOptionsProcessor?.SetCommandLine(commandLineForOptions);

Expand Down

0 comments on commit 8d0ca82

Please sign in to comment.