示例#1
0
        private void VisitTreeAndBuildClassDefinitions(CapturedVariablesTreeNode currentNode)
        {
            var variablesFromThisScopeWhichWereCaptured = currentNode
                                                          .VariablesDefinedInScope
                                                          .Where(var => var.ReferencingLambdas.Count > 0)
                                                          .ToList();

            if (variablesFromThisScopeWhichWereCaptured.Count > 0)
            {
                if (currentNode is CapturedVariablesTreeNodeClassScope)
                {
                    if (!_capturedVarsClassDefs.ContainsKey(currentNode.ScopeIndex))
                    {
                        var classDef        = SyntaxTreeBuilder.BuildClassDefinition();
                        var typeDeclaration = new type_declaration(((CapturedVariablesTreeNodeClassScope)currentNode).ClassName, classDef);
                        _capturedVarsClassDefs.Add(currentNode.ScopeIndex,
                                                   new ScopeClassDefinition(currentNode.CorrespondingSyntaxTreeNode,
                                                                            typeDeclaration,
                                                                            currentNode,
                                                                            compiler_string_consts.self_word));
                    }
                }
                else
                {
                    if (!_capturedVarsClassDefs.ContainsKey(currentNode.ScopeIndex))
                    {
                        var classDef        = SyntaxTreeBuilder.BuildClassDefinition();
                        var typeDeclaration = new type_declaration(GeneratedClassName, classDef);
                        _capturedVarsClassDefs.Add(currentNode.ScopeIndex,
                                                   new ScopeClassDefinition(currentNode.CorrespondingSyntaxTreeNode,
                                                                            typeDeclaration,
                                                                            currentNode));
                    }


                    var vars = variablesFromThisScopeWhichWereCaptured
                               .Select(field => field.SymbolInfo.sym_info as IVAriableDefinitionNode)
                               .ToList();

                    var fieldNames = vars
                                     .Select(var => new ident(var.name))
                                     .ToList();

                    var fieldTypes = vars
                                     .Select(var => SyntaxTreeBuilder.BuildSemanticType(var.type))
                                     .ToList();

                    var classFields = SyntaxTreeBuilder.BuildClassFieldsSection(fieldNames, fieldTypes);

                    ((class_definition)_capturedVarsClassDefs[currentNode.ScopeIndex].ClassDeclaration.type_def).body
                    .Add(
                        classFields);

                    if (currentNode is CapturedVariablesTreeNodeProcedureScope)
                    {
                        var constructorSection = SyntaxTreeBuilder.BuildSimpleConstructorSection(fieldNames,
                                                                                                 fieldNames.Select(
                                                                                                     id =>
                                                                                                     new ident("_" +
                                                                                                               id.name))
                                                                                                 .ToList(),
                                                                                                 fieldTypes);
                        ((class_definition)_capturedVarsClassDefs[currentNode.ScopeIndex].ClassDeclaration.type_def)
                        .body.Add(constructorSection);
                    }
                }

                foreach (var capturedVar in variablesFromThisScopeWhichWereCaptured)
                {
                    VisitCapturedVar(currentNode, capturedVar);
                }
            }

            foreach (CapturedVariablesTreeNode childNode in currentNode.ChildNodes)
            {
                VisitTreeAndBuildClassDefinitions(childNode);
            }

            if (variablesFromThisScopeWhichWereCaptured.Count > 0)
            {
                var vars = variablesFromThisScopeWhichWereCaptured
                           .Select(x =>
                                   new
                {
                    IVarDefinitionNode = x.SymbolInfo.sym_info as IVAriableDefinitionNode,
                    VarDeclNode        = x.SyntaxTreeNodeWithVarDeclaration
                })
                           .Where(x => x.IVarDefinitionNode != null)
                           .ToList();

                foreach (var var in vars)
                {
                    foreach (CapturedVariablesTreeNode childNode in currentNode.ChildNodes)
                    {
                        _rewriteReferencesForNodesThatAreChildNodesToThoseThatContainCapturedVariableInfo.Add(
                            new RewriteReferencesForNodesThatAreChildNodesToThoseThatContainCapturedVariableInfo
                        {
                            TreeNode        = childNode,
                            Varname         = var.IVarDefinitionNode.name,
                            NodeWithVarDecl = var.VarDeclNode
                        });
                    }
                }
            }
        }