Skip to content

Conversation

@RikkiGibson
Copy link
Member

@RikkiGibson RikkiGibson commented Apr 18, 2025

Design doc: https://github.com/rikkigibson/roslyn/blob/file-based-programs-ide/docs/features/file-based-programs-vscode.md

  • language server failing to notify client when project finishes loading? (punting)
  • stop showing misc files warning dialog for FBPs (punting)
  • remove document
  • feature flag in FileBasedProgramsWorkspaceProviderFactory
  • fix razor and non-file uris in general
    • when razor doc opened, use LanguageNames.CSharp, pass the doc as AdditionalDoc, pass nothing for ordinary documents
  • address subscribe to NeedsReload threading concern

See also dotnet/vscode-csharp#8253

@ghost ghost added Area-Infrastructure untriaged Issues and PRs which have not yet been triaged by a lead labels Apr 18, 2025
var root = tree.GetRoot();
return
//root.DescendantNodes(descendIntoChildren: node => node.IsKind(SyntaxKind.CompilationUnit)).OfType<GlobalStatementSyntax>().Any() ||
root.GetLeadingTrivia().FirstOrDefault().IsKind(SyntaxKind.ShebangDirectiveTrivia);
Copy link
Member

Choose a reason for hiding this comment

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

this feels expensive. if we're just checking leading trivial, we can get hte text, and just check if it literally starts with a #!. because you're getting the leading trivia, only checking the first, and forcing it to ahve that. now it's just a two char check, instead of a full lex/parse.

</PropertyGroup>
<ItemGroup>
<Compile Include="{documentFilePath}" />
Copy link
Member

Choose a reason for hiding this comment

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

this is not at all safe. (effectively, this is like sql injection). We should not be manually making xml. We should use an xml creation lib to get to this to happen.

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 is going to be deleted and replaced with usage of API described in #78159.

internal interface ILspFileBasedProgramWorkspace : ILspService
{
public Task<Document?> AddMiscellaneousDocumentAsync(Uri uri, SourceText documentText, string languageId, ILspLogger logger, CancellationToken cancellationToken);
public void TryRemoveMiscellaneousDocument(Uri uri, bool removeFromMetadataWorkspace);
Copy link
Member

Choose a reason for hiding this comment

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

doc the heck out of these. esp. threading concerns.

@RikkiGibson RikkiGibson force-pushed the file-based-programs-ide branch from dfc63d5 to 2558d31 Compare May 5, 2025 22:06
@RikkiGibson RikkiGibson force-pushed the file-based-programs-ide branch from 2558d31 to ed23c0c Compare May 5, 2025 23:29
var preferredBuildHostKind = GetKindForProject(projectPath);
var (buildHost, actualBuildHostKind) = await buildHostProcessManager.GetBuildHostWithFallbackAsync(preferredBuildHostKind, projectPath, cancellationToken);
if (preferredBuildHostKind != actualBuildHostKind)
preferredBuildHostKindThatWeDidNotGet = preferredBuildHostKind;
Copy link
Member

Choose a reason for hiding this comment

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

We still need to move this block into the TryLoadProjectAsync() method, since the GetKindForProject is implicitly looking at the project file contents. In the case of the file-based programs, the selection is trivially "just use .NET Core".

foreach (var project in projectsToRemove)
{
project.Dispose();
_loadedProjects.AddOrUpdate(projectPath, addValueFactory: _ => throw new InvalidOperationException(), updateValueFactory: (_, arr) => arr.Remove(project));
Copy link
Member

Choose a reason for hiding this comment

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

Add a comment obviously that we only expect this getting the update path.

}

/// <summary>
/// Creates a 'LoadedProject' which has bare minimum information, but, which documents can be added to and obtained from.
Copy link
Member

Choose a reason for hiding this comment

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

Use a cref.

// We should never be changing the fundamental identity of this project; if this happens we really should have done a full unload/reload.
Contract.ThrowIfFalse(newProjectInfo.FilePath == _mostRecentFileInfo.FilePath);
Contract.ThrowIfFalse(newProjectInfo.TargetFramework == _mostRecentFileInfo.TargetFramework);
Contract.ThrowIfFalse(_mostRecentFileInfo.TargetFramework == null || newProjectInfo.TargetFramework == _mostRecentFileInfo.TargetFramework);
Copy link
Member

Choose a reason for hiding this comment

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

Can be removed now.

ContentFilePaths = [],
FileGlobs = []
};
await loadedProject.UpdateWithNewProjectInfoAsync(projectFileInfo, _logger);
Copy link
Member

Choose a reason for hiding this comment

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

We still need to remember to set the "HasAllInformation" flag 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.

Considering the following scenarios:

  1. ordinary project. HasAllInformation should always be true, when this method runs, I think.
  2. loose file, not part of a file-based program. HasAllInformation should be false.
  3. file-based program entry point (currently). HasAllInformation should be true.

So I was wondering if we should pass in a flag like forMiscellaneousFiles when creating the LoadedProject, and finally say HasAllInformation = !forMiscellaneousFiles || checkHeuristic() within this method (since it's FBP-ness can change from edit-to-edit.)

Copy link
Member Author

Choose a reason for hiding this comment

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

Done

@RikkiGibson RikkiGibson force-pushed the file-based-programs-ide branch from ed23c0c to 6150e84 Compare May 6, 2025 03:08
{
const BuildHostProcessKind buildHostKind = BuildHostProcessKind.NetCore;
var buildHost = await buildHostProcessManager.GetBuildHostAsync(buildHostKind, cancellationToken);
var documentPath = projectToLoad.Path;
Copy link
Member

Choose a reason for hiding this comment

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

We only ever need the path from projectToLoad, right? Should we just pass that in?

Comment on lines 228 to 231
else
{
newProjects.Add(project);
}
Copy link
Member

Choose a reason for hiding this comment

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

If we're going to re-create the array all the time, just do ImmutableArray.RemoveRange().

@RikkiGibson RikkiGibson force-pushed the file-based-programs-ide branch from 869120b to d57b93f Compare May 6, 2025 19:19
@RikkiGibson
Copy link
Member Author

"Support unloading projects" is a bit gnarly, I am going to make a pass tomorrow to clean it up and add comments to make our assumptions clear.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area-Infrastructure untriaged Issues and PRs which have not yet been triaged by a lead VSCode

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants