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;

        }
Exemplo n.º 3
0
        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
            });
        }