// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt) // This code is distributed under the GNU LGPL (for details please see \doc\license.txt) using Languages.Facade; using PascalABCCompiler; using PascalABCCompiler.Parsers; using PascalABCCompiler.SyntaxTree; using PascalABCCompiler.SyntaxTreeConverters; using PascalABCCompiler.TreeRealization; using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; namespace CodeCompletion { public class DomSyntaxTreeVisitor : AbstractVisitor { private SymScope returned_scope;//vozvrashaemyj scope posle vyzova visit private Stack saved_returned_scopes = new Stack();//nuzhen dlja lambd private List returned_scopes = new List();//hranit spisok scopov (metodov) posle vyzova visit, esli search_all=true public SymScope entry_scope;//korenvoj scope unita public SymScope impl_scope; private string cur_type_name; private location cur_loc; private DomConverter converter; private bool is_proc_realization=false; private string meth_name; private string cur_unit_file_name; private Languages.Facade.ILanguage currentUnitLanguage; private RetValue cnst_val; private ExpressionEvaluator ev = new ExpressionEvaluator(); public bool add_doc_from_text=true; private bool search_all = false;//flag, iskat vse peregruzki ili tolko odnu. sdelal dlja effektivnosti. true zadaetsja tolko v visit(method_call) internal bool parse_only_interface = false; private template_type_reference converted_template_type = null; private List pending_is_pattern_vars = new List(); private static Compiler compiler; public static bool use_semantic_for_intellisense; private Dictionary method_call_cache = new Dictionary(); public HashSet cur_used_assemblies; public DomSyntaxTreeVisitor(DomConverter converter) { //tcst = new TreeConverterSymbolTable(false); this.converter = converter; } public override void visit(default_operator node) { node.type_name.visit(this); } public void Convert(compilation_unit cu) { method_call_cache.Clear(); try { cu.visit(this); } catch(Exception e) { #if DEBUG File.AppendAllText("log.txt", e.Message + Environment.NewLine + e.StackTrace + Environment.NewLine); #endif //throw e; //System.Diagnostics.Debug.WriteLine(e.StackTrace); } cur_used_assemblies = new HashSet(PascalABCCompiler.NetHelper.NetHelper.cur_used_assemblies); if (use_semantic_for_intellisense && !parse_only_interface) try { CorrectTreeWithSemantic(cu); } catch (Exception e) { #if DEBUG File.AppendAllText("log.txt", e.Message + Environment.NewLine + e.StackTrace + Environment.NewLine); #endif } } private type_definition BuildSyntaxNodeForTypeReference(type_node tn) { if (tn.instance_params != null && tn.instance_params.Count > 0) { var ttr = new template_type_reference(); var ntr = new named_type_reference(); ttr.name = ntr; ttr.params_list = new template_param_list(); var arr = tn.original_generic.full_name.Split('.'); for (int i = 0; i < arr.Length; i++) { var s = arr[i]; if (i < arr.Length - 1) ntr.names.Add(new ident(s)); else { var id = new ident_with_templateparams(); ntr.Add(new ident(s)); foreach (var gen_td in tn.instance_params) { if (gen_td.PrintableName.StartsWith("AnonymousType#")) { SymScope tmp = cur_scope; TypeScope ts = null; cur_scope = ts = new TypeScope(SymbolKind.Class, cur_scope, null); tmp.AddName(gen_td.PrintableName, cur_scope); ts.loc = get_location(gen_td.location); ts.si = new SymInfo("class", SymbolKind.Class, ""); foreach (var prop in (gen_td as common_type_node).properties) { ElementScope es = new ElementScope(); es.si = new SymInfo(prop.name, SymbolKind.Property, ""); BuildSyntaxNodeForTypeReference(prop.property_type).visit(this); es.sc = returned_scope; ts.AddName(prop.name, es); } returned_scope = cur_scope; cur_scope = tmp; ttr.params_list.Add(new named_type_reference(gen_td.PrintableName)); } else ttr.params_list.Add(BuildSyntaxNodeForTypeReference(gen_td)); } } } return ttr; } else { var ntr = new named_type_reference(); if (tn.IsDelegate) { var invokeMeth = tn.find_first_in_type("Invoke"); if (invokeMeth != null) { var fn = invokeMeth.sym_info as function_node; procedure_header header; if (fn.return_value_type != null) { header = new function_header(BuildSyntaxNodeForTypeReference(fn.return_value_type)); } else { header = new procedure_header(); } header.parameters = new formal_parameters(); foreach (var param in fn.parameters) { var tparam = new typed_parameters(); tparam.vars_type = BuildSyntaxNodeForTypeReference(param.type); tparam.idents = new ident_list(); tparam.idents.Add(new ident(param.name)); header.parameters.Add(tparam); } return header; } ntr.names.Add(new ident(tn.PrintableName.Replace("()", ""))); return ntr; } else if (tn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.array_kind) { array_type arr_type = new array_type(null, BuildSyntaxNodeForTypeReference(tn.element_type)); return arr_type; } var arr = tn.full_name.Split('.'); foreach (string s in arr) { if (s.IndexOf("implementation__") == -1) ntr.names.Add(new ident(s)); } return ntr; } } private TypeScope GetIntellisenseTypeByType(Type t) { if (t.GetGenericArguments().Length == 0) return TypeTable.get_compiled_type(t); else { List gen_args = new List(); foreach (var gen_tn in t.GetGenericArguments()) { gen_args.Add(TypeTable.get_compiled_type(gen_tn)); } return CompiledScope.get_type_instance(t.GetGenericTypeDefinition(), gen_args); } } private TypeScope GetCorrectedType(TypeScope ts, type_node tn, SymScope topScope) { if (ts is TypeSynonim) { var corrected_type = GetCorrectedType((ts as TypeSynonim).actType, tn, topScope); if (!corrected_type.IsEqual((ts as TypeSynonim).actType)) return corrected_type; return ts; } else if (tn is compiled_type_node) { var ctn = tn as compiled_type_node; if (ctn.compiled_type.IsArray) { if (ctn.rank > 1) return new ArrayScope(GetIntellisenseTypeByType((ctn.element_type as compiled_type_node).compiled_type), new TypeScope[ctn.rank]); return new ArrayScope(GetIntellisenseTypeByType((ctn.element_type as compiled_type_node).compiled_type), null); } if (ctn.compiled_type.GetGenericArguments().Length == 0) return TypeTable.get_compiled_type(ctn.compiled_type); else { List gen_args = new List(); foreach (var gen_tn in ctn.compiled_type.GetGenericArguments()) { gen_args.Add(GetIntellisenseTypeByType(gen_tn)); } return CompiledScope.get_type_instance(ctn.compiled_type.GetGenericTypeDefinition(), gen_args); } } else if (tn is ref_type_node && ts is PointerScope) { var corrected_type = GetCorrectedType((ts as PointerScope).elementType, tn.element_type, topScope); if (!corrected_type.IsEqual((ts as PointerScope).elementType)) return new PointerScope(corrected_type); return ts; } else { if (tn.full_name.IndexOf("$") != -1 && !tn.IsDelegate|| tn.full_name.IndexOf("#") != -1 && tn.full_name.IndexOf("AnonymousType#") == -1) return ts; if (ts is FileScope && tn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.typed_file) return ts; if (ts is FileScope && tn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.binary_file) return ts; var ntr = BuildSyntaxNodeForTypeReference(tn); cur_scope = topScope; ntr.visit(this); if (returned_scope != null && returned_scope is TypeScope) { var correctedType = returned_scope as TypeScope; if (!correctedType.IsTypeStrictEqual(ts)) return correctedType; } else if (returned_scope != null && returned_scope is ProcScope) { var procType = new ProcType(returned_scope as ProcScope); if (!procType.IsEqual(ts)) return procType; } return ts; } } /*private TypeScope CreateTypeScopeBySemanticType(type_node tn) { if (tn is common_generic_instance_type_node) { var ts = new TypeScope(); var gitn = tn as common_generic_instance_type_node; ts.gener foreach (var field in gitn.fields) { ts.AddName(field.name, CreateTypeScopeBySemanticType(field.type)); } } return null; }*/ private void CorrectVariableType(var_definition_node vdn) { location loc = null; if (vdn is namespace_variable) { loc = (vdn as namespace_variable).loc; } else if (vdn is local_variable) { loc = (vdn as local_variable).loc; } else if (vdn is local_block_variable) { loc = (vdn as local_block_variable).loc; } if (loc == null) return; var es = FindScopeByLocation(loc.begin_line_num,loc.begin_column_num) as ElementScope; if (es != null) { es.sc = GetCorrectedType(es.sc as TypeScope, vdn.type, es.topScope); es.MakeDescription(); } } private void CorrectTreeWithSemantic(compilation_unit cu) { var co = new CompilerOptions(); co.SavePCU = false; co.GenerateCode = false; if (!currentUnitLanguage.LanguageIntellisenseSupport.ApplySyntaxTreeConvertersForIntellisense) co.UnitSyntaxTree = cu; co.SourceFileName = cu.source_context.FileName; co.ForIntellisense = true; co.SaveDocumentation = false; //if (compiler == null) compiler = new Compiler(); compiler.CompilerOptions = co; compiler.ClearAfterCompilation = false; compiler.Compile(); foreach (var lv in compiler.CompiledVariables) CorrectVariableType(lv); compiler.ClearAll(/*false*/); } public SymScope FindScopeByLocation(int line, int col) { try { SymScope ss = entry_scope.FindScopeByLocation(line,col); if (ss != null) return ss; if (impl_scope != null) return impl_scope.FindScopeByLocation(line,col); //if (impl_scope != null) return impl_scope.FindScopeByLocation(line,col); } catch { } return null; } private void save_return_value() { saved_returned_scopes.Push(returned_scope); } private void restore_return_value() { returned_scope = saved_returned_scopes.Pop(); } public override void visit(syntax_tree_node _syntax_tree_node) { throw new Exception("The method or operation is not implemented."); } private bool HasVariablesInBlock(statement_list _statement_list) { foreach (statement stmt in _statement_list.subnodes) if (stmt is var_statement) return true; return false; } private bool has_lambdas(expression node) { if (node is function_lambda_definition) return true; else if (node is dot_node) { dot_node dn = node as dot_node; if (has_lambdas(dn.left)) return true; if (has_lambdas(dn.right)) return true; } else if (node is method_call) { method_call mc = node as method_call; if (has_lambdas(mc.dereferencing_value)) return true; if (mc.parameters != null) foreach (expression e in mc.parameters.expressions) { if (has_lambdas(e)) return true; } } else if (node is new_expr) { new_expr ne = node as new_expr; if (ne.params_list != null) foreach (expression e in ne.params_list.expressions) { if (has_lambdas(e)) return true; } } else if (node is tuple_node) { tuple_node tn = node as tuple_node; foreach (expression e in tn.el.expressions) { if (has_lambdas(e)) return true; } } else if (node is PascalABCCompiler.SyntaxTree.question_colon_expression) { PascalABCCompiler.SyntaxTree.question_colon_expression expr = node as PascalABCCompiler.SyntaxTree.question_colon_expression; if (has_lambdas(expr.ret_if_true)) return true; if (has_lambdas(expr.ret_if_false)) return true; } return false; } public override void visit(template_type_name node) { throw new Exception("The method or operation is not implemented."); } public override void visit(statement_list _statement_list) { SymScope tmp = cur_scope; if (HasVariablesInBlock(_statement_list)) { SymScope stmt_scope = new BlockScope(cur_scope); cur_scope.AddName("$block_scope",stmt_scope); stmt_scope.loc = get_location(_statement_list); cur_scope = stmt_scope; } //try { foreach (statement stmt in _statement_list.subnodes) stmt.visit(this); } //catch(Exception e) { } cur_scope = tmp; } public override void visit(expression _expression) { throw new Exception("The method or operation is not implemented."); } public override void visit(assign _assign) { visit_is_patterns(_assign.from); if (pending_is_pattern_vars.Count > 0) { foreach (var_def_statement vds in pending_is_pattern_vars) vds.visit(this); pending_is_pattern_vars.Clear(); } if (_assign.from is function_lambda_definition) { _assign.to.visit(this); TypeScope tmp_awaitedProcType = awaitedProcType; if (returned_scope != null && returned_scope is TypeScope) { if (returned_scope is ProcScope) returned_scope = new ProcType(returned_scope as ProcScope); awaitedProcType = returned_scope as TypeScope; } _assign.from.visit(this); awaitedProcType = tmp_awaitedProcType; } else if (has_lambdas(_assign.from)) _assign.from.visit(this); else if (_assign.to is ident && cur_scope != null && cur_scope.Name.StartsWith("<>lambda") && (_assign.to as ident).name.Equals(currentUnitLanguage.LanguageIntellisenseSupport.ResultVariableName, currentUnitLanguage.CaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase)) { var sc = cur_scope.FindNameOnlyInThisType(currentUnitLanguage.LanguageIntellisenseSupport.ResultVariableName); if (sc is ElementScope) { ElementScope es = sc as ElementScope; if (es.sc is TypeScope && (es.sc as TypeScope).IsDelegate) { _assign.from.visit(this); (cur_scope as ProcScope).return_type = returned_scope as TypeScope; es.sc = returned_scope; es.MakeDescription(); } } } if (_assign.first_assignment_defines_type) { _assign.from.visit(this); var variableScope = (ElementScope)cur_scope.FindName(((ident)_assign.to).name); variableScope.sc = returned_scope; } } public override void visit(bin_expr _bin_expr) { try { _bin_expr.left.visit(this); RetValue left = cnst_val; TypeScope tleft = returned_scope as TypeScope; cnst_val.prim_val = null; _bin_expr.right.visit(this); TypeScope tright = returned_scope as TypeScope; RetValue right = cnst_val; cnst_val.prim_val = null; if (left.prim_val != null && right.prim_val != null) { ev.eval_stack.Push(left); ev.eval_stack.Push(right); switch (_bin_expr.operation_type) { case Operators.Plus: ev.EvalPlus(); break; case Operators.Minus: ev.EvalMinus(); break; case Operators.Multiplication: ev.EvalMult(); break; case Operators.Division: ev.EvalDiv(); break; case Operators.IntegerDivision: ev.EvalIDiv(); break; case Operators.BitwiseAND: ev.EvalAnd(); break; case Operators.BitwiseOR: ev.EvalOr(); break; case Operators.BitwiseXOR: ev.EvalXor(); break; case Operators.BitwiseLeftShift: ev.EvalBitwiseLeft(); break; case Operators.BitwiseRightShift: ev.EvalBitwiseRight(); break; case Operators.Equal: ev.EvalEqual(); break; case Operators.NotEqual: ev.EvalNotEqual(); break; case Operators.Less: ev.EvalLess(); break; case Operators.LessEqual: ev.EvalLessEqual(); break; case Operators.Greater: ev.EvalGreater(); break; case Operators.GreaterEqual: ev.EvalGreaterEqual(); break; case Operators.LogicalAND: ev.EvalAnd(); break; case Operators.LogicalOR: ev.EvalOr(); break; case Operators.ModulusRemainder: ev.EvalRem(); break; default: ev.eval_stack.Clear(); break; } if (ev.eval_stack.Count > 0) { cnst_val = ev.eval_stack.Pop(); returned_scope = TypeTable.get_type(cnst_val.prim_val); } else { cnst_val.prim_val = null; } } else { cnst_val.prim_val = null; } if (tleft != null && tright != null) { RetValue tmp = cnst_val; string name = PascalABCCompiler.TreeConverter.name_reflector.get_name(_bin_expr.operation_type); List lst = tleft.FindOverloadNamesOnlyInType(name); List lst_right = tright.FindOverloadNamesOnlyInType(name); if (lst.Count == 0 && !char.IsLetter(name[0])) lst = tleft.FindOverloadNamesOnlyInType("operator" + name); if (lst_right.Count == 0 && !char.IsLetter(name[0])) lst_right = tright.FindOverloadNamesOnlyInType("operator" + name); if (!char.IsLetter(name[0])) name = "operator" + name; else name = "operator " + name; List meths = entry_scope.GetExtensionMethods(name, tleft); foreach (ProcScope meth in meths) lst.Add(meth); lst.AddRange(lst_right); meths = entry_scope.GetExtensionMethods(name, tright); foreach (ProcScope meth in meths) lst.Add(meth); ProcScope ps = select_method(lst.ToArray(), tleft, tright, null, false, null, _bin_expr.left, _bin_expr.right); if (ps != null) returned_scope = ps.return_type; else { if (_bin_expr.operation_type == Operators.Division) returned_scope = TypeTable.real_type; else returned_scope = tleft; } cnst_val = tmp; } else if (tleft != null) returned_scope = tleft; else returned_scope = tright; } catch (Exception e) { #if DEBUG File.AppendAllText("log.txt", e.Message + Environment.NewLine + e.StackTrace + Environment.NewLine); #endif cnst_val.prim_val = null; ev.eval_stack.Clear(); returned_scope = null; } } public override void visit(un_expr _un_expr) { try { _un_expr.subnode.visit(this); TypeScope tleft = returned_scope as TypeScope; if (cnst_val.prim_val != null) { ev.eval_stack.Push(cnst_val); switch (_un_expr.operation_type) { case Operators.BitwiseNOT: ev.EvalNot(); break; case Operators.LogicalNOT: ev.EvalNot(); returned_scope = entry_scope.FindName(StringConstants.bool_type_name); break; case Operators.Minus: ev.EvalUnmin(); break; } if (ev.eval_stack.Count > 0) { cnst_val = ev.eval_stack.Pop(); returned_scope = TypeTable.get_type(cnst_val.prim_val); } else { cnst_val.prim_val = null; returned_scope = tleft; } } } catch (Exception e) { cnst_val.prim_val = null; ev.eval_stack.Clear(); returned_scope = null; } } public override void visit(token_taginfo node) { } public override void visit(declaration_specificator node) { } public override void visit(const_node _const_node) { throw new Exception("The method or operation is not implemented."); } public override void visit(bool_const _bool_const) { returned_scope = TypeTable.bool_type;//entry_scope.FindName(StringConstants.bool_type_name); cnst_val.prim_val = _bool_const.val; } public override void visit(int32_const _int32_const) { returned_scope = TypeTable.int_type;//entry_scope.FindName(StringConstants.integer_type_name); cnst_val.prim_val = _int32_const.val; } public override void visit(double_const _double_const) { returned_scope = TypeTable.real_type;//entry_scope.FindName(StringConstants.real_type_name); cnst_val.prim_val = _double_const.val; } public override void visit(statement _statement) { throw new Exception("The method or operation is not implemented."); } public override void visit(subprogram_body _subprogram_body) { throw new Exception("The method or operation is not implemented."); } public override void visit(ident _ident) { if (!search_all) { returned_scope = cur_scope.FindName(_ident.name); if (returned_scope == null) { //cnst_val.prim_val = _ident.name; cnst_val.prim_val = null; return; } if (returned_scope is ElementScope) { ElementScope es = returned_scope as ElementScope; cnst_val.prim_val = es.cnst_val; returned_scope = es.sc; if (es.IsIndexedProperty) returned_scope = new IndexedPropertyType(es.sc as TypeScope); return; } else if (returned_scope is ProcScope) { ProcScope ps = returned_scope as ProcScope; if (ps.parameters.Count == 0 || ps.parameters[0].param_kind == parametr_kind.params_parametr || ps.parameters[0].cnst_val != null) { if (ps.return_type != null) returned_scope = ps.return_type; else returned_scope = new ProcType(ps); } else { returned_scopes = cur_scope.FindOverloadNames(_ident.name); returned_scope = returned_scopes.Find(x => x is ProcScope && ((x as ProcScope).parameters.Count == 0 || (x as ProcScope).parameters[0].param_kind == parametr_kind.params_parametr || (x as ProcScope).parameters[0].cnst_val != null)); if (returned_scope == null) { returned_scope = returned_scopes[0]; if (returned_scope is ProcScope && (returned_scope as ProcScope).return_type == null) returned_scope = new ProcType(returned_scope as ProcScope); } else if (returned_scope is ProcScope && (returned_scope as ProcScope).return_type != null) returned_scope = (returned_scope as ProcScope).return_type; else if (returned_scopes.Count > 0 && returned_scopes[0] is ProcScope && (returned_scopes[0] as ProcScope).return_type == null) returned_scope = new ProcType(returned_scopes[0] as ProcScope); } } else if (returned_scope is TypeScope) is_type = true; } else { returned_scopes = cur_scope.FindOverloadNames(_ident.name); for (int i = 0; i < returned_scopes.Count; i++) { if (returned_scopes[i] is ElementScope) { cnst_val.prim_val = (returned_scopes[i] as ElementScope).cnst_val; returned_scope = (returned_scopes[i] as ElementScope).sc; returned_scopes[i] = returned_scope; return; } else if (returned_scopes[i] is TypeScope) { is_type = true; } } search_all = false; } //cnst_val.prim_val = _ident.name; } public override void visit(addressed_value _addressed_value) { throw new Exception("The method or operation is not implemented."); } public override void visit(type_definition _type_definition) { throw new Exception("The method or operation is not implemented."); } public override void visit(named_type_reference _named_type_reference) { //throw new Exception("The method or operation is not implemented."); returned_scope = cur_scope; string suffix = ""; SymScope tmp_scope = returned_scope; for (int i = 0; i < _named_type_reference.names.Count; i++) { if (i == _named_type_reference.names.Count - 1 && converted_template_type != null) suffix = "`" + converted_template_type.params_list.params_list.Count; if (i > 0) returned_scope = returned_scope.FindNameOnlyInType(_named_type_reference.names[i].name+suffix); else returned_scope = returned_scope.FindName(_named_type_reference.names[i].name+suffix); if (returned_scope == null) { if (suffix != "") { returned_scope = tmp_scope; if (i > 0) returned_scope = returned_scope.FindNameOnlyInType(_named_type_reference.names[i].name); else returned_scope = returned_scope.FindName(_named_type_reference.names[i].name); if (returned_scope == null) { break; } } else break; } tmp_scope = returned_scope; } if (returned_scope == null || !(returned_scope is TypeScope)) returned_scope = new UnknownScope(new SymInfo(_named_type_reference.names[_named_type_reference.names.Count - 1].name, SymbolKind.Type, _named_type_reference.names[_named_type_reference.names.Count - 1].name)); } public override void visit(variable_definitions _variable_definitions) { bool is_event = false; foreach (var_def_statement vds in _variable_definitions.var_definitions) { if (vds.is_event && !is_event) is_event = true; else if (is_event) vds.is_event = true; vds.visit(this); } } public override void visit(ident_list _ident_list) { throw new Exception("The method or operation is not implemented."); } public System.Collections.Hashtable vars = new System.Collections.Hashtable(); private TypeScope awaitedProcType; public override void visit(var_def_statement _var_def_statement) { try { returned_scope = null; if (_var_def_statement.vars_type != null) _var_def_statement.vars_type.visit(this); if (_var_def_statement.vars_type == null && _var_def_statement.inital_value != null || _var_def_statement.inital_value is function_lambda_definition) { SymScope tmp_scope = returned_scope; TypeScope tmp_awaitedProcType = awaitedProcType; if (_var_def_statement.inital_value is function_lambda_definition) { if (tmp_scope is ProcScope) tmp_scope = new ProcType(tmp_scope as ProcScope); awaitedProcType = tmp_scope as TypeScope; } _var_def_statement.inital_value.visit(this); awaitedProcType = tmp_awaitedProcType; if (tmp_scope != null && _var_def_statement.inital_value is function_lambda_definition) returned_scope = tmp_scope; } // if (si == null) dn = compiled_type_node.get_type_node(PascalABCCompiler.NetHelper.NetHelper.FindType((_var_def_statement.vars_type as named_type_reference).names[0].name,unl)); //if (returned_scope == null) return; if (returned_scope is ProcScope) { returned_scope = new ProcType(returned_scope as ProcScope); } if (_var_def_statement.vars != null) foreach (ident s in _var_def_statement.vars.idents) { SymInfo si = new SymInfo(s.name, SymbolKind.Variable, s.name); if (cur_scope is TypeScope) si.kind = SymbolKind.Field; if (_var_def_statement.is_event) si.kind = SymbolKind.Event; if (returned_scope == null && false) returned_scope = new UnknownScope(new SymInfo("",SymbolKind.Class, "")); ElementScope es = new ElementScope(si, returned_scope, cur_scope); if (add_doc_from_text && this.converter.controller.docs != null && this.converter.controller.docs.ContainsKey(_var_def_statement)) es.AddDocumentation(this.converter.controller.docs[_var_def_statement]); es.acc_mod = cur_access_mod; es.is_static = _var_def_statement.var_attr == definition_attribute.Static; es.si.acc_mod = cur_access_mod; es.loc = get_location(s); cur_scope.AddName(s.name, es); es.declaringUnit = cur_scope; } } catch (Exception e) { #if DEBUG File.AppendAllText("log.txt", e.Message + Environment.NewLine + e.StackTrace + Environment.NewLine); #endif } } public string doc_name; public location get_location(SourceContext sc) { if (sc == null) { return null; } return new location(sc.begin_position.line_num, sc.begin_position.column_num, sc.end_position.line_num, sc.end_position.column_num, doc_name); } public location get_location(syntax_tree_node tn) { if (tn.source_context==null) { return null; } return new location(tn.source_context.begin_position.line_num,tn.source_context.begin_position.column_num, tn.source_context.end_position.line_num,tn.source_context.end_position.column_num,doc_name); } public override void visit(declaration _declaration) { throw new Exception("The method or operation is not implemented."); } public override void visit(declarations _declarations) { //throw new Exception("The method or operation is not implemented."); foreach (declaration decl in _declarations.defs) decl.visit(this); } public override void visit(program_tree _program_tree) { } public override void visit(program_name _program_name) { throw new Exception("The method or operation is not implemented."); } public override void visit(string_const _string_const) { returned_scope = TypeTable.string_type;//entry_scope.FindName(StringConstants.string_type_name); //cnst_val.prim_val = "'"+_string_const.Value+"'"; cnst_val.prim_val = currentUnitLanguage.LanguageIntellisenseSupport.GetStringForString(_string_const.Value); } public override void visit(expression_list _expression_list) { throw new Exception("The method or operation is not implemented."); } public override void visit(dereference _dereference) { throw new Exception("The method or operation is not implemented."); } public override void visit(roof_dereference _roof_dereference) { //throw new Exception("The method or operation is not implemented."); _roof_dereference.dereferencing_value.visit(this); TypeScope ts = returned_scope as TypeScope; while (ts is TypeSynonim) ts = (ts as TypeSynonim).actType; if (ts is PointerScope) returned_scope = (ts as PointerScope).ref_type; else returned_scope = null; } public override void visit(indexer _indexer) { //throw new Exception("The method or operation is not implemented."); _indexer.dereferencing_value.visit(this); if (returned_scope != null && returned_scope is TypeScope) { TypeScope ts = returned_scope as TypeScope; if (ts is IndexedPropertyType) returned_scope = (ts as IndexedPropertyType).propertyType; else if (ts.GetFullName() != null && (ts.GetFullName().IndexOf("System.Tuple") == 0 || ts.original_type != null && ts.original_type.GetFullName() != null && ts.original_type.GetFullName().IndexOf("(T1,") == 0)) { if (_indexer.indexes.expressions[0] is int32_const) { if ((_indexer.indexes.expressions[0] as int32_const).val >= 0) { dot_node dn = new dot_node(_indexer.dereferencing_value, new ident("Item" + ((_indexer.indexes.expressions[0] as int32_const).val + 1))); dn.visit(this); } else returned_scope = null; } else returned_scope = null; } else if (returned_scope.GetElementType() != null) returned_scope = returned_scope.GetElementType(); } } public override void visit(PascalABCCompiler.SyntaxTree.for_node _for_node) { //throw new Exception("The method or operation is not implemented."); SymScope tmp = cur_scope; //if (_for_node.type_name != null) { SymScope stmt_scope = new BlockScope(cur_scope); cur_scope.AddName("$block_scope", stmt_scope); stmt_scope.loc = get_location(_for_node); returned_scope = null; if (_for_node.type_name != null) _for_node.type_name.visit(this); if (returned_scope != null) { cur_scope = stmt_scope; ElementScope es = new ElementScope(new SymInfo(_for_node.loop_variable.name, SymbolKind.Variable, _for_node.loop_variable.name), returned_scope, cur_scope); stmt_scope.AddName(_for_node.loop_variable.name, es); es.loc = get_location(_for_node.loop_variable); returned_scope = null; } else { _for_node.initial_value.visit(this); if (returned_scope != null) { cur_scope = stmt_scope; if (_for_node.create_loop_variable) { ElementScope es = new ElementScope(new SymInfo(_for_node.loop_variable.name, SymbolKind.Variable, _for_node.loop_variable.name), returned_scope, cur_scope); stmt_scope.AddName(_for_node.loop_variable.name, es); es.loc = get_location(_for_node.loop_variable); } returned_scope = null; } } } if (_for_node.statements != null) _for_node.statements.visit(this); cur_scope = tmp; } public override void visit(PascalABCCompiler.SyntaxTree.repeat_node _repeat_node) { if (_repeat_node.statements != null) _repeat_node.statements.visit(this); } public override void visit(PascalABCCompiler.SyntaxTree.while_node _while_node) { if (_while_node.statements != null) _while_node.statements.visit(this); } public override void visit(is_pattern_expr _is_pattern_expr) { _is_pattern_expr.right.visit(this); } public override void visit(deconstructor_pattern _deconstructor_pattern) { _deconstructor_pattern.type.visit(this); if (_deconstructor_pattern.parameters.Count == 1) { var pdp = _deconstructor_pattern.parameters[0]; if (pdp is var_deconstructor_parameter) { var_deconstructor_parameter vdp = pdp as var_deconstructor_parameter; pending_is_pattern_vars.Add(new var_def_statement(vdp.identifier, _deconstructor_pattern.type, _deconstructor_pattern.source_context)); } } else { foreach (pattern_parameter pdp in _deconstructor_pattern.parameters) { if (pdp is var_deconstructor_parameter) { var_deconstructor_parameter vdp = pdp as var_deconstructor_parameter; SymScope ss = returned_scope.FindName(vdp.identifier.name); if (ss is ElementScope) { TypeScope ts = (ss as ElementScope).sc as TypeScope; pending_is_pattern_vars.Add(new var_def_statement(vdp.identifier, new named_type_reference(new ident(ts.si.name)), _deconstructor_pattern.source_context)); } } } } } public override void visit(match_with _match_with) { if (_match_with.case_list != null) { foreach (pattern_case pc in _match_with.case_list.elements) pc.visit(this); } } public override void visit(pattern_case _pattern_case) { _pattern_case.pattern.visit(this); statement stmt = merge_with_is_variables(_pattern_case.case_action); stmt.visit(this); } public void visit_is_patterns(expression expr) { if (expr is bin_expr) { bin_expr bexpr = expr as bin_expr; visit_is_patterns(bexpr.left); visit_is_patterns(bexpr.right); } else if (expr is is_pattern_expr) expr.visit(this); } public statement merge_with_is_variables(statement stmt) { if (pending_is_pattern_vars.Count > 0) { if (stmt is statement_list) { foreach (var_def_statement vds in pending_is_pattern_vars) (stmt as statement_list).Insert(0, new var_statement(vds, vds.source_context)); } else { statement_list slist = new statement_list(); slist.source_context = stmt.source_context; foreach (var_def_statement vds in pending_is_pattern_vars) { slist.Insert(0, new var_statement(vds, vds.source_context)); if (slist.source_context == null) slist.source_context = vds.source_context; } slist.Add(stmt); stmt = slist; } pending_is_pattern_vars.Clear(); } return stmt; } public override void visit(PascalABCCompiler.SyntaxTree.if_node _if_node) { visit_is_patterns(_if_node.condition); statement then_stmt = _if_node.then_body; if (pending_is_pattern_vars.Count > 0 && then_stmt != null) { statement_list slist = new statement_list(); if (_if_node.then_body.source_context != null) slist.source_context = new SourceContext(_if_node.source_context.LeftSourceContext, _if_node.then_body.source_context.RightSourceContext); else if (_if_node.else_body != null && _if_node.else_body.source_context != null) slist.source_context = new SourceContext(_if_node.source_context.LeftSourceContext, _if_node.else_body.source_context.LeftSourceContext); else slist.source_context = _if_node.source_context; slist.Add(then_stmt); then_stmt = merge_with_is_variables(slist); } if (then_stmt != null) then_stmt.visit(this); if (_if_node.else_body != null) _if_node.else_body.visit(this); } public override void visit(ref_type _ref_type) { //throw new Exception("The method or operation is not implemented."); _ref_type.pointed_to.visit(this); if (returned_scope != null && returned_scope is TypeScope) { returned_scope = new PointerScope(returned_scope as TypeScope); returned_scope.loc = get_location(_ref_type); } else { returned_scope = new PointerScope(); returned_scope.loc = get_location(_ref_type); } returned_scope.topScope = cur_scope; } public override void visit(diapason _diapason) { object left = null, right = null; try { _diapason.left.visit(this); left = cnst_val.prim_val; cnst_val.prim_val = null; _diapason.right.visit(this); right = cnst_val.prim_val; } catch (Exception e) { } if (left != null && right != null) { returned_scope = new DiapasonScope(left, right); returned_scope.loc = get_location(_diapason); returned_scope.topScope = cur_scope; } else returned_scope = null; } public override void visit(indexers_types _indexers_types) { throw new Exception("The method or operation is not implemented."); } public override void visit(array_type _array_type) { //throw new Exception("The method or operation is not implemented."); _array_type.elements_type.visit(this); if (returned_scope == null) return; SymScope of_type = returned_scope; List indexes = new List(); if (_array_type.indexers != null) { foreach (type_definition td in _array_type.indexers.indexers) { if (td != null) { td.visit(this); if (returned_scope != null) indexes.Add((TypeScope)returned_scope); else { returned_scope = null; return; } } else indexes.Add(null); } } else indexes.Add((TypeScope)entry_scope.FindName(StringConstants.integer_type_name)); TypeScope ts = of_type as TypeScope; if (of_type is ProcScope) ts = new ProcType(of_type as ProcScope); returned_scope = new ArrayScope(ts as TypeScope,indexes.ToArray()); returned_scope.topScope = cur_scope; if (_array_type.indexers == null) (returned_scope as ArrayScope).is_dynamic_arr = true; returned_scope.loc = get_location(_array_type); } public override void visit(label_definitions _label_definitions) { //throw new Exception("The method or operation is not implemented."); } public override void visit(procedure_attribute _procedure_attribute) { throw new Exception("The method or operation is not implemented."); } public override void visit(typed_parameters _typed_parametres) { throw new Exception("The method or operation is not implemented."); } public override void visit(formal_parameters _formal_parametres) { throw new Exception("The method or operation is not implemented."); } public override void visit(procedure_attributes_list _procedure_attributes_list) { throw new Exception("The method or operation is not implemented."); } private bool IsForward(procedure_header hdr) { if (hdr.proc_attributes == null) return false; for (int i=0; i lst = new List(); if (prms != null) { foreach (typed_parameters pars in prms.params_list) { pars.vars_type.visit(this); if (returned_scope != null) { foreach (ident id in pars.idents.idents) { if (returned_scope is ProcScope) returned_scope = new ProcType(returned_scope as ProcScope); ElementScope si = new ElementScope(new SymInfo(id.name, SymbolKind.Parameter, id.name), returned_scope, ps); si.loc = get_location(id); si.param_kind = pars.param_kind; if (pars.inital_value != null) { cnst_val.prim_val = null; if (pars.inital_value is nil_const) si.cnst_val = "nil"; else { pars.inital_value.visit(this); if (cnst_val.prim_val != null) si.cnst_val = cnst_val.prim_val; else si.cnst_val = pars.inital_value.ToString(); } } lst.Add(si); } } } while (ps != null) { if (ps.parameters != null) { if (ps.parameters.Count == lst.Count) { bool eq = true; for (int i = 0; i < lst.Count; i++) { TypeScope left = ps.parameters[i].sc as TypeScope; TypeScope right = lst[i].sc as TypeScope; if (!left.IsEqual(right) || ps.parameters[i].param_kind != lst[i].param_kind) { eq = false; break; } } if (eq) { if (return_type == null) return ps; if (ps.return_type != null && return_type != null) { if ((ps.return_type as TypeScope).IsEqual(return_type)) return ps; } } } } ps = ps.nextProc; } } else { while (ps != null) { if (ps.is_constructor && ps.is_static != static_constructor) { ps = ps.nextProc; continue; } else if (ps.is_constructor && ps.is_static && static_constructor) { return ps; } if (ps.parameters == null || ps.parameters.Count == 0) { if (function && ps.return_type != null && return_type == null) return ps; if (ps.return_type == null && return_type == null) return ps; if (ps.return_type != null && return_type != null) { if ((ps.return_type as TypeScope).IsEqual(return_type)) return ps; } else return null; } ps = ps.nextProc; } } returned_scope = tmp; return ps; } public override void visit(procedure_header _procedure_header) { //throw new Exception("The method or operation is not implemented."); SymScope topScope; ProcScope ps = null; ElementScope[] predef_params = null; bool not_def = false; ProcRealization pr = null; bool is_realization = false; location loc = get_location(_procedure_header); if (_procedure_header.name != null) { _procedure_header.name.visit(this); if (_procedure_header.name.class_name != null) { topScope = null; if (_procedure_header.name.ln != null && _procedure_header.name.ln.Count > 0) { SymScope tmp_scope = cur_scope; for (int i = 0; i < _procedure_header.name.ln.Count; i++) { tmp_scope = tmp_scope.FindName(_procedure_header.name.ln[i].name); if (tmp_scope == null) break; } topScope = tmp_scope; } else topScope = cur_scope.FindName(_procedure_header.name.class_name.name); if (topScope != null) { ps = topScope.FindNameOnlyInThisType(meth_name) as ProcScope; if (ps != null && ps is CompiledMethodScope) ps = null; if (ps == null) { ps = new ProcScope(meth_name, topScope); ps.head_loc = loc; bool ext = false; if (topScope is CompiledScope || topScope is ArrayScope || topScope is TypeSynonim /*&& ((topScope as TypeSynonim).actType is CompiledScope || (topScope as TypeSynonim).actType is ArrayScope || (topScope as TypeSynonim).actType is DiapasonScope)*/) ext = true; else if (!(topScope is TypeSynonim) && !(topScope is PointerScope) && !(topScope is SetScope) && !(topScope is FileScope)) ext = true; if (ext) { not_def = true; ps.is_extension = true; ps.AddName("self", new ElementScope(new SymInfo("self", SymbolKind.Parameter, "self"), topScope, cur_scope)); ps.declaringType = topScope as TypeScope; TypeScope ts = topScope as TypeScope; if (topScope is TypeSynonim) ts = (ts as TypeSynonim).actType; this.entry_scope.AddExtensionMethod(meth_name, ps, ts); ts.AddExtensionMethod(meth_name, ps, ts); } } //while (ps != null && ps.already_defined) ps = ps.nextProc; else { if (ps.parameters != null) predef_params = ps.parameters.ToArray(); ps = select_function_definition(ps, _procedure_header.parameters, null, topScope as TypeScope); } if (ps == null) { ps = new ProcScope(meth_name, cur_scope); ps.head_loc = loc; } if (ps.parameters.Count != 0 && _procedure_header.parameters != null && is_proc_realization) { predef_params = ps.parameters.ToArray(); ps.parameters.Clear(); ps.already_defined = true; } if (impl_scope == null) { pr = new ProcRealization(ps, cur_scope); pr.already_defined = true; pr.loc = cur_loc; pr.head_loc = loc; if (topScope.ElemKind == SymbolKind.Interface) pr.si.not_include = true; is_realization = true; entry_scope.AddName("$method", pr); } else { pr = new ProcRealization(ps, impl_scope); pr.already_defined = true; pr.loc = cur_loc; is_realization = true; pr.head_loc = loc; impl_scope.AddName("$method", pr); } } else { ps = new ProcScope(meth_name, cur_scope); ps.head_loc = loc; } } else { ps = new ProcScope(meth_name, cur_scope); if (_procedure_header.proc_attributes != null && has_extensionmethod_attr(_procedure_header.proc_attributes.proc_attributes) && _procedure_header.parameters.params_list.Count > 0) { ps.is_extension = true; if (_procedure_header.parameters.params_list[0].vars_type is enum_type_definition) { template_type_reference tuple = new template_type_reference(); tuple.name = new named_type_reference(new ident_list(new ident("System"), new ident("Tuple")).idents); template_param_list tpl = new template_param_list(); enum_type_definition etd = _procedure_header.parameters.params_list[0].vars_type as enum_type_definition; foreach (enumerator en in etd.enumerators.enumerators) { tpl.Add(en.name); } tuple.params_list = tpl; tuple.visit(this); } else _procedure_header.parameters.params_list[0].vars_type.visit(this); topScope = returned_scope; ps.declaringType = topScope as TypeScope; TypeScope ts = topScope as TypeScope; if (topScope is TypeSynonim) ts = (ts as TypeSynonim).actType; if (ts.original_type != null && ts.instances != null) { bool pure_instance = true; foreach (TypeScope gen_arg in ts.instances) { if (!(gen_arg is TemplateParameterScope)) pure_instance = false; } if (pure_instance) ts = ts.original_type; } this.entry_scope.AddExtensionMethod(meth_name, ps, ts); topScope.AddExtensionMethod(meth_name, ps, ts); pr = new ProcRealization(ps, cur_scope); pr.already_defined = true; pr.loc = cur_loc; pr.head_loc = loc; if (impl_scope != null) impl_scope.AddName("$method", pr); else this.entry_scope.AddName("$method", pr); } ps.head_loc = loc; if (!ps.is_extension) { if (IsForward(_procedure_header)) { cur_scope.AddName(meth_name, ps); ps.is_forward = true; } else { bool found_in_top = false; SymScope ss = null; if (cur_scope is ImplementationUnitScope) { ss = (cur_scope as ImplementationUnitScope).topScope.FindNameOnlyInThisType(meth_name); if (ss != null && ss is ProcScope) { ps = select_function_definition(ss as ProcScope, _procedure_header.parameters, null, null); if (ps == null && _procedure_header.parameters == null) ps = ss as ProcScope; if (ps == null) { ps = new ProcScope(meth_name, cur_scope); ps.head_loc = loc; } //ps = ss as ProcScope; if (ps.parameters.Count != 0 && _procedure_header.parameters != null) { predef_params = ps.parameters.ToArray(); ps.parameters.Clear(); ps.already_defined = true; } pr = new ProcRealization(ps, cur_scope); pr.already_defined = true; pr.loc = cur_loc; pr.head_loc = loc; is_realization = true; cur_scope.AddName("$method", pr); found_in_top = true; } } if (!found_in_top) //ne nashli opisanie v interface chasti modilja { //ss = cur_scope.FindNameOnlyInType(meth_name); ss = cur_scope.FindName(meth_name); if (ss != null && ss is ProcScope) { if ((ss as ProcScope).is_forward && ss == select_function_definition(ss as ProcScope, _procedure_header.parameters, null, null)) { //if ((ss as ProcScope).parameters.Count != 0 && _procedure_header.parameters != null) (ss as ProcScope).parameters.Clear(); pr = new ProcRealization(ss as ProcScope, cur_scope); pr.already_defined = true; pr.loc = cur_loc; cur_scope.AddName("$method", pr); returned_scope = pr; pr.head_loc = loc; return; } else { ps = new ProcScope(meth_name, cur_scope); ps.head_loc = loc; if (ps.topScope == ss.topScope) { while ((ss as ProcScope).nextProc != null && (ss as ProcScope).nextProc.topScope == ps.topScope) ss = (ss as ProcScope).nextProc; ProcScope tmp_ps = (ss as ProcScope).nextProc; (ss as ProcScope).nextProc = ps; ps.nextProc = tmp_ps; cur_scope.AddName(meth_name, ps); ps.si.name = meth_name; } else { ps.nextProc = ss as ProcScope; cur_scope.AddName(meth_name, ps); } //ps = select_function_definition(ss as ProcScope,_procedure_header.parameters); } } else { cur_scope.AddName(meth_name, ps); } } } } } } else { ps = new ProcScope("", cur_scope); ps.head_loc = loc; } if ((!is_realization || not_def) && ps.loc == null) ps.loc = cur_loc; //ps.head_loc = loc; ps.declaringUnit = entry_scope; if (_procedure_header.template_args != null && !ps.IsGeneric()) { Dictionary> where_types = new Dictionary>(); if (_procedure_header.where_defs != null) { foreach (where_definition wd in _procedure_header.where_defs.defs) { for (int i = 0; i < wd.names.idents.Count; i++) { string name = wd.names.idents[i].name; for (int j = 0; j < wd.types.defs.Count; j++) { wd.types.defs[j].visit(this); if (!where_types.ContainsKey(name)) where_types[name] = new List(); where_types[name].Add(returned_scope as TypeScope); } } } } foreach (ident s in _procedure_header.template_args.idents) { ps.AddTemplateParameter(s.name); List where_ts_list = null; where_types.TryGetValue(s.name, out where_ts_list); TypeScope base_ts = TypeTable.obj_type; if (where_ts_list != null) foreach (TypeScope ts in where_ts_list) { TypeScope where_ts = ts; if (where_ts == null) where_ts = TypeTable.obj_type; base_ts = new TypeScope(where_ts.si.kind, where_ts.topScope, base_ts); base_ts.AddImplementedInterface(where_ts); } TemplateParameterScope tps = new TemplateParameterScope(s.name, base_ts, ps); tps.loc = get_location(s); ps.AddName(s.name, tps); } } SetAttributes(ps, _procedure_header.proc_attributes); ps.is_static = _procedure_header.class_keyword; if (add_doc_from_text && this.converter.controller.docs != null && this.converter.controller.docs.ContainsKey(_procedure_header)) ps.AddDocumentation(this.converter.controller.docs[_procedure_header]); if (is_proc_realization) ps.already_defined = true; else { ps.loc = loc; } if (_procedure_header.name == null || _procedure_header.name.class_name == null) { ps.acc_mod = cur_access_mod; ps.si.acc_mod = cur_access_mod; } SymScope tmp = cur_scope; cur_scope = ps; if (_procedure_header.parameters != null) add_parameters(ps, _procedure_header.parameters, predef_params); cur_scope = tmp; if (cur_scope is TypeScope && !ps.is_static) ps.AddName("self", new ElementScope(new SymInfo("self", SymbolKind.Parameter, "self"), cur_scope, ps)); //cur_scope = ps; returned_scope = ps; ps.Complete(); if (pr != null && not_def) pr.Complete(); } bool has_extensionmethod_attr(List attrs) { foreach (procedure_attribute attr in attrs) { if (attr.attribute_type == PascalABCCompiler.SyntaxTree.proc_attribute.attr_extension) { return true; } } return false; } public override void visit(function_header _function_header) { SymScope topScope; ProcScope ps = null; ElementScope[] predef_params = null; bool is_realization = false; TypeScope return_type = null; bool not_def = false; ProcRealization pr = null; location loc = get_location(_function_header); returned_scope = null; if (_function_header.return_type != null && !(_function_header.return_type is enum_type_definition && _function_header.template_args != null && _function_header.template_args.Count > 0)) _function_header.return_type.visit(this); if (returned_scope != null) { if (returned_scope is ProcScope) returned_scope = new ProcType(returned_scope as ProcScope); return_type = returned_scope as TypeScope; } if (_function_header.name != null) { _function_header.name.visit(this); if (_function_header.name.class_name != null) { topScope = null; if (_function_header.name.ln != null && _function_header.name.ln.Count > 0) { SymScope tmp_scope = cur_scope; for (int i = 0; i < _function_header.name.ln.Count; i++) { tmp_scope = tmp_scope.FindName(_function_header.name.ln[i].name); if (tmp_scope == null) break; } topScope = tmp_scope; } else topScope = cur_scope.FindName(_function_header.name.class_name.name); if (topScope != null) { ps = topScope.FindNameOnlyInThisType(meth_name) as ProcScope; if (ps != null && ps is CompiledMethodScope) ps = null; if (ps == null) { ps = new ProcScope(meth_name, topScope); ps.head_loc = loc; bool ext = false; if (topScope is CompiledScope || topScope is ArrayScope || topScope is TypeSynonim /*&& ((topScope as TypeSynonim).actType is CompiledScope || (topScope as TypeSynonim).actType is ArrayScope || (topScope as TypeSynonim).actType is DiapasonScope)*/) ext = true; else if (!(topScope is TypeSynonim) && !(topScope is PointerScope) && !(topScope is SetScope) && !(topScope is FileScope)) ext = true; if (ext) { not_def = true; ps.AddName("self", new ElementScope(new SymInfo("self", SymbolKind.Parameter, "self"), topScope, cur_scope)); ps.declaringType = topScope as TypeScope; ps.is_extension = true; TypeScope ts = topScope as TypeScope; if (topScope is TypeSynonim) ts = (ts as TypeSynonim).actType; this.entry_scope.AddExtensionMethod(meth_name, ps, ts); ts.AddExtensionMethod(meth_name, ps, ts); } } else { ps = select_function_definition(ps, _function_header.parameters, return_type, topScope as TypeScope, true); } //while (ps != null && ps.already_defined) ps = ps.nextProc; if (ps == null) { ps = new ProcScope(meth_name, cur_scope); ps.head_loc = loc; } if (ps.parameters.Count != 0 && _function_header.parameters != null && is_proc_realization) { predef_params = ps.parameters.ToArray(); ps.parameters.Clear(); ps.already_defined = true; } if (impl_scope == null) { pr = new ProcRealization(ps, cur_scope); pr.already_defined = true; pr.loc = cur_loc; is_realization = true; pr.head_loc = loc; entry_scope.AddName("$method", pr); } else { pr = new ProcRealization(ps, impl_scope); pr.already_defined = true; pr.loc = cur_loc; pr.head_loc = loc; is_realization = true; impl_scope.AddName("$method", pr); } } else { ps = new ProcScope(meth_name, cur_scope); ps.head_loc = loc; } } else { ps = new ProcScope(meth_name, cur_scope); ps.head_loc = loc; if (_function_header.proc_attributes != null && has_extensionmethod_attr(_function_header.proc_attributes.proc_attributes) && _function_header.parameters.params_list.Count > 0) { ps.is_extension = true; if (_function_header.parameters.params_list[0].vars_type is enum_type_definition) { template_type_reference tuple = new template_type_reference(); tuple.name = new named_type_reference(new ident_list(new ident("System"), new ident("Tuple")).idents); template_param_list tpl = new template_param_list(); enum_type_definition etd = _function_header.parameters.params_list[0].vars_type as enum_type_definition; foreach (enumerator en in etd.enumerators.enumerators) { tpl.Add(en.name); } tuple.params_list = tpl; tuple.visit(this); } else _function_header.parameters.params_list[0].vars_type.visit(this); topScope = returned_scope; if (topScope is ProcScope) topScope = new ProcType(topScope as ProcScope); ps.declaringType = topScope as TypeScope; TypeScope ts = topScope as TypeScope; if (topScope is TypeSynonim) ts = (ts as TypeSynonim).actType; if (ts.original_type != null && ts.instances != null) { bool pure_instance = true; foreach (TypeScope gen_arg in ts.instances) { if (!(gen_arg is TemplateParameterScope) && !(gen_arg is UnknownScope)) pure_instance = false; } if (pure_instance) ts = ts.original_type; } this.entry_scope.AddExtensionMethod(meth_name, ps, ts); topScope.AddExtensionMethod(meth_name, ps, ts); /*if (topScope is TemplateParameterScope || topScope is UnknownScope) TypeTable.obj_type.AddExtensionMethod(meth_name, ps, ts);*/ pr = new ProcRealization(ps, cur_scope); pr.already_defined = true; pr.loc = cur_loc; pr.head_loc = loc; if (impl_scope != null) impl_scope.AddName("$method", pr); else this.entry_scope.AddName("$method", pr); } if (!ps.is_extension) { if (IsForward(_function_header)) { cur_scope.AddName(meth_name, ps); ps.is_forward = true; } else { bool found_in_top = false; SymScope ss = null; if (cur_scope is ImplementationUnitScope) { ss = (cur_scope as ImplementationUnitScope).topScope.FindNameOnlyInThisType(meth_name); if (ss != null && ss is ProcScope) { //while ((ss as ProcScope).already_defined && (ss as ProcScope).nextProc != null) ss = (ss as ProcScope).nextProc; //ps = ss as ProcScope; if (ps.parameters != null) predef_params = ps.parameters.ToArray(); ps = select_function_definition(ss as ProcScope, _function_header.parameters, return_type, null, true); if (ps == null && _function_header.parameters == null && _function_header.return_type == null) ps = ss as ProcScope; if (ps == null) { ps = new ProcScope(meth_name, cur_scope); ps.head_loc = loc; } if (ps.parameters.Count != 0 && _function_header.parameters != null) { ps.parameters.Clear(); ps.already_defined = true; } pr = new ProcRealization(ps, cur_scope); pr.already_defined = true; pr.loc = cur_loc; pr.head_loc = loc; is_realization = true; cur_scope.AddName("$method", pr); found_in_top = true; } } if (!found_in_top) { //ss = cur_scope.FindNameOnlyInType(meth_name); ss = cur_scope.FindName(meth_name); if (ss != null && ss is ProcScope) { if ((ss as ProcScope).is_forward && ss == select_function_definition(ss as ProcScope, _function_header.parameters, (ss as ProcScope).return_type, null, true)) { //if ((ss as ProcScope).parameters.Count != 0 && _function_header.parameters != null) (ss as ProcScope).parameters.Clear(); pr = new ProcRealization(ss as ProcScope, cur_scope); pr.already_defined = true; pr.loc = cur_loc; cur_scope.AddName("$method", pr); pr.head_loc = loc; returned_scope = pr; return; } else { ps = new ProcScope(meth_name, cur_scope); ps.head_loc = loc; if (ps.topScope == ss.topScope) { while ((ss as ProcScope).nextProc != null && (ss as ProcScope).nextProc.topScope == ps.topScope) ss = (ss as ProcScope).nextProc; ProcScope tmp_ps = (ss as ProcScope).nextProc; (ss as ProcScope).nextProc = ps; ps.nextProc = tmp_ps; cur_scope.AddName(meth_name, ps); ps.si.name = meth_name; } else { ps.nextProc = ss as ProcScope; cur_scope.AddName(meth_name, ps); } } } else { cur_scope.AddName(meth_name, ps); } } } } } } else { ps = new ProcScope("", cur_scope); ps.head_loc = loc; } if ((!is_realization || not_def) && ps.loc == null) ps.loc = cur_loc; //ps.head_loc = loc; ps.declaringUnit = entry_scope; SymScope tmp = cur_scope; if (_function_header.template_args != null && !ps.IsGeneric()) { Dictionary> where_types = new Dictionary>(); if (_function_header.where_defs != null) { foreach (where_definition wd in _function_header.where_defs.defs) { for (int i = 0; i < wd.names.idents.Count; i++) { string name = wd.names.idents[i].name; for (int j = 0; j < wd.types.defs.Count; j++) { wd.types.defs[j].visit(this); if (!where_types.ContainsKey(name)) where_types[name] = new List(); where_types[name].Add(returned_scope as TypeScope); } } } } foreach (ident s in _function_header.template_args.idents) { ps.AddTemplateParameter(s.name); List where_ts_list = null; where_types.TryGetValue(s.name, out where_ts_list); TypeScope base_ts = TypeTable.obj_type; if (where_ts_list != null) foreach (TypeScope ts in where_ts_list) { TypeScope where_ts = ts; if (where_ts == null) where_ts = TypeTable.obj_type; base_ts = new TypeScope(where_ts.si.kind, where_ts.topScope, base_ts); base_ts.AddImplementedInterface(where_ts); } TemplateParameterScope tps = new TemplateParameterScope(s.name, base_ts, ps); tps.loc = get_location(s); ps.AddName(s.name, tps); } if (ps.return_type == null) { cur_scope = ps; if (_function_header.return_type != null) _function_header.return_type.visit(this); return_type = returned_scope as TypeScope; cur_scope = tmp; } } SetAttributes(ps, _function_header.proc_attributes); ps.is_static = _function_header.class_keyword; if (add_doc_from_text && this.converter.controller.docs != null && this.converter.controller.docs.ContainsKey(_function_header)) ps.AddDocumentation(this.converter.controller.docs[_function_header]); if (is_proc_realization) { ps.already_defined = true; if (ps.loc == null) ps.loc = loc; } else { ps.loc = loc; } if (_function_header.name == null || _function_header.name.class_name == null) { ps.acc_mod = cur_access_mod; ps.si.acc_mod = cur_access_mod; } cur_scope = ps; if (_function_header.parameters != null) add_parameters(ps, _function_header.parameters, predef_params); cur_scope = tmp; if (ps.procRealization == null || ps.return_type == null) ps.return_type = return_type; //cur_scope = ps; if (cur_scope is TypeScope && !ps.is_static) ps.AddName("self", new ElementScope(new SymInfo("self", SymbolKind.Parameter, "self"), cur_scope, ps)); returned_scope = ps; var resultName = currentUnitLanguage.LanguageIntellisenseSupport.ResultVariableName; if (resultName != null) { ps.AddName(resultName, new ElementScope(new SymInfo(resultName, SymbolKind.Variable, resultName), ps.return_type, ps)); } ps.Complete(); if (pr != null && not_def) pr.Complete(); } private void add_parameters(ProcScope ps, formal_parameters parameters, ElementScope[] predef_params) { int i = 0; foreach (typed_parameters pars in parameters.params_list) { pars.vars_type.visit(this); if (returned_scope != null) { if (returned_scope is ProcScope) returned_scope = new ProcType(returned_scope as ProcScope); foreach (ident id in pars.idents.idents) { ElementScope si = new ElementScope(new SymInfo(id.name, SymbolKind.Parameter, id.name), returned_scope, ps); si.loc = get_location(id); if (pars.inital_value != null) { cnst_val.prim_val = null; if (!(pars.inital_value is nil_const)) { pars.inital_value.visit(this); if (cnst_val.prim_val != null) si.cnst_val = cnst_val.prim_val; else si.cnst_val = pars.inital_value.ToString(); } else si.cnst_val = "nil"; } ps.AddName(id.name, si); si.param_kind = pars.param_kind; si.MakeDescription(); if (si.cnst_val == null && predef_params != null && i < predef_params.Length) si.cnst_val = predef_params[i].cnst_val; ps.AddParameter(si); i++; } } } } public override void visit(procedure_definition _procedure_definition) { //throw new Exception("The method or operation is not implemented."); SymScope tmp = cur_scope; cur_loc = get_location(_procedure_definition); if (!parse_only_method_body) { is_proc_realization = true; _procedure_definition.proc_header.visit(this); is_proc_realization = false; } if (_procedure_definition.proc_body != null) { if (!parse_only_method_body && _procedure_definition.proc_header is function_header && (_procedure_definition.proc_header as function_header).return_type == null) { var fh = (_procedure_definition.proc_header as function_header); if (fh != null && fh.return_type == null && !(returned_scope is ProcScope && (returned_scope as ProcScope).procRealization != null && !(returned_scope as ProcScope).is_extension)) { var bl = _procedure_definition.proc_body as block; if (bl != null && bl.program_code != null) { if (bl.program_code.subnodes.Count == 1) { var ass = bl.program_code.subnodes[0] as assign; if (ass != null && ass.to is ident && (ass.to as ident).name.Equals(currentUnitLanguage.LanguageIntellisenseSupport.ResultVariableName, currentUnitLanguage.CaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase)) { if (!(ass.from is nil_const)) { ProcScope tmp_scope = returned_scope as ProcScope; cur_scope = returned_scope; ass.from.visit(this); if (returned_scope != null && returned_scope is TypeScope) { tmp_scope.return_type = returned_scope as TypeScope; if (tmp_scope.return_type is ProcType && (tmp_scope.return_type as ProcType).target == tmp_scope) tmp_scope.return_type = null; tmp_scope.Complete(); returned_scope = tmp_scope; } } } } } } } if (!parse_only_method_body) cur_scope = returned_scope; /*if ((ret_tn as ProcScope).return_type != null) { ret_tn.AddName("Result",new ElementScope(new SymInfo("Result", SymbolKind.Variable,"Result"),(ret_tn as ProcScope).return_type,cur_scope)); }*/ if (!parse_only_interface && !parse_only_method_header) { try { _procedure_definition.proc_body.visit(this); } catch (Exception ex) { } } if (cur_scope != null && cur_scope is ProcScope) { ProcRealization pr = (cur_scope as ProcScope).procRealization; if (pr == null) cur_scope.body_loc = get_location(_procedure_definition.proc_body); else pr.body_loc = get_location(_procedure_definition.proc_body); } } cur_scope = tmp; } private List ref_type_wait_list = new List(); private ident_list template_args = null; public override void visit(type_declaration _type_declaration) { //throw new Exception("The method or operation is not implemented."); cur_type_name = _type_declaration.type_name.name; List generic_params = new List(); if (_type_declaration.type_name is template_type_name) { template_args = (_type_declaration.type_name as template_type_name).template_args; foreach (ident id in (_type_declaration.type_name as template_type_name).template_args.list) { generic_params.Add(id.name); } } _type_declaration.type_def.visit(this); if (returned_scope != null && returned_scope is PointerScope && (returned_scope as PointerScope).ref_type is UnknownScope) { ref_type_wait_list.Add(returned_scope as PointerScope); } //else if (returned_scope != null && returned_scope is TypeScope) { /*if (!(_type_declaration.type_def is named_type_reference) && !(_type_declaration.type_def is sequence_type) && !(_type_declaration.type_def is sequence_type) && !(_type_declaration.type_def is array_type) && !(returned_scope is CompiledScope && _type_declaration.type_def is enum_type_definition))*/ if (_type_declaration.type_def is class_definition) { //(ret_tn as TypeScope).name = _type_declaration.type_name.name; returned_scope.si.name = _type_declaration.type_name.name; returned_scope.si.description = returned_scope.GetDescription(); // Это мертвый код EVA //if (!(_type_declaration.type_def is class_definition)) // returned_scope.MakeSynonimDescription(); returned_scope.loc = get_location(_type_declaration);//new location(loc.begin_line_num,loc.begin_column_num,ret_tn.loc.end_line_num,ret_tn.loc.end_column_num,ret_tn.loc.doc); if (_type_declaration.type_def is class_definition) { class_definition cl_def = _type_declaration.type_def as class_definition; string key = currentUnitLanguage.LanguageIntellisenseSupport.GetClassKeyword(cl_def.keyword); if (cl_def.attribute == class_attribute.Auto) key = "auto " + key; else if ((cl_def.attribute & class_attribute.Abstract) == class_attribute.Abstract) key = "abstract " + key; else if ((cl_def.attribute & class_attribute.Sealed) == class_attribute.Sealed) key = "sealed " + key; else if ((cl_def.attribute & class_attribute.Static) == class_attribute.Static) key = "static " + key; if (key != null && returned_scope.body_loc != null) { returned_scope.head_loc = new location(returned_scope.body_loc.begin_line_num, returned_scope.body_loc.begin_column_num, returned_scope.body_loc.begin_line_num, returned_scope.body_loc.begin_column_num + key.Length, doc_name); } if ((cl_def.attribute & class_attribute.Partial) == class_attribute.Partial) { List lst = cur_scope.FindOverloadNames(cur_type_name); if (lst != null) { var this_ts = returned_scope as TypeScope; foreach (SymScope ss in lst) { var ts = ss as TypeScope; if (ts != null) { ts.AddPartial(this_ts); this_ts.AddPartial(ts); } } } } } if (add_doc_from_text && this.converter.controller.docs != null && this.converter.controller.docs.ContainsKey(_type_declaration)) returned_scope.AddDocumentation(this.converter.controller.docs[_type_declaration]); if (!(_type_declaration.type_def is class_definition)) cur_scope.AddName(_type_declaration.type_name.name, returned_scope); } else { TypeSynonim ts = new TypeSynonim(new SymInfo(_type_declaration.type_name.name, returned_scope.si.kind, _type_declaration.type_name.name), returned_scope, generic_params); ts.loc = get_location(_type_declaration); ts.topScope = cur_scope; ts.declaringUnit = entry_scope; //ts.si.describe = "type "+ret_tn.si.name+" = "+ret_tn.si.describe; if (_type_declaration.type_def is enum_type_definition && ts.loc.begin_line_num != ts.loc.end_line_num) { location loc = get_location(_type_declaration.type_def); ts.head_loc = new location(loc.begin_line_num, loc.begin_column_num, loc.begin_line_num, loc.begin_column_num, doc_name); ts.body_loc = loc; } cur_scope.AddName(_type_declaration.type_name.name, ts); if (add_doc_from_text && this.converter.controller.docs != null && this.converter.controller.docs.ContainsKey(_type_declaration)) ts.AddDocumentation(this.converter.controller.docs[_type_declaration]); } } else if (returned_scope != null) { if (returned_scope is ProcScope) { returned_scope = new ProcType(returned_scope as ProcScope, generic_params); returned_scope.topScope = cur_scope; } cur_scope.AddName(_type_declaration.type_name.name, returned_scope); if (returned_scope is ProcType) { ((TypeScope)returned_scope).aliased = true; returned_scope.BuildDescription(); } location loc = get_location(_type_declaration); if (returned_scope.loc == null) { returned_scope.loc = loc; //ret_tn.loc = new location(loc.begin_line_num,loc.begin_column_num,ret_tn.loc.end_line_num,ret_tn.loc.end_column_num,ret_tn.loc.doc); } } returned_scope.declaringUnit = entry_scope; if (ref_type_wait_list.Count == 0) returned_scope = null; cur_type_name = null; template_args = null; } public override void visit(type_declarations _type_declarations) { //throw new Exception("The method or operation is not implemented."); Hashtable ht = new Hashtable(StringComparer.OrdinalIgnoreCase); foreach (type_declaration td in _type_declarations.types_decl) { td.visit(this); if (td.type_name != null) ht[td.type_name.name] = returned_scope; } if (ref_type_wait_list.Count > 0) { for (int i=0; i elems = new List(); pascal_set_constant set = e as pascal_set_constant; PascalABCCompiler.SyntaxTree.array_const arr = e as PascalABCCompiler.SyntaxTree.array_const; expression_list values = null; if (set != null) values = set.values; else values = arr.elements; if (values == null) return "[]"; if (values.Count > 10)//dlinnye konstanty ne pokazyvaem return null;//prosto const c: foreach (expression elem in values.expressions) { if (elem is ident || elem is int32_const || elem is char_const || elem is string_const) elems.Add(get_constant_as_string(elem));//tolko primitivy else return null; } //govnostudia ne daet podkluchit Core.dll i ne mogu vyzvat Join. urody StringBuilder sb = new StringBuilder(); for (int i = 0; i < elems.Count; i++) { sb.Append(elems[i]); if (i < elems.Count - 1) sb.Append(", "); } if (set != null) return "[" + sb.ToString() + "]"; else return "(" + sb.ToString() + ")"; } else if (e is char_const) return "'" + (e as char_const).cconst + "'"; else if (e.ToString().Contains("PascalABCCompiler.SyntaxTree")) return null; else return e.ToString(); } public override void visit(typed_const_definition _typed_const_definition) { //throw new Exception("The method or operation is not implemented."); _typed_const_definition.const_type.visit(this); if (returned_scope == null) return; cnst_val.prim_val = null; SymScope cnst_type = returned_scope; try { _typed_const_definition.const_value.visit(this); } catch (Exception e) { #if DEBUG File.AppendAllText("log.txt", e.Message + Environment.NewLine + e.StackTrace + Environment.NewLine); #endif } ElementScope es = new ElementScope(new SymInfo(_typed_const_definition.const_name.name, SymbolKind.Constant, _typed_const_definition.const_name.name), cnst_type, cnst_val.prim_val != null?cnst_val.prim_val: get_constant_as_string(_typed_const_definition.const_value), cur_scope); cur_scope.AddName(_typed_const_definition.const_name.name, es); es.loc = get_location(_typed_const_definition); es.is_static = true; es.declaringUnit = entry_scope; if (add_doc_from_text && this.converter.controller.docs != null && this.converter.controller.docs.ContainsKey(_typed_const_definition)) es.AddDocumentation(this.converter.controller.docs[_typed_const_definition]); cnst_val.prim_val = null; } public override void visit(const_definition _const_definition) { throw new Exception("The method or operation is not implemented."); } public override void visit(consts_definitions_list _consts_definitions_list) { //throw new Exception("The method or operation is not implemented."); foreach (const_definition cnst in _consts_definitions_list.const_defs) cnst.visit(this); } public override void visit(unit_name _unit_name) { throw new Exception("The method or operation is not implemented."); } public override void visit(unit_or_namespace _unit_or_namespace) { throw new Exception("The method or operation is not implemented."); } public override void visit(uses_unit_in _uses_unit_in) { throw new Exception("The method or operation is not implemented."); } public override void visit(uses_list _uses_list) { throw new Exception("The method or operation is not implemented."); } public override void visit(program_body _program_body) { throw new Exception("The method or operation is not implemented."); } public override void visit(compilation_unit _compilation_unit) { throw new Exception("The method or operation is not implemented."); } private Hashtable ns_cache; private bool is_namespace = false; public override void visit(unit_module _unit_module) { string path = get_assembly_path("mscorlib.dll", _unit_module.file_name); Assembly _as = PascalABCCompiler.NetHelper.NetHelper.LoadAssembly(path); AssemblyDocCache.Load(_as, path); PascalABCCompiler.NetHelper.NetHelper.init_namespaces(_as); List namespaces = new List(); currentUnitLanguage = Languages.Facade.LanguageProvider.Instance.SelectLanguageByExtension(_unit_module.file_name); string unitName = _unit_module.unit_name.idunit_name.name; var languageUsingStandardUnit = Languages.Facade.LanguageProvider.Instance.Languages.Find(lang => lang.SystemUnitNames.Contains(unitName)); // Пока что добавили возможость грубо отключить добавление NET пространств имен по умолчанию здесь (второе условие нужно, чтобы в стандартные модули языка они тоже не добавлялись) EVA if (currentUnitLanguage.LanguageIntellisenseSupport.AddStandardNetNamespacesToUserScope && (languageUsingStandardUnit?.LanguageIntellisenseSupport.AddStandardNetNamespacesToUserScope ?? true)) namespaces.AddRange(PascalABCCompiler.NetHelper.NetHelper.GetNamespaces(_as)); InterfaceUnitScope unit_scope = null; bool existed_ns = false; is_namespace = _unit_module.unit_name.HeaderKeyword == UnitHeaderKeyword.Namespace; if (_unit_module.unit_name.HeaderKeyword != UnitHeaderKeyword.Namespace || !CodeCompletionController.pabcNamespaces.TryGetValue(_unit_module.unit_name.idunit_name.name.ToLower(), out unit_scope)) { cur_scope = unit_scope = new InterfaceUnitScope(new SymInfo(_unit_module.unit_name.idunit_name.name, SymbolKind.Namespace, _unit_module.unit_name.idunit_name.name), null, _unit_module.unit_name.HeaderKeyword == UnitHeaderKeyword.Namespace, _unit_module.file_name); if (_unit_module.unit_name.HeaderKeyword == UnitHeaderKeyword.Namespace /*&& CodeCompletionController.comp != null && CodeCompletionController.comp.CompilerOptions.CurrentProject != null*/) { CodeCompletionController.pabcNamespaces.Add(_unit_module.unit_name.idunit_name.name.ToLower(), unit_scope); } } else { cur_scope = new InterfaceUnitScope(new SymInfo(_unit_module.unit_name.idunit_name.name, SymbolKind.Namespace, _unit_module.unit_name.idunit_name.name), null, _unit_module.unit_name.HeaderKeyword == UnitHeaderKeyword.Namespace, _unit_module.file_name); existed_ns = true; //cur_scope = unit_scope; cur_scope.symbol_table = unit_scope.symbol_table; unit_scope.AddNamespaceUnit(cur_scope as InterfaceUnitScope); unit_scope = cur_scope as InterfaceUnitScope; //cur_scope.members.RemoveAll(x => x.loc != null && x.loc.doc.file_name == _unit_module.file_name); } this.cur_unit_file_name = _unit_module.file_name; //if (XmlDoc.LookupLocalizedXmlDocForUnitWithSources(_unit_module.file_name) != null) if (!add_doc_from_text) { UnitDocCache.LoadWithSources(cur_scope, _unit_module.file_name); //this.add_doc_from_text = false; } //add_standart_types_simple(); Stack regions_stack = new Stack(); if (CodeCompletionController.comp != null && CodeCompletionController.comp.CompilerOptions.CurrentProject != null && CodeCompletionController.comp.CompilerOptions.CurrentProject.ContainsSourceFile(_unit_module.file_name)) { IReferenceInfo[] refs = CodeCompletionController.comp.CompilerOptions.CurrentProject.References; if (_unit_module.compiler_directives == null) _unit_module.compiler_directives = new List(); foreach (IReferenceInfo ri in refs) { _unit_module.compiler_directives.Add (new PascalABCCompiler.SyntaxTree.compiler_directive(new token_info("reference"), new token_info(ri.FullAssemblyName))); } } List included_files = new List(); if (_unit_module.compiler_directives != null) foreach (PascalABCCompiler.SyntaxTree.compiler_directive dir in _unit_module.compiler_directives) { if (dir.Name.text.ToLower() == "reference") { try { //System.Reflection.Assembly assm = System.Reflection.Assembly.LoadFrom(get_assembly_path(dir.Directive.text,_unit_module.file_name)); path = get_assembly_path(dir.Directive.text, _unit_module.file_name); System.Reflection.Assembly assm = PascalABCCompiler.NetHelper.NetHelper.LoadAssembly(path); PascalABCCompiler.NetHelper.NetHelper.init_namespaces(assm); AssemblyDocCache.Load(assm, path); namespaces.AddRange(PascalABCCompiler.NetHelper.NetHelper.GetNamespaces(assm)); unit_scope.AddReferencedAssembly(assm); } catch (Exception) { } //ns=new PascalABCCompiler.NetHelper.NetScope(unl,assm,tcst); } else if (dir.Name.text.ToLower() == "region") { if (cur_scope.regions == null) cur_scope.regions = new List(); regions_stack.Push(new Position(dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num, dir.source_context.end_position.line_num, dir.source_context.end_position.column_num, dir.source_context.FileName, dir.Directive.text)); } else if (dir.Name.text.ToLower() == "endregion") { if (regions_stack.Count > 0) { Position pos = regions_stack.Pop(); if (cur_scope.regions != null) { cur_scope.regions.Add(new Position(pos.line, pos.column - 1, dir.source_context.end_position.line_num, dir.source_context.end_position.column_num, pos.file_name, pos.fold_text)); } } } else if (dir.Name.text.ToLower() == "includenamespace") { string directive = dir.Directive.text.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar); Compiler.TryThrowInvalidPath(directive, dir.source_context); if (directive == "*.pas" || directive.EndsWith(Path.DirectorySeparatorChar + "*.pas")) { string udir = Path.Combine(Path.GetDirectoryName(_unit_module.file_name), directive.Replace(Path.DirectorySeparatorChar + "*.pas", "")); foreach (string file in Directory.EnumerateFiles(udir, "*.pas")) included_files.Add(file); } else included_files.Add(Path.Combine(Path.GetDirectoryName(_unit_module.file_name), directive)); } } ns_cache = new Hashtable(StringComparer.CurrentCultureIgnoreCase); doc_name = _unit_module.file_name; cur_scope.head_loc = get_location(_unit_module.unit_name); cur_scope.file_name = _unit_module.file_name; cur_scope.loc = get_location(_unit_module); //if (!existed_ns) cur_scope.AddName(_unit_module.unit_name.idunit_name.name, cur_scope); if (add_doc_from_text && this.converter.controller.docs != null && this.converter.controller.docs.ContainsKey(_unit_module.unit_name)) cur_scope.AddDocumentation(this.converter.controller.docs[_unit_module.unit_name]); entry_scope = cur_scope; if (_unit_module.unit_name.HeaderKeyword == UnitHeaderKeyword.Library) foreach (string file in included_files) { DomConverter dc = CodeCompletionController.comp_modules[file] as DomConverter; if (dc == null) { dc = new CodeCompletionController().CompileAllIfNeed(file, true); } if (dc.visitor != null) { } } // считаем основной модуль идущим первым в списке EVA var language = Languages.Facade.LanguageProvider.Instance.Languages.Find(lang => lang.SystemUnitNames.First() == unitName); if (language != null) { // добавление стандартных типов можно делать в отдельный фиктивный модуль, как в основном компиляторе // это позволит работать директиве DisableStandardUnits, а также не будет засорять сам стандартный модуль типами EVA add_standart_types(entry_scope, language.LanguageIntellisenseSupport); if (language == Languages.Facade.LanguageProvider.Instance.MainLanguage) { AddPascalStandardProcedures(); } } CodeCompletionController.comp_modules[_unit_module.file_name] = this.converter; if (!existed_ns) { foreach (string s in namespaces) { if (!ns_cache.ContainsKey(s)) { NamespaceScope ns_scope = new NamespaceScope(s); entry_scope.AddName(s, ns_scope); ns_cache[s] = s; } } } if (currentUnitLanguage.LanguageIntellisenseSupport.ApplySyntaxTreeConvertersForIntellisense) { foreach (ISyntaxTreeConverter converter in currentUnitLanguage.SyntaxTreeConverters) { _unit_module = (unit_module)converter.Convert(_unit_module, true); } } // Далее импортирумые пользовательские модули компилируются в обратном порядке, стандартные модули в порядке описания List usedUnitsNames = new List(); interface_node _interface_node = _unit_module.interface_part; if (_interface_node.uses_modules != null) { usedUnitsNames = _interface_node.uses_modules.units .Where(unit => unit.name.idents.Count == 1) .Select(unit => unit.name.idents[0].name).ToList(); (cur_scope as InterfaceUnitScope).uses_source_range = get_location(_interface_node.uses_modules); // компиляция зависимостей из секции uses for (int j = _interface_node.uses_modules.units.Count - 1; j >= 0; j--) { unit_or_namespace s = _interface_node.uses_modules.units[j]; CompileUsedUnitOrNamespace(s, Path.GetDirectoryName(_unit_module.file_name), cur_scope, ns_cache, unl, currentUnitLanguage); } } // компиляция зависимостей из конструкций import и from import if (cur_scope != null && _unit_module.initialization_part != null) { CompileImportedDependencies(_unit_module.initialization_part, cur_scope, _unit_module.file_name, ns_cache, currentUnitLanguage); } StringComparer comparer = currentUnitLanguage.CaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase; // если это стандартный модуль, то подразумевается, что в нем явно указано какие из других стандартных модулей он использует EVA if (!currentUnitLanguage.SystemUnitNames.Contains(Path.GetFileNameWithoutExtension(_unit_module.file_name))) { // Добавление всех стандартных модулей EVA foreach (var standardUnitName in currentUnitLanguage.SystemUnitNames.Except(usedUnitsNames, comparer)) { AddStandardUnit(standardUnitName, currentUnitLanguage); } } if (currentUnitLanguage.LanguageIntellisenseSupport.ApplySyntaxTreeConvertersForIntellisense && currentUnitLanguage.LanguageInformation.SyntaxTreeIsConvertedAfterUsedModulesCompilation) { var namesFromUsedUnits = CollectNamesFromUsedUnits(cur_scope); var artifacts = new CompilationArtifactsUsedBySyntaxConverters(namesFromUsedUnits); foreach (ISyntaxTreeConverter converter in currentUnitLanguage.SyntaxTreeConverters) { _unit_module = (unit_module)converter.ConvertAfterUsedModulesCompilation(_unit_module, true, in artifacts); } } DateTime start_time = DateTime.Now; System.Diagnostics.Debug.WriteLine("intellisense parsing interface started " + System.Convert.ToInt32((DateTime.Now - start_time).TotalMilliseconds)); if (is_namespace) { parse_only_class_headers = true; _unit_module.interface_part.visit(this); parse_only_class_headers = false; parse_only_method_headers = true; _unit_module.interface_part.visit(this); parse_only_method_headers = false; parse_only_method_bodies = true; _unit_module.interface_part.visit(this); } else _unit_module.interface_part.visit(this); System.Diagnostics.Debug.WriteLine("intellisense parsing interface ended " + System.Convert.ToInt32((DateTime.Now - start_time).TotalMilliseconds)); start_time = DateTime.Now; System.Diagnostics.Debug.WriteLine("intellisense parsing implementation started " + System.Convert.ToInt32((DateTime.Now - start_time).TotalMilliseconds)); if (_unit_module.implementation_part != null) _unit_module.implementation_part.visit(this); System.Diagnostics.Debug.WriteLine("intellisense parsing implementation ended " + System.Convert.ToInt32((DateTime.Now - start_time).TotalMilliseconds)); if (_unit_module.initialization_part != null) { SymScope tmp = cur_scope; SymScope stmt_scope = new BlockScope(cur_scope); cur_scope.AddName("$block_scope", stmt_scope); if (_unit_module.initialization_part.left_logical_bracket != null) { stmt_scope.loc = get_location(_unit_module.initialization_part.left_logical_bracket.source_context.Merge(_unit_module.initialization_part.right_logical_bracket.source_context)); } else { stmt_scope.loc = get_location(_unit_module.initialization_part.source_context); } cur_scope = stmt_scope; _unit_module.initialization_part.visit(this); cur_scope = tmp; } if (_unit_module.finalization_part != null) { SymScope tmp = cur_scope; SymScope stmt_scope = new BlockScope(cur_scope); cur_scope.AddName("$block_scope", stmt_scope); if (_unit_module.finalization_part.left_logical_bracket != null) { stmt_scope.loc = get_location(_unit_module.finalization_part.left_logical_bracket.source_context.Merge(_unit_module.finalization_part.right_logical_bracket.source_context)); } else { stmt_scope.loc = get_location(_unit_module.finalization_part.source_context); } cur_scope = stmt_scope; _unit_module.finalization_part.visit(this); cur_scope = tmp; } } private Dictionary> CollectNamesFromUsedUnits(SymScope currentUnitScope) { var namesFromUsedUnits = new Dictionary>(); bool IsVariableOrConstant(SymbolKind symKind) { return symKind == SymbolKind.Variable || symKind == SymbolKind.Constant || symKind == SymbolKind.Event; } foreach (var unitScope in currentUnitScope.used_units) { if (unitScope is InterfaceUnitScope interfaceScope) { namesFromUsedUnits.Add(unitScope.Name, new Dictionary()); foreach (var symbol in unitScope.symbol_table) { var scopesOrScope = ((DictionaryEntry)symbol).Value; string name; bool isVariable; if (scopesOrScope is List scopes) { name = scopes[0].Name; isVariable = IsVariableOrConstant(scopes[0].SymbolInfo.Kind); } else { var scope = (SymScope)scopesOrScope; name = scope.Name; isVariable = IsVariableOrConstant(scope.SymbolInfo.Kind); } if (name == unitScope.Name) continue; namesFromUsedUnits[unitScope.Name][name] = isVariable; } } } return namesFromUsedUnits; } public string get_assembly_path(string name, string CompFile) { string fname = (string.Format("{0}\\{1}",System.IO.Path.GetDirectoryName(CompFile), name)).ToLower(); if (System.IO.File.Exists(fname)) return fname; return Compiler.get_assembly_path(name,true); } PascalABCCompiler.TreeRealization.using_namespace_list unl = new PascalABCCompiler.TreeRealization.using_namespace_list(); public SymScope cur_scope; public static string FindPCUFileName(string UnitName, string curr_path, Languages.Facade.ILanguage currentUnitLanguage) { return CodeCompletionController.comp.FindPCUFileName(UnitName, curr_path, out _, currentUnitLanguage); } private void AddStandardUnit(string unitName, Languages.Facade.ILanguage currentUnitLanguage) { string unitPath = CodeCompletionNameHelper.FindSourceFileName(unitName, out _, currentUnitLanguage); if (unitPath != null) { DomConverter dc = CodeCompletionController.comp_modules[unitPath] as DomConverter; if (dc == null) { CodeCompletionController ccc = new CodeCompletionController(); dc = ccc.CompileAllIfNeed(unitPath, true); //dc.CompileAllIfNeed(unit_name); if (dc.visitor != null && dc.visitor.entry_scope != null) { dc.visitor.entry_scope.InitAssemblies(); entry_scope.AddUsedUnit(dc.visitor.entry_scope); // стандартные типы добавляются в PABCSystem - это не требуется, поскольку они там уже есть после Compile EVA //if (unitName == StringConstants.pascalSystemUnitName) // add_standart_types(dc.visitor.entry_scope); //get_standart_types(dc.stv); // для SPython, например, не нужно подсказывать стандартные модули в программе, это условие для этого EVA if (currentUnitLanguage.LanguageIntellisenseSupport.AddStandardUnitNamesToUserScope) { entry_scope.AddName(unitName, dc.visitor.entry_scope); } else { dc.visitor.entry_scope.AddName(unitName, dc.visitor.entry_scope); } } CodeCompletionController.comp_modules[unitPath] = dc; } else if (dc.visitor != null && dc.visitor.entry_scope != null) { dc.visitor.entry_scope.InitAssemblies(); entry_scope.AddUsedUnit(dc.visitor.entry_scope); //get_standart_types(dc.stv); if (currentUnitLanguage.LanguageIntellisenseSupport.AddStandardUnitNamesToUserScope) { entry_scope.AddName(unitName, dc.visitor.entry_scope); } } } } private void CompileUsedUnitOrNamespace(unit_or_namespace s, string curr_path, SymScope cur_scope, Hashtable ns_cache, using_namespace_list unl, Languages.Facade.ILanguage currentUnitLanguage) { try { if (s is uses_unit_in uui) { string unit_name = CodeCompletionNameHelper.FindSourceFileName(uui.in_file.Value, out _, currentUnitLanguage, curr_path); if (unit_name == null) throw new InvalidOperationException($"uses '{uui.in_file.Value}';"); CompileUnit(unit_name, cur_scope); } else { string usedName = ""; if (s.name.idents.Count == 1) { usedName = s.name.idents[0].name; // на случай имен модулей, отличающихся от имен файла EVA string realName = GetRealNameForModule(usedName); string pcu_unit_name = FindPCUFileName(realName, curr_path, currentUnitLanguage); string unit_name = CodeCompletionNameHelper.FindSourceFileName(realName, out _, currentUnitLanguage, curr_path); /*if (pcu_unit_name != null && unit_name != null && string.Compare(System.IO.Path.GetDirectoryName(_program_module.file_name), System.IO.Path.GetDirectoryName(pcu_unit_name), true) == 0 && string.Compare(System.IO.Path.GetDirectoryName(_program_module.file_name), System.IO.Path.GetDirectoryName(unit_name), true) != 0) unit_name = null;*/ if (unit_name != null) { CompileUnit(unit_name, cur_scope); } else { unit_name = pcu_unit_name; if (unit_name != null) { IntellisensePCUReader pcu_rdr = new IntellisensePCUReader(); SymScope ss = pcu_rdr.GetUnit(unit_name); UnitDocCache.Load(ss, unit_name); cur_scope.AddUsedUnit(ss); cur_scope.AddName(usedName, ss); } else { // У пространств имен Паскаля может быть разделение по точке, но этот случай не учитывается в ветке else EVA if (CodeCompletionController.pabcNamespaces.ContainsKey(usedName.ToLower())) { InterfaceUnitScope un_scope = CodeCompletionController.pabcNamespaces[usedName.ToLower()]; cur_scope.AddUsedUnit(un_scope); cur_scope.AddName(usedName, un_scope); } else if (PascalABCCompiler.NetHelper.NetHelper.IsNetNamespace(usedName)) { var ns_scope = new NamespaceScope(usedName); ns_cache[usedName] = usedName; cur_scope.AddName(usedName, ns_scope); cur_scope.AddUsedUnit(ns_scope); } // Не поддерживается в основном компиляторе EVA /*else if (PascalABCCompiler.NetHelper.NetHelper.IsType(usedName) && allow_import_types) { Type t = PascalABCCompiler.NetHelper.NetHelper.FindType(usedName); cur_scope.AddUsedUnit(new NamespaceTypeScope(TypeTable.get_compiled_type(new SymInfo(t.Name, SymbolKind.Class, t.FullName), t))); }*/ } } } else { usedName = string.Join(".", s.name.idents.Select(id => id.name)); cur_scope.AddUsedUnit(new NamespaceScope(usedName)); } unl.AddElement(new using_namespace(usedName)); } } catch (Exception e) { #if DEBUG File.AppendAllText("log.txt", e.Message + Environment.NewLine + e.StackTrace + Environment.NewLine); #endif } } private void CompileUnit(string unit_name, SymScope cur_scope) { var dc = (DomConverter)CodeCompletionController.comp_modules[unit_name] ?? new CodeCompletionController().CompileAllIfNeed(unit_name, true); if (dc.visitor != null) { dc.visitor.entry_scope.InitAssemblies(); cur_scope.AddUsedUnit(dc.visitor.entry_scope); cur_scope.AddName(Path.GetFileNameWithoutExtension(unit_name), dc.visitor.entry_scope); } } private string GetRealNameForModule(string nameInUses) { // для такого пока не реализована поддержка в конверторах синтаксического дерева EVA /*var specialModulesAliases = Languages.Facade.LanguageProvider.Instance.Languages.SelectMany(l => l.LanguageInformation.SpecialModulesAliases != null ? l.LanguageInformation.SpecialModulesAliases : new Dictionary()); if (specialModulesAliases.Count() > 0) { var foundPair = specialModulesAliases.FirstOrDefault(kv => kv.Key == str); if (!foundPair.Equals(default(KeyValuePair))) { realName = foundPair.Value; } }*/ if (currentUnitLanguage.LanguageInformation.SpecialModulesAliases != null && currentUnitLanguage.LanguageInformation.SpecialModulesAliases.TryGetValue(nameInUses, out var realName)) return realName; return nameInUses; } private void CompileImportedUnit(string importedName, statement importStatement, as_statement_list asStatementsList, string curr_path, SymScope cur_scope, using_namespace_list unl, ILanguage currentUnitLanguage) { try { var comparer = currentUnitLanguage.CaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase; // на случай имен модулей, отличающихся от имен файла EVA string realName = GetRealNameForModule(importedName); string pcu_unit_name = FindPCUFileName(realName, curr_path, currentUnitLanguage); string unit_name = CodeCompletionNameHelper.FindSourceFileName(realName, out _, currentUnitLanguage, curr_path); if (unit_name != null) { DomConverter dc = (DomConverter)CodeCompletionController.comp_modules[unit_name] ?? new CodeCompletionController().CompileAllIfNeed(unit_name, true); if (dc.visitor != null) { dc.visitor.entry_scope.InitAssemblies(); AddImportedNamesToCurScope(importStatement, asStatementsList, cur_scope, importedName, dc.visitor.entry_scope, comparer); } } else { unit_name = pcu_unit_name; if (unit_name != null) { IntellisensePCUReader pcu_rdr = new IntellisensePCUReader(); SymScope ss = pcu_rdr.GetUnit(unit_name); UnitDocCache.Load(ss, unit_name); AddImportedNamesToCurScope(importStatement, asStatementsList, cur_scope, importedName, ss, comparer); } } unl.AddElement(new using_namespace(importedName)); } catch (Exception e) { #if DEBUG File.AppendAllText("log.txt", e.Message + Environment.NewLine + e.StackTrace + Environment.NewLine); #endif } } private static void AddImportedNamesToCurScope(statement importStatement, as_statement_list asStatementsList, SymScope currentScope, string importedModuleName, SymScope importedModuleScope, StringComparison comparer) { if (importStatement is import_statement import) { int fictiveUnitIndex = currentScope.used_units.FindIndex(unit => unit.Name.Equals(importedModuleName + "?ModuleName", comparer)); SymScope fictiveUnit = fictiveUnitIndex > -1 ? currentScope.used_units[fictiveUnitIndex] : null; if (fictiveUnit == null) { fictiveUnit = new InterfaceUnitScope(new SymInfo(importedModuleName + "?ModuleName", SymbolKind.Namespace, ""), null); currentScope.AddUsedUnit(fictiveUnit); } string aliasName = asStatementsList.as_statements.Find(st => st.real_name.name == importedModuleName).alias.name; SymScope moduleScope = importedModuleScope.CopyWithNewSymInfo(); fictiveUnit.AddName(aliasName, moduleScope); // Поправляем реальное имя, которое портится в InterfaceUnitScope.AddName() EVA moduleScope.si.name = importedModuleName; moduleScope.si.aliasName = aliasName; } else if (importStatement is from_import_statement fromImport) { int fictiveUnitIndex = currentScope.used_units.FindIndex(unit => unit.Name.Equals(importedModuleName, comparer)); SymScope fictiveUnit = fictiveUnitIndex > -1 ? currentScope.used_units[fictiveUnitIndex] : null; if (fromImport.is_star) { if (fictiveUnit != null) currentScope.used_units.RemoveAt(fictiveUnitIndex); currentScope.AddUsedUnit(importedModuleScope); } else { if (fictiveUnit == null) { fictiveUnit = new InterfaceUnitScope(new SymInfo(importedModuleName, SymbolKind.Namespace, ""), null); currentScope.AddUsedUnit(fictiveUnit); } foreach (var asStatement in asStatementsList.as_statements) { SymScope nameScope = importedModuleScope.FindNameOnlyInType(asStatement.real_name.name)?.CopyWithNewSymInfo(); if (nameScope != null) { fictiveUnit.AddName(asStatement.alias.name, nameScope); // Поправляем реальное имя, которое портится в InterfaceUnitScope.AddName() EVA nameScope.si.name = asStatement.real_name.name; nameScope.si.aliasName = asStatement.alias.name; } } } } } public override void visit(program_module _program_module) { //Assembly _as = System.Reflection.Assembly.LoadFrom(get_assembly_path("mscorlib.dll",_program_module.file_name)); string path = get_assembly_path("mscorlib.dll", _program_module.file_name); System.Reflection.Assembly _as = PascalABCCompiler.NetHelper.NetHelper.LoadAssembly(path); List namespaces = new List(); PascalABCCompiler.NetHelper.NetHelper.init_namespaces(_as); AssemblyDocCache.Load(_as, path); currentUnitLanguage = Languages.Facade.LanguageProvider.Instance.SelectLanguageByName(_program_module.Language); // Пока что добавили возможость грубо отключить добавление NET пространств имен по умолчанию здесь EVA if (currentUnitLanguage.LanguageIntellisenseSupport.AddStandardNetNamespacesToUserScope) namespaces.AddRange(PascalABCCompiler.NetHelper.NetHelper.GetNamespaces(_as)); //List netScopes = new List(); //PascalABCCompiler.NetHelper.NetScope ns=new PascalABCCompiler.NetHelper.NetScope(unl,_as,tcst); InterfaceUnitScope unit_scope = null; cur_scope = unit_scope = new InterfaceUnitScope(new SymInfo(_program_module.program_name != null ? _program_module.program_name.prog_name.name : "", SymbolKind.Namespace, "program"), null); CodeCompletionController.comp_modules[_program_module.file_name] = this.converter; Stack regions_stack = new Stack(); if (CodeCompletionController.comp != null && CodeCompletionController.comp.CompilerOptions.CurrentProject != null && CodeCompletionController.comp.CompilerOptions.CurrentProject.ContainsSourceFile(_program_module.file_name)) { IReferenceInfo[] refs = CodeCompletionController.comp.CompilerOptions.CurrentProject.References; if (_program_module.compiler_directives == null) _program_module.compiler_directives = new List(); foreach (IReferenceInfo ri in refs) { _program_module.compiler_directives.Add (new PascalABCCompiler.SyntaxTree.compiler_directive(new token_info("reference"), new token_info(ri.FullAssemblyName))); } } List included_files = new List(); if (_program_module.compiler_directives != null) foreach (PascalABCCompiler.SyntaxTree.compiler_directive dir in _program_module.compiler_directives) { #if DEBUG // SSM test 05.08.17 if (dir == null) File.AppendAllText("log.txt", "dir == null" + Environment.NewLine + _program_module.compiler_directives.Count + Environment.NewLine); #endif if (dir.Name.text.ToLower() == "reference") { try { //System.Reflection.Assembly assm = System.Reflection.Assembly.LoadFrom(get_assembly_path(dir.Directive.text,_program_module.file_name)); path = get_assembly_path(dir.Directive.text, _program_module.file_name); System.Reflection.Assembly assm = PascalABCCompiler.NetHelper.NetHelper.LoadAssembly(path); if (assm != null) { PascalABCCompiler.NetHelper.NetHelper.init_namespaces(assm); AssemblyDocCache.Load(assm, path); namespaces.AddRange(PascalABCCompiler.NetHelper.NetHelper.GetNamespaces(assm)); unit_scope.AddReferencedAssembly(assm); } } catch (Exception e) { } } else if (dir.Name.text.ToLower() == "region") { if (cur_scope.regions == null) cur_scope.regions = new List(); regions_stack.Push(new Position(dir.source_context.begin_position.line_num, dir.source_context.begin_position.column_num, dir.source_context.end_position.line_num, dir.source_context.end_position.column_num, dir.source_context.FileName, dir.Directive.text)); } else if (dir.Name.text.ToLower() == "endregion") { if (regions_stack.Count > 0) { Position pos = regions_stack.Pop(); if (cur_scope.regions != null) { cur_scope.regions.Add(new Position(pos.line, pos.column - 1, dir.source_context.end_position.line_num, dir.source_context.end_position.column_num, pos.file_name, pos.fold_text)); } } } else if (dir.Name.text.ToLower() == "includenamespace") { string directive = dir.Directive.text.Replace('/', Path.DirectorySeparatorChar).Replace('\\', Path.DirectorySeparatorChar); Compiler.TryThrowInvalidPath(directive, dir.source_context); if (directive == "*.pas" || directive.EndsWith(Path.DirectorySeparatorChar + "*.pas")) { string udir = Path.Combine(Path.GetDirectoryName(_program_module.file_name), directive.Replace(Path.DirectorySeparatorChar + "*.pas", "")); foreach (string file in Directory.EnumerateFiles(udir, "*.pas")) included_files.Add(file); } else included_files.Add(Path.Combine(Path.GetDirectoryName(_program_module.file_name), directive)); } } doc_name = _program_module.file_name; cur_scope.loc = get_location(_program_module); cur_scope.file_name = _program_module.file_name; entry_scope = cur_scope; if (_program_module.program_name != null) { cur_scope.head_loc = get_location(_program_module.program_name); cur_scope.AddName(_program_module.program_name.prog_name.name, cur_scope); } Hashtable ns_cache = new Hashtable(StringComparer.CurrentCultureIgnoreCase); foreach (string file in included_files) { DomConverter dc = CodeCompletionController.comp_modules[file] as DomConverter; if (dc == null) { dc = new CodeCompletionController().CompileAllIfNeed(file, true); } if (dc.visitor != null) { } } if (currentUnitLanguage.LanguageIntellisenseSupport.ApplySyntaxTreeConvertersForIntellisense) { foreach (ISyntaxTreeConverter converter in currentUnitLanguage.SyntaxTreeConverters) { _program_module = (program_module)converter.Convert(_program_module, true); } } // Далее импортирумые пользовательские модули компилируются в обратном порядке, стандартные модули в порядке описания List usedUnitsNames = new List(); if (_program_module.used_units != null) { usedUnitsNames = _program_module.used_units.units .Where(unit => unit.name.idents.Count == 1) .Select(unit => unit.name.idents[0].name).ToList(); unit_scope.uses_source_range = get_location(_program_module.used_units); // компиляция зависимостей из секции uses for (int j = _program_module.used_units.units.Count - 1; j >= 0; j--) { unit_or_namespace s = _program_module.used_units.units[j]; CompileUsedUnitOrNamespace(s, Path.GetDirectoryName(_program_module.file_name), cur_scope, ns_cache, unl, currentUnitLanguage); } } // компиляция зависимостей из конструкций import и from import if (cur_scope != null && _program_module.program_block.program_code != null) { CompileImportedDependencies(_program_module.program_block.program_code, cur_scope, _program_module.file_name, ns_cache, currentUnitLanguage); } StringComparer comparer = currentUnitLanguage.CaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase; // Добавление всех стандартных модулей EVA foreach (var unitName in currentUnitLanguage.SystemUnitNames.Except(usedUnitsNames, comparer)) { AddStandardUnit(unitName, currentUnitLanguage); } foreach (string s in namespaces) { if (!ns_cache.ContainsKey(s)) { NamespaceScope ns_scope = new NamespaceScope(s); cur_scope.AddName(s, ns_scope); ns_cache[s] = s; } } if (currentUnitLanguage.LanguageIntellisenseSupport.ApplySyntaxTreeConvertersForIntellisense && currentUnitLanguage.LanguageInformation.SyntaxTreeIsConvertedAfterUsedModulesCompilation) { var namesFromUsedUnits = CollectNamesFromUsedUnits(cur_scope); var artifacts = new CompilationArtifactsUsedBySyntaxConverters(namesFromUsedUnits); foreach (ISyntaxTreeConverter converter in currentUnitLanguage.SyntaxTreeConverters) { _program_module = (program_module)converter.ConvertAfterUsedModulesCompilation(_program_module, true, in artifacts); } } //PascalABCCompiler.TreeRealization.common_type_node ctn = new ; if (_program_module.program_block.defs != null) foreach (declaration decl in _program_module.program_block.defs.defs) { try { decl.visit(this); } catch (Exception e) { #if DEBUG File.AppendAllText("log.txt", e.Message + Environment.NewLine + e.StackTrace + Environment.NewLine); #endif } } if (cur_scope != null && _program_module.program_block.program_code != null) { var left_line_num = _program_module.program_block.program_code.left_logical_bracket.source_context != null ? _program_module.program_block.program_code.left_logical_bracket.source_context.end_position.line_num : 1; var left_column_num = _program_module.program_block.program_code.left_logical_bracket.source_context != null ? _program_module.program_block.program_code.left_logical_bracket.source_context.end_position.column_num : 1; var right_line_num = _program_module.program_block.program_code.source_context.end_position.line_num; var right_column_num = _program_module.program_block.program_code.source_context.end_position.column_num; if (_program_module.program_block.program_code.right_logical_bracket == null || _program_module.program_block.program_code.right_logical_bracket.source_context == null) { right_line_num += 2; right_column_num += 2; _program_module.program_block.program_code.source_context = new SourceContext(_program_module.program_block.program_code.source_context.begin_position.line_num, _program_module.program_block.program_code.source_context.begin_position.column_num, right_line_num, right_column_num); } cur_scope.body_loc = new location(left_line_num, left_column_num, right_line_num, right_column_num, doc_name); cur_scope.loc = new location(cur_scope.loc.begin_line_num, cur_scope.loc.begin_column_num, right_line_num, right_column_num, doc_name); _program_module.program_block.program_code.visit(this); } } private void CompileImportedDependencies(statement_list statementList, SymScope cur_scope, string fileName, Hashtable ns_cache, Languages.Facade.ILanguage currentUnitLanguage) { var importStatements = statementList.list.Where(st => st is import_statement || st is from_import_statement); foreach (var importStatement in importStatements.Reverse()) { if (importStatement is import_statement import) { foreach (var unitNode in import.modules_names.as_statements.Select(st => st.real_name).Reverse()) { CompileImportedUnit(unitNode.name, import, import.modules_names, Path.GetDirectoryName(fileName), cur_scope, unl, currentUnitLanguage); } } else if (importStatement is from_import_statement fromImport) { var comparer = currentUnitLanguage.CaseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase; // Стандартные модули подсоединятся автоматически (import в другой ветке в любом случае нужен) if (currentUnitLanguage.SystemUnitNames.Contains(cur_scope.Name, comparer) || !currentUnitLanguage.SystemUnitNames.Contains(fromImport.module_name.name, comparer)) { CompileImportedUnit(fromImport.module_name.name, fromImport, fromImport.imported_names, Path.GetDirectoryName(fileName), cur_scope, unl, currentUnitLanguage); } } } } private void add_standart_types(SymScope cur_scope, ILanguageIntellisenseSupport languageIntellisenseSupport) { var standardTypesData = new List>() { Tuple.Create(PascalABCCompiler.Parsers.KeywordKind.ObjectType, TypeTable.obj_type), Tuple.Create(PascalABCCompiler.Parsers.KeywordKind.IntType, TypeTable.int_type), Tuple.Create(PascalABCCompiler.Parsers.KeywordKind.DoubleType, TypeTable.real_type), Tuple.Create(PascalABCCompiler.Parsers.KeywordKind.StringType, TypeTable.string_type), Tuple.Create(PascalABCCompiler.Parsers.KeywordKind.CharType, TypeTable.char_type), Tuple.Create(PascalABCCompiler.Parsers.KeywordKind.BoolType, TypeTable.bool_type), Tuple.Create(PascalABCCompiler.Parsers.KeywordKind.ByteType, TypeTable.byte_type), Tuple.Create(PascalABCCompiler.Parsers.KeywordKind.ShortType, TypeTable.int16_type), Tuple.Create(PascalABCCompiler.Parsers.KeywordKind.SByteType, TypeTable.sbyte_type), Tuple.Create(PascalABCCompiler.Parsers.KeywordKind.UShortType, TypeTable.uint16_type), Tuple.Create(PascalABCCompiler.Parsers.KeywordKind.UIntType, TypeTable.uint32_type), Tuple.Create(PascalABCCompiler.Parsers.KeywordKind.Int64Type, TypeTable.int64_type), Tuple.Create(PascalABCCompiler.Parsers.KeywordKind.UIntType, TypeTable.uint32_type), Tuple.Create(PascalABCCompiler.Parsers.KeywordKind.UInt64Type, TypeTable.uint64_type), Tuple.Create(PascalABCCompiler.Parsers.KeywordKind.FloatType, TypeTable.float_type), Tuple.Create(PascalABCCompiler.Parsers.KeywordKind.PointerType, TypeTable.ptr_type) }; foreach (var data in standardTypesData) { var keywordKind = data.Item1; var type = data.Item2; var type_name = languageIntellisenseSupport.GetStandardTypeByKeyword(keywordKind); if (type_name != null) { var typeClone = TypeTable.StandardTypeClone(type); cur_scope.AddName(type_name, typeClone); } } } public void AddPascalStandardProcedures() { ProcScope ps = new ProcScope(StringConstants.set_length_procedure_name, null); ps.AddParameter(new ElementScope(new SymInfo("arr", SymbolKind.Parameter, "arr"), new ArrayScope(), null, ps)); ps.parameters[0].param_kind = parametr_kind.var_parametr; ps.AddParameter(new ElementScope(new SymInfo("length", SymbolKind.Parameter, "length"), TypeTable.int_type, null, ps)); ps.Complete(); cur_scope.AddName(StringConstants.set_length_procedure_name, ps); cur_scope.AddName(StringConstants.true_const_name, new ElementScope(new SymInfo(StringConstants.true_const_name, SymbolKind.Constant, StringConstants.true_const_name), TypeTable.bool_type, true, null)); cur_scope.AddName(StringConstants.false_const_name, new ElementScope(new SymInfo(StringConstants.false_const_name, SymbolKind.Constant, StringConstants.false_const_name), TypeTable.bool_type, false, null)); ps = new ProcScope(StringConstants.new_procedure_name, null); ElementScope prm = new ElementScope(new SymInfo("p", SymbolKind.Parameter, "p"), TypeTable.ptr_type, null, ps); prm.param_kind = parametr_kind.var_parametr; ps.AddParameter(prm); ps.Complete(); cur_scope.AddName(StringConstants.new_procedure_name, ps); ps = new ProcScope(StringConstants.dispose_procedure_name, null); prm = new ElementScope(new SymInfo("p", SymbolKind.Parameter, "p"), TypeTable.ptr_type, null, ps); prm.param_kind = parametr_kind.var_parametr; ps.AddParameter(prm); ps.Complete(); cur_scope.AddName(StringConstants.dispose_procedure_name, ps); ps = new ProcScope(StringConstants.IncProcedure, null); prm = new ElementScope(new SymInfo("i", SymbolKind.Parameter, "i"), TypeTable.int16_type, null, ps); prm.param_kind = parametr_kind.var_parametr; ps.AddParameter(prm); ps.Complete(); ps.si.not_include = true; cur_scope.AddName(StringConstants.IncProcedure, ps); ps = new ProcScope(StringConstants.IncProcedure, null); prm = new ElementScope(new SymInfo("i", SymbolKind.Parameter, "i"), TypeTable.uint16_type, null, ps); prm.param_kind = parametr_kind.var_parametr; ps.AddParameter(prm); ps.Complete(); ps.si.not_include = true; cur_scope.AddName(StringConstants.IncProcedure, ps); ps = new ProcScope(StringConstants.IncProcedure, null); prm = new ElementScope(new SymInfo("i", SymbolKind.Parameter, "i"), TypeTable.sbyte_type, null, ps); prm.param_kind = parametr_kind.var_parametr; ps.AddParameter(prm); ps.Complete(); ps.si.not_include = true; cur_scope.AddName(StringConstants.IncProcedure, ps); ps = new ProcScope(StringConstants.IncProcedure, null); prm = new ElementScope(new SymInfo("i", SymbolKind.Parameter, "i"), TypeTable.int64_type, null, ps); prm.param_kind = parametr_kind.var_parametr; ps.AddParameter(prm); ps.Complete(); ps.si.not_include = true; cur_scope.AddName(StringConstants.IncProcedure, ps); ps = new ProcScope(StringConstants.IncProcedure, null); prm = new ElementScope(new SymInfo("i", SymbolKind.Parameter, "i"), TypeTable.uint64_type, null, ps); prm.param_kind = parametr_kind.var_parametr; ps.AddParameter(prm); ps.Complete(); ps.si.not_include = true; cur_scope.AddName(StringConstants.IncProcedure, ps); ps = new ProcScope(StringConstants.IncProcedure, null); prm = new ElementScope(new SymInfo("i", SymbolKind.Parameter, "i"), TypeTable.uint32_type, null, ps); prm.param_kind = parametr_kind.var_parametr; ps.AddParameter(prm); ps.Complete(); ps.si.not_include = true; cur_scope.AddName(StringConstants.IncProcedure, ps); } public override void visit(hex_constant _hex_constant) { //throw new Exception("The method or operation is not implemented."); returned_scope = TypeTable.uint64_type;//entry_scope.FindName(StringConstants.ulong_type_name); cnst_val.prim_val = _hex_constant.val; } public override void visit(get_address _get_address) { //throw new Exception("The method or operation is not implemented."); _get_address.address_of.visit(this); if (returned_scope != null && returned_scope is TypeScope) { returned_scope = new PointerScope(returned_scope as TypeScope); } else returned_scope = null; } public override void visit(case_variant _case_variant) { //throw new Exception("The method or operation is not implemented."); } public override void visit(compiler_directive_if _compiler_directive_if) { } public override void visit(compiler_directive_list _compiler_directive_list) { } public override void visit(case_node _case_node) { if (_case_node.conditions != null) for (int i = 0; i < _case_node.conditions.variants.Count; i++) _case_node.conditions.variants[i].exec_if_true.visit(this); if (_case_node.else_statement != null) _case_node.else_statement.visit(this); } public override void visit(method_name _method_name) { if (_method_name.meth_name is operator_name_ident) _method_name.meth_name.visit(this); else meth_name = _method_name.meth_name.name; } public override void visit(dot_node _dot_node) { bool tmp = search_all; search_all = false; _dot_node.left.visit(this); search_all = tmp; if (returned_scope != null) { if (_dot_node.right is ident) { if (!search_all) { if (returned_scope is NamespaceScope) { returned_scope = returned_scope.FindNameOnlyInType((_dot_node.right as ident).name); return; } if (returned_scope is InterfaceUnitScope) { returned_scope = returned_scope.FindNameOnlyInType((_dot_node.right as ident).name); } else { TypeScope ts = returned_scope as TypeScope; if (returned_scope is ProcScope) ts = (returned_scope as ProcScope).return_type; if (ts != null) returned_scope = ts.FindNameOnlyInType((_dot_node.right as ident).name); if (returned_scope == null) { List meths = entry_scope.GetExtensionMethods((_dot_node.right as ident).name, ts); if (meths.Count > 0) { method_call mc = new method_call(_dot_node, new expression_list()); search_all = true; mc.visit(this); return; } } else if (returned_scope is ProcScope) { method_call mc = new method_call(_dot_node, new expression_list()); search_all = true; mc.visit(this); return; } } if (returned_scope != null && returned_scope is ProcScope && (returned_scope as ProcScope).return_type != null) { ProcScope ps = returned_scope as ProcScope; if (ps.parameters.Count == 0 || ps.is_extension || ps.parameters[0].param_kind == parametr_kind.params_parametr || ps.parameters[0].cnst_val != null) returned_scope = ps.return_type; return; } else if (returned_scope is ElementScope) { ElementScope es = returned_scope as ElementScope; this.cnst_val.prim_val = es.cnst_val; returned_scope = es.sc; if (es.IsIndexedProperty) returned_scope = new IndexedPropertyType(es.sc as TypeScope); return; } else if (returned_scope is TypeScope) is_type = true; else if (returned_scope is ProcScope && (returned_scope as ProcScope).is_constructor) { returned_scope = (returned_scope as ProcScope).declaringType; return; } } else { TypeScope ts = returned_scope as TypeScope; if (returned_scope is ProcScope) ts = (returned_scope as ProcScope).return_type; returned_scopes = returned_scope.FindOverloadNamesOnlyInType((_dot_node.right as ident).name); if (ts != null) { List meths = entry_scope.GetExtensionMethods((_dot_node.right as ident).name, ts); if (meths.Count > 0) { if (returned_scopes == null) returned_scopes = new List(); foreach (ProcScope meth in meths) returned_scopes.Add(meth); } } search_all = false; } } } } public override void visit(PascalABCCompiler.SyntaxTree.empty_statement _empty_statement) { //throw new Exception("The method or operation is not implemented."); } public override void visit(PascalABCCompiler.SyntaxTree.goto_statement _goto_statement) { //throw new Exception("The method or operation is not implemented."); } public override void visit(PascalABCCompiler.SyntaxTree.labeled_statement _labeled_statement) { //throw new Exception("The method or operation is not implemented."); if (_labeled_statement.to_statement != null) _labeled_statement.to_statement.visit(this); } private bool is_type = false; public override void visit(with_statement _with_statement) { //throw new Exception("The method or operation is not implemented."); SymScope tmp = cur_scope; WithScope ws = new WithScope(cur_scope); for (int i=_with_statement.do_with.expressions.Count-1; i>=0; i--) { is_type = false; _with_statement.do_with.expressions[i].visit(this); if (returned_scope != null) { ws.AddWithScope(returned_scope,is_type); } is_type = false; } cur_scope.AddName("$with_block",ws); ws.loc = get_location(_with_statement); cur_scope = ws; _with_statement.what_do.visit(this); cur_scope = tmp; } internal static bool is_good_overload(ProcScope ps, List args) { if (ps.parameters == null || ps.parameters.Count == 0) if (args.Count == 0) return true; else return false; if (args.Count == 0) if (ps.parameters.Count == 1 && ps.parameters[0].param_kind == parametr_kind.params_parametr) return true; else if (ps.IsExtension && ps.parameters.Count == 1) return true; else return false; if (args.Count == ps.parameters.Count || ps.IsExtension && args.Count == ps.parameters.Count - 1) { int off = 0; if (ps.IsExtension && args.Count == ps.parameters.Count - 1) off = 1; for (int i = 0; i < args.Count; i++) { if (args[i] is UnknownScope) continue; if (!(args[i] is TypeScope)) return false; TypeScope ts = args[i] as TypeScope; ElementScope parameter = ps.parameters[i + off]; if (!ts.IsConvertable(parameter.sc as TypeScope)) { if (parameter.param_kind == parametr_kind.params_parametr) { if (!(parameter.sc is TypeScope && (parameter.sc as TypeScope).IsArray && ts.IsConvertable((parameter.sc as TypeScope).elementType))) return false; } else return false; } if (parameter.param_kind == parametr_kind.var_parametr || parameter.param_kind == parametr_kind.const_parametr) { TypeScope param_ts = parameter.sc as TypeScope; if (param_ts is CompiledScope && ps is CompiledMethodScope) param_ts = param_ts.GetElementType(); if (param_ts == null || !ts.IsEqual(param_ts)) return false; } } return true; } else { //if (args.Count < ps.parameters.Count) // return false; int min_arg_cnt = Math.Min(args.Count, ps.parameters.Count); for (int i = 0; i < min_arg_cnt; i++) { if (!(args[i] is TypeScope)) return false; TypeScope ts = args[i] as TypeScope; if (!ts.IsConvertable(ps.parameters[i].sc as TypeScope)) { if (ps.parameters[i].param_kind == parametr_kind.params_parametr) { TypeScope pts = ps.parameters[i].sc as TypeScope; if (!(pts != null && pts.elementType != null && ts.IsConvertable(pts.elementType))) return false; } else return false; } //else if (args.Count > ps.parameters.Count && i == min_arg_cnt - 1 && ps.parameters[i].param_kind != parametr_kind.params_parametr) // return false; } if (args.Count < ps.parameters.Count) { for (int i = min_arg_cnt; i < ps.parameters.Count; i++) { if (ps.parameters[i].cnst_val != null || ps.parameters[i].param_kind == parametr_kind.params_parametr && i == ps.parameters.Count - 1) return true; else return false; } } else if (args.Count > ps.parameters.Count) { for (int i = min_arg_cnt; i < args.Count; i++) { if (ps.parameters[min_arg_cnt - 1].param_kind == parametr_kind.params_parametr) { if (!(args[i] is TypeScope)) return false; TypeScope ts = args[i] as TypeScope; TypeScope pts = ps.parameters[min_arg_cnt - 1].sc as TypeScope; if (!(pts != null && pts.elementType != null && ts.IsConvertable(pts.elementType))) return false; } else return false; } } return true; } } internal static bool is_good_exact_overload(ProcScope ps, List args) { if (ps.parameters == null || ps.parameters.Count == 0) if (args.Count == 0) return true; else return false; if (args.Count == 0) if (ps.parameters.Count == 1 && ps.parameters[0].param_kind == parametr_kind.params_parametr) return true; else return false; if (args.Count == ps.parameters.Count || ps.IsExtension && args.Count == ps.parameters.Count - 1) { int off = 0; if (ps.IsExtension && args.Count == ps.parameters.Count - 1) off = 1; for (int i = 0; i < args.Count; i++) { if (!(args[i] is TypeScope)) return false; TypeScope ts = args[i] as TypeScope; ElementScope parameter = ps.parameters[i + off]; if (ps.IsExtension && i == 0 && ts.IsEqual((parameter.sc as TypeScope).GetElementType())) continue; if (!ts.IsEqual(parameter.sc as TypeScope)) { if (parameter.param_kind == parametr_kind.params_parametr) { TypeScope pts = parameter.sc as TypeScope; if (!(pts != null && pts.elementType != null && ts.IsEqual(pts.elementType))) return false; } else return false; } } return true; } else { if (args.Count < ps.parameters.Count) return false; int min_arg_cnt = Math.Min(args.Count, ps.parameters.Count); for (int i = 0; i < min_arg_cnt; i++) { if (!(args[i] is TypeScope)) return false; TypeScope ts = args[i] as TypeScope; if (!ts.IsEqual(ps.parameters[i].sc as TypeScope)) { if (ps.parameters[i].param_kind == parametr_kind.params_parametr) { TypeScope pts = ps.parameters[i].sc as TypeScope; if (!(pts != null && pts.elementType != null && ts.IsEqual(pts.elementType))) return false; } else return false; } else if (i == ps.parameters.Count - 1 && ps.parameters[i].param_kind != parametr_kind.params_parametr) return false; } return true; } } private SymScope[] selected_methods = null; private bool disable_lambda_compilation = false; private ProcScope select_method(SymScope[] meths, TypeScope tleft, TypeScope tright, TypeScope obj, bool obj_instanced, List arg_types, params expression[] args) { if (arg_types == null) arg_types = new List(); List arg_types2 = new List(); SymScope[] saved_selected_methods = selected_methods; selected_methods = meths; if (arg_types.Count > 0) { foreach (TypeScope ts in arg_types) arg_types2.Add(ts); } else if (tleft != null || tright != null) { if (tleft != null) { arg_types.Add(tleft); arg_types2.Add(tleft); } if (tright != null) { arg_types.Add(tright); arg_types2.Add(tright); } } else if (args != null) { bool tmp_disable_lambda_compilation = disable_lambda_compilation; disable_lambda_compilation = true; foreach (expression e in args) { e.visit(this); returned_scopes.Clear(); arg_types.Add(returned_scope); arg_types2.Add(returned_scope as TypeScope); } disable_lambda_compilation = false; disable_lambda_compilation = tmp_disable_lambda_compilation; } selected_methods = saved_selected_methods; List good_procs = new List(); for (int i = 0; i < meths.Length; i++) { if (meths[i] is ProcScope) { if (is_good_overload(meths[i] as ProcScope, arg_types)) good_procs.Add(meths[i] as ProcScope); } else if (meths[i] is ProcType) { if (is_good_overload((meths[i] as ProcType).target, arg_types)) good_procs.Add((meths[i] as ProcType).target); } } if (good_procs.Count > 1) for (int i = 0; i < good_procs.Count; i++) if (DomSyntaxTreeVisitor.is_good_exact_overload(good_procs[i] as ProcScope, arg_types)) return good_procs[i].GetInstance(arg_types2); if (good_procs.Count == 0) { for (int i = 0; i < meths.Length; i++) { if (meths[i] is ProcScope) { if (obj != null && !(meths[i] as ProcScope).IsStatic) { good_procs.Add(meths[i] as ProcScope); } } } } /*if (good_procs.Count == 0) { for (int i = 0; i < meths.Length; i++) { if (meths[i] is ProcScope) { if ((meths[i] as ProcScope).parameters.Count == arg_types.Count) { good_procs.Add(meths[i] as ProcScope); break; } } } }*/ if (good_procs.Count > 0) { if (obj != null) { if (!obj_instanced && obj.GetElementType() != null && good_procs[0].IsExtension && !(good_procs[0].parameters[0].sc is TemplateParameterScope)) obj = obj.GetElementType(); arg_types2.Insert(0, obj); arg_types.Insert(0, obj); for (int i = 0; i < good_procs.Count; i++) if (DomSyntaxTreeVisitor.is_good_exact_overload(good_procs[i] as ProcScope, arg_types)) return good_procs[i].GetInstance(arg_types2); } return good_procs[0].GetInstance(arg_types2); } return null; } public override void visit(method_call _method_call) { if (method_call_cache.ContainsKey(_method_call)) { returned_scope = method_call_cache[_method_call]; return; } search_all = true; returned_scope = null; _method_call.dereferencing_value.visit(this); search_all = false; this.cnst_val.prim_val = null; SymScope[] names = returned_scopes.ToArray(); List parameters = new List(); TypeScope obj = null; bool obj_instanced = false; if (names.Length > 0 && names[0] is TypeScope) { returned_scope = names[0]; method_call_cache.Add(_method_call, returned_scope); return; } foreach (SymScope ss in names) { if (ss is ProcScope && (ss as ProcScope).is_extension) { ProcScope proc = ss as ProcScope; if (_method_call.dereferencing_value is dot_node) { (_method_call.dereferencing_value as dot_node).left.visit(this); obj = returned_scope as TypeScope; if (obj != null && proc.parameters != null && proc.parameters.Count > 0 && !(proc.parameters[0].sc is TemplateParameterScope || proc.parameters[0].sc is UnknownScope)) { TypeScope param_type = proc.parameters[0].sc as TypeScope; if (obj.implemented_interfaces != null) { foreach (TypeScope interf in obj.implemented_interfaces) { if (interf.original_type != null && param_type.original_type != null && interf.original_type == param_type.original_type) { List generic_args = interf.GetInstances(); if (generic_args != null && generic_args.Count > 0) { obj = generic_args[0]; obj_instanced = true; } } } } } } } } if (_method_call.parameters != null) { parameters.AddRange(_method_call.parameters.expressions); } List lambda_types = new List(); List param_types = new List(); ProcScope ps = select_method(names, null, null, obj, obj_instanced, param_types, parameters.ToArray()); bool has_lambda = false; if (_method_call.parameters != null && ps != null) for (int i = 0; i < _method_call.parameters.expressions.Count; i++) { expression e = _method_call.parameters.expressions[i]; if (e is function_lambda_definition) { TypeScope tmp_awaitedProcType = awaitedProcType; if (ps.parameters != null && ps.parameters.Count > i + (ps.IsExtension ? 1 : 0)) awaitedProcType = ps.parameters[i + (ps.IsExtension ? 1 : 0)].sc as TypeScope; bool tmp_disable_lambda_compilation = disable_lambda_compilation; disable_lambda_compilation = false; e.visit(this); disable_lambda_compilation = tmp_disable_lambda_compilation; awaitedProcType = tmp_awaitedProcType; has_lambda = true; param_types[obj == null ? i : i + 1] = returned_scope; } } if (has_lambda) ps = select_method(names, null, null, obj, obj_instanced, param_types, parameters.ToArray()); returned_scopes.Clear(); if (ps != null) { if (ps.return_type != null) { if (ps.name == "Copy" && ps.return_type.Name == "Array" && _method_call.parameters.expressions.Count > 0) { _method_call.parameters.expressions[0].visit(this); } else { returned_scope = ps.return_type; if (ps.return_type.lazy_instance) returned_scope = ps.return_type.original_type.GetInstance(ps.return_type.instances); } } else if (ps.is_constructor) returned_scope = ps.declaringType; else returned_scope = null; } else if (names.Length > 0) { returned_scope = null; foreach (SymScope ss in names) if (ss is ProcScope) { ps = ss as ProcScope; if (ps.return_type != null) { returned_scope = ps.return_type; if (ps.IsExtension && ps.IsGeneric() && obj != null) { TypeScope elem_ts = obj.GetElementType(); if (elem_ts == null) elem_ts = obj; returned_scope = ps.return_type.GetInstance(new List() { elem_ts }); } break; } else returned_scope = null; } else if (ss is TypeScope) { returned_scope = ss; } } method_call_cache.Add(_method_call, returned_scope); cnst_val.prim_val = null; } public override void visit(pascal_set_constant _pascal_set_constant) { TypeScope element_type = null; List element_types = new List(); if (_pascal_set_constant.values != null) foreach (expression ex in _pascal_set_constant.values.expressions) { ex.visit(this); if (returned_scope != null && returned_scope is TypeScope) element_types.Add(returned_scope as TypeScope); } if (element_types.Count > 0) { element_type = element_types[0]; for (int i = 1; i < element_types.Count; i++) { if (element_type.IsConvertable(element_types[i], true)) element_type = element_types[i]; else if (!element_types[i].IsConvertable(element_type, true)) { element_type = TypeTable.obj_type; break; } //else element_type = TypeTable.obj_type; } } if (element_type != null) returned_scope = new SetScope(element_type); else returned_scope = cur_scope.FindName(StringConstants.set_name); cnst_val.prim_val = null; } public override void visit(PascalABCCompiler.SyntaxTree.array_const _array_const) { //throw new Exception("The method or operation is not implemented."); cnst_val.prim_val = null; } public override void visit(write_accessor_name _write_accessor_name) { //throw new Exception("The method or operation is not implemented."); } public override void visit(read_accessor_name _read_accessor_name) { //throw new Exception("The method or operation is not implemented."); } public override void visit(property_accessors _property_accessors) { //throw new Exception("The method or operation is not implemented."); } public override void visit(simple_property _simple_property) { //throw new Exception("The method or operation is not implemented."); _simple_property.property_type.visit(this); if (returned_scope == null) return; ElementScope es = new ElementScope(new SymInfo(_simple_property.property_name.name, SymbolKind.Property, _simple_property.property_name.name), returned_scope, cur_scope); es.declaringUnit = entry_scope; if (_simple_property.array_default != null) { TypeScope ts = cur_scope as TypeScope; if (_simple_property.parameter_list != null) { ts.elementType = returned_scope as TypeScope; for (int i = 0; i < _simple_property.parameter_list.parameters.Count; i++) { _simple_property.parameter_list.parameters[i].type.visit(this); if (returned_scope == null || !(returned_scope is TypeScope)) return; for (int j = 0; j < _simple_property.parameter_list.parameters[i].names.idents.Count; j++) ts.AddIndexer(returned_scope as TypeScope, _simple_property.attr == definition_attribute.Static); } } } if (_simple_property.parameter_list != null) { es.elementType = returned_scope as TypeScope; ProcScope ps = new ProcScope("#getset" + _simple_property.property_name.name, cur_scope); ps.procRealization = new ProcRealization(ps, ps.topScope); ps.already_defined = true; cur_scope.AddName("#getset" + _simple_property.property_name.name, ps); for (int i = 0; i < _simple_property.parameter_list.parameters.Count; i++) { _simple_property.parameter_list.parameters[i].type.visit(this); if (returned_scope == null || !(returned_scope is TypeScope)) return; for (int j = 0; j < _simple_property.parameter_list.parameters[i].names.idents.Count; j++) { ps.loc = get_location(_simple_property); ps.si.not_include = true; string param_name = _simple_property.parameter_list.parameters[i].names.idents[j].name; ps.AddName(param_name, new ElementScope(new SymInfo(param_name, SymbolKind.Parameter, null),returned_scope, ps)); es.AddIndexer(returned_scope as TypeScope); } } es.MakeDescription(); } es.loc = get_location(_simple_property); if (add_doc_from_text && this.converter.controller.docs != null && this.converter.controller.docs.ContainsKey(_simple_property)) es.AddDocumentation(this.converter.controller.docs[_simple_property]); if (_simple_property.attr == definition_attribute.Static) es.is_static = true; es.acc_mod = cur_access_mod; es.si.acc_mod = cur_access_mod; if (_simple_property.accessors != null && _simple_property.accessors.write_accessor == null) { es.is_readonly = true; es.MakeDescription(); } cur_scope.AddName(_simple_property.property_name.name, es); //if (_simple_property.accessors != null && _simple_property.accessors.write_accessor != null && _simple_property.accessors.write_accessor.pr != null) // _simple_property.accessors.write_accessor.pr.visit(this); } public override void visit(index_property _index_property) { //throw new Exception("The method or operation is not implemented."); if (_index_property.is_default != null) { TypeScope ts = cur_scope as TypeScope; if (_index_property.parameter_list != null) { for (int i = 0; i < _index_property.parameter_list.parameters.Count; i++) { _index_property.parameter_list.parameters[i].type.visit(this); if (returned_scope == null || !(returned_scope is TypeScope)) return; for (int j = 0; j < _index_property.parameter_list.parameters[i].names.idents.Count; j++) ts.AddIndexer(returned_scope as TypeScope, _index_property.attr == definition_attribute.Static); } } } } public override void visit(class_members _class_members) { //throw new Exception("The method or operation is not implemented."); } public override void visit(access_modifer_node _access_modifer_node) { //throw new Exception("The method or operation is not implemented."); } private access_modifer cur_access_mod = access_modifer.none; private bool parse_only_method_header = false; private bool parse_only_method_body = false; private bool parse_only_class_headers = false; private bool parse_only_method_headers = false; private bool parse_only_method_bodies = false; private Dictionary class_members = new Dictionary(); public override void visit(class_body_list _class_body) { Dictionary scopes = new Dictionary(); if (!parse_only_method_bodies) { parse_only_method_header = true; foreach (class_members mems in _class_body.class_def_blocks) { if (mems.access_mod != null) cur_access_mod = mems.access_mod.access_level; foreach (declaration decl in mems.members) { try { decl.visit(this); scopes.Add(decl, returned_scope); if (parse_only_method_headers) class_members.Add(decl, returned_scope); } catch (Exception e) { } } cur_access_mod = access_modifer.none; } } parse_only_method_header = false; parse_only_method_body = true; if (!parse_only_method_headers) { foreach (class_members mems in _class_body.class_def_blocks) { if (mems.access_mod != null) cur_access_mod = mems.access_mod.access_level; foreach (declaration decl in mems.members) { try { if (decl is procedure_definition) { if (parse_only_method_bodies) cur_scope = class_members[decl]; else cur_scope = scopes[decl]; decl.visit(this); } } catch (Exception e) { } } cur_access_mod = access_modifer.none; } } parse_only_method_body = false; } private bool has_cyclic_inheritance(TypeScope ts) { TypeScope tmp = ts.baseScope; while (tmp != null) if (tmp == ts) return true; else tmp = tmp.baseScope; return false; } public override void visit(class_definition _class_definition) { //throw new Exception("The method or operation is not implemented."); SymScope tmp = cur_scope; TypeScope ss = null; returned_scope = null; if (_class_definition.class_parents != null && _class_definition.class_parents.types.Count > 0) _class_definition.class_parents.types[0].visit(this); if (returned_scope is TypeScope && has_cyclic_inheritance(returned_scope as TypeScope)) returned_scope = null; if (cur_type_name != null) { ss = cur_scope.FindNameOnlyInType(cur_type_name) as TypeScope; if (parse_only_class_headers && ss != null) { ss.Clear(); //ss.declaringUnit.members.Remove(ss); ss.declaringUnit = cur_scope; ss.topScope = cur_scope; cur_scope.members.Add(ss); } } if (ss == null || !(ss.members != null && ss.members.Count == 0) && !parse_only_class_headers && !parse_only_method_bodies) { if (_class_definition.keyword == class_keyword.Record) { ss = new TypeScope(SymbolKind.Struct, cur_scope, returned_scope); if (cur_type_name == null) cur_type_name = "$record"; } else if (_class_definition.keyword == class_keyword.Class) { ss = new TypeScope(SymbolKind.Class, cur_scope, returned_scope); if ((_class_definition.attribute & class_attribute.Sealed) == class_attribute.Sealed) ss.is_final = true; if ((_class_definition.attribute & class_attribute.Abstract) == class_attribute.Abstract) ss.is_abstract = true; if (cur_type_name == null) cur_type_name = "$class"; } else if (_class_definition.keyword == class_keyword.Interface || _class_definition.keyword == class_keyword.TemplateInterface) { ss = new TypeScope(SymbolKind.Interface, cur_scope, returned_scope); if (cur_type_name == null) cur_type_name = "$interface"; } else if (_class_definition.keyword == class_keyword.TemplateClass) { ss = new TypeScope(SymbolKind.Class, cur_scope, returned_scope); if (cur_type_name == null) cur_type_name = "$class"; } else if (_class_definition.keyword == class_keyword.TemplateRecord) { ss = new TypeScope(SymbolKind.Struct, cur_scope, returned_scope); if (cur_type_name == null) cur_type_name = "$record"; } if (ss != null) { if (template_args != null && template_args.Count > 0) cur_scope.AddName(cur_type_name+"`"+ template_args.Count, ss); else cur_scope.AddName(cur_type_name, ss); } } else { ss.baseScope = returned_scope as TypeScope; if ((_class_definition.attribute & class_attribute.Sealed) == class_attribute.Sealed) ss.is_final = true; if ((_class_definition.attribute & class_attribute.Abstract) == class_attribute.Abstract) ss.is_abstract = true; if (ss.baseScope == null) ss.baseScope = TypeTable.obj_type; } if ((_class_definition.attribute & class_attribute.Static) == class_attribute.Static) { ss.is_static = true; ss.si.is_static = true; } int num = 0; if (_class_definition.keyword != class_keyword.Interface) num = 1; else ss.baseScope = null; if (parse_only_class_headers) { returned_scope = ss; return; } if (_class_definition.class_parents != null && _class_definition.class_parents.types.Count > num) { for (int i = num; i < _class_definition.class_parents.types.Count; i++) { _class_definition.class_parents.types[i].visit(this); if (returned_scope != null && returned_scope is TypeScope && has_cyclic_inheritance(returned_scope as TypeScope)) returned_scope = null; if (returned_scope != null && returned_scope is TypeScope && (returned_scope as TypeScope).si.kind == SymbolKind.Interface) ss.AddImplementedInterface(returned_scope as TypeScope); } } if (has_cyclic_inheritance(ss)) ss.baseScope = null; if (ss.loc != null) ss.predef_loc = ss.loc; ss.loc = get_location(_class_definition); cur_scope = ss; if (!parse_only_method_bodies) { if (_class_definition.template_args != null) { foreach (ident id in _class_definition.template_args.idents) ss.AddGenericParameter(id.name, get_location(id)); } else if (template_args != null) { foreach (ident id in template_args.idents) ss.AddGenericParameter(id.name, get_location(id)); } } string tmp_name = cur_type_name; cur_type_name = null; if (_class_definition.body != null) { _class_definition.body.visit(this); ss.body_loc = get_location(_class_definition); ss.real_body_loc = get_location(_class_definition.body); ss.AddDefaultConstructorIfNeed(); if (((_class_definition.attribute & PascalABCCompiler.SyntaxTree.class_attribute.Auto) == class_attribute.Auto)) { ProcScope ps = new ProcScope(StringConstants.default_constructor_name, ss, true); foreach (class_members members in _class_definition.body.class_def_blocks) { foreach (declaration decl in members.members) { var_def_statement vds = decl as var_def_statement; if (vds == null) continue; if (vds.vars_type != null) vds.vars_type.visit(this); else vds.inital_value.visit(this); foreach (ident id in vds.vars.list) { ps.parameters.Add(new ElementScope(new SymInfo(id.name, SymbolKind.Parameter, id.name), returned_scope, ps)); } } } ps.return_type = ss; ps.Complete(); ss.AddName(StringConstants.default_constructor_name, ps); } } mark_as_possible_abstract(ss); cur_type_name = tmp_name; returned_scope = ss; cur_scope = tmp; } private void mark_as_possible_abstract(TypeScope ts) { if (ts.is_abstract) return; if (ts.baseScope == null || !ts.baseScope.is_abstract) return; List meths = ts.baseScope.GetAbstractMethods(); foreach (ProcScope abstr_meth in meths) { bool has_override = false; foreach (ProcScope meth in ts.GetMethods()) { if (meth.name == abstr_meth.name && meth.IsParamsEquals(abstr_meth)) { has_override = true; break; } } if (!has_override) { ts.is_abstract = true; break; } } } public override void visit(default_indexer_property_node _default_indexer_property_node) { //throw new Exception("The method or operation is not implemented."); } public override void visit(known_type_definition _known_type_definition) { //throw new Exception("The method or operation is not implemented."); } public override void visit(set_type_definition _set_type_definition) { //throw new Exception("The method or operation is not implemented."); _set_type_definition.of_type.visit(this); TypeScope ts = returned_scope as TypeScope; if (returned_scope is ProcScope) ts = new ProcType(returned_scope as ProcScope); returned_scope = new SetScope(ts); returned_scope.topScope = cur_scope; } public override void visit(record_const_definition _record_const_definition) { //throw new Exception("The method or operation is not implemented."); } public override void visit(record_const _record_const) { // throw new Exception("The method or operation is not implemented."); } public override void visit(record_type _record_type) { //throw new Exception("The method or operation is not implemented."); SymScope tmp = cur_scope; RecordScope rs = new RecordScope(); rs.loc = get_location(_record_type); cur_scope.AddName("$record",rs); cur_scope = rs; if (_record_type.parts.fixed_part != null) foreach (var_def_statement vds in _record_type.parts.fixed_part.vars) { vds.visit(this); } returned_scope = cur_scope; cur_scope = tmp; } public override void visit(enum_type_definition _enum_type_definition) { bool is_tuple = false; template_type_reference tuple = new template_type_reference(); tuple.name = new named_type_reference(new ident_list(new ident("System"), new ident("Tuple")).idents); template_param_list tpl = new template_param_list(); tuple.params_list = tpl; if (_enum_type_definition.enumerators != null) foreach (enumerator en in _enum_type_definition.enumerators.enumerators) { if (!(en.name is named_type_reference)) { is_tuple = true; } else { named_type_reference ntr = en.name as named_type_reference; if (ntr.names.Count > 1 || ntr.names.Count == 0) { is_tuple = true; } else { SymScope ss = cur_scope.FindName(ntr.FirstIdent.name); if (ss != null && ss is TypeScope) { is_tuple = true; } } } tpl.Add(en.name); } if (is_tuple) { tuple.visit(this); return; } //throw new Exception("The method or operation is not implemented."); EnumScope enum_scope = new EnumScope(SymbolKind.Enum, cur_scope, TypeTable.get_compiled_type(new SymInfo(typeof(Enum).Name, SymbolKind.Enum, typeof(Enum).FullName), typeof(Enum))); enum_scope.loc = get_location(_enum_type_definition); enum_scope.topScope = cur_scope; List elems = new List(); if (_enum_type_definition.enumerators != null) foreach (enumerator en in _enum_type_definition.enumerators.enumerators) { var name = (en.name as named_type_reference).FirstIdent.name; ElementScope ss = new ElementScope(new SymInfo(name, SymbolKind.Constant, name),/*cur_scope.FindName(StringConstants.integer_type_name)*/enum_scope, cur_scope); ss.is_static = true; ss.cnst_val = name; elems.Add(ss); ss.loc = get_location(en); cur_scope.AddName(name, ss); enum_scope.AddName(name, ss); enum_scope.AddEnumConstant(name); if (this.converter.controller.docs.ContainsKey(en)) ss.AddDocumentation(this.converter.controller.docs[en]); } for (int i = 0; i < elems.Count; i++) elems[i].MakeDescription(); returned_scope = enum_scope; } public override void visit(char_const _char_const) { returned_scope = TypeTable.char_type;//entry_scope.FindName(StringConstants.char_type_name); if (in_kav) cnst_val.prim_val = currentUnitLanguage.LanguageIntellisenseSupport.GetStringForChar(_char_const.cconst); //cnst_val.prim_val = "'"+_char_const.cconst.ToString()+"'"; else cnst_val.prim_val = _char_const.cconst; } public override void visit(raise_statement _raise_statement) { //throw new Exception("The method or operation is not implemented."); } public override void visit(sharp_char_const _sharp_char_const) { returned_scope = TypeTable.char_type;//entry_scope.FindName(StringConstants.char_type_name); cnst_val.prim_val = currentUnitLanguage.LanguageIntellisenseSupport.GetStringForSharpChar(_sharp_char_const.char_num); } private bool in_kav=true; public override void visit(literal_const_line _literal_const_line) { //entry_scope.FindName(StringConstants.string_type_name); StringBuilder sb = new StringBuilder(); in_kav = false; for (int i = 0; i < _literal_const_line.literals.Count; i++) { _literal_const_line.literals[i].visit(this); if (cnst_val.prim_val != null && cnst_val.prim_val is char) sb.Append((char)cnst_val.prim_val); else if (cnst_val.prim_val != null && cnst_val.prim_val is string) sb.Append((string)cnst_val.prim_val); } in_kav = true; returned_scope = TypeTable.string_type; cnst_val.prim_val = sb.ToString(); } public override void visit(string_num_definition _string_num_definition) { //throw new Exception("The method or operation is not implemented."); try { _string_num_definition.num_of_symbols.visit(this); } catch(Exception e) { } returned_scope = new ShortStringScope(TypeTable.string_type,cnst_val.prim_val);//entry_scope.FindName(StringConstants.string_type_name); returned_scope.topScope = cur_scope; returned_scope.loc = get_location(_string_num_definition); } public override void visit(variant _variant) { //throw new Exception("The method or operation is not implemented."); } public override void visit(variant_list _variant_list) { //throw new Exception("The method or operation is not implemented."); } public override void visit(variant_type _variant_type) { //throw new Exception("The method or operation is not implemented."); } public override void visit(variant_types _variant_types) { //throw new Exception("The method or operation is not implemented."); } public override void visit(variant_record_type _variant_record_type) { //throw new Exception("The method or operation is not implemented."); } public override void visit(procedure_call _procedure_call) { //throw new Exception("The method or operation is not implemented."); if (has_lambdas(_procedure_call.func_name)) { _procedure_call.func_name.visit(this); } } public override void visit(class_predefinition _class_predefinition) { //throw new Exception("The method or operation is not implemented."); } public override void visit(nil_const _nil_const) { returned_scope = new NullTypeScope(); } public override void visit(file_type_definition _file_type_definition) { //throw new Exception("The method or operation is not implemented."); if (_file_type_definition.elem_type != null) _file_type_definition.elem_type.visit(this); returned_scope = new FileScope(returned_scope as TypeScope, cur_scope); } public override void visit(constructor _constructor) { SymScope topScope = cur_scope; ProcScope ps = null; location loc = get_location(_constructor); bool is_realization = false; if (_constructor.name != null) { _constructor.name.visit(this); if (_constructor.name.class_name != null) { topScope = cur_scope.FindName(_constructor.name.class_name.name); if (topScope != null) { ps = topScope.FindNameOnlyInThisType(meth_name) as ProcScope; if (ps == null) { ps = new ProcScope(StringConstants.default_constructor_name, cur_scope, true); ps.head_loc = loc; } else ps = select_function_definition(ps, _constructor.parameters, topScope as TypeScope, topScope as TypeScope, false, _constructor.class_keyword); //while (ps != null && ps.already_defined) ps = ps.nextProc; if (ps == null) { ps = new ProcScope(meth_name, cur_scope); ps.head_loc = loc; } if (ps.parameters.Count != 0 && _constructor.parameters != null) { ps.parameters.Clear(); ps.already_defined = true; } if (impl_scope == null) { ProcRealization pr = new ProcRealization(ps, cur_scope); pr.already_defined = true; ps.procRealization = pr; pr.loc = cur_loc; pr.head_loc = loc; is_realization = true; entry_scope.AddName("$method", pr); } else { ProcRealization pr = new ProcRealization(ps, impl_scope); pr.already_defined = true; ps.procRealization = pr; pr.loc = cur_loc; pr.head_loc = loc; is_realization = true; impl_scope.AddName("$method", pr); } } else { ps = new ProcScope(StringConstants.default_constructor_name, cur_scope, true); ps.head_loc = loc; } } else { ps = new ProcScope(StringConstants.default_constructor_name, cur_scope, true); ps.head_loc = loc; SymScope ss = cur_scope.FindNameOnlyInThisType(StringConstants.default_constructor_name); if (ss != null && ss is ProcScope) { if (ps.topScope == ss.topScope) { while ((ss as ProcScope).nextProc != null) ss = (ss as ProcScope).nextProc; (ss as ProcScope).nextProc = ps; } else ps.nextProc = ss as ProcScope; cur_scope.AddName("$method", ps); ps.si.name = StringConstants.default_constructor_name; } else { cur_scope.AddName(meth_name, ps); } ps.return_type = cur_scope as TypeScope; } } else { ps = new ProcScope(StringConstants.default_constructor_name, cur_scope, true); ps.head_loc = loc; SymScope ss = cur_scope.FindNameOnlyInType(StringConstants.default_constructor_name); if (ss != null && ss is ProcScope) { while ((ss as ProcScope).nextProc != null) ss = (ss as ProcScope).nextProc; (ss as ProcScope).nextProc = ps; cur_scope.AddName("$method", ps); ps.si.name = StringConstants.default_constructor_name; } else { cur_scope.AddName(StringConstants.default_constructor_name, ps); } ps.return_type = cur_scope as TypeScope; } if (!is_realization && ps.loc == null) { ps.loc = cur_loc; } //ps.head_loc = loc; ps.declaringUnit = entry_scope; ps.is_static = _constructor.class_keyword; SetAttributes(ps, _constructor.proc_attributes); if (add_doc_from_text && this.converter.controller.docs != null && this.converter.controller.docs.ContainsKey(_constructor)) ps.AddDocumentation(this.converter.controller.docs[_constructor]); if (is_proc_realization) ps.already_defined = true; else ps.loc = loc; if (_constructor.name == null || _constructor.name.class_name == null) { ps.acc_mod = cur_access_mod; ps.si.acc_mod = cur_access_mod; } if (_constructor.parameters != null) foreach (typed_parameters pars in _constructor.parameters.params_list) { pars.vars_type.visit(this); if (returned_scope != null) { if (returned_scope is ProcScope) returned_scope = new ProcType(returned_scope as ProcScope); foreach (ident id in pars.idents.idents) { ElementScope si = new ElementScope(new SymInfo(id.name, SymbolKind.Parameter, id.name), returned_scope, ps); si.loc = get_location(id); ps.AddName(id.name, si); if (pars.inital_value != null) { pars.inital_value.visit(this); if (returned_scope is NullTypeScope) si.cnst_val = "nil"; else si.cnst_val = cnst_val.prim_val; } si.param_kind = pars.param_kind; si.MakeDescription(); ps.AddParameter(si); } } } if (cur_scope is TypeScope && !ps.is_static) ps.AddName("self", new ElementScope(new SymInfo("self", SymbolKind.Parameter, "self"), cur_scope, ps)); //cur_scope = ps; returned_scope = ps; ps.Complete(); } public override void visit(destructor _destructor) { //throw new Exception("The method or operation is not implemented."); SymScope topScope = cur_scope; ProcScope ps = null; location loc = get_location(_destructor); bool is_realization = false; _destructor.name.visit(this); if (_destructor.name.class_name != null) { topScope = cur_scope.FindName(_destructor.name.class_name.name); if (topScope != null) { ps = topScope.FindNameOnlyInThisType(meth_name) as ProcScope; if (ps == null) { ps = new ProcScope(meth_name, cur_scope); ps.head_loc = loc; } else ps = select_function_definition(ps, _destructor.parameters, null, topScope as TypeScope); //while (ps != null && ps.already_defined) ps = ps.nextProc; if (ps == null) { ps = new ProcScope(meth_name, cur_scope); ps.head_loc = loc; } if (ps.parameters.Count != 0 && _destructor.parameters != null) { ps.parameters.Clear(); ps.already_defined = true; } if (impl_scope == null) { ProcRealization pr = new ProcRealization(ps, cur_scope); pr.already_defined = true; pr.loc = cur_loc; pr.head_loc = loc; is_realization = true; entry_scope.AddName("$method", pr); } else { ProcRealization pr = new ProcRealization(ps, impl_scope); pr.already_defined = true; pr.loc = cur_loc; pr.head_loc = loc; is_realization = true; impl_scope.AddName("$method", pr); } } else { ps = new ProcScope(meth_name, cur_scope); ps.head_loc = loc; } } else { ps = new ProcScope(meth_name, cur_scope); ps.head_loc = loc; SymScope ss = cur_scope.FindNameOnlyInThisType(meth_name); if (ss != null && ss is ProcScope) { while ((ss as ProcScope).nextProc != null) ss = (ss as ProcScope).nextProc; (ss as ProcScope).nextProc = ps; cur_scope.AddName("$method", ps); ps.si.name = meth_name; } else { cur_scope.AddName(meth_name, ps); } } if (!is_realization && ps.loc == null) ps.loc = cur_loc; //ps.head_loc = loc; ps.declaringUnit = entry_scope; SetAttributes(ps, _destructor.proc_attributes); if (add_doc_from_text && this.converter.controller.docs != null && this.converter.controller.docs.ContainsKey(_destructor)) ps.AddDocumentation(this.converter.controller.docs[_destructor]); if (is_proc_realization) ps.already_defined = true; else ps.loc = loc; if (_destructor.name == null || _destructor.name.class_name == null) { ps.acc_mod = cur_access_mod; ps.si.acc_mod = cur_access_mod; } if (_destructor.parameters != null) foreach (typed_parameters pars in _destructor.parameters.params_list) { pars.vars_type.visit(this); if (returned_scope != null) { if (returned_scope is ProcScope) returned_scope = new ProcType(returned_scope as ProcScope); foreach (ident id in pars.idents.idents) { ElementScope si = new ElementScope(new SymInfo(id.name, SymbolKind.Parameter, id.name), returned_scope, ps); si.loc = get_location(id); ps.AddName(id.name, si); si.param_kind = pars.param_kind; si.MakeDescription(); ps.AddParameter(si); } } } if (cur_scope is TypeScope) ps.AddName("self", new ElementScope(new SymInfo("self", SymbolKind.Parameter, "self"), cur_scope, ps)); //cur_scope = ps; returned_scope = ps; ps.Complete(); } public override void visit(inherited_method_call _inherited_method_call) { //throw new Exception("The method or operation is not implemented."); } public override void visit(typecast_node _typecast_node) { if (_typecast_node.cast_op == op_typecast.is_op) { returned_scope = TypeTable.bool_type; } else _typecast_node.type_def.visit(this); } public override void visit(interface_node _interface_node) { if (_interface_node.interface_definitions != null) foreach (declaration decl in _interface_node.interface_definitions.defs) { try { decl.visit(this); } catch (Exception e) { #if DEBUG File.AppendAllText("log.txt", e.Message + Environment.NewLine + e.StackTrace + Environment.NewLine); #endif } } } public override void visit(implementation_node _implementation_node) { var currentLanguage = Languages.Facade.LanguageProvider.Instance.SelectLanguageByExtension(this.cur_unit_file_name); SymScope tmp = cur_scope; unl.Clear(); cur_scope = new ImplementationUnitScope(new SymInfo("$implementation", SymbolKind.Namespace, "implementation"), cur_scope); tmp.AddName("$implementation", cur_scope); (tmp as InterfaceUnitScope).impl_scope = cur_scope as ImplementationUnitScope; cur_scope.loc = get_location(_implementation_node); if (_implementation_node.uses_modules != null) { (cur_scope as ImplementationUnitScope).uses_source_range = get_location(_implementation_node.uses_modules); for (int j = _implementation_node.uses_modules.units.Count - 1; j >= 0; j--) { unit_or_namespace s = _implementation_node.uses_modules.units[j]; CompileUsedUnitOrNamespace(s, Path.GetDirectoryName(this.cur_unit_file_name), cur_scope, ns_cache, unl, currentLanguage); } } impl_scope = cur_scope; if (_implementation_node.implementation_definitions != null) foreach (declaration decl in _implementation_node.implementation_definitions.defs) { try { if (parse_only_interface && !need_to_parse(decl)) continue; decl.visit(this); } catch (Exception e) { #if DEBUG File.AppendAllText("log.txt", e.Message + Environment.NewLine + e.StackTrace + Environment.NewLine); #endif cur_scope = impl_scope; } } } private bool need_to_parse(declaration _declaration) { if (!(_declaration is procedure_definition)) return false; procedure_definition proc = _declaration as procedure_definition; if (proc.proc_header.name.class_name != null) return true; if (proc.proc_header.proc_attributes == null) return false; if (has_extensionmethod_attr(proc.proc_header.proc_attributes.proc_attributes)) return true; return false; } public override void visit(diap_expr _diap_expr) { //throw new Exception("The method or operation is not implemented."); } public override void visit(block _block) { //throw new Exception("The method or operation is not implemented."); if (_block.defs != null) _block.defs.visit(this); if (_block.program_code != null) _block.program_code.visit(this); //cur_scope.loc = get_location(_block.program_code); } public override void visit(proc_block _proc_block) { //throw new Exception("The method or operation is not implemented."); } public override void visit(array_of_named_type_definition _array_of_named_type_definition) { //throw new Exception("The method or operation is not implemented."); } public override void visit(array_of_const_type_definition _array_of_const_type_definition) { //throw new Exception("The method or operation is not implemented."); } public override void visit(literal _literal) { //throw new Exception("The method or operation is not implemented."); } public override void visit(case_variants _case_variants) { //throw new Exception("The method or operation is not implemented."); } public override void visit(diapason_expr _diapason_expr) { _diapason_expr.left.visit(this); } public override void visit(var_def_list_for_record _var_def_list) { //throw new Exception("The method or operation is not implemented."); } public override void visit(record_type_parts _record_type_parts) { //throw new Exception("The method or operation is not implemented."); } public override void visit(property_array_default _property_array_default) { //throw new Exception("The method or operation is not implemented."); } public override void visit(property_interface _property_interface) { // throw new Exception("The method or operation is not implemented."); } public override void visit(property_parameter _property_parameter) { //throw new Exception("The method or operation is not implemented."); } public override void visit(property_parameter_list _property_parameter_list) { //throw new Exception("The method or operation is not implemented."); } public override void visit(inherited_ident _inherited_ident) { //throw new Exception("The method or operation is not implemented."); } public override void visit(format_expr _format_expr) { //throw new Exception("The method or operation is not implemented."); returned_scope = TypeTable.string_type; } public override void visit(initfinal_part _initfinal_part) { //throw new Exception("The method or operation is not implemented."); } public override void visit(token_info _token_info) { throw new Exception("The method or operation is not implemented."); } public override void visit(raise_stmt _raise_stmt) { //throw new Exception("The method or operation is not implemented."); } public override void visit(op_type_node _op_type_node) { throw new Exception("The method or operation is not implemented."); } public override void visit(file_type _file_type) { if (_file_type.file_of_type != null) _file_type.file_of_type.visit(this); returned_scope = new FileScope(returned_scope as TypeScope, cur_scope); } public override void visit(known_type_ident _known_type_ident) { throw new Exception("The method or operation is not implemented."); } public override void visit(exception_handler _exception_handler) { SymScope tmp = cur_scope; SymScope stmt_scope = new BlockScope(cur_scope); cur_scope.AddName("$block_scope", stmt_scope); stmt_scope.loc = get_location(_exception_handler); if (_exception_handler.statements.source_context != null) stmt_scope.loc = new location(stmt_scope.loc.begin_line_num, stmt_scope.loc.begin_column_num, _exception_handler.statements.source_context.end_position.line_num, _exception_handler.statements.source_context.end_position.column_num, stmt_scope.loc.file_name); returned_scope = null; if (_exception_handler.variable == null) return; if (_exception_handler.type_name != null) _exception_handler.type_name.visit(this); else returned_scope = cur_scope.FindName(_exception_handler.variable.name); if (returned_scope != null) { cur_scope = stmt_scope; ElementScope es = new ElementScope(new SymInfo(_exception_handler.variable.name, SymbolKind.Variable, _exception_handler.variable.name), returned_scope, cur_scope); es.loc = get_location(_exception_handler.variable); stmt_scope.AddName(_exception_handler.variable.name, es); } _exception_handler.statements.visit(this); cur_scope = tmp; } public override void visit(exception_ident _exception_ident) { //throw new Exception("The method or operation is not implemented."); } public override void visit(exception_handler_list _exception_handler_list) { foreach (exception_handler eh in _exception_handler_list.handlers) eh.visit(this); } public override void visit(exception_block _exception_block) { if (_exception_block.handlers != null) _exception_block.handlers.visit(this); if (_exception_block.stmt_list != null) _exception_block.stmt_list.visit(this); if (_exception_block.else_stmt_list != null) _exception_block.else_stmt_list.visit(this); } public override void visit(try_handler _try_handler) { } public override void visit(try_handler_finally _try_handler_finally) { _try_handler_finally.stmt_list.visit(this); } public override void visit(try_handler_except _try_handler_except) { _try_handler_except.except_block.visit(this); } public override void visit(try_stmt _try_stmt) { if (_try_stmt.stmt_list != null) _try_stmt.stmt_list.visit(this); if (_try_stmt.handler != null) _try_stmt.handler.visit(this); } public override void visit(inherited_message _inherited_message) { //throw new Exception("The method or operation is not implemented."); } public override void visit(external_directive _external_directive) { } public override void visit(using_list _using_list) { throw new Exception("The method or operation is not implemented."); } public override void visit(jump_stmt _jump_stmt) { throw new Exception("The method or operation is not implemented."); } public override void visit(loop_stmt _loop_stmt) { SymScope tmp = cur_scope; SymScope stmt_scope = new BlockScope(cur_scope); cur_scope.AddName("$block_scope", stmt_scope); stmt_scope.loc = get_location(_loop_stmt); cur_scope = stmt_scope; if (_loop_stmt.stmt != null) _loop_stmt.stmt.visit(this); cur_scope = tmp; } public override void visit(foreach_stmt _foreach_stmt) { //throw new Exception("The method or operation is not implemented."); SymScope tmp = cur_scope; if (_foreach_stmt.type_name != null) { SymScope stmt_scope = new BlockScope(cur_scope); cur_scope.AddName("$block_scope", stmt_scope); stmt_scope.loc = get_location(_foreach_stmt); if (_foreach_stmt.type_name is no_type_foreach) { cur_scope = stmt_scope; _foreach_stmt.in_what.visit(this); if (returned_scope != null) returned_scope = returned_scope.GetElementType(); if (returned_scope == null) returned_scope = TypeTable.obj_type; } else { if (has_lambdas(_foreach_stmt.in_what)) { cur_scope = stmt_scope; _foreach_stmt.in_what.visit(this); } _foreach_stmt.type_name.visit(this); } if (returned_scope != null) { cur_scope = stmt_scope; if (returned_scope is ProcScope) returned_scope = new ProcType(returned_scope as ProcScope); ElementScope es = new ElementScope(new SymInfo(_foreach_stmt.identifier.name, SymbolKind.Variable, _foreach_stmt.identifier.name), returned_scope, cur_scope); es.loc = get_location(_foreach_stmt.identifier); stmt_scope.AddName(_foreach_stmt.identifier.name, es); } } if (_foreach_stmt.stmt != null) _foreach_stmt.stmt.visit(this); cur_scope = tmp; } public override void visit(addressed_value_funcname _addressed_value_funcname) { throw new Exception("The method or operation is not implemented."); } public override void visit(named_type_reference_list _named_type_reference_list) { throw new Exception("The method or operation is not implemented."); } public override void visit(template_param_list _template_param_list) { throw new Exception("The method or operation is not implemented."); } public override void visit(template_type_reference _template_type_reference) { returned_scope = null; converted_template_type = _template_type_reference; _template_type_reference.name.visit(this); converted_template_type = null; List gen_args = new List(); if (returned_scope != null && returned_scope is TypeScope) { TypeScope ts = returned_scope as TypeScope; if (_template_type_reference.params_list != null) { List instances = new List(); foreach (type_definition td in _template_type_reference.params_list.params_list) { returned_scope = null; td.visit(this); if (returned_scope is TypeScope) //instances.Add(ret_tn as TypeScope); //ts.AddGenericInstanciation(ret_tn as TypeScope); gen_args.Add(returned_scope as TypeScope); else if (returned_scope is ProcScope) gen_args.Add(new ProcType(returned_scope as ProcScope)); } } if (gen_args.Count > 0) ts = ts.GetInstance(gen_args, true); //ts.MakeInstance(); //ret_tn = ts.GetGenericInstance(gen_args); //ts.si.describe = ts.ToString(); //else returned_scope = ts; } } public override void visit(int64_const _int64_const) { //throw new Exception("The method or operation is not implemented."); returned_scope = TypeTable.int64_type;//entry_scope.FindName(StringConstants.long_type_name); cnst_val.prim_val = _int64_const.val; } public override void visit(uint64_const _uint64_const) { returned_scope = TypeTable.uint64_type;//entry_scope.FindName(StringConstants.ulong_type_name); cnst_val.prim_val = _uint64_const.val; } public override void visit(new_expr _new_expr) { _new_expr.type.visit(this); if (_new_expr.new_array && returned_scope != null && returned_scope is TypeScope) { List indexes = new List(); indexes.Add(TypeTable.int_type); for (int i = 1; i < _new_expr.params_list.expressions.Count; i++) indexes.Add(TypeTable.int_type); if (indexes.Count > 1) { for (int i = 0; i < indexes.Count; i++) { indexes[i] = null; } } returned_scope = new ArrayScope(returned_scope as TypeScope, indexes.ToArray()); if (indexes.Count == 1) (returned_scope as ArrayScope).is_dynamic_arr = true; } save_return_value(); if (_new_expr.params_list != null) foreach (expression ex in _new_expr.params_list.expressions) { if (ex is function_lambda_definition) ex.visit(this); } restore_return_value(); /*if (ret_tn != null && ret_tn is TypeScope) { TypeScope ts = ret_tn as TypeScope; ret_tn = ts.GetConstructor(); }*/ } public override void visit(where_type_specificator_list _type_definition_list) { throw new Exception("The method or operation is not implemented."); } public override void visit(where_definition _where_definition) { //throw new Exception("The method or operation is not implemented."); } public override void visit(where_definition_list _where_definition_list) { //throw new Exception("The method or operation is not implemented."); } public override void visit(PascalABCCompiler.SyntaxTree.sizeof_operator _sizeof_operator) { returned_scope = TypeTable.int_type; } public override void visit(PascalABCCompiler.SyntaxTree.typeof_operator _typeof_operator) { //throw new Exception("The method or operation is not implemented."); returned_scope = TypeTable.get_compiled_type(new SymInfo(null, SymbolKind.Class,null),typeof(Type)); } public override void visit(PascalABCCompiler.SyntaxTree.compiler_directive _compiler_directive) { //throw new Exception("The method or operation is not implemented."); } private string get_operator_sign(Operators op) { switch(op) { case Operators.Plus : return StringConstants.plus_name; case Operators.Minus : return StringConstants.minus_name; case Operators.Division : return StringConstants.div_name; case Operators.IntegerDivision: return StringConstants.div_name; case Operators.Multiplication : return StringConstants.mul_name; case Operators.ModulusRemainder : return StringConstants.mod_name; case Operators.Less : return StringConstants.sm_name; case Operators.LessEqual : return StringConstants.smeq_name; case Operators.Greater : return StringConstants.gr_name; case Operators.GreaterEqual : return StringConstants.greq_name; case Operators.Equal : return StringConstants.eq_name; case Operators.NotEqual : return StringConstants.noteq_name; case Operators.AssignmentAddition : return StringConstants.plusassign_name; case Operators.AssignmentMultiplication : return StringConstants.multassign_name; case Operators.AssignmentSubtraction : return StringConstants.minusassign_name; case Operators.AssignmentDivision : return StringConstants.divassign_name; case Operators.Implicit : return "implicit"; case Operators.Explicit : return "explicit"; case Operators.In: return StringConstants.in_name; case Operators.Power: return StringConstants.power_name; case Operators.LogicalOR: return StringConstants.or_name; case Operators.LogicalAND: return StringConstants.and_name; case Operators.BitwiseXOR: return StringConstants.xor_name; case Operators.LogicalNOT: return StringConstants.not_name; } return ""; } public override void visit(operator_name_ident _operator_name_ident) { //throw new Exception("The method or operation is not implemented."); string sign = get_operator_sign(_operator_name_ident.operator_type); if (sign.Length > 0 && char.IsLetter(sign[0])) sign = " " + sign; meth_name = "operator"+sign; } public override void visit(var_statement _var_statement) { //throw new Exception("The method or operation is not implemented."); _var_statement.var_def.visit(this); foreach (var_def_statement vds in pending_is_pattern_vars) { vds.visit(this); } } public override void visit(PascalABCCompiler.SyntaxTree.question_colon_expression _question_colon_expression) { _question_colon_expression.ret_if_true.visit(this); TypeScope type1 = returned_scope as TypeScope; _question_colon_expression.ret_if_false.visit(this); TypeScope type2 = returned_scope as TypeScope; if (type1 == null) { returned_scope = type2; return; } if (type2 == null) { returned_scope = type1; return; } if (type1.IsConvertable(type2, true)) { if (!(type2 is NullTypeScope)) returned_scope = type2; else returned_scope = type1; return; } returned_scope = type1; } public override void visit(expression_as_statement _expression_as_statement) { //throw new Exception("The method or operation is not implemented."); if (has_lambdas(_expression_as_statement.expr) || _expression_as_statement.expr is unnamed_type_object) _expression_as_statement.expr.visit(this); } public override void visit(declarations_as_statement _declarations_as_statement) { foreach (declaration decl in _declarations_as_statement.defs.defs) decl.visit(this); } public override void visit(array_size _array_size) { throw new Exception("The method or operation is not implemented."); } public override void visit(enumerator _enumerator) { throw new Exception("The method or operation is not implemented."); } public override void visit(enumerator_list _enumerator_list) { throw new Exception("The method or operation is not implemented."); } public override void visit(switch_stmt _switch_stmt) { throw new Exception("The method or operation is not implemented."); } public override void visit(type_definition_attr_list _type_definition_attr_list) { throw new Exception("The method or operation is not implemented."); } public override void visit(type_definition_attr _type_definition_attr) { throw new Exception("The method or operation is not implemented."); } public override void visit(lock_stmt _lock_stmt) { if (_lock_stmt != null) _lock_stmt.stmt.visit(this); } public override void visit(documentation_comment_list node) { throw new NotImplementedException(); } public override void visit(documentation_comment_section node) { throw new NotImplementedException(); } public override void visit(documentation_comment_tag node) { throw new NotImplementedException(); } public override void visit(documentation_comment_tag_param node) { throw new NotImplementedException(); } public override void visit(ident_with_templateparams node) { bool tmp_search_all = search_all; node.name.visit(this); if ((tmp_search_all || returned_scope == null) && returned_scopes.Count > 0) { List template_params = new List(); foreach (type_definition td in node.template_params.params_list) { td.visit(this); if (returned_scope is TypeScope) template_params.Add(returned_scope as TypeScope); else { return; } } for (int i = 0; i < returned_scopes.Count; i++) { ProcScope ps = returned_scopes[i] as ProcScope; TypeScope ts = returned_scopes[i] as TypeScope; if (ps != null) returned_scopes[i] = ps.GetInstance(template_params); else returned_scopes[i] = ts.GetInstance(template_params, true); } } else if (returned_scope is ProcScope) { ProcScope ps = returned_scope as ProcScope; List template_params = new List(); foreach (type_definition td in node.template_params.params_list) { td.visit(this); if (returned_scope is TypeScope) template_params.Add(returned_scope as TypeScope); else { returned_scope = ps; return; } } returned_scope = ps.GetInstance(template_params); } else if (returned_scope is TypeScope) { TypeScope ts = returned_scope as TypeScope; List template_params = new List(); foreach (type_definition td in node.template_params.params_list) { td.visit(this); if (returned_scope is TypeScope) template_params.Add(returned_scope as TypeScope); else if (returned_scope is ProcScope) template_params.Add(new ProcType(returned_scope as ProcScope)); else { returned_scope = ts; return; } } returned_scope = ts.GetInstance(template_params, true); } } public override void visit(bracket_expr _bracket_expr) { _bracket_expr.expr.visit(this); } public override void visit(attribute _attribute) { } public override void visit(attribute_list _attribute_list) { } public override void visit(simple_attribute_list _simple_attribute_list) { } public override void visit(function_lambda_definition _function_lambda_definition) { ProcScope ps = new ProcScope(_function_lambda_definition.lambda_name, this.cur_scope); ps.loc = get_location(_function_lambda_definition); ps.si.not_include = true; if (!disable_lambda_compilation) cur_scope.AddName(_function_lambda_definition.lambda_name, ps); if (_function_lambda_definition.ident_list != null) for (int i=0; i<_function_lambda_definition.ident_list.idents.Count; i++) { ident id = _function_lambda_definition.ident_list.idents[i]; TypeScope param_type = new UnknownScope(new SymInfo("T", SymbolKind.Type, "T")); if (awaitedProcType != null) { if (awaitedProcType is TypeSynonim) awaitedProcType = (awaitedProcType as TypeSynonim).GetLeafActType(); if (awaitedProcType is ProcType) { if ((awaitedProcType as ProcType).target.parameters.Count > 0) param_type = (awaitedProcType as ProcType).target.parameters[i].sc as TypeScope; } else if (awaitedProcType.IsDelegate && awaitedProcType.instances != null && awaitedProcType.instances.Count > 0) { param_type = awaitedProcType.instances[Math.Min(i, awaitedProcType.instances.Count - 1)]; } else if (awaitedProcType.IsDelegate) { var invokeMeth = awaitedProcType.FindNameOnlyInType("Invoke") as ProcScope; if (invokeMeth != null && invokeMeth.parameters != null && invokeMeth.parameters.Count > i) { param_type = invokeMeth.parameters[i].sc as TypeScope; } } } /*if (selected_methods != null) { foreach (ProcScope meth in selected_methods) { if (meth.parameters != null && meth.parameters.Count > 0 && (meth.parameters[1].sc as TypeScope).IsDelegate && (meth.parameters[1].sc as TypeScope).IsGeneric) { } } }*/ ElementScope es = new ElementScope(new SymInfo(id.name, SymbolKind.Parameter, ""), param_type, ps); ps.AddName(id.name, es); ps.AddParameter(es); es.loc = get_location(id); } SymScope tmp = cur_scope; cur_scope = ps; TypeScope saved_return_type = ps.return_type; if (!disable_lambda_compilation) { string resultName = currentUnitLanguage.LanguageIntellisenseSupport.ResultVariableName; if (awaitedProcType != null) { var invokeMeth = awaitedProcType.FindNameOnlyInType("Invoke") as ProcScope; if (invokeMeth != null && invokeMeth.return_type != null && resultName != null) { cur_scope.AddName(resultName, new ElementScope(new SymInfo(resultName,SymbolKind.Variable,resultName), invokeMeth.return_type, cur_scope)); } } statement_list sl = _function_lambda_definition.proc_body as statement_list; if (sl != null && sl.list.Count == 1 && sl.list[0] is assign && (sl.list[0] as assign).to is ident && ((sl.list[0] as assign).to as ident).name.Equals(resultName, currentUnitLanguage.CaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase)) { (sl.list[0] as assign).from.visit(this); ps.return_type = returned_scope as TypeScope; } else _function_lambda_definition.proc_body.visit(this); } cur_scope = tmp; if (_function_lambda_definition.usedkeyword == 2) ps.return_type = null; else if (saved_return_type == ps.return_type) ps.return_type = new UnknownScope(new SymInfo("",SymbolKind.Class,""));// returned_scope as TypeScope; returned_scope = new ProcType(ps); } public override void visit(function_lambda_call _function_lambda_call) { // } public override void visit(semantic_check _semantic_check) { } public override void visit(lambda_inferred_type lit) //lroman// { } public override void visit(same_type_node stn) //SS 22/06/13// { } public override void visit(name_assign_expr _name_assign_expr) // SSM 27.06.13 { returned_scope = null; if (_name_assign_expr.expr == null) _name_assign_expr.expr = new ident(_name_assign_expr.name.name); _name_assign_expr.expr.visit(this); if (returned_scope != null) { ElementScope es = new ElementScope(new SymInfo(_name_assign_expr.name.name, SymbolKind.Property, ""), returned_scope, cur_scope); cur_scope.AddName(_name_assign_expr.name.name, es); } else { ElementScope es = new ElementScope(new SymInfo(_name_assign_expr.name.name, SymbolKind.Property, ""), new UnknownScope(new SymInfo("",SymbolKind.Type,"")), cur_scope); cur_scope.AddName(_name_assign_expr.name.name, es); } } public override void visit(name_assign_expr_list _name_assign_expr_list) // SSM 27.06.13 { foreach (name_assign_expr expr in _name_assign_expr_list.name_expr) expr.visit(this); } public override void visit(unnamed_type_object _unnamed_type_object) // SSM 27.06.13 { SymScope tmp = cur_scope; TypeScope ts = null; cur_scope = ts = new TypeScope(SymbolKind.Class, cur_scope, null); tmp.AddName("class", cur_scope); ts.loc = get_location(_unnamed_type_object); ts.si = new SymInfo("class", SymbolKind.Class, ""); if (_unnamed_type_object.ne_list != null) _unnamed_type_object.ne_list.visit(this); returned_scope = cur_scope; cur_scope = tmp; } public override void visit(semantic_type_node stn) // SSM { } public override void visit(sequence_type _sequence_type) { template_type_reference ttr = new template_type_reference(); List names = new List(); names.Add(new ident("System")); names.Add(new ident("Collections")); names.Add(new ident("Generic")); names.Add(new ident("IEnumerable")); ttr.name = new named_type_reference(names); ttr.source_context = _sequence_type.source_context; ttr.params_list = new template_param_list(); ttr.params_list.params_list.Add(_sequence_type.elements_type); visit(ttr); } public override void visit(assign_var_tuple _assign_var_tuple) { _assign_var_tuple.expr.visit(this); TypeScope ts = returned_scope as TypeScope; if (ts != null && ts.instances != null && ts.instances.Count > 0) { for (int i = 0; i < _assign_var_tuple.idents.idents.Count; i++) { ident id = _assign_var_tuple.idents.idents[i]; if (id != null) { SymInfo si = new SymInfo(id.name, SymbolKind.Variable, id.name); ElementScope es = new ElementScope(si, ts.instances[Math.Min(i, ts.instances.Count-1)], cur_scope); es.acc_mod = cur_access_mod; es.si.acc_mod = cur_access_mod; es.loc = get_location(id); cur_scope.AddName(id.name, es); es.declaringUnit = cur_scope; } } } } public override void visit(tuple_node _tuple_node) { method_call mc = new method_call(); mc.parameters = _tuple_node.el; mc.dereferencing_value = new dot_node(new ident("Tuple"), new ident(StringConstants.default_constructor_name)); mc.visit(this); } public override void visit(slice_expr _slice_expr) { _slice_expr.v.visit(this); } public override void visit(slice_expr_question _slice_expr_question) { _slice_expr_question.v.visit(this); } public override void visit(dot_question_node _dot_question_node) { dot_node dn = new dot_node(_dot_question_node.left, _dot_question_node.right, _dot_question_node.source_context); dn.visit(this); } public override void visit(modern_proc_type _modern_proc_type) { template_type_reference ttr = new template_type_reference(); List names = new List(); if (_modern_proc_type.res != null) { names.Add(new ident("System")); names.Add(new ident("Func")); } else { names.Add(new ident("System")); names.Add(new ident("Action")); } ttr.name = new named_type_reference(names); ttr.source_context = _modern_proc_type.source_context; ttr.params_list = new template_param_list(); if (_modern_proc_type.aloneparam != null) { ttr.params_list.params_list.Add(_modern_proc_type.aloneparam); if (_modern_proc_type.res != null) ttr.params_list.params_list.Add(_modern_proc_type.res); } else { if (_modern_proc_type.el != null) foreach (enumerator en in _modern_proc_type.el.enumerators) { ttr.params_list.params_list.Add(en.name); // Здесь исправил SSM 15.1.16 } if (_modern_proc_type.res != null) ttr.params_list.params_list.Add(_modern_proc_type.res); } if (ttr.params_list.params_list.Count > 0) visit(ttr); else visit(ttr.name); } public override void visit(diapason_expr_new _diapason_expr_new) { method_call mc = new method_call(); mc.parameters = new expression_list(new List { _diapason_expr_new.left, _diapason_expr_new.right }); mc.dereferencing_value = new dot_node(new ident(StringConstants.pascalSystemUnitName), new ident("InternalRange")); mc.visit(this); } public override void visit(array_const_new acn) { TypeScope element_type = null; List element_types = new List(); foreach (expression ex in acn.elements.expressions) { ex.visit(this); if (returned_scope != null && returned_scope is TypeScope) element_types.Add(returned_scope as TypeScope); } element_type = element_types[0]; for (int i = 1; i < element_types.Count; i++) { if (element_type.IsConvertable(element_types[i], true)) element_type = element_types[i]; else if (!element_types[i].IsConvertable(element_type, true)) { element_type = TypeTable.obj_type; break; } } returned_scope = new ArrayScope(element_type,null); cnst_val.prim_val = null; } public override void visit(bigint_const bi) { /*method_call mc = new method_call(); mc.parameters = new expression_list(new uint64_const(bi.val, bi.source_context),bi.source_context); mc.dereferencing_value = new dot_node(new ident("System"), new ident("Numerics"), new ident("BigInteger"), new ident("Create")); mc.visit(this);*/ var names = new List { new ident("System"), new ident("Numerics"), new ident("BigInteger") }; var ntr = new named_type_reference(names, bi.source_context); var ne = new new_expr(ntr, new expression_list(new uint64_const(bi.val)), bi.source_context); ne.visit(this); } public override void visit(let_var_expr _let_var_expr) { var_def_statement vds = new var_def_statement(_let_var_expr.id, _let_var_expr.ex, _let_var_expr.source_context); vds.visit(this); } } }