public static (Location codeBehindLocation, List <Location> incorrectCodeBehindLocations, List <Location> lazinatorObjectLocationsExcludingCodeBehind) CategorizeLocations(LazinatorConfig config, INamedTypeSymbol lazinatorObject, List <Location> mainTypeLocations) { string generatedCodeFileExtension = config?.GeneratedCodeFileExtension ?? ".laz.cs"; bool useFullyQualifiedNames = (config?.UseFullyQualifiedNames ?? false) || lazinatorObject.ContainingType != null || lazinatorObject.IsGenericType; string correctCodeBehindName = RoslynHelpers.GetEncodableVersionOfIdentifier(lazinatorObject, useFullyQualifiedNames) + generatedCodeFileExtension; var nonGeneratedLocations = mainTypeLocations.Where(x => !x.SourceTree.FilePath.EndsWith(generatedCodeFileExtension)).ToList(); var codeBehindLocations = mainTypeLocations.Where(x => x.SourceTree.FilePath.EndsWith(generatedCodeFileExtension)).ToList(); IEnumerable <Location> possiblyCorrectCodeBehindLocations = mainTypeLocations.Where(x => x.SourceTree.FilePath.EndsWith(correctCodeBehindName)); Location codeBehindLocation = possiblyCorrectCodeBehindLocations.FirstOrDefault(); List <Location> incorrectCodeBehindLocations = codeBehindLocations.Where(x => x != codeBehindLocation).ToList(); return(codeBehindLocation, incorrectCodeBehindLocations, nonGeneratedLocations); }
public static async Task <Solution> AttemptFixGenerateLazinatorCodeBehind(Document originalDocument, LazinatorPairInformation lazinatorPairInformation, CancellationToken cancellationToken) { var originalSolution = originalDocument.Project.Solution; LazinatorConfig config = lazinatorPairInformation.LoadLazinatorConfig(); var semanticModel = await originalDocument.GetSemanticModelAsync(cancellationToken); LazinatorCompilation generator = null; if (!RecycleLazinatorCompilation || _LastLazinatorCompilation == null) { generator = new LazinatorCompilation(semanticModel.Compilation, lazinatorPairInformation.LazinatorObject.Name, lazinatorPairInformation.LazinatorObject.GetFullMetadataName(), config); if (RecycleLazinatorCompilation) { _LastLazinatorCompilation = generator; } } else { generator = _LastLazinatorCompilation; generator.Initialize(semanticModel.Compilation, lazinatorPairInformation.LazinatorObject.Name, lazinatorPairInformation.LazinatorObject.GetFullMetadataName()); } var d = new ObjectDescription(generator.ImplementingTypeSymbol, generator, originalDocument.FilePath); var codeBehind = d.GetCodeBehind(); string fileExtension = config?.GeneratedCodeFileExtension ?? ".laz.cs"; var project = originalDocument.Project; string codeBehindFilePath = null; string codeBehindName = null; string[] codeBehindFolders = null; bool useFullyQualifiedNames = (config?.UseFullyQualifiedNames ?? false) || generator.ImplementingTypeSymbol.ContainingType != null || generator.ImplementingTypeSymbol.IsGenericType; codeBehindName = RoslynHelpers.GetEncodableVersionOfIdentifier(generator.ImplementingTypeSymbol, useFullyQualifiedNames) + fileExtension; string[] GetFolders(string fileName) { return(fileName.Split('\\', '/').Where(x => !x.Contains(".cs") && !x.Contains(".csproj")).ToArray()); } if (config?.GeneratedCodePath == null) { // use short form of name in same location as original code codeBehindFilePath = originalDocument.FilePath; codeBehindFolders = GetFolders(codeBehindFilePath).Skip(GetFolders(originalDocument.Project.FilePath).Count()).ToArray(); } else { // we have a config file specifying a common directory codeBehindFilePath = config.GeneratedCodePath; if (!codeBehindFilePath.EndsWith("\\")) { codeBehindFilePath += "\\"; } codeBehindFolders = config.RelativeGeneratedCodePath.Split('\\', '/'); } codeBehindFilePath = System.IO.Path.GetDirectoryName(codeBehindFilePath); while (codeBehindFilePath.EndsWith(".cs")) { var lastSlash = codeBehindFilePath.IndexOfAny(new char[] { '\\', '/' }); if (lastSlash >= 0) { codeBehindFilePath = codeBehindFilePath.Substring(0, lastSlash); } } while (codeBehindFilePath.EndsWith("\\")) { codeBehindFilePath = codeBehindFilePath.Substring(0, codeBehindFilePath.Length - 1); } codeBehindFilePath += "\\" + codeBehindName; Solution revisedSolution; if (lazinatorPairInformation.CodeBehindLocation == null) { // The file does not already exist // codeBehindFilePath = System.IO.Path.GetDirectoryName(codeBehindFilePath); // omit file name Document documentToAdd = project.AddDocument(codeBehindName, codeBehind, codeBehindFolders, codeBehindFilePath); //if (config.GeneratedCodePath != null) // documentToAdd = documentToAdd.WithFolders(codeBehindFolders); revisedSolution = documentToAdd.Project.Solution; } else { // the file does already exist var currentDocumentWithCode = originalSolution.GetDocument(lazinatorPairInformation.CodeBehindLocation.SourceTree); var replacementDocument = currentDocumentWithCode.WithText(SourceText.From(codeBehind)); revisedSolution = originalSolution.WithDocumentText(currentDocumentWithCode.Id, SourceText.From(codeBehind)); } revisedSolution = await AddAnnotationToIndicateSuccess(revisedSolution, true); return(revisedSolution); }