public override void Update(Project workspaceProject, ProjectSnapshot projectSnapshot) { if (projectSnapshot == null) { throw new ArgumentNullException(nameof(projectSnapshot)); } _foregroundDispatcher.AssertForegroundThread(); if (_updates.TryGetValue(projectSnapshot.FilePath, out var updateItem) && !updateItem.Task.IsCompleted) { updateItem.Cts.Cancel(); } updateItem?.Cts.Dispose(); var cts = new CancellationTokenSource(); var updateTask = Task.Factory.StartNew( () => UpdateWorkspaceStateAsync(workspaceProject, projectSnapshot, cts.Token), cts.Token, TaskCreationOptions.None, _foregroundDispatcher.BackgroundScheduler).Unwrap(); updateTask.ConfigureAwait(false); updateItem = new UpdateItem(updateTask, cts); _updates[projectSnapshot.FilePath] = updateItem; }
// Internal for testing internal void TryUpdateViewImportDependencies(string documentFilePath, ProjectSnapshot project) { // Upon the completion of https://github.com/aspnet/Razor/issues/2633 this will no longer be necessary. if (!documentFilePath.EndsWith("_ViewImports.cshtml", StringComparison.Ordinal)) { return; } // Adding a _ViewImports, need to refresh all open documents. var importAddedFilePath = documentFilePath; var documentsToBeRefreshed = new List <DefaultDocumentSnapshot>(); foreach (var filePath in project.DocumentFilePaths) { if (string.Equals(filePath, importAddedFilePath, StringComparison.Ordinal)) { continue; } if (_projectSnapshotManagerAccessor.Instance.IsDocumentOpen(filePath)) { var document = (DefaultDocumentSnapshot)project.GetDocument(filePath); // This document cares about the import documentsToBeRefreshed.Add(document); } } foreach (var document in documentsToBeRefreshed) { var delegatingTextLoader = new DelegatingTextLoader(document); _projectSnapshotManagerAccessor.Instance.DocumentChanged(project.FilePath, document.FilePath, delegatingTextLoader); } }
protected virtual void SerializeToFile(ProjectSnapshot projectSnapshot, string publishFilePath) { var fileInfo = new FileInfo(publishFilePath); using var writer = fileInfo.CreateText(); _serializer.Serialize(writer, projectSnapshot); }
public UpdateWorkspaceWorkItem( Project?workspaceProject, ProjectSnapshot projectSnapshot, ProjectWorkspaceStateGenerator workspaceStateGenerator, ProjectSnapshotManagerDispatcher projectSnapshotManagerDispatcher) { if (projectSnapshot is null) { throw new ArgumentNullException(nameof(projectSnapshot)); } if (workspaceStateGenerator is null) { throw new ArgumentNullException(nameof(workspaceStateGenerator)); } if (projectSnapshotManagerDispatcher is null) { throw new ArgumentNullException(nameof(projectSnapshotManagerDispatcher)); } _workspaceProject = workspaceProject; _projectSnapshot = projectSnapshot; _workspaceStateGenerator = workspaceStateGenerator; _projectSnapshotManagerDispatcher = projectSnapshotManagerDispatcher; }
// Internal for testing internal void Publish(ProjectSnapshot projectSnapshot) { if (projectSnapshot is null) { throw new ArgumentNullException(nameof(projectSnapshot)); } lock (_publishLock) { string configurationFilePath = null; try { if (!_projectConfigurationFilePathStore.TryGet(projectSnapshot.FilePath, out configurationFilePath)) { return; } // We don't want to serialize the project until it's ready to avoid flashing as the project loads different parts. // Since the project.razor.json from last session likely still exists the experience is unlikely to be degraded by this delay. // An exception is made for when there's no existing project.razor.json because some flashing is preferable to having no TagHelper knowledge. if (ShouldSerialize(configurationFilePath)) { SerializeToFile(projectSnapshot, configurationFilePath); } } catch (Exception ex) { _logger.LogWarning($@"Could not update Razor project configuration file '{configurationFilePath}': {ex}"); } } }
public override RazorProjectEngine Create(ProjectSnapshot project, RazorProjectFileSystem fileSystem, Action <RazorProjectEngineBuilder> configure) { if (project == null) { throw new ArgumentNullException(nameof(project)); } if (fileSystem == null) { throw new ArgumentNullException(nameof(fileSystem)); } // When we're running in the editor, the editor provides a configure delegate that will include // the editor settings and tag helpers. // // This service is only used in process in Visual Studio, and any other callers should provide these // things also. configure = configure ?? ((b) => { }); // The default configuration currently matches the newest MVC configuration. // // We typically want this because the language adds features over time - we don't want to a bunch of errors // to show up when a document is first opened, and then go away when the configuration loads, we'd prefer the opposite. var configuration = project.Configuration ?? DefaultConfiguration; // If there's no factory to handle the configuration then fall back to a very basic configuration. // // This will stop a crash from happening in this case (misconfigured project), but will still make // it obvious to the user that something is wrong. var factory = SelectFactory(configuration) ?? _fallback; return(factory.Create(configuration, fileSystem, configure)); }
public static MProject_Project MProject_Project(ProjectSnapshot dbProjectSnapshot) { var projectSpecificationComponents = new List <MProject_ProjectSpecificationComponent>(); foreach (var dbProjectSnapshotComponent in dbProjectSnapshot.ProjectSnapshotComponents.ToList()) { projectSpecificationComponents.Add( new MProject_ProjectSpecificationComponent( dbProjectSnapshotComponent.ConsumableReference, dbProjectSnapshotComponent.UnitOfMeasureCode, dbProjectSnapshotComponent.Quantity)); } var projectSpecification = new MProject_ProjectSpecification( dbProjectSnapshot.DesignSnapshot.Artifact.Value, dbProjectSnapshot.Artifact.ArtifactTypeCode, dbProjectSnapshot.Artifact.ArtifactValueTypeCode, dbProjectSnapshot.Artifact.Value, projectSpecificationComponents); var project = new MProject_Project( dbProjectSnapshot.ProjectId, dbProjectSnapshot.ProjectSnapshotId, dbProjectSnapshot.Name, dbProjectSnapshot.UpdateDateTimeUtc, projectSpecification); return(project); }
protected virtual void SerializeToFile(ProjectSnapshot projectSnapshot, string publishFilePath) { // We need to avoid having an incomplete file at any point, but our // project.razor.json is large enough that it will be written as multiple operations. var tempFilePath = string.Concat(publishFilePath, TempFileExt); var tempFileInfo = new FileInfo(tempFilePath); if (tempFileInfo.Exists) { Debug.Fail($"'{tempFileInfo.FullName}' should not exist but it does. This could be caused by failures during serialization or early process termination."); tempFileInfo.Delete(); } // This needs to be in explicit brackets because the operation needs to be completed // by the time we move the tempfile into its place using (var writer = tempFileInfo.CreateText()) { _serializer.Serialize(writer, projectSnapshot); var fileInfo = new FileInfo(publishFilePath); if (fileInfo.Exists) { fileInfo.Delete(); } } tempFileInfo.MoveTo(publishFilePath); }
// Internal for testing internal void Publish(ProjectSnapshot projectSnapshot) { if (projectSnapshot is null) { throw new ArgumentNullException(nameof(projectSnapshot)); } lock (_publishLock) { string publishFilePath = null; try { if (!PublishFilePathMappings.TryGetValue(projectSnapshot.FilePath, out publishFilePath)) { return; } SerializeToFile(projectSnapshot, publishFilePath); } catch (Exception ex) { _logger.LogWarning($@"Could not update Razor project configuration file '{publishFilePath}': {ex}"); } } }
public override bool TryResolvePotentialProject(string documentFilePath, out ProjectSnapshot projectSnapshot) { if (documentFilePath == null) { throw new ArgumentNullException(nameof(documentFilePath)); } _foregroundDispatcher.AssertForegroundThread(); var normalizedDocumentPath = _filePathNormalizer.Normalize(documentFilePath); var projects = _projectSnapshotManagerAccessor.Instance.Projects; for (var i = 0; i < projects.Count; i++) { if (projects[i].FilePath == _miscellaneousHostProject.FilePath) { // We don't resolve documents to belonging to the miscellaneous project. continue; } var projectDirectory = _filePathNormalizer.GetDirectory(projects[i].FilePath); if (normalizedDocumentPath.StartsWith(projectDirectory, FilePathComparison.Instance)) { projectSnapshot = projects[i]; return(true); } } projectSnapshot = null; return(false); }
public void Subscribe() { // Fundamentally we have a Razor half of the world as as soon as the document is open - and then later // the C# half of the world will be initialized. This code is in general pretty tolerant of // unexpected /impossible states. // // We also want to successfully shut down if the buffer is something other than .cshtml. IVsHierarchy hierarchy = null; string projectPath = null; var isSupportedProject = false; if (_textBuffer.ContentType.IsOfType(RazorLanguage.ContentType) && // We expect the document to have a hierarchy even if it's not a real 'project'. // However the hierarchy can be null when the document is in the process of closing. (hierarchy = _projectService.GetHierarchy(_textBuffer)) != null) { projectPath = _projectService.GetProjectPath(hierarchy); isSupportedProject = _projectService.IsSupportedProject(hierarchy); } if (!isSupportedProject || projectPath == null) { return; } _isSupportedProject = isSupportedProject; _projectPath = projectPath; _project = _projectManager.GetProjectWithFilePath(projectPath); _projectManager.Changed += ProjectManager_Changed; OnContextChanged(_project); }
/// <summary> /// Add a project and snapshots to the datasource. /// This provides a way to manually generate snapshots with specific projects and historical values. /// Requires a valid 'report.To' date. /// </summary> /// <param name="report"></param> /// <param name="snapshots"></param> public ProjectReport Add(ProjectReport report, IEnumerable <ProjectSnapshot> snapshots) { this.User.ThrowIfNotAuthorized(Permissions.ReportsSpl); if (!report.To.HasValue) { throw new InvalidOperationException("Argument 'report.To' must have a valid date."); } if (report.From.HasValue && report.From > report.To) { throw new InvalidOperationException("Argument 'report.From' must be equal to or greater than 'report.To'."); } foreach (var snapshot in snapshots) { // All the snapshot dates must match the reported 'to' date. // Regrettably I had to manually recreate this from the mapped objects because EF is attempting to set the primary key with the mapped objects. var snap = new ProjectSnapshot() { ProjectId = snapshot.ProjectId, SnapshotOn = report.To.Value, Assessed = snapshot.Assessed, Appraised = snapshot.Appraised, Market = snapshot.Market, NetBook = snapshot.NetBook, Metadata = snapshot.Metadata }; this.Context.ProjectSnapshots.Add(snap); } this.Context.Add(report); this.Context.CommitTransaction(); return(report); }
public override RazorProjectEngine Create(ProjectSnapshot project, RazorProjectFileSystem fileSystem, Action <RazorProjectEngineBuilder> configure) { return(RazorProjectEngine.Create(project.Configuration, fileSystem, b => { RazorExtensions.Register(b); })); }
/// <summary> /// Generate snapshots for all SPL projects using the passed 'to' date as the snapshot date. /// </summary> /// <param name="to"></param> /// <returns></returns> private IEnumerable <ProjectSnapshot> GenerateSnapshots(DateTime to, DateTime?from) { var splProjects = this.Context.Projects .Include(p => p.Agency) .Include(p => p.Status) .Where(p => p.Workflow.Code == "SPL"); Dictionary <int?, ProjectSnapshot> fromSnapshots = new Dictionary <int?, ProjectSnapshot>(); if (from != null) { fromSnapshots = this.Context.ProjectSnapshots .Include(s => s.Project).ThenInclude(p => p.Agency) .Include(s => s.Project).ThenInclude(p => p.Status) .Where(s => s.SnapshotOn == from) .ToDictionary(s => (int?)s.ProjectId, s => s); } IEnumerable <ProjectSnapshot> projectSnapshots = new HashSet <ProjectSnapshot>(); foreach (Project project in splProjects) { JsonConvert.PopulateObject(project.Metadata ?? "{}", project); ProjectSnapshot snapshot = new ProjectSnapshot(project); snapshot.SnapshotOn = to; snapshot.BaselineIntegrity = project.NetProceeds ?? 0 - (fromSnapshots.GetValueOrDefault(project.Id)?.NetProceeds ?? 0); projectSnapshots = projectSnapshots.Append(snapshot); } return(projectSnapshots); }
private ProjectSnapshotHandleProxy ConvertToProxy(ProjectSnapshot project) { var projectWorkspaceState = new ProjectWorkspaceState(project.TagHelpers); var projectFilePath = _session.ConvertLocalPathToSharedUri(project.FilePath); var projectHandleProxy = new ProjectSnapshotHandleProxy(projectFilePath, project.Configuration, project.RootNamespace, projectWorkspaceState); return(projectHandleProxy); }
private JObject Serialize(ProjectSnapshot snapshot) { var serializer = new JsonSerializer(); serializer.Converters.RegisterRazorConverters(); return(JObject.FromObject(snapshot, serializer)); }
internal TagHelperCollectionViewModel(ProjectSnapshot project, Action <Exception> errorHandler) { _project = project; _errorHandler = errorHandler; TagHelpers = new ObservableCollection <TagHelperItemViewModel>(); InitializeTagHelpers(); }
/// <summary> /// Initialize field _snapshot. /// </summary> /// <param name="route">User name, project name and snapshot name.</param> private async Task Init(SnapshotRoute route) { var request = new HandlerData <SnapshotRoute, ProjectSnapshot> { Data = route }; _snapshot = await _mediator.Send(request); }
public override IProjectEngineFactory FindSerializableFactory(ProjectSnapshot project) { if (project == null) { throw new ArgumentNullException(nameof(project)); } return(SelectFactory(project.Configuration ?? DefaultConfiguration, requireSerializable: true)); }
internal ProjectSnapshotViewModel(ProjectSnapshot project) { Project = project; Id = project.WorkspaceProject?.Id; Properties = new ObservableCollection <PropertyViewModel>(); InitializeProperties(); }
internal static OmniSharpProjectSnapshot Convert(ProjectSnapshot projectSnapshot) { if (projectSnapshot == null) { return(null); } return(new OmniSharpProjectSnapshot(projectSnapshot)); }
private void OnContextChanged(ProjectSnapshot project) { _project = project; // Hack: When the context changes we want to replace the template engine held by the parser. // This code isn't super well factored now - it's intended to be limited to one spot until // we have time to a proper redesign. if (TextBuffer.Properties.TryGetProperty(typeof(RazorEditorParser), out RazorEditorParser legacyParser) && legacyParser.TemplateEngine != null && _projectPath != null) { var factory = _workspace.Services.GetLanguageServices(RazorLanguage.Name).GetRequiredService <CodeAnalysis.Razor.RazorTemplateEngineFactoryService>(); var existingEngine = legacyParser.TemplateEngine; var projectDirectory = Path.GetDirectoryName(_projectPath); var templateEngine = factory.Create(projectDirectory, builder => { var existingVSParserOptions = existingEngine.Engine.Features.FirstOrDefault( feature => string.Equals( feature.GetType().Name, "VisualStudioParserOptionsFeature", StringComparison.Ordinal)); if (existingVSParserOptions == null) { Debug.Fail("The VS Parser options should have been set."); } else { builder.Features.Add(existingVSParserOptions); } var existingTagHelperFeature = existingEngine.Engine.Features .OfType <ITagHelperFeature>() .FirstOrDefault(); if (existingTagHelperFeature == null) { Debug.Fail("The VS TagHelperFeature should have been set."); } else { builder.Features.Add(existingTagHelperFeature); } }); legacyParser.TemplateEngine = templateEngine; } var handler = ContextChanged; if (handler != null) { handler(this, EventArgs.Empty); } }
public RazorProjectEngine Create(ProjectSnapshot project, Action <RazorProjectEngineBuilder> configure) { if (project == null) { throw new ArgumentNullException(nameof(project)); } return(Create(project, RazorProjectFileSystem.Create(Path.GetDirectoryName(project.FilePath)), configure)); }
public override void ReportError(Exception exception, ProjectSnapshot project) { if (exception == null) { throw new ArgumentNullException(nameof(exception)); } // Do nothing. }
public override RazorProjectEngine Create( ProjectSnapshot project, RazorProjectFileSystem fileSystem, Action <RazorProjectEngineBuilder> configure) { var remoteFileSystem = new RemoteRazorProjectFileSystem(_filePathNormalizer); return(base.Create(project, remoteFileSystem, configure)); }
internal ProjectPropertyCollectionViewModel(ProjectSnapshot project) { _project = project; Properties = new ObservableCollection <ProjectPropertyItemViewModel>(); Properties.Add(new ProjectPropertyItemViewModel("Language Version", _project.Configuration?.LanguageVersion.ToString())); Properties.Add(new ProjectPropertyItemViewModel("Configuration", FormatConfiguration(_project))); Properties.Add(new ProjectPropertyItemViewModel("Extensions", FormatExtensions(_project))); Properties.Add(new ProjectPropertyItemViewModel("Project", Path.GetFileName(_project.FilePath))); }
private void Unsubscribe() { _projectManager.Changed -= ProjectManager_Changed; _editorSettingsManager.Changed -= EditorSettingsManager_Changed; // Detached from project. _isSupportedProject = false; _project = null; OnContextChanged(project: null); }
private void CaptureProjectDocumentsAsLatest(ProjectSnapshot projectSnapshot) { foreach (var documentPath in projectSnapshot.DocumentFilePaths) { if (DocumentLookup.ContainsKey(documentPath)) { var document = projectSnapshot.GetDocument(documentPath); MarkAsLatestVersion(document); } } }
// Internal for testing internal void EnqueuePublish(ProjectSnapshot projectSnapshot) { // A race is not possible here because we use the main thread to synchronize the updates // by capturing the sync context. _pendingProjectPublishes[projectSnapshot.FilePath] = projectSnapshot; if (!_deferredPublishTasks.TryGetValue(projectSnapshot.FilePath, out var update) || update.IsCompleted) { _deferredPublishTasks[projectSnapshot.FilePath] = PublishAfterDelayAsync(projectSnapshot.FilePath); } }
protected override bool ShouldSerialize(ProjectSnapshot projectSnapshot, string configurationFilePath) { if (_useRealShouldSerialize) { return(base.ShouldSerialize(projectSnapshot, configurationFilePath)); } else { return(_shouldSerialize); } }