コード例 #1
0
        private SyntaxTree processTrees(SyntaxTree[] trees, CSharpParseOptions parseoptions)
        {
            // this method gives us the ability to check all the generated syntax trees,
            // add generated constructors to partial classes when none of the parts has a constructor
            // merge accesses and assigns from different source files into one property etc.
            // we pass the usings from the compilation units along because the new compilation unit will
            // have to the same (combined) list of usings
            // When compiling in VO/Vulcan dialect we also collect the literal symbols from the compilation unit.
            // When we have one or more of these then we create a symbol table in the class "Xs$SymbolTable"
            var partialClasses = new Dictionary <string, List <PartialPropertyElement> >(XSharpString.Comparer);
            var symbolTable    = new Dictionary <string, FieldDeclarationSyntax>();
            var pszTable       = new Dictionary <string, Tuple <string, FieldDeclarationSyntax> >();

            foreach (var tree in trees)
            {
                var compilationunit = tree.GetRoot() as Syntax.CompilationUnitSyntax;
                if (compilationunit.NeedsProcessing)
                {
                    foreach (var member in compilationunit.Members)
                    {
                        if (member is Syntax.NamespaceDeclarationSyntax)
                        {
                            processNameSpace(member as Syntax.NamespaceDeclarationSyntax, partialClasses, compilationunit.Usings);
                        }
                        else
                        {
                            var node = member.Green as CSharpSyntaxNode;
                            if (node.XNode is XP.EntityContext)
                            {
                                processType(node.XNode as XP.EntityContext, partialClasses, compilationunit.Usings);
                            }
                        }
                    }
                }
                if (_options.HasRuntime)
                {
                    if (compilationunit.LiteralSymbols.Count > 0)
                    {
                        foreach (var pair in compilationunit.LiteralSymbols)
                        {
                            if (!symbolTable.ContainsKey(pair.Key))
                            {
                                symbolTable.Add(pair.Key, pair.Value);
                            }
                        }
                        compilationunit.LiteralSymbols.Clear();
                    }
                    if (compilationunit.LiteralPSZs.Count > 0)
                    {
                        foreach (var pair in compilationunit.LiteralPSZs)
                        {
                            if (!pszTable.ContainsKey(pair.Key))
                            {
                                pszTable.Add(pair.Key, pair.Value);
                            }
                        }
                        compilationunit.LiteralSymbols.Clear();
                    }
                }
            }
            if (partialClasses.Count > 0 || symbolTable.Count > 0 || pszTable.Count > 0)
            {
                // Create a new tree which shall have the generated constructors and properties
                // and return this tree to the caller.
                // we copy the attributes, modifiers etc from one of the class instances to make sure that
                // do not specify a conflicting modifier.
                var trans = CreateTransform(null, _options, _pool, _syntaxFactory, _fileName);
                SyntaxListBuilder <UsingDirectiveSyntax> usingslist = _pool.Allocate <UsingDirectiveSyntax>();
                var members    = _pool.Allocate <MemberDeclarationSyntax>();
                var clsmembers = _pool.Allocate <MemberDeclarationSyntax>();
                foreach (var element in partialClasses)
                {
                    var  name                       = element.Key;
                    bool hasctor                    = false;
                    bool haspartialprop             = false;
                    XP.IPartialPropertyContext ctxt = null;
                    XP.Namespace_Context       xns;
                    foreach (var val in element.Value)
                    {
                        var xnode = val.Type;
                        ctxt = xnode;
                        if (xnode.Data.HasInstanceCtor)
                        {
                            hasctor = true;
                        }
                        if (xnode.Data.PartialProps)
                        {
                            haspartialprop = true;
                        }
                    }
                    if (ctxt.CsNode is InterfaceDeclarationSyntax)
                    {
                        var ifdecl = ctxt.Get <InterfaceDeclarationSyntax>();
                        // ctxt.Parent is XP.EntityContext
                        // ctxt.Parent.Parent may be XP.Namespace_Context
                        xns = ctxt.Parent.Parent as XP.Namespace_Context;
                        if (haspartialprop)
                        {
                            clsmembers.Clear();
                            var props = GeneratePartialProperties(element.Value, usingslist, trans);
                            if (props != null)
                            {
                                foreach (var prop in props)
                                {
                                    clsmembers.Add(prop);
                                }
                            }
                            if (clsmembers.Count > 0)
                            {
                                var decl = _syntaxFactory.InterfaceDeclaration(
                                    default(SyntaxList <AttributeListSyntax>),
                                    ifdecl.Modifiers,
                                    ifdecl.Keyword,
                                    ifdecl.Identifier,
                                    ifdecl.TypeParameterList,
                                    ifdecl.BaseList,
                                    ifdecl.ConstraintClauses,
                                    ifdecl.OpenBraceToken,
                                    clsmembers,
                                    ifdecl.CloseBraceToken,
                                    null);
                                ifdecl.XGenerated = true;
                                members.Add(WrapInNamespace(trans, decl, xns, _options.DefaultNamespace));
                            }
                        }
                    }
                    else if (ctxt.CsNode is StructDeclarationSyntax)
                    {
                        var strucdecl = ctxt.Get <StructDeclarationSyntax>();
                        // ctxt.Parent is XP.EntityContext
                        // ctxt.Parent.Parent may be XP.Namespace_Context
                        xns = ctxt.Parent.Parent as XP.Namespace_Context;
                        if (haspartialprop)
                        {
                            clsmembers.Clear();
                            var props = GeneratePartialProperties(element.Value, usingslist, trans);
                            if (props != null)
                            {
                                foreach (var prop in props)
                                {
                                    clsmembers.Add(prop);
                                }
                            }
                            if (clsmembers.Count > 0)
                            {
                                var decl = _syntaxFactory.StructDeclaration(
                                    default(SyntaxList <AttributeListSyntax>),
                                    strucdecl.Modifiers,
                                    strucdecl.Keyword,
                                    strucdecl.Identifier,
                                    strucdecl.TypeParameterList,
                                    strucdecl.BaseList,
                                    strucdecl.ConstraintClauses,
                                    strucdecl.OpenBraceToken,
                                    clsmembers,
                                    strucdecl.CloseBraceToken,
                                    null);
                                strucdecl.XGenerated = true;
                                members.Add(WrapInNamespace(trans, decl, xns, _options.DefaultNamespace));
                            }
                        }
                    }
                    else if (ctxt.CsNode is ClassDeclarationSyntax)
                    {
                        // ctxt.Parent is XP.EntityContext
                        // ctxt.Parent.Parent may be XP.Namespace_Context
                        xns = ctxt.Parent.Parent as XP.Namespace_Context;
                        if (!hasctor || haspartialprop)
                        {
                            clsmembers.Clear();
                            var classdecl = ctxt.Get <ClassDeclarationSyntax>();
                            if (!hasctor && !classdecl.IsStatic() && _options.VOClipperConstructors && trans != null)
                            {
                                var ctor = trans.GenerateDefaultCtor(classdecl.Identifier, ctxt as XP.Class_Context);
                                if (ctor != null)
                                {
                                    clsmembers.Add(ctor);
                                }
                            }
                            if (haspartialprop)
                            {
                                var props = GeneratePartialProperties(element.Value, usingslist, trans);
                                if (props != null)
                                {
                                    foreach (var prop in props)
                                    {
                                        clsmembers.Add(prop);
                                    }
                                }
                            }
                            if (clsmembers.Count > 0)
                            {
                                var decl = _syntaxFactory.ClassDeclaration(
                                    default(SyntaxList <AttributeListSyntax>),
                                    classdecl.Modifiers,
                                    classdecl.Keyword,
                                    classdecl.Identifier,
                                    classdecl.TypeParameterList,
                                    classdecl.BaseList,
                                    classdecl.ConstraintClauses,
                                    classdecl.OpenBraceToken,
                                    clsmembers,
                                    classdecl.CloseBraceToken,
                                    null);
                                decl.XGenerated = true;

                                members.Add(WrapInNamespace(trans, decl, xns, _options.DefaultNamespace));
                            }
                        }
                    }
                }
                if (symbolTable.Count > 0)
                {
                    // build internal static symbol table class
                    members.Add(_generateSymbolsClass(symbolTable, trans));
                }
                if (pszTable.Count > 0)
                {
                    // build internal static psz table class
                    members.Add(_generatePszClass(pszTable, trans));
                }
                var eof    = SyntaxFactory.Token(SyntaxKind.EndOfFileToken);
                var result = _syntaxFactory.CompilationUnit(
                    default(SyntaxList <ExternAliasDirectiveSyntax>),
                    usingslist,
                    default(SyntaxList <AttributeListSyntax>),
                    members,
                    eof);
                result.XGenerated = true;
                var tree = (CSharpSyntaxTree)CSharpSyntaxTree.Create((Syntax.CompilationUnitSyntax)result.CreateRed(), parseoptions);
                tree.Generated = true;
                _pool.Free(members);
                _pool.Free(usingslist);
                _pool.Free(clsmembers);
                return(tree);
            }
            return(null);
        }
コード例 #2
0
 internal PartialPropertyElement(XP.IPartialPropertyContext type, IEnumerable <Syntax.UsingDirectiveSyntax> usings)
 {
     Type   = type;
     Usings = usings;
 }