public override void visit(assign assignment) { var to = assignment.to as ident; var from = assignment.from; if (to != null && assignment.operator_type == Operators.Assignment && to.name.ToLower() == RESULT_KEY_WORD) { var converted = syntaxTreeVisitor.convert_strong(from); if (converted is typed_expression) { delegated_methods dm = converted.type as delegated_methods; if (dm.empty_param_method != null) { converted = syntaxTreeVisitor.convert_typed_expression_to_function_call(converted as typed_expression); } } resultExpressionsTypes.Add(new Tuple <type_node, expression, expression_node>(converted.type, from, converted)); } }
public override void visit(ident id) { var idName = id.name.ToLower(); SymbolInfo si = _visitor.context.find_first(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.common_method_node || // SSM bug fix #167 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 || si.sym_info.semantic_node_type == semantic_node_type.basic_function_node && idName == "exit") { 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 PascalSharp.Internal.TreeConverter.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 PascalSharp.Internal.TreeConverter.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); } } } } }