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)); }
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); }
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))); }
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); }
// 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)); }
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)); }