Example #1
0
        public override Task <IEnumerable <FileInformation> > MigrateClassAsync()
        {
            LogStart();

            _metricsContext.CollectActionMetrics(WebFormsActionType.ClassConversion, ActionName);
            // NOTE: We could just read the file from the disk and retrieve the bytes like
            // that but instead I opted to "rebuild" the type in case we wanted to add comments
            // or something else to these undefined code files, most likely though we may still
            // want to scan parts of these files and remove/alter/take note of certain lines/info

            var newRelativePath = FilePathHelper.RemoveDuplicateDirectories(FilePathHelper.AlterFileName(_relativePath, newFileName: _originalClassSymbol.Name));

            // NOTE: Removed temporarily until usings can be better determined, at the moment, too
            // many are being removed
            //var sourceClassComponents = GetSourceClassComponents();

            var namespaceNames = _sourceFileSemanticModel.GetOriginalUsingNamespaces().Append(Constants.BlazorComponentsNamespace);

            namespaceNames = CodeSyntaxHelper.RemoveFrameworkUsings(namespaceNames);
            var usingStatements = CodeSyntaxHelper.BuildUsingStatements(namespaceNames);
            var namespaceNode   = CodeSyntaxHelper.BuildNamespace(_originalClassSymbol.ContainingNamespace?.ToDisplayString(), _originalDeclarationSyntax);
            var fileText        = CodeSyntaxHelper.GetFileSyntaxAsString(namespaceNode, usingStatements);

            DoCleanUp();
            LogEnd();

            var result = new[] { new FileInformation(newRelativePath, Encoding.UTF8.GetBytes(fileText)) };

            return(Task.FromResult((IEnumerable <FileInformation>)result));
        }
Example #2
0
        public void AlterFileName_Properly_Replaces_File_Name_When_Extension_Not_Changed()
        {
            var inputFileName          = "FileName1.aspx.cs";
            var expectedOutputFileName = "FileName2.aspx.cs";
            var actualOutputFileName   = FilePathHelper.AlterFileName(inputFileName, newFileName: "FileName2", oldExtension: ".aspx.cs");

            Assert.AreEqual(expectedOutputFileName, actualOutputFileName);
        }
Example #3
0
        public void AlterFileName_Does_Not_Modify_Leading_Paths()
        {
            var leadingPath  = Path.Combine("C:", "Dir1", "Dir2");
            var inputString  = Path.Combine(leadingPath, "FileName.txt");
            var outputString = FilePathHelper.AlterFileName(inputString, newFileName: "NewFileName");

            Assert.True(outputString.StartsWith(leadingPath));
        }
        private string GetNewRelativePath()
        {
            // TODO: Potentially remove certain folders from beginning of relative path
            var newRelativePath = FilePathHelper.AlterFileName(_relativePath,
                                                               oldExtension: Constants.ControlCodeBehindExtension,
                                                               newExtension: Constants.RazorCodeBehindFileExtension);

            return(FilePathHelper.RemoveDuplicateDirectories(Path.Combine(Constants.RazorComponentDirectoryName, newRelativePath)));
        }
Example #5
0
        public void AlterFileName_Works_Properly_When_Name_And_Extension_Are_Changed()
        {
            var inputFileName          = "FileName1.aspx.cs";
            var expectedOutputFileName = "FileName2.razor";
            var actualOutputFileName   = FilePathHelper.AlterFileName(inputFileName,
                                                                      newFileName: "FileName2",
                                                                      oldExtension: ".aspx.cs",
                                                                      newExtension: ".razor");

            Assert.AreEqual(expectedOutputFileName, actualOutputFileName);
        }
Example #6
0
        // View file converters will return razor file contents with
        // only view layer, code behind will be created in another file
        public override Task <IEnumerable <FileInformation> > MigrateFileAsync()
        {
            LogStart();
            _metricsContext.CollectActionMetrics(WebFormsActionType.FileConversion, ChildActionType);

            var result = new List <FileInformation>();

            try
            {
                var htmlString = File.ReadAllText(FullPath);

                // Replace directives first to build up list of user controls to be converted later by the ControlConverters
                var projectName = Path.GetFileName(ProjectPath);
                htmlString = EmbeddedCodeReplacers.ReplaceDirectives(htmlString, RelativePath, projectName, _viewImportService, _metricsContext);

                // Convert the Web Forms controls to Blazor equivalent
                var migratedDocument = GetRazorContents(htmlString);
                var contents         = migratedDocument.DocumentNode.WriteTo();

                // We comment out the unknown user controls here instead of during
                // traversal because the post-order nature may comment out controls
                // that are migrated as part of an ancestor control before that ancestor
                // can be processed
                contents = ControlConverter.ConvertEmbeddedCode(contents, RelativePath, _viewImportService);
                contents = UnknownControlRemover.RemoveUnknownTags(contents);

                // Currently just changing extension to .razor, keeping filename and directory the same
                // but Razor files are renamed and moved around, can't always use same filename/directory in the future
                var newRelativePath = FilePathHelper.AlterFileName(RelativePath, newExtension: ".razor");

                if (RelativePath.EndsWith(Constants.WebFormsPageMarkupFileExtension, StringComparison.InvariantCultureIgnoreCase))
                {
                    newRelativePath = Path.Combine(Constants.RazorPageDirectoryName, newRelativePath);
                }
                else if (RelativePath.EndsWith(Constants.WebFormsMasterPageMarkupFileExtension, StringComparison.InvariantCultureIgnoreCase))
                {
                    newRelativePath = Path.Combine(Constants.RazorLayoutDirectoryName, newRelativePath);
                }
                else if (RelativePath.EndsWith(Constants.WebFormsControlMarkupFileExtenion, StringComparison.InvariantCultureIgnoreCase))
                {
                    newRelativePath = Path.Combine(Constants.RazorComponentDirectoryName, newRelativePath);
                }
                else
                {
                    // Default action: file type is not supported. Set newRelativePath to null to
                    // prevent file creation.
                    newRelativePath = null;
                }

                DoCleanUp();
                LogEnd();

                if (newRelativePath != null)
                {
                    var fileInformation = new FileInformation(FilePathHelper.RemoveDuplicateDirectories(newRelativePath),
                                                              Encoding.UTF8.GetBytes(contents));
                    result.Add(fileInformation);
                }
            }
            catch (Exception e)
            {
                LogHelper.LogError(e, $"{Rules.Config.Constants.WebFormsErrorTag}Error migrating view file {FullPath}. A new file could not be generated.");
            }

            return(Task.FromResult((IEnumerable <FileInformation>)result));
        }
