private NamespaceClassDefinition CreateNamespaceDefinition( string @namespace, IEnumerable <Calculation> calculationsInNamespace, IEnumerable <StatementSyntax> propertyDefinitions, IEnumerable <string> propertyAssignments, string className = null) { ClassStatementSyntax classStatement = SyntaxFactory .ClassStatement(className ?? $"{@namespace}Calculations") .WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword))); SyntaxList <InheritsStatementSyntax> inherits = SyntaxFactory.SingletonList(SyntaxFactory.InheritsStatement(_compilerOptions.UseLegacyCode ? SyntaxFactory.ParseTypeName("LegacyBaseCalculation") : SyntaxFactory.ParseTypeName("BaseCalculation"))); IEnumerable <StatementSyntax> namespaceFunctionPointers = CreateNamespaceFunctionPointers(calculationsInNamespace); StatementSyntax initialiseMethodDefinition = CreateInitialiseMethod(calculationsInNamespace, propertyAssignments, className); ClassBlockSyntax classBlock = SyntaxFactory.ClassBlock(classStatement, inherits, new SyntaxList <ImplementsStatementSyntax>(), SyntaxFactory.List(propertyDefinitions .Concat(namespaceFunctionPointers) .Concat(new[] { initialiseMethodDefinition }).ToArray()), SyntaxFactory.EndClassStatement()); return(new NamespaceClassDefinition(@namespace, classBlock)); }
async Task<Solution> MoveClassIntoNewFileAsync(Document document, ClassStatementSyntax typeDecl, string className, CancellationToken cancellationToken) { // symbol representing the type var semanticModel = await document.GetSemanticModelAsync(cancellationToken); var typeSymbol = semanticModel.GetDeclaredSymbol(typeDecl, cancellationToken); // remove type from current files var currentSyntaxTree = await document.GetSyntaxTreeAsync(); var currentRoot = await currentSyntaxTree.GetRootAsync(); //In VB you have to remove th parent of det declaration node. That is the "ClassBlockSyntax" var replacedRoot = currentRoot.RemoveNode(typeDecl.Parent, SyntaxRemoveOptions.KeepNoTrivia); document = document.WithSyntaxRoot(replacedRoot); // create new tree for a new file // we drag all the imports because we don't know which are needed // and there is no easy way to find out which var currentUsings = currentRoot.DescendantNodesAndSelf().Where(s => s is ImportsStatementSyntax); var currentNs = (NamespaceStatementSyntax)currentRoot.DescendantNodesAndSelf().First(s => s is NamespaceStatementSyntax); SyntaxList<StatementSyntax> c; if(currentNs != null) { //We have to wrap the content of the class in the namespace. var temp = SyntaxFactory.SingletonList( SyntaxFactory.NamespaceBlock( SyntaxFactory.NamespaceStatement(SyntaxFactory.ParseName(currentNs.Name.ToString())), SyntaxFactory.SingletonList(typeDecl.Parent), SyntaxFactory.EndNamespaceStatement() )); c = SyntaxFactory.List(temp.Select(i => ((StatementSyntax)i))); } else { c = SyntaxFactory.SingletonList(typeDecl.Parent); } var newFileTree = SyntaxFactory.CompilationUnit() .WithImports(SyntaxFactory.List(currentUsings.Select(i => ((ImportsStatementSyntax)i)))) .WithMembers(c) .WithoutLeadingTrivia() .NormalizeWhitespace(); var codeText = newFileTree.ToFullString(); //TODO: handle name conflicts var newDocument = document.Project.AddDocument(className, SourceText.From(codeText), document.Folders); newDocument = await RemoveUnusedImportDirectivesAsync(newDocument, cancellationToken); return newDocument.Project.Solution; }
public override void VisitClassStatement(ClassStatementSyntax node) { if (_targetPatternRegEx.Match(node.Identifier.ToString()).Success) { RecordMatchAndContext(node, BlockType.None); } base.VisitClassStatement(node); }
public IEnumerable <SourceFile> GenerateCalcs(IEnumerable <Calculation> calculations, IDictionary <string, Funding> funding) { SyntaxList <OptionStatementSyntax> optionsList = new SyntaxList <OptionStatementSyntax>(new[] { SyntaxFactory.OptionStatement(SyntaxFactory.Token(SyntaxKind.StrictKeyword), SyntaxFactory.Token(_compilerOptions.OptionStrictEnabled ? SyntaxKind.OnKeyword : SyntaxKind.OffKeyword)) }); SyntaxList <ImportsStatementSyntax> standardImports = StandardImports(); string identifier = _typeIdentifierGenerator.GenerateIdentifier("CalculationContext"); SyntaxTokenList modifiers = SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PublicKeyword)); ClassStatementSyntax classStatement = SyntaxFactory .ClassStatement(identifier) .WithModifiers(modifiers); SyntaxList <InheritsStatementSyntax> inherits = SyntaxFactory.SingletonList(SyntaxFactory.InheritsStatement(_compilerOptions.UseLegacyCode ? SyntaxFactory.ParseTypeName("LegacyBaseCalculation") : SyntaxFactory.ParseTypeName("BaseCalculation"))); IEnumerable <StatementSyntax> methods = CreateMembers(calculations, funding); ClassBlockSyntax classBlock = SyntaxFactory.ClassBlock(classStatement, inherits, new SyntaxList <ImplementsStatementSyntax>(), SyntaxFactory.List(methods), SyntaxFactory.EndClassStatement()); SyntaxList <StatementSyntax> members = SyntaxFactory.SingletonList <StatementSyntax>(classBlock); CompilationUnitSyntax syntaxTree = SyntaxFactory.CompilationUnit().WithOptions(optionsList); syntaxTree = syntaxTree.WithImports(standardImports); syntaxTree = syntaxTree.WithMembers(members); try { syntaxTree = syntaxTree.NormalizeWhitespace(); } catch (Exception e) { throw new Exception($"Error compiling source code. Please check your code's structure is valid. {e.Message}", e); } string sourceCode = syntaxTree.ToFullString(); yield return(new SourceFile { FileName = "Calculations.vb", SourceCode = sourceCode }); }