コード例 #1
0
        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;
        }
コード例 #2
0
        // 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;
            }
コード例 #5
0
        // 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}");
                }
            }
        }
コード例 #6
0
        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));
        }
コード例 #7
0
            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);
            }
コード例 #8
0
        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);
        }
コード例 #9
0
        // 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}");
                }
            }
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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);
        }
コード例 #12
0
        /// <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);
        }
コード例 #13
0
 public override RazorProjectEngine Create(ProjectSnapshot project, RazorProjectFileSystem fileSystem, Action <RazorProjectEngineBuilder> configure)
 {
     return(RazorProjectEngine.Create(project.Configuration, fileSystem, b =>
     {
         RazorExtensions.Register(b);
     }));
 }
コード例 #14
0
        /// <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);
        }
コード例 #16
0
        private JObject Serialize(ProjectSnapshot snapshot)
        {
            var serializer = new JsonSerializer();

            serializer.Converters.RegisterRazorConverters();

            return(JObject.FromObject(snapshot, serializer));
        }
コード例 #17
0
        internal TagHelperCollectionViewModel(ProjectSnapshot project, Action <Exception> errorHandler)
        {
            _project      = project;
            _errorHandler = errorHandler;

            TagHelpers = new ObservableCollection <TagHelperItemViewModel>();
            InitializeTagHelpers();
        }
コード例 #18
0
        /// <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);
        }
コード例 #19
0
        public override IProjectEngineFactory FindSerializableFactory(ProjectSnapshot project)
        {
            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }

            return(SelectFactory(project.Configuration ?? DefaultConfiguration, requireSerializable: true));
        }
コード例 #20
0
        internal ProjectSnapshotViewModel(ProjectSnapshot project)
        {
            Project = project;

            Id         = project.WorkspaceProject?.Id;
            Properties = new ObservableCollection <PropertyViewModel>();

            InitializeProperties();
        }
コード例 #21
0
        internal static OmniSharpProjectSnapshot Convert(ProjectSnapshot projectSnapshot)
        {
            if (projectSnapshot == null)
            {
                return(null);
            }

            return(new OmniSharpProjectSnapshot(projectSnapshot));
        }
コード例 #22
0
        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);
            }
        }
コード例 #23
0
        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));
        }
コード例 #24
0
        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)));
        }
コード例 #27
0
        private void Unsubscribe()
        {
            _projectManager.Changed        -= ProjectManager_Changed;
            _editorSettingsManager.Changed -= EditorSettingsManager_Changed;

            // Detached from project.
            _isSupportedProject = false;
            _project            = null;
            OnContextChanged(project: null);
        }
コード例 #28
0
 private void CaptureProjectDocumentsAsLatest(ProjectSnapshot projectSnapshot)
 {
     foreach (var documentPath in projectSnapshot.DocumentFilePaths)
     {
         if (DocumentLookup.ContainsKey(documentPath))
         {
             var document = projectSnapshot.GetDocument(documentPath);
             MarkAsLatestVersion(document);
         }
     }
 }
コード例 #29
0
        // 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);
            }
        }
コード例 #30
0
 protected override bool ShouldSerialize(ProjectSnapshot projectSnapshot, string configurationFilePath)
 {
     if (_useRealShouldSerialize)
     {
         return(base.ShouldSerialize(projectSnapshot, configurationFilePath));
     }
     else
     {
         return(_shouldSerialize);
     }
 }