Example #7
0
        public override Task <IEnumerable <FileInformation> > MigrateClassAsync()
        {
            LogStart();

            _metricsContext.CollectActionMetrics(WebFormsActionType.ClassConversion, ActionName);
            var className     = _originalDeclarationSyntax.Identifier.ToString();
            var namespaceName = _originalClassSymbol.ContainingNamespace?.ToDisplayString();

            // NOTE: Removed temporarily until usings can be better determined, at the moment, too
            // many are being removed
            //var requiredNamespaceNames = _sourceFileSemanticModel
            //    .GetNamespacesReferencedByType(_originalDeclarationSyntax)
            //    .Select(namespaceSymbol => namespaceSymbol.ToDisplayString());

            var requiredNamespaceNames = _sourceFileSemanticModel.GetOriginalUsingNamespaces()
                                         .Union(MiddlewareSyntaxHelper.RequiredNamespaces);

            requiredNamespaceNames = CodeSyntaxHelper.RemoveFrameworkUsings(requiredNamespaceNames);

            // Make this call once now so we don't have to keep doing it later
            var originalDescendantNodes = _originalDeclarationSyntax.DescendantNodes();
            var keepableMethods         = originalDescendantNodes.OfType <MethodDeclarationSyntax>();

            var processRequestMethod = keepableMethods.Where(method => LifecycleManagerService.IsProcessRequestMethod(method)).SingleOrDefault();
            IEnumerable <StatementSyntax> preHandleStatements;

            if (processRequestMethod != null)
            {
                preHandleStatements = processRequestMethod.Body.Statements.AddComment(string.Format(Constants.CodeOriginCommentTemplate, Constants.ProcessRequestMethodName));
                keepableMethods     = keepableMethods.Where(method => !method.IsEquivalentTo(processRequestMethod));
                _lifecycleManager.RegisterMiddlewareClass(WebFormsAppLifecycleEvent.RequestHandlerExecute, className, namespaceName, className, false);
            }
            else
            {
                preHandleStatements = new[]
                {
                    CodeSyntaxHelper.GetBlankLine().AddComment(string.Format(Constants.IdentificationFailureCommentTemplate, ProcessRequestDiscovery, InvokePopulationOperation))
                };
            }

            // We have completed any possible registration by this point
            _lifecycleManager.NotifyMiddlewareSourceProcessed();

            var fileText = string.Empty;

            try
            {
                var middlewareClassDeclaration = MiddlewareSyntaxHelper.ConstructMiddlewareClass(
                    middlewareClassName: className,
                    shouldContinueAfterInvoke: false,
                    constructorAdditionalStatements: originalDescendantNodes.OfType <ConstructorDeclarationSyntax>().FirstOrDefault()?.Body?.Statements,
                    preHandleStatements: preHandleStatements,
                    additionalFieldDeclarations: originalDescendantNodes.OfType <FieldDeclarationSyntax>(),
                    additionalPropertyDeclarations: originalDescendantNodes.OfType <PropertyDeclarationSyntax>(),
                    additionalMethodDeclarations: keepableMethods);

                var namespaceNode = CodeSyntaxHelper.BuildNamespace(namespaceName, middlewareClassDeclaration);
                fileText = CodeSyntaxHelper.GetFileSyntaxAsString(namespaceNode, CodeSyntaxHelper.BuildUsingStatements(requiredNamespaceNames));
            }
            catch (Exception e)
            {
                LogHelper.LogError(e, $"{Rules.Config.Constants.WebFormsErrorTag}Failed to construct new HttpHandler file content from {OriginalClassName} class at {_fullPath}");
            }

            DoCleanUp();
            LogEnd();

            // Http modules are turned into middleware and so we use a new middleware directory
            var newRelativePath = FilePathHelper.RemoveDuplicateDirectories(Path.Combine(Constants.MiddlewareDirectoryName, FilePathHelper.AlterFileName(_relativePath, newFileName: className)));
            // TODO: Potentially remove certain folders from beginning of relative path
            var result = new[] { new FileInformation(newRelativePath, Encoding.UTF8.GetBytes(fileText)) };

            return(Task.FromResult((IEnumerable <FileInformation>)result));
        }