未验证 提交 612510d6 编写于 作者: G Gen Lu 提交者: GitHub

Merge pull request #30921 from genlu/projectinfo

Add support for default namespace to workspace
...@@ -252,6 +252,23 @@ public async Task Project_AssemblyName_Change() ...@@ -252,6 +252,23 @@ public async Task Project_AssemblyName_Change()
} }
} }
[Fact]
public async Task Project_DefaultNamespace_Change()
{
using (var workspace = new WorkCoordinatorWorkspace(SolutionCrawler))
{
var solutionInfo = GetInitialSolutionInfo_2Projects_10Documents(workspace);
workspace.OnSolutionAdded(solutionInfo);
await WaitWaiterAsync(workspace.ExportProvider);
var project = workspace.CurrentSolution.Projects.First(p => p.Name == "P1").WithDefaultNamespace("newNamespace");
var worker = await ExecuteOperation(workspace, w => w.ChangeProject(project.Id, project.Solution));
Assert.Equal(5, worker.SyntaxDocumentIds.Count);
Assert.Equal(5, worker.DocumentIds.Count);
}
}
[Fact] [Fact]
public async Task Project_AnalyzerOptions_Change() public async Task Project_AnalyzerOptions_Change()
{ {
......
...@@ -505,7 +505,8 @@ private async Task EnqueueProjectConfigurationChangeWorkItemAsync(ProjectChanges ...@@ -505,7 +505,8 @@ private async Task EnqueueProjectConfigurationChangeWorkItemAsync(ProjectChanges
!object.Equals(oldProject.CompilationOptions, newProject.CompilationOptions) || !object.Equals(oldProject.CompilationOptions, newProject.CompilationOptions) ||
!object.Equals(oldProject.AssemblyName, newProject.AssemblyName) || !object.Equals(oldProject.AssemblyName, newProject.AssemblyName) ||
!object.Equals(oldProject.Name, newProject.Name) || !object.Equals(oldProject.Name, newProject.Name) ||
!object.Equals(oldProject.AnalyzerOptions, newProject.AnalyzerOptions)) !object.Equals(oldProject.AnalyzerOptions, newProject.AnalyzerOptions) ||
!object.Equals(oldProject.DefaultNamespace, newProject.DefaultNamespace))
{ {
projectConfigurationChange = projectConfigurationChange.With(InvocationReasons.ProjectConfigurationChanged); projectConfigurationChange = projectConfigurationChange.With(InvocationReasons.ProjectConfigurationChanged);
} }
......
...@@ -74,6 +74,7 @@ internal abstract partial class AbstractLegacyProject : ForegroundThreadAffiniti ...@@ -74,6 +74,7 @@ internal abstract partial class AbstractLegacyProject : ForegroundThreadAffiniti
FilePath = projectFilePath, FilePath = projectFilePath,
Hierarchy = hierarchy, Hierarchy = hierarchy,
ProjectGuid = GetProjectIDGuid(hierarchy), ProjectGuid = GetProjectIDGuid(hierarchy),
DefaultNamespace = GetDefaultNamespace(hierarchy, language)
}); });
Hierarchy = hierarchy; Hierarchy = hierarchy;
...@@ -302,5 +303,50 @@ private static void ComputeFolderNames(uint folderItemID, List<string> names, IV ...@@ -302,5 +303,50 @@ private static void ComputeFolderNames(uint folderItemID, List<string> names, IV
} }
} }
} }
/// <summary>
/// Get the default namespace of the project ("" if not defined, which means global namespace),
/// or null if it is unknown or not applicable.
/// </summary>
/// <remarks>
/// This only has meaning in C# and is explicitly set to null in VB.
/// </remarks>>
private static string GetDefaultNamespace(IVsHierarchy hierarchy, string language)
{
// While both csproj and vbproj might define <rootnamespace> property in the project file,
// they are very different things.
//
// In C#, it's called default namespace (even though we got the value from rootnamespace property),
// and it doesn't affect the semantic of the code in anyway, just something used by VS.
// For example, when you create a new class, the namespace for the new class is based on it.
// Therefore, we can't get this info from compiler.
//
// However, in VB, it's actually called root namespace, and that info is part of the VB compilation
// (parsed from arguments), because VB compiler needs it to determine the root of all the namespace
// declared in the compilation.
//
// Unfortunately, although being different concepts, default namespace and root namespace are almost
// used interchangebly in VS. For example, (1) the value is define in "rootnamespace" property in project
// files and, (2) the property name we use to call into DTE project below to retrieve the value is
// called "DefaultNamespace".
if (hierarchy != null && language == LanguageNames.CSharp)
{
if (hierarchy.TryGetProject(out var dteProject))
{
try
{
return (string)dteProject.Properties.Item("DefaultNamespace").Value;
}
catch (ArgumentException)
{
// DefaultNamespace does not exist for this project.
return string.Empty;
}
}
}
return null;
}
} }
} }
...@@ -13,5 +13,7 @@ internal sealed class VisualStudioProjectCreationInfo ...@@ -13,5 +13,7 @@ internal sealed class VisualStudioProjectCreationInfo
public IVsHierarchy Hierarchy { get; set; } public IVsHierarchy Hierarchy { get; set; }
public Guid ProjectGuid { get; set; } public Guid ProjectGuid { get; set; }
public string DefaultNamespace { get; set; }
} }
} }
...@@ -51,7 +51,8 @@ public VisualStudioProject CreateAndAddToWorkspace(string projectUniqueName, str ...@@ -51,7 +51,8 @@ public VisualStudioProject CreateAndAddToWorkspace(string projectUniqueName, str
language: language, language: language,
filePath: creationInfo.FilePath, filePath: creationInfo.FilePath,
compilationOptions: creationInfo.CompilationOptions, compilationOptions: creationInfo.CompilationOptions,
parseOptions: creationInfo.ParseOptions); parseOptions: creationInfo.ParseOptions)
.WithDefaultNamespace(creationInfo.DefaultNamespace);
// HACK: update this since we're still on the UI thread. Note we can only update this if we don't have projects -- the workspace // HACK: update this since we're still on the UI thread. Note we can only update this if we don't have projects -- the workspace
// only lets us really do this with OnSolutionAdded for now. // only lets us really do this with OnSolutionAdded for now.
......
...@@ -177,6 +177,14 @@ public async Task TestUpdateOutputRefFilePath() ...@@ -177,6 +177,14 @@ public async Task TestUpdateOutputRefFilePath()
await VerifySolutionUpdate(code, s => s.WithProjectOutputRefFilePath(s.ProjectIds[0], "test.dll")); await VerifySolutionUpdate(code, s => s.WithProjectOutputRefFilePath(s.ProjectIds[0], "test.dll"));
} }
[Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)]
public async Task TestUpdateDefaultNamespace()
{
var code = @"class Test { void Method() { } }";
await VerifySolutionUpdate(code, s => s.WithProjectDefaultNamespace(s.ProjectIds[0], "TestClassLibrary"));
}
[Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)] [Fact, Trait(Traits.Feature, Traits.Features.RemoteHost)]
public async Task TestUpdateDocumentInfo() public async Task TestUpdateDocumentInfo()
{ {
......
...@@ -384,7 +384,8 @@ private Task<ProjectInfo> CreateProjectInfoAsync(ProjectFileInfo projectFileInfo ...@@ -384,7 +384,8 @@ private Task<ProjectInfo> CreateProjectInfoAsync(ProjectFileInfo projectFileInfo
analyzerReferences: analyzerReferences, analyzerReferences: analyzerReferences,
additionalDocuments: additionalDocuments, additionalDocuments: additionalDocuments,
isSubmission: false, isSubmission: false,
hostObjectType: null); hostObjectType: null)
.WithDefaultNamespace(projectFileInfo.DefaultNamespace);
}); });
} }
......
...@@ -119,6 +119,19 @@ private ProjectFileInfo CreateProjectFileInfo(MSB.Execution.ProjectInstance proj ...@@ -119,6 +119,19 @@ private ProjectFileInfo CreateProjectFileInfo(MSB.Execution.ProjectInstance proj
outputRefFilePath = GetAbsolutePathRelativeToProject(outputRefFilePath); outputRefFilePath = GetAbsolutePathRelativeToProject(outputRefFilePath);
} }
// Get the default namespace for C# project, which is a C# only concept at the moment.
// We need the language check because "rootnamespace" property is also used in VB for
// completely different purpose.
string defaultNamespace = null;
if (Language == LanguageNames.CSharp)
{
defaultNamespace = project.ReadPropertyString(PropertyNames.RootNamespace);
if (string.IsNullOrWhiteSpace(defaultNamespace))
{
defaultNamespace = string.Empty;
}
}
var targetFramework = project.ReadPropertyString(PropertyNames.TargetFramework); var targetFramework = project.ReadPropertyString(PropertyNames.TargetFramework);
if (string.IsNullOrWhiteSpace(targetFramework)) if (string.IsNullOrWhiteSpace(targetFramework))
{ {
...@@ -139,6 +152,7 @@ private ProjectFileInfo CreateProjectFileInfo(MSB.Execution.ProjectInstance proj ...@@ -139,6 +152,7 @@ private ProjectFileInfo CreateProjectFileInfo(MSB.Execution.ProjectInstance proj
project.FullPath, project.FullPath,
outputFilePath, outputFilePath,
outputRefFilePath, outputRefFilePath,
defaultNamespace,
targetFramework, targetFramework,
commandLineArgs, commandLineArgs,
docs, docs,
......
...@@ -35,6 +35,15 @@ internal sealed class ProjectFileInfo ...@@ -35,6 +35,15 @@ internal sealed class ProjectFileInfo
/// </summary> /// </summary>
public string OutputRefFilePath { get; } public string OutputRefFilePath { get; }
/// <summary>
/// The default namespace of the project ("" if not defined, which means global namespace),
/// or null if it is unknown or not applicable.
/// </summary>
/// <remarks>
/// This only has meaning in C# and is explicitly set to null in VB.
/// </remarks>>
public string DefaultNamespace { get; }
/// <summary> /// <summary>
/// The target framework of this project. /// The target framework of this project.
/// This takes the form of the 'short name' form used by NuGet (e.g. net46, netcoreapp2.0, etc.) /// This takes the form of the 'short name' form used by NuGet (e.g. net46, netcoreapp2.0, etc.)
...@@ -78,6 +87,7 @@ public override string ToString() ...@@ -78,6 +87,7 @@ public override string ToString()
string filePath, string filePath,
string outputFilePath, string outputFilePath,
string outputRefFilePath, string outputRefFilePath,
string defaultNamespace,
string targetFramework, string targetFramework,
ImmutableArray<string> commandLineArgs, ImmutableArray<string> commandLineArgs,
ImmutableArray<DocumentFileInfo> documents, ImmutableArray<DocumentFileInfo> documents,
...@@ -92,6 +102,7 @@ public override string ToString() ...@@ -92,6 +102,7 @@ public override string ToString()
this.FilePath = filePath; this.FilePath = filePath;
this.OutputFilePath = outputFilePath; this.OutputFilePath = outputFilePath;
this.OutputRefFilePath = outputRefFilePath; this.OutputRefFilePath = outputRefFilePath;
this.DefaultNamespace = defaultNamespace;
this.TargetFramework = targetFramework; this.TargetFramework = targetFramework;
this.CommandLineArgs = commandLineArgs; this.CommandLineArgs = commandLineArgs;
this.Documents = documents; this.Documents = documents;
...@@ -105,6 +116,7 @@ public override string ToString() ...@@ -105,6 +116,7 @@ public override string ToString()
string filePath, string filePath,
string outputFilePath, string outputFilePath,
string outputRefFilePath, string outputRefFilePath,
string defaultNamespace,
string targetFramework, string targetFramework,
ImmutableArray<string> commandLineArgs, ImmutableArray<string> commandLineArgs,
ImmutableArray<DocumentFileInfo> documents, ImmutableArray<DocumentFileInfo> documents,
...@@ -117,6 +129,7 @@ public override string ToString() ...@@ -117,6 +129,7 @@ public override string ToString()
filePath, filePath,
outputFilePath, outputFilePath,
outputRefFilePath, outputRefFilePath,
defaultNamespace,
targetFramework, targetFramework,
commandLineArgs, commandLineArgs,
documents, documents,
...@@ -131,6 +144,7 @@ public static ProjectFileInfo CreateEmpty(string language, string filePath, Diag ...@@ -131,6 +144,7 @@ public static ProjectFileInfo CreateEmpty(string language, string filePath, Diag
filePath, filePath,
outputFilePath: null, outputFilePath: null,
outputRefFilePath: null, outputRefFilePath: null,
defaultNamespace: null,
targetFramework: null, targetFramework: null,
commandLineArgs: ImmutableArray<string>.Empty, commandLineArgs: ImmutableArray<string>.Empty,
documents: ImmutableArray<DocumentFileInfo>.Empty, documents: ImmutableArray<DocumentFileInfo>.Empty,
......
...@@ -62,6 +62,15 @@ internal Project(Solution solution, ProjectState projectState) ...@@ -62,6 +62,15 @@ internal Project(Solution solution, ProjectState projectState)
/// </summary> /// </summary>
public string OutputRefFilePath => _projectState.OutputRefFilePath; public string OutputRefFilePath => _projectState.OutputRefFilePath;
/// <summary>
/// The default namespace of the project ("" if not defined, which means global namespace),
/// or null if it is unknown or not applicable.
/// </summary>
/// <remarks>
/// This only has meaning in C# and is explicitly set to null in VB.
/// </remarks>>
internal string DefaultNamespace => _projectState.DefaultNamespace;
/// <summary> /// <summary>
/// <see langword="true"/> if this <see cref="Project"/> supports providing data through the /// <see langword="true"/> if this <see cref="Project"/> supports providing data through the
/// <see cref="GetCompilationAsync(CancellationToken)"/> method. /// <see cref="GetCompilationAsync(CancellationToken)"/> method.
...@@ -342,6 +351,14 @@ public Project WithAssemblyName(string assemblyName) ...@@ -342,6 +351,14 @@ public Project WithAssemblyName(string assemblyName)
return this.Solution.WithProjectAssemblyName(this.Id, assemblyName).GetProject(this.Id); return this.Solution.WithProjectAssemblyName(this.Id, assemblyName).GetProject(this.Id);
} }
/// <summary>
/// Creates a new instance of this project updated to have the new default namespace.
/// </summary>
internal Project WithDefaultNamespace(string defaultNamespace)
{
return this.Solution.WithProjectDefaultNamespace(this.Id, defaultNamespace).GetProject(this.Id);
}
/// <summary> /// <summary>
/// Creates a new instance of this project updated to have the specified compilation options. /// Creates a new instance of this project updated to have the specified compilation options.
/// </summary> /// </summary>
......
...@@ -58,6 +58,15 @@ public sealed class ProjectInfo ...@@ -58,6 +58,15 @@ public sealed class ProjectInfo
/// </summary> /// </summary>
public string OutputRefFilePath => Attributes.OutputRefFilePath; public string OutputRefFilePath => Attributes.OutputRefFilePath;
/// <summary>
/// The default namespace of the project ("" if not defined, which means global namespace),
/// or null if it is unknown or not applicable.
/// </summary>
/// <remarks>
/// This only has meaning in C# and is explicitly set to null in VB.
/// </remarks>>
internal string DefaultNamespace => Attributes.DefaultNamespace;
/// <summary> /// <summary>
/// True if this is a submission project for interactive sessions. /// True if this is a submission project for interactive sessions.
/// </summary> /// </summary>
...@@ -144,6 +153,7 @@ public sealed class ProjectInfo ...@@ -144,6 +153,7 @@ public sealed class ProjectInfo
string filePath, string filePath,
string outputFilePath, string outputFilePath,
string outputRefFilePath, string outputRefFilePath,
string defaultNamespace,
CompilationOptions compilationOptions, CompilationOptions compilationOptions,
ParseOptions parseOptions, ParseOptions parseOptions,
IEnumerable<DocumentInfo> documents, IEnumerable<DocumentInfo> documents,
...@@ -165,6 +175,7 @@ public sealed class ProjectInfo ...@@ -165,6 +175,7 @@ public sealed class ProjectInfo
filePath, filePath,
outputFilePath, outputFilePath,
outputRefFilePath, outputRefFilePath,
defaultNamespace,
isSubmission, isSubmission,
hasAllInformation), hasAllInformation),
compilationOptions, compilationOptions,
...@@ -201,7 +212,7 @@ public sealed class ProjectInfo ...@@ -201,7 +212,7 @@ public sealed class ProjectInfo
{ {
return Create( return Create(
id, version, name, assemblyName, language, id, version, name, assemblyName, language,
filePath, outputFilePath, outputRefFilePath: null, compilationOptions, parseOptions, filePath, outputFilePath, outputRefFilePath: null, defaultNamespace: null, compilationOptions, parseOptions,
documents, projectReferences, metadataReferences, analyzerReferences, additionalDocuments, documents, projectReferences, metadataReferences, analyzerReferences, additionalDocuments,
isSubmission, hostObjectType, hasAllInformation: true); isSubmission, hostObjectType, hasAllInformation: true);
} }
...@@ -230,7 +241,7 @@ public sealed class ProjectInfo ...@@ -230,7 +241,7 @@ public sealed class ProjectInfo
{ {
return Create( return Create(
id, version, name, assemblyName, language, id, version, name, assemblyName, language,
filePath, outputFilePath, outputRefFilePath, compilationOptions, parseOptions, filePath, outputFilePath, outputRefFilePath, defaultNamespace: null, compilationOptions, parseOptions,
documents, projectReferences, metadataReferences, analyzerReferences, additionalDocuments, documents, projectReferences, metadataReferences, analyzerReferences, additionalDocuments,
isSubmission, hostObjectType, hasAllInformation: true); isSubmission, hostObjectType, hasAllInformation: true);
} }
...@@ -321,6 +332,11 @@ public ProjectInfo WithOutputRefFilePath(string outputRefFilePath) ...@@ -321,6 +332,11 @@ public ProjectInfo WithOutputRefFilePath(string outputRefFilePath)
return With(attributes: Attributes.With(outputRefPath: outputRefFilePath)); return With(attributes: Attributes.With(outputRefPath: outputRefFilePath));
} }
internal ProjectInfo WithDefaultNamespace(string defaultNamespace)
{
return With(attributes: Attributes.With(defaultNamespace: defaultNamespace));
}
public ProjectInfo WithCompilationOptions(CompilationOptions compilationOptions) public ProjectInfo WithCompilationOptions(CompilationOptions compilationOptions)
{ {
return With(compilationOptions: compilationOptions); return With(compilationOptions: compilationOptions);
...@@ -402,6 +418,11 @@ internal class ProjectAttributes : IChecksummedObject, IObjectWritable ...@@ -402,6 +418,11 @@ internal class ProjectAttributes : IChecksummedObject, IObjectWritable
/// </summary> /// </summary>
public string OutputRefFilePath { get; } public string OutputRefFilePath { get; }
/// <summary>
/// The default namespace of the project.
/// </summary>
public string DefaultNamespace { get; }
/// <summary> /// <summary>
/// True if this is a submission project for interactive sessions. /// True if this is a submission project for interactive sessions.
/// </summary> /// </summary>
...@@ -423,6 +444,7 @@ internal class ProjectAttributes : IChecksummedObject, IObjectWritable ...@@ -423,6 +444,7 @@ internal class ProjectAttributes : IChecksummedObject, IObjectWritable
string filePath, string filePath,
string outputFilePath, string outputFilePath,
string outputRefFilePath, string outputRefFilePath,
string defaultNamespace,
bool isSubmission, bool isSubmission,
bool hasAllInformation) bool hasAllInformation)
{ {
...@@ -435,6 +457,7 @@ internal class ProjectAttributes : IChecksummedObject, IObjectWritable ...@@ -435,6 +457,7 @@ internal class ProjectAttributes : IChecksummedObject, IObjectWritable
FilePath = filePath; FilePath = filePath;
OutputFilePath = outputFilePath; OutputFilePath = outputFilePath;
OutputRefFilePath = outputRefFilePath; OutputRefFilePath = outputRefFilePath;
DefaultNamespace = defaultNamespace;
IsSubmission = isSubmission; IsSubmission = isSubmission;
HasAllInformation = hasAllInformation; HasAllInformation = hasAllInformation;
} }
...@@ -447,6 +470,7 @@ internal class ProjectAttributes : IChecksummedObject, IObjectWritable ...@@ -447,6 +470,7 @@ internal class ProjectAttributes : IChecksummedObject, IObjectWritable
Optional<string> filePath = default, Optional<string> filePath = default,
Optional<string> outputPath = default, Optional<string> outputPath = default,
Optional<string> outputRefPath = default, Optional<string> outputRefPath = default,
Optional<string> defaultNamespace = default,
Optional<bool> isSubmission = default, Optional<bool> isSubmission = default,
Optional<bool> hasAllInformation = default) Optional<bool> hasAllInformation = default)
{ {
...@@ -457,6 +481,7 @@ internal class ProjectAttributes : IChecksummedObject, IObjectWritable ...@@ -457,6 +481,7 @@ internal class ProjectAttributes : IChecksummedObject, IObjectWritable
var newFilepath = filePath.HasValue ? filePath.Value : FilePath; var newFilepath = filePath.HasValue ? filePath.Value : FilePath;
var newOutputPath = outputPath.HasValue ? outputPath.Value : OutputFilePath; var newOutputPath = outputPath.HasValue ? outputPath.Value : OutputFilePath;
var newOutputRefPath = outputRefPath.HasValue ? outputRefPath.Value : OutputRefFilePath; var newOutputRefPath = outputRefPath.HasValue ? outputRefPath.Value : OutputRefFilePath;
var newDefaultNamespace = defaultNamespace.HasValue ? defaultNamespace.Value : DefaultNamespace;
var newIsSubmission = isSubmission.HasValue ? isSubmission.Value : IsSubmission; var newIsSubmission = isSubmission.HasValue ? isSubmission.Value : IsSubmission;
var newHasAllInformation = hasAllInformation.HasValue ? hasAllInformation.Value : HasAllInformation; var newHasAllInformation = hasAllInformation.HasValue ? hasAllInformation.Value : HasAllInformation;
...@@ -467,6 +492,7 @@ internal class ProjectAttributes : IChecksummedObject, IObjectWritable ...@@ -467,6 +492,7 @@ internal class ProjectAttributes : IChecksummedObject, IObjectWritable
newFilepath == FilePath && newFilepath == FilePath &&
newOutputPath == OutputFilePath && newOutputPath == OutputFilePath &&
newOutputRefPath == OutputRefFilePath && newOutputRefPath == OutputRefFilePath &&
newDefaultNamespace == DefaultNamespace &&
newIsSubmission == IsSubmission && newIsSubmission == IsSubmission &&
newHasAllInformation == HasAllInformation) newHasAllInformation == HasAllInformation)
{ {
...@@ -482,6 +508,7 @@ internal class ProjectAttributes : IChecksummedObject, IObjectWritable ...@@ -482,6 +508,7 @@ internal class ProjectAttributes : IChecksummedObject, IObjectWritable
newFilepath, newFilepath,
newOutputPath, newOutputPath,
newOutputRefPath, newOutputRefPath,
newDefaultNamespace,
newIsSubmission, newIsSubmission,
newHasAllInformation); newHasAllInformation);
} }
...@@ -501,6 +528,7 @@ public void WriteTo(ObjectWriter writer) ...@@ -501,6 +528,7 @@ public void WriteTo(ObjectWriter writer)
writer.WriteString(FilePath); writer.WriteString(FilePath);
writer.WriteString(OutputFilePath); writer.WriteString(OutputFilePath);
writer.WriteString(OutputRefFilePath); writer.WriteString(OutputRefFilePath);
writer.WriteString(DefaultNamespace);
writer.WriteBoolean(IsSubmission); writer.WriteBoolean(IsSubmission);
writer.WriteBoolean(HasAllInformation); writer.WriteBoolean(HasAllInformation);
...@@ -519,10 +547,11 @@ public static ProjectAttributes ReadFrom(ObjectReader reader) ...@@ -519,10 +547,11 @@ public static ProjectAttributes ReadFrom(ObjectReader reader)
var filePath = reader.ReadString(); var filePath = reader.ReadString();
var outputFilePath = reader.ReadString(); var outputFilePath = reader.ReadString();
var outputRefFilePath = reader.ReadString(); var outputRefFilePath = reader.ReadString();
var defaultNamespace = reader.ReadString();
var isSubmission = reader.ReadBoolean(); var isSubmission = reader.ReadBoolean();
var hasAllInformation = reader.ReadBoolean(); var hasAllInformation = reader.ReadBoolean();
return new ProjectAttributes(projectId, VersionStamp.Create(), name, assemblyName, language, filePath, outputFilePath, outputRefFilePath, isSubmission, hasAllInformation); return new ProjectAttributes(projectId, VersionStamp.Create(), name, assemblyName, language, filePath, outputFilePath, outputRefFilePath, defaultNamespace, isSubmission, hasAllInformation);
} }
private Checksum _lazyChecksum; private Checksum _lazyChecksum;
......
...@@ -268,6 +268,9 @@ public async Task<VersionStamp> GetSemanticVersionAsync(CancellationToken cancel ...@@ -268,6 +268,9 @@ public async Task<VersionStamp> GetSemanticVersionAsync(CancellationToken cancel
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)] [DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public string OutputRefFilePath => this.ProjectInfo.OutputRefFilePath; public string OutputRefFilePath => this.ProjectInfo.OutputRefFilePath;
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public string DefaultNamespace => this.ProjectInfo.DefaultNamespace;
[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)] [DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public HostLanguageServices LanguageServices => _languageServices; public HostLanguageServices LanguageServices => _languageServices;
...@@ -424,6 +427,16 @@ public ProjectState UpdateOutputRefFilePath(string outputRefFilePath) ...@@ -424,6 +427,16 @@ public ProjectState UpdateOutputRefFilePath(string outputRefFilePath)
return this.With(projectInfo: this.ProjectInfo.WithOutputRefFilePath(outputRefFilePath).WithVersion(this.Version.GetNewerVersion())); return this.With(projectInfo: this.ProjectInfo.WithOutputRefFilePath(outputRefFilePath).WithVersion(this.Version.GetNewerVersion()));
} }
public ProjectState UpdateDefaultNamespace(string defaultNamespace)
{
if (defaultNamespace == this.DefaultNamespace)
{
return this;
}
return this.With(projectInfo: this.ProjectInfo.WithDefaultNamespace(defaultNamespace).WithVersion(this.Version.GetNewerVersion()));
}
public ProjectState UpdateCompilationOptions(CompilationOptions options) public ProjectState UpdateCompilationOptions(CompilationOptions options)
{ {
if (options == this.CompilationOptions) if (options == this.CompilationOptions)
......
...@@ -304,6 +304,20 @@ public Solution WithProjectOutputRefFilePath(ProjectId projectId, string outputR ...@@ -304,6 +304,20 @@ public Solution WithProjectOutputRefFilePath(ProjectId projectId, string outputR
return new Solution(newState); return new Solution(newState);
} }
/// <summary>
/// Creates a new solution instance with the project specified updated to have the default namespace.
/// </summary>
internal Solution WithProjectDefaultNamespace(ProjectId projectId, string defaultNamespace)
{
var newState = _state.WithProjectDefaultNamespace(projectId, defaultNamespace);
if (newState == _state)
{
return this;
}
return new Solution(newState);
}
/// <summary> /// <summary>
/// Creates a new solution instance with the project specified updated to have the name. /// Creates a new solution instance with the project specified updated to have the name.
/// </summary> /// </summary>
......
...@@ -656,6 +656,29 @@ public SolutionState WithProjectOutputRefFilePath(ProjectId projectId, string ou ...@@ -656,6 +656,29 @@ public SolutionState WithProjectOutputRefFilePath(ProjectId projectId, string ou
return this.ForkProject(newProjectState); return this.ForkProject(newProjectState);
} }
/// <summary>
/// Creates a new solution instance with the project specified updated to have the default namespace.
/// </summary>
public SolutionState WithProjectDefaultNamespace(ProjectId projectId, string defaultNamespace)
{
if (projectId == null)
{
throw new ArgumentNullException(nameof(projectId));
}
CheckContainsProject(projectId);
var oldProjectState = this.GetProjectState(projectId);
var newProjectState = oldProjectState.UpdateDefaultNamespace(defaultNamespace);
if (oldProjectState == newProjectState)
{
return this;
}
return this.ForkProject(newProjectState);
}
/// <summary> /// <summary>
/// Creates a new solution instance with the project specified updated to have the name. /// Creates a new solution instance with the project specified updated to have the name.
/// </summary> /// </summary>
......
...@@ -1445,7 +1445,8 @@ private ProjectInfo CreateProjectInfo(Project project) ...@@ -1445,7 +1445,8 @@ private ProjectInfo CreateProjectInfo(Project project)
project.AdditionalDocuments.Select(d => CreateDocumentInfoWithText(d)), project.AdditionalDocuments.Select(d => CreateDocumentInfoWithText(d)),
project.IsSubmission, project.IsSubmission,
project.State.HostObjectType, project.State.HostObjectType,
project.OutputRefFilePath); project.OutputRefFilePath)
.WithDefaultNamespace(project.DefaultNamespace);
} }
private DocumentInfo CreateDocumentInfoWithText(TextDocument doc) private DocumentInfo CreateDocumentInfoWithText(TextDocument doc)
......
...@@ -267,6 +267,11 @@ private async Task<Project> UpdateProjectInfoAsync(Project project, Checksum inf ...@@ -267,6 +267,11 @@ private async Task<Project> UpdateProjectInfoAsync(Project project, Checksum inf
project = project.Solution.WithProjectOutputRefFilePath(project.Id, newProjectInfo.OutputRefFilePath).GetProject(project.Id); project = project.Solution.WithProjectOutputRefFilePath(project.Id, newProjectInfo.OutputRefFilePath).GetProject(project.Id);
} }
if (project.State.ProjectInfo.Attributes.DefaultNamespace != newProjectInfo.DefaultNamespace)
{
project = project.Solution.WithProjectDefaultNamespace(project.Id, newProjectInfo.DefaultNamespace).GetProject(project.Id);
}
if (project.State.ProjectInfo.Attributes.HasAllInformation != newProjectInfo.HasAllInformation) if (project.State.ProjectInfo.Attributes.HasAllInformation != newProjectInfo.HasAllInformation)
{ {
project = project.Solution.WithHasAllInformation(project.Id, newProjectInfo.HasAllInformation).GetProject(project.Id); project = project.Solution.WithHasAllInformation(project.Id, newProjectInfo.HasAllInformation).GetProject(project.Id);
...@@ -516,7 +521,9 @@ private async Task<ProjectInfo> CreateProjectInfoAsync(Checksum projectChecksum) ...@@ -516,7 +521,9 @@ private async Task<ProjectInfo> CreateProjectInfoAsync(Checksum projectChecksum)
projectInfo.Id, projectInfo.Version, projectInfo.Name, projectInfo.AssemblyName, projectInfo.Id, projectInfo.Version, projectInfo.Name, projectInfo.AssemblyName,
projectInfo.Language, projectInfo.FilePath, projectInfo.OutputFilePath, projectInfo.Language, projectInfo.FilePath, projectInfo.OutputFilePath,
compilationOptions, parseOptions, compilationOptions, parseOptions,
documents, p2p, metadata, analyzers, additionals, projectInfo.IsSubmission).WithHasAllInformation(projectInfo.HasAllInformation); documents, p2p, metadata, analyzers, additionals, projectInfo.IsSubmission)
.WithHasAllInformation(projectInfo.HasAllInformation)
.WithDefaultNamespace(projectInfo.DefaultNamespace);
} }
private async Task<List<T>> CreateCollectionAsync<T>(ChecksumCollection collections) private async Task<List<T>> CreateCollectionAsync<T>(ChecksumCollection collections)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册