提交 db53207f 编写于 作者: K Kevin Pilch-Bisson

Start trying to populate the workspace on the background when in DeferredProjectLoad.

上级 1723eeac
......@@ -738,7 +738,7 @@ internal void AddProjectReference(ProjectReference projectReference)
// This project is already pushed to listening workspace hosts, but it's possible that our target
// project hasn't been yet. Get the dependent project into the workspace as well.
var targetProject = this.ProjectTracker.GetProject(projectReference.ProjectId);
this.ProjectTracker.StartPushingToWorkspaceAndNotifyOfOpenDocuments(SpecializedCollections.SingletonEnumerable(targetProject));
this.ProjectTracker.StartPushingToWorkspaceAndNotifyOfOpenDocuments(SpecializedCollections.SingletonEnumerable(targetProject), p => p.CreateProjectInfoForCurrentState());
this.ProjectTracker.NotifyWorkspaceHosts(host => host.OnProjectReferenceAdded(this.Id, projectReference));
}
......@@ -1389,7 +1389,7 @@ private static void StartPushingToWorkspaceAndNotifyOfOpenDocuments(AbstractProj
// it here. It's important to do this after everything else happens in this method, so we don't get
// strange ordering issues. It's still possible that this won't actually push changes if the workspace
// host isn't ready to receive events yet.
project.ProjectTracker.StartPushingToWorkspaceAndNotifyOfOpenDocuments(SpecializedCollections.SingletonEnumerable(project));
project.ProjectTracker.StartPushingToWorkspaceAndNotifyOfOpenDocuments(SpecializedCollections.SingletonEnumerable(project), p => p.CreateProjectInfoForCurrentState());
}
private static MetadataReferenceResolver CreateMetadataReferenceResolver(IMetadataService metadataService, string projectDirectory, string outputDirectory)
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.CodeAnalysis;
using Microsoft.VisualStudio.Shell.Interop;
namespace Microsoft.VisualStudio.LanguageServices.ProjectSystem
......
......@@ -80,7 +80,9 @@ internal void SolutionClosed()
_pushedProjects.Clear();
}
internal void StartPushingToWorkspaceAndNotifyOfOpenDocuments(IEnumerable<AbstractProject> projects)
internal void StartPushingToWorkspaceAndNotifyOfOpenDocuments(
IEnumerable<AbstractProject> projects,
Func<AbstractProject, ProjectInfo> getProjectInfo)
{
AssertIsForeground();
......@@ -103,7 +105,7 @@ internal void StartPushingToWorkspaceAndNotifyOfOpenDocuments(IEnumerable<Abstra
AddToPushListIfNeeded(project, inOrderToPush, visited);
}
var projectInfos = inOrderToPush.Select(p => p.CreateProjectInfoForCurrentState()).ToImmutableArray();
var projectInfos = inOrderToPush.Select(p => getProjectInfo(p)).ToImmutableArray();
// We need to enable projects to start pushing changes to workspace hosts even before we add the solution/project to the host.
// This is required because between the point we capture the project info for current state and the point where we start pushing to workspace hosts,
......
......@@ -29,6 +29,11 @@ internal sealed partial class VisualStudioProjectTracker : ForegroundThreadAffin
#region Mutable fields accessed only from foreground thread - don't need locking for access (all accessing methods must have AssertIsForeground).
private readonly List<WorkspaceHostState> _workspaceHosts;
/// <summary>
/// TODO: Figure out the right way to get this to the MSBuildProjectLoader.
/// </summary>
private readonly Workspace _workspace;
/// <summary>
/// The list of projects loaded in this batch between <see cref="IVsSolutionLoadEvents.OnBeforeLoadProjectBatch" /> and
/// <see cref="IVsSolutionLoadEvents.OnAfterLoadProjectBatch(bool)"/>.
......@@ -97,10 +102,16 @@ void IVisualStudioHostProjectContainer.NotifyNonDocumentOpenedForProject(IVisual
AssertIsForeground();
var abstractProject = (AbstractProject)project;
StartPushingToWorkspaceAndNotifyOfOpenDocuments(SpecializedCollections.SingletonEnumerable(abstractProject));
StartPushingToWorkspaceAndNotifyOfOpenDocuments(SpecializedCollections.SingletonEnumerable(abstractProject), s_getProjectInfoForProject);
}
private static readonly Func<AbstractProject, ProjectInfo> s_getProjectInfoForProject = GetProjectInfoForProject;
private static ProjectInfo GetProjectInfoForProject(AbstractProject project)
{
return project.CreateProjectInfoForCurrentState();
}
public VisualStudioProjectTracker(IServiceProvider serviceProvider)
public VisualStudioProjectTracker(IServiceProvider serviceProvider, Workspace workspace)
: base(assertIsForeground: true)
{
_projectMap = new Dictionary<ProjectId, AbstractProject>();
......@@ -108,6 +119,7 @@ public VisualStudioProjectTracker(IServiceProvider serviceProvider)
_serviceProvider = serviceProvider;
_workspaceHosts = new List<WorkspaceHostState>(capacity: 1);
_workspace = workspace;
_vsSolution = (IVsSolution)serviceProvider.GetService(typeof(SVsSolution));
_runningDocumentTable = (IVsRunningDocumentTable4)serviceProvider.GetService(typeof(SVsRunningDocumentTable));
......@@ -242,7 +254,7 @@ public void StartSendingEventsToWorkspaceHost(IVisualStudioWorkspaceHost host)
if (interactiveProjects.Any())
{
hostData.StartPushingToWorkspaceAndNotifyOfOpenDocuments(interactiveProjects);
hostData.StartPushingToWorkspaceAndNotifyOfOpenDocuments(interactiveProjects, s_getProjectInfoForProject);
}
}
......@@ -312,7 +324,7 @@ private void AddProject_Foreground(AbstractProject project)
if (_solutionLoadComplete)
{
StartPushingToWorkspaceAndNotifyOfOpenDocuments_Foreground(SpecializedCollections.SingletonEnumerable(project));
StartPushingToWorkspaceAndNotifyOfOpenDocuments_Foreground(SpecializedCollections.SingletonEnumerable(project), s_getProjectInfoForProject);
}
else
{
......@@ -326,12 +338,12 @@ private void AddProject_Foreground(AbstractProject project)
/// Otherwise, it is scheduled on foreground task scheduler.
/// </summary>
/// <remarks>This method may be called on a background thread.</remarks>
internal void StartPushingToWorkspaceAndNotifyOfOpenDocuments(IEnumerable<AbstractProject> projects)
internal void StartPushingToWorkspaceAndNotifyOfOpenDocuments(IEnumerable<AbstractProject> projects, Func<AbstractProject, ProjectInfo> getProjectInfo)
{
ExecuteOrScheduleForegroundAffinitizedAction(() => StartPushingToWorkspaceAndNotifyOfOpenDocuments_Foreground(projects));
ExecuteOrScheduleForegroundAffinitizedAction(() => StartPushingToWorkspaceAndNotifyOfOpenDocuments_Foreground(projects, getProjectInfo));
}
private void StartPushingToWorkspaceAndNotifyOfOpenDocuments_Foreground(IEnumerable<AbstractProject> projects)
private void StartPushingToWorkspaceAndNotifyOfOpenDocuments_Foreground(IEnumerable<AbstractProject> projects, Func<AbstractProject, ProjectInfo> getProjectInfo)
{
AssertIsForeground();
......@@ -339,7 +351,7 @@ private void StartPushingToWorkspaceAndNotifyOfOpenDocuments_Foreground(IEnumera
{
foreach (var hostState in _workspaceHosts)
{
hostState.StartPushingToWorkspaceAndNotifyOfOpenDocuments(projects);
hostState.StartPushingToWorkspaceAndNotifyOfOpenDocuments(projects, getProjectInfo);
}
}
}
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading;
using Microsoft.VisualStudio.Shell.Interop;
using Roslyn.Utilities;
......@@ -59,6 +60,9 @@ int IVsSolutionEvents.OnBeforeCloseSolution(object pUnkReserved)
}
_solutionLoadComplete = false;
_solutionFilename = null;
_solutionParsingCancellationTokenSource.Cancel();
_solutionParsingCancellationTokenSource = new CancellationTokenSource();
return VSConstants.S_OK;
}
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.CodeAnalysis;
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.Shell.Interop;
using System.Threading.Tasks;
using System.Threading;
using Microsoft.CodeAnalysis.MSBuild;
using System.Collections.Generic;
using Microsoft.VisualStudio.LanguageServices.ProjectSystem;
using Roslyn.Utilities;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem
{
internal partial class VisualStudioProjectTracker : IVsSolutionLoadEvents
{
private string _solutionFilename;
private CancellationTokenSource _solutionParsingCancellationTokenSource = new CancellationTokenSource();
private bool _inDeferredProjectLoad = true;
int IVsSolutionLoadEvents.OnBeforeOpenSolution(string pszSolutionFilename)
{
this._solutionFilename = pszSolutionFilename;
return VSConstants.S_OK;
}
......@@ -39,7 +52,7 @@ int IVsSolutionLoadEvents.OnAfterLoadProjectBatch(bool fIsBackgroundIdleBatch)
{
// This batch was loaded eagerly. This might be because the user is force expanding the projects in the
// Solution Explorer, or they had some files open in an .suo we need to push.
StartPushingToWorkspaceAndNotifyOfOpenDocuments(_projectsLoadedThisBatch);
StartPushingToWorkspaceAndNotifyOfOpenDocuments(_projectsLoadedThisBatch, s_getProjectInfoForProject);
}
_projectsLoadedThisBatch.Clear();
......@@ -51,6 +64,94 @@ int IVsSolutionLoadEvents.OnAfterBackgroundSolutionLoadComplete()
{
AssertIsForeground();
if (_inDeferredProjectLoad)
{
var componentModel = _serviceProvider.GetService(typeof(SComponentModel)) as IComponentModel;
var workspaceProjectFactory = componentModel.GetService<IWorkspaceProjectContextFactory>();
LoadSolutionInBackground(workspaceProjectFactory);
}
else
{
PushCompleteSolutionToWorkspace(s_getProjectInfoForProject);
}
return VSConstants.S_OK;
}
private async void LoadSolutionInBackground(IWorkspaceProjectContextFactory workspaceProjectContextFactory)
{
var solutionInfo = await Task.Run(LoadSolutionInfoAsync, _solutionParsingCancellationTokenSource.Token).ConfigureAwait(true);
var projectToProjectInfo = new Dictionary<AbstractProject, ProjectInfo>();
// TODO: Sort this topologically somehow?
foreach (var projectInfo in solutionInfo.Projects)
{
if (_projectPathToIdMap.ContainsKey(projectInfo.FilePath))
{
continue;
}
var projectContext = workspaceProjectContextFactory.CreateProjectContext(
projectInfo.Language,
projectInfo.Name,
projectInfo.FilePath,
Guid.Empty,
null,
projectInfo.CommandLineOpt);
foreach (var documentInfo in projectInfo.Documents)
{
projectContext.AddSourceFile(documentInfo.FilePath, folderNames: documentInfo.Folders);
}
foreach (var documentInfo in projectInfo.AdditionalDocuments)
{
projectContext.AddAdditionalFile(documentInfo.FilePath);
}
foreach (var reference in projectInfo.MetadataReferences)
{
projectContext.AddMetadataReference(reference.Display, reference.Properties);
}
foreach (var reference in projectInfo.ProjectReferences)
{
// TODO: If this was eagerly loaded already, this cast will fail?
projectContext.AddProjectReference(
(IWorkspaceProjectContext)_projectMap[reference.ProjectId],
new MetadataReferenceProperties(aliases: reference.Aliases, embedInteropTypes: reference.EmbedInteropTypes));
}
foreach (var reference in projectInfo.AnalyzerReferences)
{
projectContext.AddAnalyzerReference(reference.FullPath);
}
projectToProjectInfo[(AbstractProject)projectContext] = projectInfo;
}
PushCompleteSolutionToWorkspace(p => projectToProjectInfo[p]);
}
private IVisualStudioHostDocument CreateHostDocument(AbstractProject project, DocumentInfo documentInfo)
{
return DocumentProvider.TryGetDocumentForFile(
project,
documentInfo.FilePath,
SourceCodeKind.Regular,
tb => true,
itemid => SpecializedCollections.EmptyReadOnlyList<string>());
}
private Task<SolutionInfo> LoadSolutionInfoAsync()
{
var loader = new MSBuildProjectLoader(_workspace);
return loader.LoadSolutionInfoAsync(_solutionFilename, _solutionParsingCancellationTokenSource.Token);
}
private void PushCompleteSolutionToWorkspace(Func<AbstractProject, ProjectInfo> getProjectInfo)
{
// We are now completely done, so let's simply ensure all projects are added.
StartPushingToWorkspaceAndNotifyOfOpenDocuments_Foreground(this.ImmutableProjects);
......@@ -59,8 +160,6 @@ int IVsSolutionLoadEvents.OnAfterBackgroundSolutionLoadComplete()
// Check that the set of analyzers is complete and consistent.
GetAnalyzerDependencyCheckingService()?.CheckForConflictsAsync();
return VSConstants.S_OK;
}
private AnalyzerDependencyCheckingService GetAnalyzerDependencyCheckingService()
......
......@@ -77,7 +77,7 @@ internal static HostServices CreateHostServices(SVsServiceProvider serviceProvid
protected void InitializeStandardVisualStudioWorkspace(SVsServiceProvider serviceProvider, SaveEventsService saveEventsService)
{
var projectTracker = new VisualStudioProjectTracker(serviceProvider);
var projectTracker = new VisualStudioProjectTracker(serviceProvider, this);
// Ensure the document tracking service is initialized on the UI thread
var documentTrackingService = this.Services.GetService<IDocumentTrackingService>();
......
......@@ -59,13 +59,13 @@ internal static CPSProject CreateCPSProject(VisualStudioProjectTracker projectTr
object hierarchy,
string binOutputPath)
{
Contract.ThrowIfNull(hierarchy);
//Contract.ThrowIfNull(hierarchy);
var vsHierarchy = hierarchy as IVsHierarchy;
if (vsHierarchy == null)
{
throw new ArgumentException(nameof(hierarchy));
}
//if (vsHierarchy == null)
//{
// throw new ArgumentException(nameof(hierarchy));
//}
Func<ProjectId, IVsReportExternalErrors> getExternalErrorReporter = id => GetExternalErrorReporter(id, languageName);
return new CPSProject(_visualStudioWorkspace.ProjectTracker, getExternalErrorReporter, projectDisplayName, projectFilePath,
vsHierarchy, languageName, projectGuid, binOutputPath, _serviceProvider, _visualStudioWorkspace, _hostDiagnosticUpdateSource,
......
......@@ -38,8 +38,9 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ProjectSystemShim.Fr
_monitorSelectionMock = New MockShellMonitorSelection(solutionIsFullyLoaded)
_serviceProvider = New MockServiceProvider(_monitorSelectionMock)
_projectTracker = New VisualStudioProjectTracker(_serviceProvider)
_workspace = New TestWorkspace()
_projectTracker = New VisualStudioProjectTracker(_serviceProvider, _workspace)
Dim metadataReferenceProvider = New VisualStudioMetadataReferenceManager(_serviceProvider, _workspace.Services.GetService(Of ITemporaryStorageService)())
Dim ruleSetFileProvider = New VisualStudioRuleSetManager(
DirectCast(_serviceProvider.GetService(GetType(SVsFileChangeEx)), IVsFileChangeEx),
......
......@@ -428,7 +428,8 @@ private async Task<ProjectId> LoadProjectAsync(string projectFilePath, IProjectF
analyzerReferences: analyzerReferences,
additionalDocuments: additionalDocs,
isSubmission: false,
hostObjectType: null));
hostObjectType: null,
commandLineOpt: string.Join(" ", projectFileInfo.CommandLineArgs)));
return projectId;
}
......
......@@ -1251,7 +1251,6 @@ static Microsoft.CodeAnalysis.ProjectId.CreateFromSerialized(System.Guid id, str
static Microsoft.CodeAnalysis.ProjectId.CreateNewId(string debugName = null) -> Microsoft.CodeAnalysis.ProjectId
static Microsoft.CodeAnalysis.ProjectId.operator !=(Microsoft.CodeAnalysis.ProjectId left, Microsoft.CodeAnalysis.ProjectId right) -> bool
static Microsoft.CodeAnalysis.ProjectId.operator ==(Microsoft.CodeAnalysis.ProjectId left, Microsoft.CodeAnalysis.ProjectId right) -> bool
static Microsoft.CodeAnalysis.ProjectInfo.Create(Microsoft.CodeAnalysis.ProjectId id, Microsoft.CodeAnalysis.VersionStamp version, string name, string assemblyName, string language, string filePath = null, string outputFilePath = null, Microsoft.CodeAnalysis.CompilationOptions compilationOptions = null, Microsoft.CodeAnalysis.ParseOptions parseOptions = null, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.DocumentInfo> documents = null, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.ProjectReference> projectReferences = null, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.MetadataReference> metadataReferences = null, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.Diagnostics.AnalyzerReference> analyzerReferences = null, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.DocumentInfo> additionalDocuments = null, bool isSubmission = false, System.Type hostObjectType = null) -> Microsoft.CodeAnalysis.ProjectInfo
static Microsoft.CodeAnalysis.ProjectReference.operator !=(Microsoft.CodeAnalysis.ProjectReference left, Microsoft.CodeAnalysis.ProjectReference right) -> bool
static Microsoft.CodeAnalysis.ProjectReference.operator ==(Microsoft.CodeAnalysis.ProjectReference left, Microsoft.CodeAnalysis.ProjectReference right) -> bool
static Microsoft.CodeAnalysis.Recommendations.RecommendationOptions.FilterOutOfScopeLocals.get -> Microsoft.CodeAnalysis.Options.PerLanguageOption<bool>
......
......@@ -25,6 +25,7 @@ Microsoft.CodeAnalysis.Editing.SyntaxGenerator.AddSwitchSections(Microsoft.CodeA
Microsoft.CodeAnalysis.Options.DocumentOptionSet
Microsoft.CodeAnalysis.Options.DocumentOptionSet.GetOption<T>(Microsoft.CodeAnalysis.Options.PerLanguageOption<T> option) -> T
Microsoft.CodeAnalysis.Options.OptionSet.OptionSet() -> void
Microsoft.CodeAnalysis.ProjectInfo.CommandLineOpt.get -> string
Microsoft.CodeAnalysis.Solution.Options.get -> Microsoft.CodeAnalysis.Options.OptionSet
Microsoft.CodeAnalysis.Workspace.DocumentActiveContextChanged -> System.EventHandler<Microsoft.CodeAnalysis.DocumentActiveContextChangedEventArgs>
Microsoft.CodeAnalysis.Workspace.RaiseDocumentActiveContextChangedEventAsync(Microsoft.CodeAnalysis.Text.SourceTextContainer sourceTextContainer, Microsoft.CodeAnalysis.DocumentId oldActiveContextDocumentId, Microsoft.CodeAnalysis.DocumentId newActiveContextDocumentId) -> System.Threading.Tasks.Task
......@@ -37,6 +38,7 @@ override Microsoft.CodeAnalysis.Options.DocumentOptionSet.GetOption(Microsoft.Co
override Microsoft.CodeAnalysis.Options.DocumentOptionSet.WithChangedOption(Microsoft.CodeAnalysis.Options.OptionKey optionAndLanguage, object value) -> Microsoft.CodeAnalysis.Options.OptionSet
static Microsoft.CodeAnalysis.CodeStyle.CodeStyleOption<T>.Default.get -> Microsoft.CodeAnalysis.CodeStyle.CodeStyleOption<T>
static Microsoft.CodeAnalysis.CodeStyle.CodeStyleOption<T>.FromXElement(System.Xml.Linq.XElement element) -> Microsoft.CodeAnalysis.CodeStyle.CodeStyleOption<T>
static Microsoft.CodeAnalysis.ProjectInfo.Create(Microsoft.CodeAnalysis.ProjectId id, Microsoft.CodeAnalysis.VersionStamp version, string name, string assemblyName, string language, string filePath = null, string outputFilePath = null, Microsoft.CodeAnalysis.CompilationOptions compilationOptions = null, Microsoft.CodeAnalysis.ParseOptions parseOptions = null, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.DocumentInfo> documents = null, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.ProjectReference> projectReferences = null, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.MetadataReference> metadataReferences = null, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.Diagnostics.AnalyzerReference> analyzerReferences = null, System.Collections.Generic.IEnumerable<Microsoft.CodeAnalysis.DocumentInfo> additionalDocuments = null, bool isSubmission = false, System.Type hostObjectType = null, string commandLineOpt = null) -> Microsoft.CodeAnalysis.ProjectInfo
static Microsoft.CodeAnalysis.Simplification.SimplificationOptions.NamingPreferences.get -> Microsoft.CodeAnalysis.Options.PerLanguageOption<string>
static Microsoft.CodeAnalysis.Simplification.SimplificationOptions.QualifyEventAccess.get -> Microsoft.CodeAnalysis.Options.PerLanguageOption<bool>
static Microsoft.CodeAnalysis.Simplification.SimplificationOptions.QualifyFieldAccess.get -> Microsoft.CodeAnalysis.Options.PerLanguageOption<bool>
......
......@@ -94,6 +94,11 @@ public sealed class ProjectInfo
/// </summary>
public Type HostObjectType { get; }
/// <summary>
/// The command line arguments to compile this project. May be <see langword="null" />
/// </summary>
public string CommandLineOpt { get; }
/// <summary>
/// True if project information is complete. In some workspace hosts, it is possible
/// a project only has partial information. In such cases, a project might not have all
......@@ -118,6 +123,7 @@ public sealed class ProjectInfo
IEnumerable<DocumentInfo> additionalDocuments,
bool isSubmission,
Type hostObjectType,
string commandLineOpt,
bool hasAllInformation)
{
if (id == null)
......@@ -156,6 +162,7 @@ public sealed class ProjectInfo
this.AdditionalDocuments = additionalDocuments.ToImmutableReadOnlyListOrEmpty();
this.IsSubmission = isSubmission;
this.HostObjectType = hostObjectType;
this.CommandLineOpt = commandLineOpt;
this.HasAllInformation = hasAllInformation;
}
......@@ -179,6 +186,7 @@ public sealed class ProjectInfo
IEnumerable<DocumentInfo> additionalDocuments,
bool isSubmission,
Type hostObjectType,
string commandLineOpt,
bool hasAllInformation)
{
return new ProjectInfo(
......@@ -198,6 +206,7 @@ public sealed class ProjectInfo
additionalDocuments,
isSubmission,
hostObjectType,
commandLineOpt,
hasAllInformation);
}
......@@ -220,13 +229,14 @@ public sealed class ProjectInfo
IEnumerable<AnalyzerReference> analyzerReferences = null,
IEnumerable<DocumentInfo> additionalDocuments = null,
bool isSubmission = false,
Type hostObjectType = null)
Type hostObjectType = null,
string commandLineOpt = null)
{
return Create(
id, version, name, assemblyName, language,
filePath, outputFilePath, compilationOptions, parseOptions,
documents, projectReferences, metadataReferences, analyzerReferences, additionalDocuments,
isSubmission, hostObjectType, hasAllInformation: true);
isSubmission, hostObjectType, commandLineOpt, hasAllInformation: true);
}
private ProjectInfo With(
......@@ -246,6 +256,7 @@ public sealed class ProjectInfo
IEnumerable<DocumentInfo> additionalDocuments = null,
Optional<bool> isSubmission = default(Optional<bool>),
Optional<Type> hostObjectType = default(Optional<Type>),
Optional<string> commandLineOpt = default(Optional<string>),
Optional<bool> hasAllInformation = default(Optional<bool>))
{
var newId = id ?? this.Id;
......@@ -264,6 +275,7 @@ public sealed class ProjectInfo
var newAdditionalDocuments = additionalDocuments ?? this.AdditionalDocuments;
var newIsSubmission = isSubmission.HasValue ? isSubmission.Value : this.IsSubmission;
var newHostObjectType = hostObjectType.HasValue ? hostObjectType.Value : this.HostObjectType;
var newCommandLineOpt = commandLineOpt.HasValue ? commandLineOpt.Value : this.CommandLineOpt;
var newHasAllInformation = hasAllInformation.HasValue ? hasAllInformation.Value : this.HasAllInformation;
if (newId == this.Id &&
......@@ -282,6 +294,7 @@ public sealed class ProjectInfo
newAdditionalDocuments == this.AdditionalDocuments &&
newIsSubmission == this.IsSubmission &&
newHostObjectType == this.HostObjectType &&
newCommandLineOpt == this.CommandLineOpt &&
newHasAllInformation == this.HasAllInformation)
{
return this;
......@@ -304,6 +317,7 @@ public sealed class ProjectInfo
newAdditionalDocuments,
newIsSubmission,
newHostObjectType,
newCommandLineOpt,
newHasAllInformation);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册