private void SubstituteForEachLoopVariables() { var forEachScopes = _capturedVarsTreeNodesDictionary.Where(n => n.Value is CapturedVariablesTreeNodeForEachScope) .Select(n => (CapturedVariablesTreeNodeForEachScope)n.Value) .ToList(); foreach (var forEachScope in forEachScopes) { var forEachNode = forEachScope.CorrespondingSyntaxTreeNode as foreach_stmt; if (forEachNode != null) { CapturedVariablesSubstitutionClassGenerator.ScopeClassDefinition generatedClass; if (_generatedScopeClassesInfo.TryGetValue(forEachScope.ScopeIndex, out generatedClass)) { var nodesToAdd = new List<statement>(); var bodyStmtList = (statement_list)forEachNode.stmt; nodesToAdd.Add(generatedClass.GeneratedVarStatementForScope); if (generatedClass.AssignNodeForUpperClassFieldInitialization != null) { nodesToAdd.Add(generatedClass.AssignNodeForUpperClassFieldInitialization); } var substDotNode = new dot_node(new ident(generatedClass.GeneratedSubstitutingFieldName), new ident(forEachNode.identifier.name)); var assignNode = new assign(substDotNode, new ident(forEachNode.identifier.name)); // TODO: SourceContexts!!!!! nodesToAdd.Add(assignNode); bodyStmtList.subnodes.InsertRange(0, nodesToAdd); } else { var si = forEachScope.SymbolInfoLoopVar; var scopeWhereVarDefined = _capturedVarsTreeNodesDictionary[si.scope.ScopeNum]; var idRef = scopeWhereVarDefined .VariablesDefinedInScope .Find(var => var.SymbolInfo == si); //TODO: !!!!!!!!!!!!!!!!!!!!!! var substKey = new SubstitutionKey(forEachNode.identifier.name, idRef.SyntaxTreeNodeWithVarDeclaration, forEachNode); if (_substitutionsInfo.ContainsKey(substKey)) // Если нашли замену, то переменная где-то захватывалась { if (forEachNode.type_name == null) //Нужно, чтобы переменная цикла создалась в этом случае в контескте с этим же именем что и была { forEachNode.type_name = new no_type_foreach(); } var substDotNode = _substitutionsInfo[substKey]; var assignNode = new assign(substDotNode, new ident(forEachNode.identifier.name)); // TODO: SourceContexts!!!!! (((statement_list)forEachNode.stmt).subnodes).Insert(0, assignNode); } } } } }
private void SubstituteForLoopVariables() { var forScopes = _capturedVarsTreeNodesDictionary.Where(n => n.Value is CapturedVariablesTreeNodeForScope) .Select(n => (CapturedVariablesTreeNodeForScope) n.Value) .ToList(); foreach (var forScope in forScopes) { var forNode = forScope.CorrespondingSyntaxTreeNode as for_node; if (forNode != null) { CapturedVariablesSubstitutionClassGenerator.ScopeClassDefinition generatedClass; if (_generatedScopeClassesInfo.TryGetValue(forScope.ScopeIndex, out generatedClass)) { var nodesToAdd = new List<statement>(); var enclosedStatementList = (statement_list) forScope.EnclosedUpperBlockScope.CorrespondingSyntaxTreeNode; nodesToAdd.Add(generatedClass.GeneratedVarStatementForScope); if (generatedClass.AssignNodeForUpperClassFieldInitialization != null) { nodesToAdd.Add(generatedClass.AssignNodeForUpperClassFieldInitialization); } var forNodeIndex = enclosedStatementList.subnodes.FindIndex(stmt => stmt == forNode); enclosedStatementList.subnodes.InsertRange(forNodeIndex, nodesToAdd); var substDotNode = new dot_node(new ident(generatedClass.GeneratedSubstitutingFieldName), new ident(forNode.loop_variable.name)); var assignNode = new assign(substDotNode, new ident(forNode.loop_variable.name)); // TODO: SourceContexts!!!!! ((statement_list)forNode.statements).subnodes.Insert(0, assignNode); } else { var si = forScope.SymbolInfoLoopVar; var scopeWhereVarDefined = _capturedVarsTreeNodesDictionary[si.scope.ScopeNum]; var idRef = scopeWhereVarDefined .VariablesDefinedInScope .Find(var => var.SymbolInfo == si); //TODO: !!!!!!!!!!!!!!!!!!!!!! var substKey = new SubstitutionKey(forNode.loop_variable.name, idRef.SyntaxTreeNodeWithVarDeclaration, forNode); if (_substitutionsInfo.ContainsKey(substKey)) // Если нашли замену, то переменная где-то захватывалась { forNode.create_loop_variable = true; var substDotNode = _substitutionsInfo[substKey]; var assignNode = new assign(substDotNode, new ident(forNode.loop_variable.name)); // TODO: SourceContexts!!!!! (((statement_list)forNode.statements).subnodes).Insert(0, assignNode); } } } } }
public override void visit(ident id) { var idName = id.name.ToLower(); var si = _visitor.context.find(idName); if (si == null) { if (InLambdaContext) { _visitor.AddError(new ThisTypeOfVariablesCannotBeCaptured(_visitor.get_location(id))); return; } return; } if (si.sym_info.semantic_node_type == semantic_node_type.namespace_variable || si.sym_info.semantic_node_type == semantic_node_type.common_namespace_function_node || si.sym_info.semantic_node_type == semantic_node_type.namespace_constant_definition || si.sym_info.semantic_node_type == semantic_node_type.compiled_function_node || si.sym_info.semantic_node_type == semantic_node_type.compiled_namespace_node || si.sym_info.semantic_node_type == semantic_node_type.compiled_variable_definition || si.sym_info.semantic_node_type == semantic_node_type.common_type_node || si.sym_info.semantic_node_type == semantic_node_type.compiled_type_node || si.sym_info.semantic_node_type == semantic_node_type.basic_interface_node || si.sym_info.semantic_node_type == semantic_node_type.common_unit_node || si.sym_info.semantic_node_type == semantic_node_type.compiled_unit_node || si.sym_info.semantic_node_type == semantic_node_type.template_type) { return; } var acceptableVarType = si.sym_info.semantic_node_type == semantic_node_type.local_variable || si.sym_info.semantic_node_type == semantic_node_type.local_block_variable || si.sym_info.semantic_node_type == semantic_node_type.common_parameter || si.sym_info.semantic_node_type == semantic_node_type.class_field; if (!(acceptableVarType) && InLambdaContext) { _visitor.AddError(new ThisTypeOfVariablesCannotBeCaptured(_visitor.get_location(id))); return; } if (si.sym_info.semantic_node_type == semantic_node_type.class_field && InLambdaContext) { var semClassField = (class_field)si.sym_info; if (semClassField.polymorphic_state != polymorphic_state.ps_common) { _visitor.AddError(new ThisTypeOfVariablesCannotBeCaptured(_visitor.get_location(id))); return; } } if (si.scope == null) { return; } var scopeIndex = si.scope.ScopeNum; var selfWordInClass = false; CapturedVariablesTreeNode scope; if (_scopesCapturedVarsNodesDictionary.TryGetValue(scopeIndex, out scope)) { var prScope = scope as CapturedVariablesTreeNodeProcedureScope; if (prScope != null && acceptableVarType) { if (si.sym_info.semantic_node_type == semantic_node_type.local_variable) { if (!(idName == compiler_string_consts.self_word && si.scope is SymbolTable.ClassMethodScope && _classScope != null) && InLambdaContext) { _visitor.AddError(new ThisTypeOfVariablesCannotBeCaptured(_visitor.get_location(id))); } } if (si.sym_info.semantic_node_type == semantic_node_type.common_parameter && prScope.FunctionNode.parameters.First(v => v.name.ToLower() == idName).parameter_type != parameter_type.value && InLambdaContext) { _visitor.AddError(new CannotCaptureNonValueParameters(_visitor.get_location(id))); } if (idName == compiler_string_consts.self_word && si.scope is SymbolTable.ClassMethodScope && _classScope != null) { var selfField = _classScope.VariablesDefinedInScope.Find(var => var.SymbolInfo == si); if (selfField == null) { _classScope.VariablesDefinedInScope.Add( new CapturedVariablesTreeNode.CapturedSymbolInfo(null, si)); } selfWordInClass = true; } else { var field = prScope.VariablesDefinedInScope.Find(var => var.SymbolInfo == si); if (field == null) { prScope.VariablesDefinedInScope.Add(new CapturedVariablesTreeNode.CapturedSymbolInfo(null, si)); } } } var clScope = scope as CapturedVariablesTreeNodeClassScope; if (clScope != null && acceptableVarType) { var field = clScope.VariablesDefinedInScope.Find(var => var.SymbolInfo == si); if (field == null) { clScope.VariablesDefinedInScope.Add(new CapturedVariablesTreeNode.CapturedSymbolInfo(null, si)); } if (si.access_level != access_level.al_public) { if (!clScope.NonPublicMembersNamesMapping.ContainsKey(idName)) { var name = LambdaHelper.GetNameForNonPublicMember(idName); var semClassField = (class_field) si.sym_info; var pn = new common_property_node(name, _visitor.context._ctn, null, field_access_level.fal_public, semClassField.polymorphic_state); pn.internal_property_type = _visitor.convert_strong(id).type; clScope.NonPublicMembersNamesMapping.Add(idName, new Tuple<string, class_field, semantic_node>(name, semClassField, pn)); } } } var idRef = (selfWordInClass ? _classScope : scope) .VariablesDefinedInScope .Find(var => var.SymbolInfo == si); if (idRef == null) //TODO: Осторожнее переделать { { return; } } if (_currentTreeNode.CorrespondingSyntaxTreeNode != null) { var varName = ((IVAriableDefinitionNode)idRef.SymbolInfo.sym_info).name; //TODO: случай параметров и полей класса!!!!!!!!!!!!!!!!!! var substKey = new SubstitutionKey(varName, idRef.SyntaxTreeNodeWithVarDeclaration, _currentTreeNode.CorrespondingSyntaxTreeNode); if (!_identsReferences.ContainsKey(substKey)) { _identsReferences.Add(substKey, new List<ident>()); } _identsReferences[substKey].Add(id); } if (InLambdaContext && scope is CapturedVariablesTreeNodeLambdaScope && scopeIndex < _currentLambdaScopeNodeStack.Peek().ScopeIndex) //TODO: Захват параметров лямбды в другой лямбде { _visitor.AddError(new ThisTypeOfVariablesCannotBeCaptured(_visitor.get_location(id))); return; } if (!InLambdaContext || scopeIndex >= _currentLambdaScopeNodeStack.Peek().ScopeIndex) { return; } var stackAsList = _currentLambdaScopeNodeStack.ToList(); stackAsList.RemoveAt(0); if (!_currentLambdaScopeNodeStack.Peek().CapturedVarsSymbolInfo.Contains(si)) { _currentLambdaScopeNodeStack.Peek().CapturedVarsSymbolInfo.Add(si); foreach (var capturedVariablesTreeNodeLambdaScope in stackAsList) { if (!capturedVariablesTreeNodeLambdaScope.CapturedVarsSymbolInfo.Contains(si)) { capturedVariablesTreeNodeLambdaScope.CapturedVarsSymbolInfo.Add(si); } } } if (!idRef.ReferencingLambdas.Contains(_currentLambdaScopeNodeStack.Peek())) { idRef.ReferencingLambdas.Add(_currentLambdaScopeNodeStack.Peek()); foreach (var capturedVariablesTreeNodeLambdaScope in stackAsList) { if (!idRef.ReferencingLambdas.Contains(capturedVariablesTreeNodeLambdaScope)) { idRef.ReferencingLambdas.Add(capturedVariablesTreeNodeLambdaScope); } } } } }
private void RewriteReferencesForNodesThatAreChildNodesToThoseThatContainCapturedVariable(CapturedVariablesTreeNode node, string varName, syntax_tree_node nodeWithVarDecl) { if (node is CapturedVariablesTreeNodeLambdaScope) { RewriteReferencesForNodesThatAreChildNodesToThoseThatContainCapturedVariable(node.ChildNodes[0], varName, nodeWithVarDecl); return; } if (!(node is CapturedVariablesTreeNodeBlockScope || node is CapturedVariablesTreeNodeForScope || node is CapturedVariablesTreeNodeForEachScope)) { return; } var substKey = new SubstitutionKey(varName, nodeWithVarDecl, node.CorrespondingSyntaxTreeNode); if (!_substitutions.ContainsKey(substKey)) { var parentNode = node.ParentNode; var isReferenceFound = false; SubstitutionKey parentSubstKey = null; while (parentNode != null && !isReferenceFound) { parentSubstKey = new SubstitutionKey(varName, nodeWithVarDecl, parentNode.CorrespondingSyntaxTreeNode); if (_substitutions.ContainsKey(parentSubstKey)) { isReferenceFound = true; } else { parentNode = parentNode.ParentNode; } } if (isReferenceFound) { _substitutions.Add(substKey, _substitutions[parentSubstKey]); } } foreach (CapturedVariablesTreeNode childNode in node.ChildNodes) { RewriteReferencesForNodesThatAreChildNodesToThoseThatContainCapturedVariable(childNode, varName, nodeWithVarDecl); } }
private void AddReferencesToIdentInLambda(type_declaration upperScopeWhereVarsAreCapturedClass, CapturedVariablesTreeNode scope, string varName, syntax_tree_node syntaxTreeNodeWithVarDeclaration, dot_node substDotNode, bool nestedLambda) { for (var i = 0; i < scope.ChildNodes.Count; i++) { if (!(scope.ChildNodes[i] is CapturedVariablesTreeNodeLambdaScope)) { var substKey = new SubstitutionKey(varName, syntaxTreeNodeWithVarDeclaration, scope.ChildNodes[i].CorrespondingSyntaxTreeNode); if (_capturedVarsClassDefs.ContainsKey(scope.ChildNodes[i].ScopeIndex)) { var cl = _capturedVarsClassDefs[scope.ChildNodes[i].ScopeIndex]; if (cl.AssignNodeForUpperClassFieldInitialization == null) { var fieldType = SyntaxTreeBuilder.BuildSimpleType(upperScopeWhereVarsAreCapturedClass.type_name.name); var field = SyntaxTreeBuilder.BuildClassFieldsSection( new List<ident> { new ident(cl.GeneratedUpperClassFieldName) }, new List<type_definition> { fieldType }); var clClass = (class_definition) cl.ClassDeclaration.type_def; clClass.body.Add(field); cl.AssignNodeForUpperClassFieldInitialization = new assign( new dot_node(new ident(cl.GeneratedSubstitutingFieldName),new ident(cl.GeneratedUpperClassFieldName)), new ident(compiler_string_consts.self_word)); } } if (!_substitutions.ContainsKey(substKey)) { _substitutions.Add(substKey, substDotNode); } AddReferencesToIdentInLambda(upperScopeWhereVarsAreCapturedClass, scope.ChildNodes[i], varName, syntaxTreeNodeWithVarDeclaration, substDotNode, nestedLambda); } else { var scopeAsLambda = scope.ChildNodes[i] as CapturedVariablesTreeNodeLambdaScope; if (scopeAsLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.HasValue) { dot_node substDotNode1; if (!nestedLambda) { var parts = new Stack<ident>(); var dn = substDotNode; parts.Push((ident)dn.right); while (!(dn.left is ident && dn.right is ident)) { dn = (dot_node)dn.left; parts.Push((ident)dn.right); } substDotNode1 = new dot_node(new ident(_capturedVarsClassDefs[scopeAsLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.Value].GeneratedUpperClassFieldName), parts.Pop()); while (parts.Count > 0) { substDotNode1 = new dot_node(substDotNode1, parts.Pop()); } } else { var parts = new Stack<ident>(); var dn = substDotNode; parts.Push((ident)dn.right); while (!(dn.left is ident && dn.right is ident)) { dn = (dot_node)dn.left; parts.Push((ident)dn.right); } parts.Push((ident)dn.left); substDotNode1 = new dot_node(new ident(_capturedVarsClassDefs[scopeAsLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.Value].GeneratedUpperClassFieldName), parts.Pop()); while (parts.Count > 0) { substDotNode1 = new dot_node(substDotNode1, parts.Pop()); } } var substKey = new SubstitutionKey(varName, syntaxTreeNodeWithVarDeclaration, scope.ChildNodes[0].CorrespondingSyntaxTreeNode); if (!_substitutions.ContainsKey(substKey)) { _substitutions.Add(substKey, substDotNode1); } AddReferencesToIdentInLambda(_capturedVarsClassDefs[scopeAsLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.Value].ClassDeclaration, scopeAsLambda.ChildNodes[0], varName, syntaxTreeNodeWithVarDeclaration, substDotNode1, true); } else { AddReferencesToIdentInLambda(upperScopeWhereVarsAreCapturedClass, scope.ChildNodes[0], varName, syntaxTreeNodeWithVarDeclaration, substDotNode, nestedLambda); } } } }
private void VisitCapturedVar(CapturedVariablesTreeNode scope, CapturedVariablesTreeNode.CapturedSymbolInfo symbolInfo) { var varName = ((IVAriableDefinitionNode)symbolInfo.SymbolInfo.sym_info).name.ToLower(); var isSelfWordInClass = scope is CapturedVariablesTreeNodeClassScope && varName == compiler_string_consts.self_word; foreach (var referencingLambda in symbolInfo.ReferencingLambdas.OrderByDescending(rl => rl.ScopeIndex)) { if (scope != referencingLambda.ParentNode) { var upperScopesStack = new Stack<CapturedVariablesTreeNode>(); var crawlUpScope = referencingLambda.ParentNode; var anotherLambdaIsOnTheWay = crawlUpScope is CapturedVariablesTreeNodeLambdaScope; while (crawlUpScope != null && crawlUpScope != scope && !anotherLambdaIsOnTheWay) { upperScopesStack.Push(crawlUpScope); crawlUpScope = crawlUpScope.ParentNode; anotherLambdaIsOnTheWay = crawlUpScope is CapturedVariablesTreeNodeLambdaScope; } if (anotherLambdaIsOnTheWay || crawlUpScope == null) { continue; } var upperScopeWhereVarsAreCaptured = scope; var upperScopeWhereVarsAreCapturedClass = _capturedVarsClassDefs[upperScopeWhereVarsAreCaptured.ScopeIndex].ClassDeclaration; var substKey = new SubstitutionKey(varName, symbolInfo.SyntaxTreeNodeWithVarDeclaration, scope.CorrespondingSyntaxTreeNode); if (!_substitutions.ContainsKey(substKey)) { _substitutions.Add(substKey, new dot_node( new ident( _capturedVarsClassDefs[upperScopeWhereVarsAreCaptured.ScopeIndex] .GeneratedSubstitutingFieldName), new ident(varName))); } while (upperScopesStack.Count != 0) { var foundScopeWhereVarsWereCaptured = false; while (upperScopesStack.Count != 0 && !foundScopeWhereVarsWereCaptured) { if ( upperScopesStack.Peek() .VariablesDefinedInScope.Exists(var => var.ReferencingLambdas.Count > 0)) { foundScopeWhereVarsWereCaptured = true; } else { var curScope = upperScopesStack.Pop(); if (upperScopeWhereVarsAreCaptured == scope && upperScopeWhereVarsAreCaptured is CapturedVariablesTreeNodeClassScope) { continue; } substKey = new SubstitutionKey(varName, symbolInfo.SyntaxTreeNodeWithVarDeclaration, curScope.CorrespondingSyntaxTreeNode); dot_node dotnode; if (upperScopeWhereVarsAreCaptured != scope) { dotnode = new dot_node( new ident( _capturedVarsClassDefs[upperScopeWhereVarsAreCaptured.ScopeIndex] .GeneratedSubstitutingFieldName), new ident( _capturedVarsClassDefs[upperScopeWhereVarsAreCaptured.ScopeIndex] .GeneratedUpperClassFieldName)); var nodeForDotNodeCalc = upperScopeWhereVarsAreCaptured.ParentNode; while (nodeForDotNodeCalc != scope) { if (_capturedVarsClassDefs.ContainsKey(nodeForDotNodeCalc.ScopeIndex) && _capturedVarsClassDefs[nodeForDotNodeCalc.ScopeIndex] .AssignNodeForUpperClassFieldInitialization != null) { dotnode = new dot_node(dotnode, new ident( _capturedVarsClassDefs[ nodeForDotNodeCalc.ScopeIndex] .GeneratedUpperClassFieldName)); } nodeForDotNodeCalc = nodeForDotNodeCalc.ParentNode; } if (!isSelfWordInClass) { dotnode = new dot_node(dotnode, new ident(varName)); } } else { dotnode = new dot_node(new ident( _capturedVarsClassDefs[ upperScopeWhereVarsAreCaptured.ScopeIndex] .GeneratedSubstitutingFieldName), new ident(varName)); } if (!_substitutions.ContainsKey(substKey)) { _substitutions.Add(substKey, dotnode); } } } if (foundScopeWhereVarsWereCaptured) { var nextNodeWhereVarsAreCaptured = upperScopesStack.Pop(); if (!_capturedVarsClassDefs.ContainsKey(nextNodeWhereVarsAreCaptured.ScopeIndex)) { var classDef = SyntaxTreeBuilder.BuildClassDefinition(); var typeDeclaration = new type_declaration(GeneratedClassName, classDef); _capturedVarsClassDefs.Add(nextNodeWhereVarsAreCaptured.ScopeIndex, new ScopeClassDefinition( nextNodeWhereVarsAreCaptured.CorrespondingSyntaxTreeNode, typeDeclaration, nextNodeWhereVarsAreCaptured)); } var nextNodeWhereVarsAreCapturedClass = (class_definition) _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex].ClassDeclaration .type_def; if ( _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex] .AssignNodeForUpperClassFieldInitialization == null) { var fieldType = SyntaxTreeBuilder.BuildSimpleType(upperScopeWhereVarsAreCapturedClass.type_name.name); var field = SyntaxTreeBuilder.BuildClassFieldsSection( new List<ident> { new ident( _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex] .GeneratedUpperClassFieldName) }, new List<type_definition> {fieldType}); nextNodeWhereVarsAreCapturedClass.body.Add(field); _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex] .AssignNodeForUpperClassFieldInitialization = new assign( new dot_node( new ident( _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex] .GeneratedSubstitutingFieldName), new ident( _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex] .GeneratedUpperClassFieldName)), new ident( _capturedVarsClassDefs[upperScopeWhereVarsAreCaptured.ScopeIndex] .GeneratedSubstitutingFieldName)); } substKey = new SubstitutionKey(varName, symbolInfo.SyntaxTreeNodeWithVarDeclaration, nextNodeWhereVarsAreCaptured.CorrespondingSyntaxTreeNode); var dot = new dot_node( new ident( _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex] .GeneratedSubstitutingFieldName), new ident( _capturedVarsClassDefs[nextNodeWhereVarsAreCaptured.ScopeIndex] .GeneratedUpperClassFieldName)); var nodeForDotNodeCalculation = nextNodeWhereVarsAreCaptured.ParentNode; while (nodeForDotNodeCalculation != scope) { if (_capturedVarsClassDefs.ContainsKey(nodeForDotNodeCalculation.ScopeIndex) && _capturedVarsClassDefs[nodeForDotNodeCalculation.ScopeIndex] .AssignNodeForUpperClassFieldInitialization != null) { dot = new dot_node(dot, new ident( _capturedVarsClassDefs[nodeForDotNodeCalculation.ScopeIndex] .GeneratedUpperClassFieldName)); } nodeForDotNodeCalculation = nodeForDotNodeCalculation.ParentNode; } if (!isSelfWordInClass) { dot = new dot_node(dot, new ident(varName)); } if (!_substitutions.ContainsKey(substKey)) { _substitutions.Add(substKey, dot); } upperScopeWhereVarsAreCaptured = nextNodeWhereVarsAreCaptured; upperScopeWhereVarsAreCapturedClass = _capturedVarsClassDefs[upperScopeWhereVarsAreCaptured.ScopeIndex].ClassDeclaration; } } if (!(upperScopeWhereVarsAreCaptured == scope && upperScopeWhereVarsAreCaptured is CapturedVariablesTreeNodeClassScope)) { if (upperScopeWhereVarsAreCaptured != scope) { var dotnode1 = new dot_node( new ident(compiler_string_consts.self_word), new ident( _capturedVarsClassDefs[upperScopeWhereVarsAreCaptured.ScopeIndex] .GeneratedUpperClassFieldName)); if (upperScopeWhereVarsAreCaptured != scope) { var nodeForDotNodeCalc = upperScopeWhereVarsAreCaptured.ParentNode; while (nodeForDotNodeCalc != scope) { if (_capturedVarsClassDefs.ContainsKey(nodeForDotNodeCalc.ScopeIndex) && _capturedVarsClassDefs[nodeForDotNodeCalc.ScopeIndex] .AssignNodeForUpperClassFieldInitialization != null) { dotnode1 = new dot_node(dotnode1, new ident( _capturedVarsClassDefs[nodeForDotNodeCalc.ScopeIndex] .GeneratedUpperClassFieldName)); } nodeForDotNodeCalc = nodeForDotNodeCalc.ParentNode; } } if (!isSelfWordInClass) { var classScope = scope as CapturedVariablesTreeNodeClassScope; if (classScope != null) { Tuple<string, class_field, semantic_node> publicProperty; if (classScope.NonPublicMembersNamesMapping.TryGetValue(varName, out publicProperty)) { dotnode1 = new dot_node(dotnode1, new ident(publicProperty.Item1)); } else { dotnode1 = new dot_node(dotnode1, new ident(varName)); } } else { dotnode1 = new dot_node(dotnode1, new ident(varName)); } } _lambdaIdReferences.Add(new LambdaReferencesSubstitutionInfo { LambdaScope = referencingLambda, VarName = varName, SyntaxTreeNodeWithVarDeclaration = symbolInfo.SyntaxTreeNodeWithVarDeclaration, DotNode = dotnode1 }); } else { var dotnode1 = new dot_node( new ident(compiler_string_consts.self_word), new ident(varName)); _lambdaIdReferences.Add(new LambdaReferencesSubstitutionInfo { LambdaScope = referencingLambda, VarName = varName, SyntaxTreeNodeWithVarDeclaration = symbolInfo.SyntaxTreeNodeWithVarDeclaration, DotNode = dotnode1 }); } } if (!referencingLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.HasValue || upperScopeWhereVarsAreCaptured.ScopeIndex > referencingLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod) { referencingLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod = upperScopeWhereVarsAreCaptured.ScopeIndex; } } else { if (!_capturedVarsClassDefs.ContainsKey(scope.ScopeIndex)) { var classDef = SyntaxTreeBuilder.BuildClassDefinition(); var typeDeclaration = new type_declaration(GeneratedClassName, classDef); _capturedVarsClassDefs.Add(scope.ScopeIndex, new ScopeClassDefinition( scope.CorrespondingSyntaxTreeNode, typeDeclaration, scope)); } var substKey = new SubstitutionKey(varName, symbolInfo.SyntaxTreeNodeWithVarDeclaration, scope.CorrespondingSyntaxTreeNode); if (!_substitutions.ContainsKey(substKey)) { if (!isSelfWordInClass) { string propertyName = null; var classScope = scope as CapturedVariablesTreeNodeClassScope; if (classScope != null) { Tuple<string, class_field, semantic_node> publicProperty; if (classScope.NonPublicMembersNamesMapping.TryGetValue(varName, out publicProperty)) { propertyName = publicProperty.Item1; } } _substitutions.Add(substKey, new dot_node( new ident( _capturedVarsClassDefs[scope.ScopeIndex] .GeneratedSubstitutingFieldName), new ident(propertyName ?? varName))); } } var dotnode1 = new dot_node( new ident(compiler_string_consts.self_word), new ident(varName)); _lambdaIdReferences.Add(new LambdaReferencesSubstitutionInfo { LambdaScope = referencingLambda, VarName = varName, SyntaxTreeNodeWithVarDeclaration = symbolInfo.SyntaxTreeNodeWithVarDeclaration, DotNode = dotnode1 }); if (!referencingLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod.HasValue || scope.ScopeIndex > referencingLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod) { referencingLambda.ScopeIndexOfClassWhereLambdaWillBeAddedAsMethod = scope.ScopeIndex; } } if (!_lambdasToBeAddedAsMethods.Contains(referencingLambda)) { _lambdasToBeAddedAsMethods.Add(referencingLambda); } } }