diff --git a/CodeCompletion/DomSyntaxTreeVisitor.cs b/CodeCompletion/DomSyntaxTreeVisitor.cs index a08846617..16d4d64c0 100644 --- a/CodeCompletion/DomSyntaxTreeVisitor.cs +++ b/CodeCompletion/DomSyntaxTreeVisitor.cs @@ -1811,7 +1811,9 @@ namespace CodeCompletion } catch (Exception e) { - +#if DEBUG + File.AppendAllText("log.txt", e.Message + Environment.NewLine + e.StackTrace + Environment.NewLine); +#endif } if (returned_scope != null /*&& cnst_val.prim_val != null*/) { @@ -1840,7 +1842,9 @@ namespace CodeCompletion } 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: _typed_const_definition.const_value.ToString(), cur_scope); cur_scope.AddName(_typed_const_definition.const_name.name, es); @@ -1989,7 +1993,10 @@ namespace CodeCompletion is_extensions_unit = true; } CodeCompletionController.comp_modules[_unit_module.file_name] = this.converter; + DateTime start_time = DateTime.Now; + System.Diagnostics.Debug.WriteLine("intellisense parsing interface started " + System.Convert.ToInt32((DateTime.Now - start_time).TotalMilliseconds)); _unit_module.interface_part.visit(this); + System.Diagnostics.Debug.WriteLine("intellisense parsing interface ended " + System.Convert.ToInt32((DateTime.Now - start_time).TotalMilliseconds)); foreach (string s in namespaces) { if (!ns_cache.ContainsKey(s)) @@ -1999,8 +2006,11 @@ namespace CodeCompletion ns_cache[s] = s; } } + 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; @@ -3814,7 +3824,9 @@ namespace CodeCompletion } catch (Exception e) { - +#if DEBUG + File.AppendAllText("log.txt", e.Message + Environment.NewLine + e.StackTrace + Environment.NewLine); +#endif } } if (i == s.name.idents.Count - 1 && i > 0 /*&& PascalABCCompiler.NetHelper.NetHelper.IsNetNamespace(str)*/) @@ -3843,7 +3855,9 @@ namespace CodeCompletion } catch (Exception e) { - +#if DEBUG + File.AppendAllText("log.txt", e.Message + Environment.NewLine + e.StackTrace + Environment.NewLine); +#endif } } @@ -4441,22 +4455,24 @@ namespace CodeCompletion //List netScopes = new List(); //PascalABCCompiler.NetHelper.NetScope ns=new PascalABCCompiler.NetHelper.NetScope(unl,_as,tcst); if (_c_module.compiler_directives != null) - foreach (PascalABCCompiler.SyntaxTree.compiler_directive dir in _c_module.compiler_directives) - { - if (dir.Name.text == "reference") + foreach (PascalABCCompiler.SyntaxTree.compiler_directive dir in _c_module.compiler_directives) { - try + if (dir.Name.text == "reference") { - //System.Reflection.Assembly assm = System.Reflection.Assembly.LoadFrom(get_assembly_path(dir.Directive.text,_c_module.file_name)); - System.Reflection.Assembly assm = PascalABCCompiler.NetHelper.NetHelper.LoadAssembly(get_assembly_path(dir.Directive.text,_c_module.file_name)); - PascalABCCompiler.NetHelper.NetHelper.init_namespaces(assm); - } - catch (Exception e) - { - + try + { + //System.Reflection.Assembly assm = System.Reflection.Assembly.LoadFrom(get_assembly_path(dir.Directive.text,_c_module.file_name)); + System.Reflection.Assembly assm = PascalABCCompiler.NetHelper.NetHelper.LoadAssembly(get_assembly_path(dir.Directive.text, _c_module.file_name)); + PascalABCCompiler.NetHelper.NetHelper.init_namespaces(assm); + } + catch (Exception e) + { +#if DEBUG + File.AppendAllText("log.txt", e.Message + Environment.NewLine + e.StackTrace + Environment.NewLine); +#endif + } } } - } cur_scope = new InterfaceUnitScope(new SymInfo("", SymbolKind.Block,"module"),null); doc = new document(_c_module.file_name); cur_scope.loc = get_location(_c_module); diff --git a/NETGenerator/NETGenerator.cs b/NETGenerator/NETGenerator.cs index adc1c07a0..51aca4b59 100644 --- a/NETGenerator/NETGenerator.cs +++ b/NETGenerator/NETGenerator.cs @@ -5869,8 +5869,12 @@ namespace PascalABCCompiler.NETGenerator if (value.function_code is IStatementsListNode) { IStatementNode[] statements = (value.function_code as IStatementsListNode).statements; - if (statements.Length > 0 && statements[0] is IExternalStatementNode) + if (statements.Length > 0 && (statements[0] is IExternalStatementNode || statements[0] is IPInvokeStatementNode)) + { + MakeAttribute(value); return; + } + } num_scope++; @@ -6385,13 +6389,21 @@ namespace PascalABCCompiler.NETGenerator else ret_type = helper.GetTypeReference(meth.return_value_type).tp; Type[] param_types = GetParamTypes(meth);//получаем параметры процедуры - - IExternalStatementNode esn = (IExternalStatementNode)statements[0]; - string module_name = Tools.ReplaceAllKeys(esn.module_name, StandartDirectories); - MethodBuilder methb = cur_type.DefinePInvokeMethod(meth.name, module_name, esn.name, - MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.PinvokeImpl | MethodAttributes.HideBySig, - CallingConventions.Standard, ret_type, param_types, CallingConvention.Winapi, - CharSet.Ansi);//определяем PInvoke-метод + MethodBuilder methb = null; + if (statements[0] is IExternalStatementNode) + { + IExternalStatementNode esn = (IExternalStatementNode)statements[0]; + string module_name = Tools.ReplaceAllKeys(esn.module_name, StandartDirectories); + methb = cur_type.DefinePInvokeMethod(meth.name, module_name, esn.name, + MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.PinvokeImpl | MethodAttributes.HideBySig, + CallingConventions.Standard, ret_type, param_types, CallingConvention.Winapi, + CharSet.Ansi);//определяем PInvoke-метод + } + else + { + methb = cur_type.DefineMethod(meth.name, MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.PinvokeImpl | MethodAttributes.HideBySig, ret_type, param_types);//определяем PInvoke-метод + methb.SetImplementationFlags(MethodImplAttributes.PreserveSig); + } methb.SetImplementationFlags(MethodImplAttributes.PreserveSig); helper.AddMethod(meth, methb); IParameterNode[] parameters = meth.parameters; @@ -6420,7 +6432,7 @@ namespace PascalABCCompiler.NETGenerator { IStatementsListNode sl = (IStatementsListNode)value.function_code; IStatementNode[] statements = sl.statements; - if (statements.Length > 0 && statements[0] is IExternalStatementNode) + if (statements.Length > 0 && (statements[0] is IExternalStatementNode || statements[0] is IPInvokeStatementNode)) { ConvertExternalMethod(value); return; diff --git a/Parsers/PascalABCParserNewSaushkin/ABCPascal.cs b/Parsers/PascalABCParserNewSaushkin/ABCPascal.cs index 7eb33fc5e..1b0ba0a33 100644 --- a/Parsers/PascalABCParserNewSaushkin/ABCPascal.cs +++ b/Parsers/PascalABCParserNewSaushkin/ABCPascal.cs @@ -2,7 +2,7 @@ // This CSharp output file generated by Gardens Point LEX // Version: 1.1.3.301 // Machine: IVAN-PC -// DateTime: 08.04.2018 15:51:55 +// DateTime: 02.05.2018 20:34:16 // UserName: Ivan // GPLEX input file // GPLEX frame file diff --git a/Parsers/PascalABCParserNewSaushkin/ABCPascal.y b/Parsers/PascalABCParserNewSaushkin/ABCPascal.y index ff28098e7..ef661e498 100644 --- a/Parsers/PascalABCParserNewSaushkin/ABCPascal.y +++ b/Parsers/PascalABCParserNewSaushkin/ABCPascal.y @@ -311,17 +311,27 @@ uses_clause if (parsertools.build_tree_for_formatter) { if ($1 == null) - $1 = new uses_closure($3 as uses_list,@$); - else ($1 as uses_closure).AddUsesList($3 as uses_list,@$); - $$ = $1; + { + $$ = new uses_closure($3 as uses_list,@$); + } + else { + ($1 as uses_closure).AddUsesList($3 as uses_list,@$); + $$ = $1; + } } else { if ($1 == null) - $1 = $3; - else ($1 as uses_list).AddUsesList($3 as uses_list,@$); - $$ = $1; - $$.source_context = @$; + { + $$ = $3; + $$.source_context = @$; + } + else + { + ($1 as uses_list).AddUsesList($3 as uses_list,@$); + $$ = $1; + $$.source_context = @$; + } } } ; @@ -1457,8 +1467,8 @@ class_attributes1 } | class_attributes1 class_attribute { - $1 = ((class_attribute)$1) | ((class_attribute)$2); - $$ = $1; + $$ = ((class_attribute)$1) | ((class_attribute)$2); + //$$ = $1; } ; @@ -1712,6 +1722,8 @@ method_decl_withattr | attribute_declarations method_decl { ($2 as declaration).attributes = $1 as attribute_list; + if ($2 is procedure_definition && ($2 as procedure_definition).proc_header != null) + ($2 as procedure_definition).proc_header.attributes = $1 as attribute_list; $$ = $2; } ; diff --git a/Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs b/Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs index 7c5034d6d..82e23f027 100644 --- a/Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs +++ b/Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs @@ -2,7 +2,7 @@ // GPPG version 1.3.6 // Machine: IVAN-PC -// DateTime: 08.04.2018 15:51:57 +// DateTime: 02.05.2018 20:34:18 // UserName: Ivan // Input file @@ -2520,17 +2520,27 @@ public partial class GPPGParser: ShiftReduceParser class_attributes1, class_attribute { - ValueStack[ValueStack.Depth-2].ob = ((class_attribute)ValueStack[ValueStack.Depth-2].ob) | ((class_attribute)ValueStack[ValueStack.Depth-1].ob); - CurrentSemanticValue.ob = ValueStack[ValueStack.Depth-2].ob; + CurrentSemanticValue.ob = ((class_attribute)ValueStack[ValueStack.Depth-2].ob) | ((class_attribute)ValueStack[ValueStack.Depth-1].ob); + //$$ = $1; } break; case 289: // class_or_interface_keyword -> tkClass @@ -3861,6 +3871,8 @@ public partial class GPPGParser: ShiftReduceParser attribute_declarations, method_decl { (ValueStack[ValueStack.Depth-1].stn as declaration).attributes = ValueStack[ValueStack.Depth-2].stn as attribute_list; + if (ValueStack[ValueStack.Depth-1].stn is procedure_definition && (ValueStack[ValueStack.Depth-1].stn as procedure_definition).proc_header != null) + (ValueStack[ValueStack.Depth-1].stn as procedure_definition).proc_header.attributes = ValueStack[ValueStack.Depth-2].stn as attribute_list; CurrentSemanticValue.stn = ValueStack[ValueStack.Depth-1].stn; } break; diff --git a/TestSuite/CompilationSamples/Program1129.pas b/TestSuite/CompilationSamples/Program1129.pas new file mode 100644 index 000000000..a98f6190e --- /dev/null +++ b/TestSuite/CompilationSamples/Program1129.pas @@ -0,0 +1,10 @@ +type + t1 = class + [System.Runtime.InteropServices.DllImport('kernel32.dll')] + class function Beep(a,b: integer): boolean; external;//Подпрограмма должна иметь атрибут DllImport + + end; + +begin + writeln(t1.Beep(200,400)); +end. \ No newline at end of file diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index d2320a155..671cbef1f 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -12161,6 +12161,7 @@ namespace PascalABCCompiler.TreeConverter if (_procedure_definition.proc_body != null) if (!is_pinvoke(_procedure_definition.proc_body)) AddError(get_location(_procedure_definition.proc_body), "EXPECTED_EXTERNAL_STATEMENT"); + must_visit_body = true; } if (contextChanger.IsActive()) @@ -12448,8 +12449,8 @@ namespace PascalABCCompiler.TreeConverter { make_attributes_for_declaration(_function_header, context.top_function); } - if (context.converted_type != null && has_dll_import_attribute(context.top_function)) - AddError(get_dll_import_attribute(context.top_function).location, "DLLIMPORT_ATTRIBUTE_CANNOT_BE_APPLIED_TO_METHOD"); + //if (context.converted_type != null && has_dll_import_attribute(context.top_function)) + // AddError(get_dll_import_attribute(context.top_function).location, "DLLIMPORT_ATTRIBUTE_CANNOT_BE_APPLIED_TO_METHOD"); if (_function_header.name.class_name != null) with_class_name = true; if (_function_header.class_keyword && !has_static_attr(_function_header.proc_attributes.proc_attributes))