private void check_property_params(static_property_reference pr, location loc)
 {
     if (pr.property.parameters.Count != pr.fact_parametres.Count)
     {
         AddError(loc, "PROPERTY_{0}_REFERENCE_WITH_INVALID_PARAMS_COUNT", pr.property.name);
     }
 }
 private addressed_expression create_addressed_with_type_expression(type_node tn, SyntaxTree.ident id_right,
     SymbolInfo si_right)
 {
     definition_node dn = null;
     if (!internal_is_assign)
     dn = context.check_name_node_type(id_right.name, si_right, get_location(id_right),
         general_node_type.variable_node, general_node_type.property_node, general_node_type.event_node);
     else
         dn = context.check_name_node_type(id_right.name, si_right, get_location(id_right),
         general_node_type.variable_node, general_node_type.property_node, general_node_type.event_node,general_node_type.constant_definition);
     if (dn.general_node_type == general_node_type.constant_definition)
         AddError(get_location(id_right), "CAN_NOT_ASSIGN_TO_CONSTANT_OBJECT");
     switch (dn.general_node_type)
     {
         case general_node_type.variable_node:
             {
                 return create_class_static_field_reference(tn, dn, id_right);
             }
         case general_node_type.property_node:
             {
                 property_node pn = (property_node)dn;
                 if (pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static)
                 {
                     AddError(new CanNotReferenceToNonStaticPropertyWithType(pn, get_location(id_right), tn));
                 }
                 static_property_reference pr = new static_property_reference(pn, get_location(id_right));
                 return pr;
             }
         case general_node_type.event_node:
             {
                 if (dn.semantic_node_type == semantic_node_type.compiled_event)
                 {
                     compiled_event ce = (compiled_event)dn;
                     if (!ce.is_static)
                     {
                         //throw new NonStaticAndStaticEvevnt();
                     }
                     static_event_reference ser = new static_event_reference(ce, get_location(id_right));
                     return ser;
                 }
                 else if (dn.semantic_node_type == semantic_node_type.common_event)
                 {
                     common_event ce = (common_event)dn;
                     if (!ce.is_static)
                     {
                         //throw new NonStaticAndStaticEvevnt();
                     }
                     static_event_reference ser = new static_event_reference(ce, get_location(id_right));
                     return ser;
                 }
                 else if (dn.semantic_node_type == semantic_node_type.common_namespace_event)
                 {
                     common_namespace_event cne = dn as common_namespace_event;
                     static_event_reference ser = new static_event_reference(cne, get_location(id_right));
                     return ser;
                 }
                 break;
             }
     		default : return null;
     }
     throw new CompilerInternalError("Invalid right type expression");
 }
 private addressed_expression ident_address_reciving(SymbolInfo si, SyntaxTree.ident _ident)
 {
     location lloc = get_location(_ident);
     definition_node dn = null;
     if (!internal_is_assign)
         dn = context.check_name_node_type(_ident.name, si, lloc,
         general_node_type.variable_node, general_node_type.property_node, general_node_type.event_node);
     else
         dn = context.check_name_node_type(_ident.name, si, lloc,
         general_node_type.variable_node, general_node_type.property_node, general_node_type.event_node, general_node_type.constant_definition);
     if (dn.general_node_type == general_node_type.constant_definition)
         AddError(get_location(_ident), "CAN_NOT_ASSIGN_TO_CONSTANT_OBJECT");
     switch (dn.general_node_type)
     {
         case general_node_type.variable_node:
             {
                 local_variable lv = dn as local_variable;
                 if (lv != null && (lv.function is common_method_node))
                 {
                     //self variable
                     if ((lv.function as common_method_node).self_variable == lv)
                         AddError(lloc, "VARIABLE_{0}_READONLY", lv.name);
                 }
                 return create_variable_reference(dn, lloc);
             }
         case general_node_type.property_node:
             {
                 property_node pn = (property_node)dn;
                 if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
                 {
                     static_property_reference spr = new static_property_reference(pn, lloc);
                     return spr;
                 }
                 //this_node thisnode=new this_node(context.converted_type,lloc);
                 if (pn.comprehensive_type.Scope == null && pn is compiled_property_node)
                 	(pn.comprehensive_type as compiled_type_node).init_scope();
                 non_static_property_reference nspr = new non_static_property_reference(pn, GetCurrentObjectReference(pn.comprehensive_type.Scope, pn, lloc), lloc);
                 return nspr;
             }
         case general_node_type.event_node:
             {
                 if (dn.semantic_node_type == semantic_node_type.compiled_event)
                 {
                     compiled_event ce = (compiled_event)dn;
                     if (ce.is_static)
                     {
                         static_event_reference ser = new static_event_reference(ce, get_location(_ident));
                         return ser;
                     }
                     nonstatic_event_reference nser = new nonstatic_event_reference(
                         GetCurrentObjectReference(ce.comprehensive_type.Scope, ce, lloc), ce, lloc);
                     return nser;
                 }
                 else if (dn.semantic_node_type == semantic_node_type.common_event)
                 {
                 	common_event ce = (common_event)dn;
                 	if (ce.is_static)
                     {
                         static_event_reference ser = new static_event_reference(ce, get_location(_ident));
                         return ser;
                     }
                     nonstatic_event_reference nser = new nonstatic_event_reference(
                         GetCurrentObjectReference(ce.comprehensive_type.Scope, ce, lloc), ce, lloc);
                     return nser;
                 }
                 else if (dn.semantic_node_type == semantic_node_type.common_namespace_event)
                 {
                     common_namespace_event cne = (common_namespace_event)dn;
                     static_event_reference ser = new static_event_reference(cne, get_location(_ident));
                     return ser;
                 }
                 break;
             }
     }
     return null;
 }
        public override void visit(SyntaxTree.indexer _indexer)
        {
            //SSM 11/02/16 - нет, это глупость
            /*if (_indexer.dereferencing_value is SyntaxTree.question_colon_expression) // то разбросать индекс по компонентам
            {
                var q = _indexer.dereferencing_value as SyntaxTree.question_colon_expression;
                var nodeToVisit = new SyntaxTree.question_colon_expression(q.condition, new indexer(q.ret_if_true as addressed_value, _indexer.indexes, _indexer.source_context),
                    new indexer(q.ret_if_false as addressed_value, _indexer.indexes, _indexer.source_context), _indexer.source_context);
                visit(nodeToVisit);
                return;
            }*/
            //end SSM 11/02/16

            //lroman
            if (_indexer.dereferencing_value is closure_substituting_node)
            {
                var nodeToVisit = new indexer(((closure_substituting_node) _indexer.dereferencing_value).substitution,
                                              _indexer.indexes);
                visit(nodeToVisit);
                return;
            }

            motivation mot = motivation_keeper.motivation;
            SyntaxTree.ident idi = _indexer.dereferencing_value as SyntaxTree.ident;
            if (idi != null)
            {
                SymbolInfo si = context.find(idi.name);
                if (si == null)
                {
                    AddError(new UndefinedNameReference(idi.name, get_location(idi)));
                }
                if (si.sym_info.general_node_type == general_node_type.type_node)
                {
                    indexer_as_type_indexes((type_node)si.sym_info, _indexer.indexes, mot, get_location(idi));
                    return;
                }
                if (si.sym_info.general_node_type == general_node_type.property_node)
                {
                    property_node pn = (property_node)si.sym_info;
                    if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
                    {
                        static_property_reference spr = new static_property_reference(pn, get_location(idi));
                        indexer_as_property_indexes(spr, _indexer.indexes, mot, get_location(idi));
                        return;
                    }
                    else
                    {
                        this_node thisnode = new this_node(pn.comprehensive_type, get_location(_indexer));
                        location loc111 = get_location(idi);
                        non_static_property_reference nspr = new non_static_property_reference(pn, thisnode, loc111);
                        indexer_as_property_indexes(nspr, _indexer.indexes, mot, loc111);
                        return;
                    }
                }
                expression_node en = ident_value_reciving(si, idi);
              
                indexer_as_expression_index(en, _indexer.indexes, mot, get_location(idi));
                return;
            }
            else
            {
                SyntaxTree.dot_node dotnd = _indexer.dereferencing_value as SyntaxTree.dot_node;
                if (dotnd != null)
                {
                    SyntaxTree.ident id = dotnd.right as SyntaxTree.ident;
                    semantic_node sn = convert_semantic_strong(dotnd.left);
                    switch (sn.general_node_type)
                    {
                        case general_node_type.type_node:
                            {
                                type_node ttp = (type_node)sn;
                                SymbolInfo si = ttp.find_in_type(id.name, context.CurrentScope);
                                if (si == null)
                                {
                                    AddError(new UndefinedNameReference(id.name, get_location(id)));
                                }
                                if (si.sym_info.general_node_type == general_node_type.property_node)
                                {
                                    property_node pn = (property_node)si.sym_info;
                                    static_property_reference spr = new static_property_reference(pn, get_location(id));
                                    indexer_as_property_indexes(spr, _indexer.indexes, mot, get_location(dotnd));
                                    return;
                                }
                                expression_node exp1 = create_static_expression(ttp, id, si);
                                indexer_as_expression_index(exp1, _indexer.indexes, mot, get_location(id));
                                return;
                            }
                        case general_node_type.namespace_node:
                        case general_node_type.unit_node:
                            {
                                SymbolInfo si = null;
                                if (sn is namespace_node)
                                    si = ((namespace_node)sn).find(id.name);
                                else
                                    si = ((unit_node)sn).find_only_in_namespace(id.name);
                                if (si == null)
                                {
                                    AddError(new UndefinedNameReference(id.name, get_location(id)));
                                }
                                location lloc = get_location(id);
                                if (si.sym_info.general_node_type == general_node_type.type_node)
                                {
                                    type_node tn = (type_node)si.sym_info;
                                    indexer_as_type_indexes(tn, _indexer.indexes, mot, lloc);
                                    return;
                                }
                                expression_node exp2 = ident_value_reciving(si, id);
                                indexer_as_expression_index(exp2, _indexer.indexes, mot, get_location(id));
                                return;
                            }
                        case general_node_type.expression:
                            {
                                expression_node ex = (expression_node)sn;
                                SymbolInfo si = ex.type.find_in_type(id.name, context.CurrentScope);
                                if (si == null)
                                {
                                    AddError(new UndefinedNameReference(id.name, get_location(id)));
                                }
                                if (si.sym_info.general_node_type == general_node_type.property_node)
                                {
                                    property_node pn = (property_node)si.sym_info;
                                    if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
                                    {
                                        AddError(new CanNotReferenceToStaticPropertyWithExpression(pn, get_location(dotnd), ex.type));
                                    }
                                    location lloc11 = get_location(dotnd);
                                    try_convert_typed_expression_to_function_call(ref ex);
                                    non_static_property_reference nspr = new non_static_property_reference(pn, ex, lloc11);
                                    indexer_as_property_indexes(nspr, _indexer.indexes, mot, lloc11);
                                    return;
                                }
                                expression_node en2 = expression_value_reciving(id, si, ex, false);
                                indexer_as_expression_index(en2, _indexer.indexes, mot, get_location(id));
                                return;
                            }
                    }
                }
                else
                {
                    expression_node expr = convert_strong(_indexer.dereferencing_value);
                    indexer_as_expression_index(expr, _indexer.indexes, mot, get_location(_indexer.dereferencing_value));
                    return;
                }
            }
            /*expression_node left=convert_strong(_indexer.dereferencing_value);
            foreach(SyntaxTree.expression exp in _indexer.indexes.expressions)
            {
                expression_node right=convert_strong(exp);
                SymbolInfo si=left.type.find_in_type(compiler_string_consts.indexer_name);
                definition_node dn=check_name_node_type(compiler_string_consts.indexer_name,si,get_location(exp),
                    general_node_type.function_node);
                expression_nodeArrayList exprs=new expression_nodeArrayList();
                exprs.Add(right);
                function_node fn=convertion_data_and_alghoritms.select_function(exprs,si,get_location(exp));
                base_function_call_with_method bfc=create_not_static_method_call(fn,left,get_location(exp),false);
                bfc.parameters.AddRange(exprs);
                left=bfc;
            }*/
            /*switch (mot)
            {
                case motivation.address_reciving:
                {
                    return_addressed_value(left);
                    return;
                }
                case motivation.expression_evaluation:
                {
                    return_value(left);
                    return;
                }
                case motivation.semantic_node_reciving:
                {
                    return_semantic_value(left);
                    return;
                }		
            }*/
        }
 private void indexer_as_property_indexes(static_property_reference spr, SyntaxTree.expression_list parameters,
     motivation mot, location loc)
 {
     /*if (spr.property.parameters.Count==0)
     {
         switch(mot)
         {
             case motivation.expression_evaluation:
             case motivation.semantic_node_reciving:
             {
                 function_node fn=spr.property.get_function;
                 base_function_call_with_method bfc=convertion_data_and_alghoritms.create_simple_function_call(fn,loc,new expression_node[0]);
                 return_value(bfc);
                 return;
             }
             case motivation.address_reciving:
             {
                 return_addressed_value(spr);
                 return;
             }
         }
         throw new CompilerInternalError("Unsupported motivation");
     }*/
     if (spr.property.parameters.Count != 0)
     {
         if (parameters.expressions.Count != spr.property.parameters.Count)
         {
             AddError(loc, "PROPERTY_{0}_REFERENCE_WITH_INVALID_PARAMS_COUNT", spr.property.name);
         }
         for (int i = 0; i < parameters.expressions.Count; i++)
         {
             expression_node exp = convert_strong(parameters.expressions[i]);
             exp = convertion_data_and_alghoritms.convert_type(exp, spr.property.parameters[i].type);
             spr.fact_parametres.AddElement(exp);
         }
     }
     switch (mot)
     {
         case motivation.expression_evaluation:
         case motivation.semantic_node_reciving:
             {
                 function_node fn = spr.property.get_function;
                 if (fn == null)
                 {
                     AddError(new ThisPropertyCanNotBeReaded(spr.property, loc));
                 }
                 //expression_node bfc=convertion_data_and_alghoritms.create_simple_function_call(fn,loc,spr.fact_params.ToArray());
                 base_function_call bfc = create_static_method_call(fn, loc, spr.property.comprehensive_type, false);
                 bfc.parameters.AddRange(spr.fact_parametres);
                 if (spr.property.parameters.Count != 0)
                 {
                     return_value(bfc);
                     return;
                 }
                 indexer_as_expression_index(bfc, parameters, mot, loc);
                 return;
             }
         case motivation.address_reciving:
             {
                 if (spr.property.parameters.Count != 0)
                 {
                     return_addressed_value(spr);
                     return;
                 }
                 function_node fn = spr.property.get_function;
                 if (fn == null)
                 {
                     AddError(new ThisPropertyCanNotBeReaded(spr.property, loc));
                 }
                 base_function_call bfc = create_static_method_call(fn, loc, spr.property.comprehensive_type, false);
                 bfc.parameters.AddRange(spr.fact_parametres);
                 indexer_as_expression_index(bfc, parameters, mot, loc);
                 return;
             }
     }
     throw new CompilerInternalError("Unsupported motivation");
 }
 private void indexer_as_type_indexes(type_node type, SyntaxTree.expression_list parameters, motivation mot,
     location loc)
 {
     if (type.default_property_node == null)
     {
         if (type.semantic_node_type != semantic_node_type.delegated_method)
         {
             AddError(loc, "NO_DEFAULT_PROPERTY_TO_TYPE_{0}", type.PrintableName);
         }
         else
         {
             AddError(loc, "NO_DEFAULT_PROPERTY_TO_FUNCTION_TYPE");
         }
     }
     if (type.default_property_node.polymorphic_state != SemanticTree.polymorphic_state.ps_static)
     {
         AddError(new CanNotReferenceToNonStaticPropertyWithType(type.default_property_node, loc, type));
     }
     static_property_reference spr = new static_property_reference(type.default_property_node, loc);
     indexer_as_property_indexes(spr, parameters, mot, loc);
     return;
 }
        public override void visit(SyntaxTree.indexer _indexer)
        {
            //SSM 11/02/16 - нет, это глупость
            /*if (_indexer.dereferencing_value is SyntaxTree.question_colon_expression) // то разбросать индекс по компонентам
            {
                var q = _indexer.dereferencing_value as SyntaxTree.question_colon_expression;
                var nodeToVisit = new SyntaxTree.question_colon_expression(q.condition, new indexer(q.ret_if_true as addressed_value, _indexer.indexes, _indexer.source_context),
                    new indexer(q.ret_if_false as addressed_value, _indexer.indexes, _indexer.source_context), _indexer.source_context);
                visit(nodeToVisit);
                return;
            }*/
            //end SSM 11/02/16

            // SSM 18.08.16 - пробуем обработать захват enn[i] в yieldах где enn - поле класса и нуждается в переименовании
            // Так же ниже делает lroman
            if (_indexer.dereferencing_value is yield_unknown_ident)
            {
                var yui = (yield_unknown_ident)_indexer.dereferencing_value;
                var av = ProcessUnknownIdent(yui);
                var nodeToVisit = new indexer(av,_indexer.indexes);
                visit(nodeToVisit);
                return;
            }

            //lroman
            if (_indexer.dereferencing_value is closure_substituting_node)
            {
                var nodeToVisit = new indexer(((closure_substituting_node) _indexer.dereferencing_value).substitution,
                                              _indexer.indexes);
                visit(nodeToVisit);
                return;
            }

            var mot = motivation_keeper.motivation;
            motivation_keeper.reset();
            SyntaxTree.ident idi = _indexer.dereferencing_value as SyntaxTree.ident;
            if (idi != null)
            {
                SymbolInfo si = context.find(idi.name);
                if (si == null)
                {
                    AddError(new UndefinedNameReference(idi.name, get_location(idi)));
                }
                if (si.sym_info.general_node_type == general_node_type.type_node)
                {
                    indexer_as_type_indexes((type_node)si.sym_info, _indexer.indexes, mot, get_location(idi));
                    return;
                }
                if (si.sym_info.general_node_type == general_node_type.property_node)
                {
                    property_node pn = (property_node)si.sym_info;
                    if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
                    {
                        static_property_reference spr = new static_property_reference(pn, get_location(idi));
                        indexer_as_property_indexes(spr, _indexer.indexes, mot, get_location(idi));
                        return;
                    }
                    else
                    {
                        this_node thisnode = new this_node(pn.comprehensive_type, get_location(_indexer));
                        location loc111 = get_location(idi);
                        non_static_property_reference nspr = new non_static_property_reference(pn, thisnode, loc111);
                        indexer_as_property_indexes(nspr, _indexer.indexes, mot, loc111);
                        return;
                    }
                }
                expression_node en = ident_value_reciving(si, idi);
              
                indexer_as_expression_index(en, _indexer.indexes, mot, get_location(idi));
                return;
            }
            else
            {
                SyntaxTree.dot_node dotnd = _indexer.dereferencing_value as SyntaxTree.dot_node;
                if (dotnd != null)
                {
                    SyntaxTree.ident id = dotnd.right as SyntaxTree.ident;
                    semantic_node sn = convert_semantic_strong(dotnd.left);
                    switch (sn.general_node_type)
                    {
                        case general_node_type.type_node:
                            {
                                type_node ttp = (type_node)sn;
                                SymbolInfo si = ttp.find_in_type(id.name, context.CurrentScope);
                                if (si == null)
                                {
                                    AddError(new UndefinedNameReference(id.name, get_location(id)));
                                }
                                if (si.sym_info.general_node_type == general_node_type.property_node)
                                {
                                    property_node pn = (property_node)si.sym_info;
                                    static_property_reference spr = new static_property_reference(pn, get_location(id));
                                    indexer_as_property_indexes(spr, _indexer.indexes, mot, get_location(dotnd));
                                    return;
                                }
                                expression_node exp1 = create_static_expression(ttp, id, si);
                                indexer_as_expression_index(exp1, _indexer.indexes, mot, get_location(id));
                                return;
                            }
                        case general_node_type.namespace_node:
                        case general_node_type.unit_node:
                            {
                                SymbolInfo si = null;
                                if (sn is namespace_node)
                                    si = ((namespace_node)sn).find(id.name);
                                else
                                    si = ((unit_node)sn).find_only_in_namespace(id.name);
                                if (si == null)
                                {
                                    AddError(new UndefinedNameReference(id.name, get_location(id)));
                                }
                                location lloc = get_location(id);
                                if (si.sym_info.general_node_type == general_node_type.type_node)
                                {
                                    type_node tn = (type_node)si.sym_info;
                                    indexer_as_type_indexes(tn, _indexer.indexes, mot, lloc);
                                    return;
                                }
                                expression_node exp2 = ident_value_reciving(si, id);
                                indexer_as_expression_index(exp2, _indexer.indexes, mot, get_location(id));
                                return;
                            }
                        case general_node_type.expression:
                            {
                                expression_node ex = (expression_node)sn;
                                SymbolInfo si = ex.type.find_in_type(id.name, context.CurrentScope);
                                if (si == null)
                                {
                                    AddError(new UndefinedNameReference(id.name, get_location(id)));
                                }
                                if (si.sym_info.general_node_type == general_node_type.property_node)
                                {
                                    property_node pn = (property_node)si.sym_info;
                                    if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static)
                                    {
                                        AddError(new CanNotReferenceToStaticPropertyWithExpression(pn, get_location(dotnd), ex.type));
                                    }
                                    location lloc11 = get_location(dotnd);
                                    try_convert_typed_expression_to_function_call(ref ex);
                                    non_static_property_reference nspr = new non_static_property_reference(pn, ex, lloc11);
                                    indexer_as_property_indexes(nspr, _indexer.indexes, mot, lloc11);
                                    return;
                                }
                                expression_node en2 = expression_value_reciving(id, si, ex, false);
                                indexer_as_expression_index(en2, _indexer.indexes, mot, get_location(id));
                                return;
                            }
                    }
                }
                else
                {
                    expression_node expr = convert_strong(_indexer.dereferencing_value);
                    indexer_as_expression_index(expr, _indexer.indexes, mot, get_location(_indexer.dereferencing_value));
                    return;
                }
            }
        }