From 6490b69c1e30c1662b2063d8f253a6952e65455c Mon Sep 17 00:00:00 2001 From: Hugo Guerrier Date: Thu, 23 May 2024 10:52:27 +0200 Subject: [PATCH] Add support for .cgpr files into GPR project handling --- ada/documentation.py | 4 +- extensions/analysis/c_api/header | 2 + extensions/java_api/jni_funcs | 1 + extensions/java_api/jni_impl | 19 +- extensions/java_api/main_class | 73 +++++--- extensions/java_api/ni_funcs | 2 + extensions/ocaml_api/module_struct | 5 +- extensions/python | 4 + ...libadalang-implementation-c-extensions.adb | 58 +++--- ...libadalang-implementation-c-extensions.ads | 16 +- testsuite/drivers/java_driver.py | 11 ++ testsuite/shared/gpr_context/empty.cgpr | 3 + testsuite/tests/c_api/gpr_config_file/main.c | 40 ++++ .../tests/c_api/gpr_config_file/test.out | 6 + .../tests/c_api/gpr_config_file/test.yaml | 7 + testsuite/tests/c_api/gpr_context/main.c | 2 +- .../tests/c_api/gpr_default_charset/main.c | 2 +- testsuite/tests/c_api/gpr_error/main.c | 2 +- testsuite/tests/c_api/gpr_implicit/main.c | 5 +- .../tests/c_api/gpr_unit_provider/main.c | 2 +- .../tests/c_api/prep_gpr_line_mode/main.c | 3 +- .../project_manager/ProjectManager.java | 171 +++++++++++++++--- .../project_manager/graal_c_api/test.out | 57 ++++++ .../project_manager/graal_c_api/test.yaml | 7 + .../java_api/project_manager/jni/test.out | 57 ++++++ .../java_api/project_manager/jni/test.yaml | 7 + .../project_manager/sources/calendar.gpr | 3 + .../sources/calendar_src/main.adb | 8 + .../project_manager/sources/empty.cgpr | 3 + .../project_manager/sources/nosuchtarget.gpr | 1 + .../project_manager/sources/other_naming.cgpr | 11 ++ .../project_manager/sources/src1/name.other | 3 + 32 files changed, 501 insertions(+), 94 deletions(-) create mode 100644 testsuite/shared/gpr_context/empty.cgpr create mode 100644 testsuite/tests/c_api/gpr_config_file/main.c create mode 100644 testsuite/tests/c_api/gpr_config_file/test.out create mode 100644 testsuite/tests/c_api/gpr_config_file/test.yaml create mode 100644 testsuite/tests/java_api/project_manager/sources/calendar.gpr create mode 100644 testsuite/tests/java_api/project_manager/sources/calendar_src/main.adb create mode 100644 testsuite/tests/java_api/project_manager/sources/empty.cgpr create mode 100644 testsuite/tests/java_api/project_manager/sources/other_naming.cgpr create mode 100644 testsuite/tests/java_api/project_manager/sources/src1/name.other diff --git a/ada/documentation.py b/ada/documentation.py index f78e245b6..7119450fd 100644 --- a/ada/documentation.py +++ b/ada/documentation.py @@ -33,8 +33,8 @@ """, 'libadalang.gpr_project_load_implicit': """ Load an implicit project in the current directory. This function uses - This function uses ``GNATCOLL.Projects.Load_Implicit_Project`` to load - the ``_default.gpr`` project file. + ``GNATCOLL.Projects.Load_Implicit_Project`` to load the + ``_default.gpr`` project file. """, 'libadalang.gpr_project_free': """ Free resources allocated for ``Self``. diff --git a/extensions/analysis/c_api/header b/extensions/analysis/c_api/header index 1bc01b109..c37fca3b5 100644 --- a/extensions/analysis/c_api/header +++ b/extensions/analysis/c_api/header @@ -41,6 +41,7 @@ ${capi.get_name('gpr_project_load')}( const ${scn_var_type} *scenario_vars, const char *target, const char *runtime, + const char *config_file, ${project_type} *project, ${str_array_type} *errors ); @@ -50,6 +51,7 @@ extern void ${capi.get_name('gpr_project_load_implicit')}( const char *target, const char *runtime, + const char *config_file, ${project_type} *project, ${str_array_type} *errors ); diff --git a/extensions/java_api/jni_funcs b/extensions/java_api/jni_funcs index 5049898e1..2b07dff00 100644 --- a/extensions/java_api/jni_funcs +++ b/extensions/java_api/jni_funcs @@ -18,6 +18,7 @@ nat = c_api.get_name ScenarioVariable[] scenarioVariables, String target, String runtime, + String configFile, List diagnostics ); diff --git a/extensions/java_api/jni_impl b/extensions/java_api/jni_impl index e320062ab..eccfd479a 100644 --- a/extensions/java_api/jni_impl +++ b/extensions/java_api/jni_impl @@ -93,6 +93,7 @@ ${api.jni_func_sig("gpr_project_load", "jobject")}( jobjectArray scenario_variables, jstring target, jstring runtime, + jstring config_file, jobject diagnostics ) { // Create the scenario variable array @@ -128,8 +129,9 @@ ${api.jni_func_sig("gpr_project_load", "jobject")}( } // Create the common project arguments - const char *target_c = to_c_string(env, target); - const char *runtime_c = to_c_string(env, runtime); + const char *target_c = target == NULL ? NULL : to_c_string(env, target); + const char *runtime_c = runtime == NULL ? NULL : to_c_string(env, runtime); + const char *config_file_c = config_file == NULL ? NULL : to_c_string(env, config_file); ${project_type} res = NULL; ${str_array_type} errors = NULL; @@ -139,6 +141,7 @@ ${api.jni_func_sig("gpr_project_load", "jobject")}( ${nat("gpr_project_load_implicit")}( target_c, runtime_c, + config_file_c, &res, &errors ); @@ -149,6 +152,7 @@ ${api.jni_func_sig("gpr_project_load", "jobject")}( scenario_variables_native, target_c, runtime_c, + config_file_c, &res, &errors ); @@ -164,8 +168,15 @@ ${api.jni_func_sig("gpr_project_load", "jobject")}( } // Free the translated strings - (*env)->ReleaseStringUTFChars(env, target, target_c); - (*env)->ReleaseStringUTFChars(env, runtime, runtime_c); + if (target_c != NULL) { + (*env)->ReleaseStringUTFChars(env, target, target_c); + } + if (runtime_c != NULL) { + (*env)->ReleaseStringUTFChars(env, runtime, runtime_c); + } + if (config_file_c != NULL) { + (*env)->ReleaseStringUTFChars(env, config_file, config_file_c); + } // The `errors` pointer is not allocated if an exception was raised during // project file loading. diff --git a/extensions/java_api/main_class b/extensions/java_api/main_class index 1855793ea..9ebbb05f4 100644 --- a/extensions/java_api/main_class +++ b/extensions/java_api/main_class @@ -265,16 +265,16 @@ nat = c_api.get_name * Create a project manager for the given project file. * * @param projectFile The GPR project file to load. - * @return The newly created project manager. */ public static ProjectManager create( final String projectFile ) { - return create( + return internalCreate( projectFile, null, - "", - "" + null, + null, + null ); } @@ -282,39 +282,51 @@ nat = c_api.get_name * Create a project manager from a project file, target and runtime. If the * project file is null, then an implicit project is loaded. * - * @param projectFile The GPR file to load. - * @param scenarioVariables The scenario variables for the project, it can be null. - * @param target The target to load. - * @param runtime The runtime to load. - * @return The newly created project manager. + * @param projectFile The GPR project file to use, if any. If null, an + * implicit project will be loaded. + * @param scenarioVariables Scenario variables to use during the + * project loading. This can be null. + * @param target Ada target to use. This can be null. + * @param runtime Ada runtime to use. This can be null. + * @param configFile The absolute path to a .cgpr file to use during + * the project loading. This can be null. */ public static ProjectManager create( final String projectFile, final ScenarioVariable[] scenarioVariables, final String target, - final String runtime + final String runtime, + final String configFile ) { return internalCreate( projectFile, scenarioVariables, target, - runtime + runtime, + configFile ); } /** * Create a project manager for an implicit project. The current directory * is used as project source directory. + * + * @param target Ada target to use. This can be null. + * @param runtime Ada runtime to use. This can be null. + * @param configFile The absolute path to a .cgpr file to use during + * the project loading. This can be null. */ public static ProjectManager createImplicit( final String target, - final String runtime + final String runtime, + final String configFile ) { return internalCreate( null, null, target, - runtime + runtime, + configFile ); } @@ -324,19 +336,31 @@ nat = c_api.get_name * * @param projectFile The GPR project file to use, if any. If null, an * implicit project will be loaded. + * @param scenarioVariables Scenario variables to use during the + * project loading. This can be null. + * @param target Ada target to use. This can be null. + * @param runtime Ada runtime to use. This can be null. + * @param configFile The absolute path to a .cgpr file to use during + * the project loading. This can be null. */ private static ProjectManager internalCreate( final String projectFile, final ScenarioVariable[] scenarioVariables, final String target, - final String runtime + final String runtime, + final String configFile ) { if(ImageInfo.inImageCode()) { - // Create the scenario variable array + // Declare native values final Pointer scenarioVariablesNative; - final int scenarioVariableNativeSize = SizeOf.get(ScenarioVariableNative.class); + final CCharPointer targetNative; + final CCharPointer runtimeNative; + final CCharPointer configFileNative; + final Pointer errorsPointer; + // Create the scenario variable array + final int scenarioVariableNativeSize = SizeOf.get(ScenarioVariableNative.class); if(scenarioVariables != null && scenarioVariables.length > 0) { final int size = scenarioVariables.length + 1; scenarioVariablesNative = UnmanagedMemory.calloc( @@ -355,10 +379,11 @@ nat = c_api.get_name final Pointer projectPointer = StackValue.get(SizeOf.get(VoidPointer.class)); projectPointer.writeWord(0, WordFactory.nullPointer()); - // Create the common native arguments - final CCharPointer targetNative = toCString(target); - final CCharPointer runtimeNative = toCString(runtime); - final Pointer errorsPointer = StackValue.get(SizeOf.get(VoidPointer.class)); + // Fill the native arguments + targetNative = target == null ? WordFactory.nullPointer() : toCString(target); + runtimeNative = runtime == null ? WordFactory.nullPointer() : toCString(runtime); + configFileNative = configFile == null ? WordFactory.nullPointer() : toCString(configFile); + errorsPointer = StackValue.get(SizeOf.get(WordPointer.class)); errorsPointer.writeWord(0, WordFactory.nullPointer()); // If the provided project file is null, call the implicit project loading. @@ -367,6 +392,7 @@ nat = c_api.get_name NI_LIB.${nat("gpr_project_load_implicit")}( targetNative, runtimeNative, + configFileNative, projectPointer, errorsPointer ); @@ -377,6 +403,7 @@ nat = c_api.get_name scenarioVariablesNative, targetNative, runtimeNative, + configFileNative, projectPointer, errorsPointer ); @@ -384,8 +411,9 @@ nat = c_api.get_name } // Free the allocated strings - UnmanagedMemory.free(targetNative); - UnmanagedMemory.free(runtimeNative); + if (target != null) UnmanagedMemory.free(targetNative); + if (runtime != null) UnmanagedMemory.free(runtimeNative); + if (configFile != null) UnmanagedMemory.free(configFileNative); // Check the langkit exception and cast it into a project manager error try { @@ -440,6 +468,7 @@ nat = c_api.get_name scenarioVariables, target, runtime, + configFile, diagnostics ); diff --git a/extensions/java_api/ni_funcs b/extensions/java_api/ni_funcs index 7f739a179..78a282c71 100644 --- a/extensions/java_api/ni_funcs +++ b/extensions/java_api/ni_funcs @@ -14,6 +14,7 @@ nat = c_api.get_name Pointer scenarioVariable, CCharPointer target, CCharPointer runtime, + CCharPointer configFile, Pointer project, Pointer errors ); @@ -24,6 +25,7 @@ nat = c_api.get_name public static native void ${nat("gpr_project_load_implicit")}( CCharPointer target, CCharPointer runtime, + CCharPointer configFile, Pointer project, Pointer errors ); diff --git a/extensions/ocaml_api/module_struct b/extensions/ocaml_api/module_struct index 8b83bbabe..db60b7a9e 100644 --- a/extensions/ocaml_api/module_struct +++ b/extensions/ocaml_api/module_struct @@ -87,7 +87,7 @@ module GPRProject = struct let gpr_project_load = foreign ~from:c_lib "${capi.get_name("gpr_project_load")}" (string @-> project_scenario_variable @-> string - @-> string @-> ptr c_type @-> ptr string_array @-> raisable void) + @-> string @-> string @-> ptr c_type @-> ptr string_array @-> raisable void) let gpr_project_create_preprocessor = foreign ~from:c_lib "${capi.get_name("gpr_project_create_preprocessor")}" @@ -101,7 +101,8 @@ module GPRProject = struct (* Use allocate_n to avoid having to give it an initial value *) let result = allocate_n ~count:1 c_type in let errors = allocate_n ~count:1 string_array in - gpr_project_load project_file scenario_vars target runtime result errors ; + gpr_project_load + project_file scenario_vars target runtime "" result errors ; (* Not sure what to do with errors here as we already have an exception *) !@ result diff --git a/extensions/python b/extensions/python index a2a267a2f..0aa5fff40 100644 --- a/extensions/python +++ b/extensions/python @@ -126,6 +126,7 @@ class GPRProject: scenario_vars: Dict[str, str] = {}, target: Opt[str] = None, runtime: Opt[str] = None, + config_file: Opt[str] = None, print_errors: bool = True): """ Load a GPR project file. @@ -152,6 +153,7 @@ class GPRProject: c_project_file = _coerce_bytes('project_file', project_file) c_target = _coerce_bytes('target', target, or_none=True) c_runtime = _coerce_bytes('runtime', runtime, or_none=True) + c_config_file = _coerce_bytes('config_file', config_file, or_none=True) if scenario_vars: items = scenario_vars.items() @@ -178,6 +180,7 @@ class GPRProject: c_scenario_vars, c_target, c_runtime, + c_config_file, ctypes.byref(c_project), ctypes.byref(c_errors), ) @@ -377,6 +380,7 @@ class GPRProject: ctypes.POINTER(_c_scenario_variable), ctypes.c_char_p, ctypes.c_char_p, + ctypes.c_char_p, ctypes.POINTER(_c_type), ctypes.POINTER(_c_string_array_ptr)], None, diff --git a/extensions/src/libadalang-implementation-c-extensions.adb b/extensions/src/libadalang-implementation-c-extensions.adb index 240040433..147196672 100644 --- a/extensions/src/libadalang-implementation-c-extensions.adb +++ b/extensions/src/libadalang-implementation-c-extensions.adb @@ -63,13 +63,13 @@ package body Libadalang.Implementation.C.Extensions is -- Add an error message to GPR_Errors procedure Load_Project - (Project_File : chars_ptr; - Scenario_Vars : System.Address; - Target, Runtime : chars_ptr; - Tree : out Project_Tree_Access; - Env : out Project_Environment_Access; - Errors : out String_Vectors.Vector; - Exc : out Exception_Occurrence); + (Project_File : chars_ptr; + Scenario_Vars : System.Address; + Target, Runtime, Config_File : chars_ptr; + Tree : out Project_Tree_Access; + Env : out Project_Environment_Access; + Errors : out String_Vectors.Vector; + Exc : out Exception_Occurrence); -- Helper to load a project file from C arguments. May set Exc to a -- ``GNATCOLL.Projects.Invalid_Project`` exception if the project cannot be -- loaded: in this case it is up to the caller to re-raise it. @@ -158,20 +158,22 @@ package body Libadalang.Implementation.C.Extensions is ------------------ procedure Load_Project - (Project_File : chars_ptr; - Scenario_Vars : System.Address; - Target, Runtime : chars_ptr; - Tree : out Project_Tree_Access; - Env : out Project_Environment_Access; - Errors : out String_Vectors.Vector; - Exc : out Exception_Occurrence) + (Project_File : chars_ptr; + Scenario_Vars : System.Address; + Target, Runtime, Config_File : chars_ptr; + Tree : out Project_Tree_Access; + Env : out Project_Environment_Access; + Errors : out String_Vectors.Vector; + Exc : out Exception_Occurrence) is - PF : constant String := + PF : constant String := (if Project_File = Null_Ptr then "" else Value (Project_File)); - Target_Value : constant String := + Target_Value : constant String := (if Target = Null_Ptr then "" else Value (Target)); - Runtime_Value : constant String := + Runtime_Value : constant String := (if Runtime = Null_Ptr then "" else Value (Runtime)); + Config_File_Value : constant String := + (if Config_File = Null_Ptr then "" else Value (Config_File)); begin GNAT.Task_Lock.Lock; @@ -181,6 +183,9 @@ package body Libadalang.Implementation.C.Extensions is Tree := new Project_Tree; Initialize (Env); Env.Set_Target_And_Runtime (Target_Value, Runtime_Value); + if Config_File_Value /= "" then + Env.Set_Config_File (Create (Filesystem_String (Config_File_Value))); + end if; if Scenario_Vars /= System.Null_Address then declare Vars : ada_gpr_project_scenario_variable_array @@ -283,11 +288,11 @@ package body Libadalang.Implementation.C.Extensions is -------------------------- procedure ada_gpr_project_load - (Project_File : chars_ptr; - Scenario_Vars : System.Address; - Target, Runtime : chars_ptr; - Project : access ada_gpr_project; - Errors : access ada_string_array_ptr) + (Project_File : chars_ptr; + Scenario_Vars : System.Address; + Target, Runtime, Config_File : chars_ptr; + Project : access ada_gpr_project; + Errors : access ada_string_array_ptr) is Prj : Project_Tree_Access; Env : Project_Environment_Access; @@ -301,6 +306,7 @@ package body Libadalang.Implementation.C.Extensions is Scenario_Vars, Target, Runtime, + Config_File, Prj, Env, Err, @@ -339,9 +345,9 @@ package body Libadalang.Implementation.C.Extensions is ----------------------------------- procedure ada_gpr_project_load_implicit - (Target, Runtime : chars_ptr; - Project : access ada_gpr_project; - Errors : access ada_string_array_ptr) + (Target, Runtime, Config_File : chars_ptr; + Project : access ada_gpr_project; + Errors : access ada_string_array_ptr) is begin ada_gpr_project_load @@ -349,6 +355,7 @@ package body Libadalang.Implementation.C.Extensions is System.Null_Address, Target, Runtime, + Config_File, Project, Errors); end ada_gpr_project_load_implicit; @@ -535,6 +542,7 @@ package body Libadalang.Implementation.C.Extensions is Scenario_Vars, Target, Runtime, + Null_Ptr, Tree, Env, Dummy_Errors, diff --git a/extensions/src/libadalang-implementation-c-extensions.ads b/extensions/src/libadalang-implementation-c-extensions.ads index d82b26b4f..56f63b917 100644 --- a/extensions/src/libadalang-implementation-c-extensions.ads +++ b/extensions/src/libadalang-implementation-c-extensions.ads @@ -44,11 +44,11 @@ package Libadalang.Implementation.C.Extensions is -- in such arrays must be a null/null association. procedure ada_gpr_project_load - (Project_File : chars_ptr; - Scenario_Vars : System.Address; - Target, Runtime : chars_ptr; - Project : access ada_gpr_project; - Errors : access ada_string_array_ptr) + (Project_File : chars_ptr; + Scenario_Vars : System.Address; + Target, Runtime, Config_File : chars_ptr; + Project : access ada_gpr_project; + Errors : access ada_string_array_ptr) with Export, Convention => C; -- Load a project file with the given parameter. On success, set -- ``Project`` to a newly allocated ``ada_gpr_project``, as well as a @@ -56,9 +56,9 @@ package Libadalang.Implementation.C.Extensions is -- ``Invalid_Project`` exception on failure. procedure ada_gpr_project_load_implicit - (Target, Runtime : chars_ptr; - Project : access ada_gpr_project; - Errors : access ada_string_array_ptr) + (Target, Runtime, Config_File : chars_ptr; + Project : access ada_gpr_project; + Errors : access ada_string_array_ptr) with Export, Convention => C; -- Load an implicit project. On success, set ``Project`` to a newly -- allocated ``ada_gpr_project``. diff --git a/testsuite/drivers/java_driver.py b/testsuite/drivers/java_driver.py index ba80f37ce..be23173c3 100644 --- a/testsuite/drivers/java_driver.py +++ b/testsuite/drivers/java_driver.py @@ -266,6 +266,17 @@ def run(self): )) args.append(main_java) + # Run the "pre_python" code if there is one + if self.test_env.get('pre_python'): + exec( + self.test_env['pre_python'], + { + 'test_env': self.test_env, + 'os': os, + 'subprocess': subprocess + } + ) + # Run the test main. Mains expect a GPR project path as their only # argument. self.run_and_check(args + [project_path]) diff --git a/testsuite/shared/gpr_context/empty.cgpr b/testsuite/shared/gpr_context/empty.cgpr new file mode 100644 index 000000000..14a6132fe --- /dev/null +++ b/testsuite/shared/gpr_context/empty.cgpr @@ -0,0 +1,3 @@ +configuration project Default is + -- Will raise an error at project loading +end Default; diff --git a/testsuite/tests/c_api/gpr_config_file/main.c b/testsuite/tests/c_api/gpr_config_file/main.c new file mode 100644 index 000000000..08a679342 --- /dev/null +++ b/testsuite/tests/c_api/gpr_config_file/main.c @@ -0,0 +1,40 @@ +#include +#include + +#include "libadalang.h" + +#include "langkit_dump.h" +#include "langkit_text.h" + +int +main (void) +{ + ada_gpr_project gpr; + ada_string_array_ptr errors; + ada_gpr_project_scenario_variable scn_var_trail = {NULL, NULL}; + + printf ("== config file ==\n\n"); + + ada_gpr_project_load ( + "simple/p.gpr", + &scn_var_trail, + NULL, + NULL, + "empty.cgpr", + &gpr, + &errors + ); + + print_exception(false); + if (errors->length > 0) { + printf("Errors:\n"); + for (int i = 0 ; i < errors->length; i++) { + printf(" - %s\n", errors->c_ptr[i]); + } + } + + ada_gpr_project_free (gpr); + abort_on_exception (); + ada_free_string_array (errors); + abort_on_exception (); +} \ No newline at end of file diff --git a/testsuite/tests/c_api/gpr_config_file/test.out b/testsuite/tests/c_api/gpr_config_file/test.out new file mode 100644 index 000000000..f4ebbc966 --- /dev/null +++ b/testsuite/tests/c_api/gpr_config_file/test.out @@ -0,0 +1,6 @@ +== config file == + +Got no exception + +Errors: + - p.gpr:1:09: no languages defined for this project diff --git a/testsuite/tests/c_api/gpr_config_file/test.yaml b/testsuite/tests/c_api/gpr_config_file/test.yaml new file mode 100644 index 000000000..e0f904cf8 --- /dev/null +++ b/testsuite/tests/c_api/gpr_config_file/test.yaml @@ -0,0 +1,7 @@ +driver: c-api +compile_units: [main.c] +input_sources: [] +sync_trees: + - ../../../shared/gpr_context +control: + - [XFAIL, "valgrind", "W320-022: GNATCOLL.Projects leaks no longer fixed"] diff --git a/testsuite/tests/c_api/gpr_context/main.c b/testsuite/tests/c_api/gpr_context/main.c index 4b4dfe37f..616555352 100644 --- a/testsuite/tests/c_api/gpr_context/main.c +++ b/testsuite/tests/c_api/gpr_context/main.c @@ -35,7 +35,7 @@ check (const char *label, printf("== %s ==\n\n", label); /* Load the requested project tree. */ - ada_gpr_project_load (root_project, &scn_var_trail, NULL, NULL, &gpr, + ada_gpr_project_load (root_project, &scn_var_trail, NULL, NULL, NULL, &gpr, &errors); abort_on_exception (); diff --git a/testsuite/tests/c_api/gpr_default_charset/main.c b/testsuite/tests/c_api/gpr_default_charset/main.c index 54b13ced0..2d2c64fd3 100644 --- a/testsuite/tests/c_api/gpr_default_charset/main.c +++ b/testsuite/tests/c_api/gpr_default_charset/main.c @@ -21,7 +21,7 @@ run (const char *project_file) int i; char *charset; - ada_gpr_project_load (project_file, &scn_var_trail, NULL, NULL, &gpr, + ada_gpr_project_load (project_file, &scn_var_trail, NULL, NULL, NULL, &gpr, &errors); abort_on_exception (); diff --git a/testsuite/tests/c_api/gpr_error/main.c b/testsuite/tests/c_api/gpr_error/main.c index b2ac0fc67..226db4f9a 100644 --- a/testsuite/tests/c_api/gpr_error/main.c +++ b/testsuite/tests/c_api/gpr_error/main.c @@ -20,7 +20,7 @@ run (const char *project_file) printf ("== %s ==\n", project_file); - ada_gpr_project_load (project_file, &scn_var_trail, NULL, NULL, &gpr, + ada_gpr_project_load (project_file, &scn_var_trail, NULL, NULL, NULL, &gpr, &errors); had_exception = print_exception (false); diff --git a/testsuite/tests/c_api/gpr_implicit/main.c b/testsuite/tests/c_api/gpr_implicit/main.c index eae03ceba..005ed7178 100644 --- a/testsuite/tests/c_api/gpr_implicit/main.c +++ b/testsuite/tests/c_api/gpr_implicit/main.c @@ -17,8 +17,9 @@ main (void) printf ("== simple ==\n\n"); ada_gpr_project_load_implicit ( - "", - "", + NULL, + NULL, + NULL, &gpr, &errors ); diff --git a/testsuite/tests/c_api/gpr_unit_provider/main.c b/testsuite/tests/c_api/gpr_unit_provider/main.c index 05ace94e6..15102d242 100644 --- a/testsuite/tests/c_api/gpr_unit_provider/main.c +++ b/testsuite/tests/c_api/gpr_unit_provider/main.c @@ -26,7 +26,7 @@ run (const char *project_file, const char *subproject) project_file, subproject == NULL ? "" : subproject); - ada_gpr_project_load (project_file, &scn_var_trail, NULL, NULL, &gpr, + ada_gpr_project_load (project_file, &scn_var_trail, NULL, NULL, NULL, &gpr, &errors); abort_on_exception (); diff --git a/testsuite/tests/c_api/prep_gpr_line_mode/main.c b/testsuite/tests/c_api/prep_gpr_line_mode/main.c index 52f7b9c64..2a1cae191 100644 --- a/testsuite/tests/c_api/prep_gpr_line_mode/main.c +++ b/testsuite/tests/c_api/prep_gpr_line_mode/main.c @@ -27,7 +27,8 @@ run_test (int *line_mode) printf ("%i", *line_mode); printf(" ==\n\n"); - ada_gpr_project_load ("foo.gpr", &scn_var_trail, NULL, NULL, &gpr, &errors); + ada_gpr_project_load ("foo.gpr", &scn_var_trail, NULL, NULL, NULL, &gpr, + &errors); abort_on_exception (); ada_free_string_array (errors); diff --git a/testsuite/tests/java_api/project_manager/ProjectManager.java b/testsuite/tests/java_api/project_manager/ProjectManager.java index fce060934..0e2768a13 100644 --- a/testsuite/tests/java_api/project_manager/ProjectManager.java +++ b/testsuite/tests/java_api/project_manager/ProjectManager.java @@ -52,13 +52,24 @@ private static void projectInfo( Libadalang.UnitProvider unitProvider = project.getProvider(subproject); + // Create an event handler + Libadalang.EventHandler eh = Libadalang.EventHandler.create( + (ctx, name, from, found, notFoundIsError) -> { + if (!found && notFoundIsError) { + System.out.println( + "Cannot find file " + new File(name).getName() + ); + } + }, + null); + try( Libadalang.AnalysisContext context = Libadalang.AnalysisContext.create( null, null, unitProvider, - null, + eh, true, 8 ) @@ -68,43 +79,109 @@ private static void projectInfo( = context.getUnitFromFile(file); System.out.println("File " + unit.getFileName(false)); System.out.println(" root = " + unit.getRoot()); + System.out.println( + " deps = " + + Arrays.toString( + ((Libadalang.CompilationUnit) unit.getRoot()) + .pUnitDependencies() + ) + ); } } } + /** Simply open the given GPR file and display its source files. */ + private static void openProject(String gprFile) { + openProject( + gprFile, + null + ); + } + /** - * Open a gpr project and list its source files. + * Open the given GPR file with a subproject to use, then display its + * source files. + */ + private static void openProject( + String gprFile, + String subproject + ) { + openProject( + gprFile, + subproject, + null, + true + ); + } + + /** + * Open a GPR project and list its source files. * * @param gprFile The gpr file - * @param lookInProjectPath If the function should look for the GPR file + * @param subproject The subproject to use. If null, use the root project * in the given project path + * @param scenarioVariables Scenario variuables to apply during project + * opening + * @param lookInProjectPath If the function should look for the GPR file + */ + private static void openProject( + String gprFile, + String subproject, + Libadalang.ScenarioVariable[] scenarioVariables, + boolean lookInProjectPath + ) { + openProject( + gprFile, + subproject, + null, + scenarioVariables, + lookInProjectPath + ); + } + + /** + * Open a gpr project and list its source files. + * + * @param gprFile The gpr file * @param subproject The subproject to use. If null, use the root project + * in the given project path + * @param configFile A configuration file to open the project with + * @param scenarioVariables Scenario variuables to apply during project + * opening + * @param lookInProjectPath If the function should look for the GPR file */ private static void openProject( String gprFile, + String subproject, + String configFile, Libadalang.ScenarioVariable[] scenarioVariables, - boolean lookInProjectPath, - String subproject + boolean lookInProjectPath ) { - String headerMsg = "Open " + gprFile; + String headerMsg = "Open " + Paths.get(gprFile).getFileName(); if (subproject != null) { headerMsg += " (" + subproject + ")"; } + if (configFile != null) { + headerMsg += " with config " + configFile; + } header(headerMsg); // Resolve the project file if needed - String projectFile = gprFile; if(lookInProjectPath) { - projectFile = Paths.get(projectPath, gprFile).toString(); + gprFile = Paths.get(projectPath, gprFile).toString(); + configFile = configFile == null ? + null : + Paths.get(projectPath, configFile).toString(); } try( Libadalang.ProjectManager project = Libadalang.ProjectManager.create( - projectFile, + gprFile, scenarioVariables, - "", - "" + null, + null, + configFile ) ) { projectInfo(project, subproject); @@ -119,23 +196,23 @@ private static void openProject( * Test opening a valid project. */ private static void testValid() { - openProject("p1.gpr", null, true, null); + openProject("p1.gpr"); openProject( "p2.gpr", + null, new Libadalang.ScenarioVariable[] { Libadalang.ScenarioVariable.create("SRC_DIR", "src2_1"), Libadalang.ScenarioVariable.create("USELESS", "useless") }, - true, - null + true ); openProject( "p2.gpr", + null, new Libadalang.ScenarioVariable[] { Libadalang.ScenarioVariable.create("SRC_DIR", "src2_2") }, - true, - null + true ); } @@ -143,27 +220,27 @@ private static void testValid() { * Test opening an invalid project. */ private static void testInvalid() { - openProject("invalid.gpr", null, true, null); + openProject("invalid.gpr"); } /** * Test opening an inexistant project. */ private static void testInexistant() { - openProject("idonotexist.gpr", null, false, null); + openProject("idonotexist.gpr", null, null, false); } /** * Test opening an aggregate project. */ private static void testAggregate() { - openProject("agg.gpr", null, true, "nosuchsubproject"); - openProject("agg.gpr", null, true, "p1"); - openProject("agg.gpr", null, true, "p2"); + openProject("agg.gpr", "nosuchsubproject"); + openProject("agg.gpr", "p1"); + openProject("agg.gpr", "p2"); } private static void testNoSuchTarget() { - openProject("nosuchtarget.gpr", null, true, null); + openProject("nosuchtarget.gpr"); } /** @@ -175,8 +252,9 @@ private static void testImplicit() { try ( Libadalang.ProjectManager project = Libadalang.ProjectManager.createImplicit( - "", - "" + null, + null, + null ) ) { projectInfo(project, null); @@ -187,6 +265,47 @@ private static void testImplicit() { } } + private static void testConfigFile() { + openProject( + "p1.gpr", + null, + "other_naming.cgpr", + null, + true + ); + } + + private static void testRuntimeConfigFile() { + openProject("calendar.gpr"); + openProject( + Paths.get(projectPath, "calendar.gpr").toString(), + null, + "light_runtime.cgpr", + null, + false + ); + } + + private static void testEmptyConfigFile() { + openProject( + "p1.gpr", + null, + "empty.cgpr", + null, + true + ); + } + + private static void testInexistantConfigFile() { + openProject( + Paths.get(projectPath, "p1.gpr").toString(), + null, + "idonotexist.cgpr", + null, + false + ); + } + /** * Run the tests */ @@ -198,5 +317,9 @@ public static void main(String[] args) { testAggregate(); testNoSuchTarget(); testImplicit(); + testConfigFile(); + testRuntimeConfigFile(); + testEmptyConfigFile(); + testInexistantConfigFile(); } } diff --git a/testsuite/tests/java_api/project_manager/graal_c_api/test.out b/testsuite/tests/java_api/project_manager/graal_c_api/test.out index a1ddc17c5..22d1e51ae 100644 --- a/testsuite/tests/java_api/project_manager/graal_c_api/test.out +++ b/testsuite/tests/java_api/project_manager/graal_c_api/test.out @@ -1,22 +1,28 @@ --- Open p1.gpr --- File pk1.ads root = + deps = [] File pk2.ads root = + deps = [, ] ------------------- --- Open p2.gpr --- File pk3.ads root = + deps = [] File pk4.ads root = + deps = [, ] ------------------- --- Open p2.gpr --- File pk3_bis.ads root = + deps = [] File pk4_bis.ads root = + deps = [, ] ------------------- --- Open invalid.gpr --- @@ -36,26 +42,77 @@ no such project: nosuchsubproject --- Open agg.gpr (p1) --- File pk1.ads root = + deps = [] File pk2.ads root = + deps = [, ] ------------------------- --- Open agg.gpr (p2) --- File pk3_bis.ads root = + deps = [] File pk4_bis.ads root = + deps = [, ] ------------------------- --- Open nosuchtarget.gpr --- Error during project opening: [Could not locate exec nosuchtarget-gnatls] +File pk1.ads + root = + deps = [] +File pk2.ads + root = + deps = [, ] ----------------------------- --- Open implicit project --- File pk1.ads root = + deps = [] File pk2.ads root = + deps = [, ] ----------------------------- +--- Open p1.gpr with config other_naming.cgpr --- +File name.other + root = + deps = [] +------------------------------------------------- + +--- Open calendar.gpr --- +File main.adb + root = + deps = [, , , , ] +------------------------- + +--- Open calendar.gpr with config light_runtime.cgpr --- +File main.adb + root = +Cannot find file a-calend.ads +Cannot find file a-calend.ads +Cannot find file a-calend.ads +Cannot find file a-calend.ads +Cannot find file a-calfor.ads +Cannot find file a-calend.ads +Cannot find file a-calend.ads +Cannot find file a-calend.ads +Cannot find file a-calend.ads +Cannot find file a-calfor.ads +Cannot find file a-calend.ads + deps = [, ] +-------------------------------------------------------- + +--- Open p1.gpr with config empty.cgpr --- +Error during project opening: + [p1.gpr:1:09: no languages defined for this project] +------------------------------------------ + +--- Open p1.gpr with config idonotexist.cgpr --- +Error during project opening: + [could not locate main configuration project idonotexist.cgpr] +------------------------------------------------ + diff --git a/testsuite/tests/java_api/project_manager/graal_c_api/test.yaml b/testsuite/tests/java_api/project_manager/graal_c_api/test.yaml index c58d362d6..345206230 100644 --- a/testsuite/tests/java_api/project_manager/graal_c_api/test.yaml +++ b/testsuite/tests/java_api/project_manager/graal_c_api/test.yaml @@ -5,3 +5,10 @@ main_class: ProjectManager projects_path: ../sources/ sync_trees: - ../sources/src1/ +pre_python: + 'subprocess.check_call([ + "gprconfig", + "--batch", + "--config=Ada,,light", + "-o", os.path.join(test_env["working_dir"], "light_runtime.cgpr") + ])' diff --git a/testsuite/tests/java_api/project_manager/jni/test.out b/testsuite/tests/java_api/project_manager/jni/test.out index a1ddc17c5..22d1e51ae 100644 --- a/testsuite/tests/java_api/project_manager/jni/test.out +++ b/testsuite/tests/java_api/project_manager/jni/test.out @@ -1,22 +1,28 @@ --- Open p1.gpr --- File pk1.ads root = + deps = [] File pk2.ads root = + deps = [, ] ------------------- --- Open p2.gpr --- File pk3.ads root = + deps = [] File pk4.ads root = + deps = [, ] ------------------- --- Open p2.gpr --- File pk3_bis.ads root = + deps = [] File pk4_bis.ads root = + deps = [, ] ------------------- --- Open invalid.gpr --- @@ -36,26 +42,77 @@ no such project: nosuchsubproject --- Open agg.gpr (p1) --- File pk1.ads root = + deps = [] File pk2.ads root = + deps = [, ] ------------------------- --- Open agg.gpr (p2) --- File pk3_bis.ads root = + deps = [] File pk4_bis.ads root = + deps = [, ] ------------------------- --- Open nosuchtarget.gpr --- Error during project opening: [Could not locate exec nosuchtarget-gnatls] +File pk1.ads + root = + deps = [] +File pk2.ads + root = + deps = [, ] ----------------------------- --- Open implicit project --- File pk1.ads root = + deps = [] File pk2.ads root = + deps = [, ] ----------------------------- +--- Open p1.gpr with config other_naming.cgpr --- +File name.other + root = + deps = [] +------------------------------------------------- + +--- Open calendar.gpr --- +File main.adb + root = + deps = [, , , , ] +------------------------- + +--- Open calendar.gpr with config light_runtime.cgpr --- +File main.adb + root = +Cannot find file a-calend.ads +Cannot find file a-calend.ads +Cannot find file a-calend.ads +Cannot find file a-calend.ads +Cannot find file a-calfor.ads +Cannot find file a-calend.ads +Cannot find file a-calend.ads +Cannot find file a-calend.ads +Cannot find file a-calend.ads +Cannot find file a-calfor.ads +Cannot find file a-calend.ads + deps = [, ] +-------------------------------------------------------- + +--- Open p1.gpr with config empty.cgpr --- +Error during project opening: + [p1.gpr:1:09: no languages defined for this project] +------------------------------------------ + +--- Open p1.gpr with config idonotexist.cgpr --- +Error during project opening: + [could not locate main configuration project idonotexist.cgpr] +------------------------------------------------ + diff --git a/testsuite/tests/java_api/project_manager/jni/test.yaml b/testsuite/tests/java_api/project_manager/jni/test.yaml index 73801fa6d..0b67311d4 100644 --- a/testsuite/tests/java_api/project_manager/jni/test.yaml +++ b/testsuite/tests/java_api/project_manager/jni/test.yaml @@ -5,3 +5,10 @@ main_class: ProjectManager projects_path: ../sources/ sync_trees: - ../sources/src1/ +pre_python: + 'subprocess.check_call([ + "gprconfig", + "--batch", + "--config=Ada,,light", + "-o", os.path.join(test_env["working_dir"], "light_runtime.cgpr") + ])' diff --git a/testsuite/tests/java_api/project_manager/sources/calendar.gpr b/testsuite/tests/java_api/project_manager/sources/calendar.gpr new file mode 100644 index 000000000..861b14669 --- /dev/null +++ b/testsuite/tests/java_api/project_manager/sources/calendar.gpr @@ -0,0 +1,3 @@ +project Calendar is + for Source_Dirs use ("calendar_src"); +end Calendar; diff --git a/testsuite/tests/java_api/project_manager/sources/calendar_src/main.adb b/testsuite/tests/java_api/project_manager/sources/calendar_src/main.adb new file mode 100644 index 000000000..b112e4157 --- /dev/null +++ b/testsuite/tests/java_api/project_manager/sources/calendar_src/main.adb @@ -0,0 +1,8 @@ +with Ada.Calendar; use Ada.Calendar; +with Ada.Calendar.Formatting; use Ada.Calendar.Formatting; + +procedure Main is + Now : Time := Clock; +begin + null; +end Main; diff --git a/testsuite/tests/java_api/project_manager/sources/empty.cgpr b/testsuite/tests/java_api/project_manager/sources/empty.cgpr new file mode 100644 index 000000000..e158c8865 --- /dev/null +++ b/testsuite/tests/java_api/project_manager/sources/empty.cgpr @@ -0,0 +1,3 @@ +configuration project P1 is + -- Will raise an error at project loading +end P1; diff --git a/testsuite/tests/java_api/project_manager/sources/nosuchtarget.gpr b/testsuite/tests/java_api/project_manager/sources/nosuchtarget.gpr index 5cbb63650..56944f439 100644 --- a/testsuite/tests/java_api/project_manager/sources/nosuchtarget.gpr +++ b/testsuite/tests/java_api/project_manager/sources/nosuchtarget.gpr @@ -1,3 +1,4 @@ project Nosuchtarget is for Target use "nosuchtarget"; + for Source_Dirs use ("src1"); end Nosuchtarget; diff --git a/testsuite/tests/java_api/project_manager/sources/other_naming.cgpr b/testsuite/tests/java_api/project_manager/sources/other_naming.cgpr new file mode 100644 index 000000000..b630e3dda --- /dev/null +++ b/testsuite/tests/java_api/project_manager/sources/other_naming.cgpr @@ -0,0 +1,11 @@ +configuration project P1 is + for Default_Language use "Ada"; + + package Naming is + for Spec_Suffix ("Ada") use ".other"; + for Body_Suffix ("Ada") use ".adb"; + + for Casing use "lowercase"; + for Dot_Replacement use "-"; + end Naming; +end P1; diff --git a/testsuite/tests/java_api/project_manager/sources/src1/name.other b/testsuite/tests/java_api/project_manager/sources/src1/name.other new file mode 100644 index 000000000..bb9972c8d --- /dev/null +++ b/testsuite/tests/java_api/project_manager/sources/src1/name.other @@ -0,0 +1,3 @@ +package Name is + type Record_Type is null record; +end Name;