=== modified file 'src/com/goldencode/p2j/cfg/Configuration.java' --- old/src/com/goldencode/p2j/cfg/Configuration.java 2023-05-12 10:05:12 +0000 +++ new/src/com/goldencode/p2j/cfg/Configuration.java 2024-06-07 10:29:14 +0000 @@ -85,6 +85,7 @@ ** ECF 20230127 Added mutable schema configuration option. ** 024 VVT 20230318 Constant added: default legacy unit test framework type. See #6237. ** 025 GBB 20230512 Logging methods replaced by CentralLogger/ConversionStatus. +** 026 ME 20240604 Added support for automatic dependency conversion when file list is used. */ /* @@ -353,6 +354,9 @@ /** The loaded schema configuration. */ private SchemaConfig schemaConfig = null; + /** The list of conversion dependencies listeners */ + private static Set> conversionDepsListeners; + /** * Holds a set of configuration parameter names whose values are OS dependent. These are * related to the system we run now, and are invisible for original P4GL code. @@ -1402,6 +1406,52 @@ loadConfigProfiles(profiles); // schema will have the default profile set if profile switching occurs } + + /** + * Add a dependency listener used for conversion only, no-op for runtime configuration. + * + * Automatic dependency resolution during conversion is enabled by setting the + * 'convert-deps' general parameter to true. + * + * @param listener the dependency listener + */ + public static void addConversionDependencyListener(Consumer listener) + { + if (listener != null && !isRuntimeConfig() && getParameter("convert-deps", false)) + { + if (conversionDepsListeners == null) + { + conversionDepsListeners = new HashSet<>(); + } + + conversionDepsListeners.add(listener); + } + } + + /** + * Remove a dependency listener used for conversion only, no-op for runtime configuration. + * + * @param listener the dependency listener + */ + public static void removeConversionDependencyListener(Consumer listener) + { + if (listener != null && conversionDepsListeners != null) + { + conversionDepsListeners.remove(listener); + } + } + + /** + * Notify dependency listeners a new dependency has been found (class or procedure). + * + * @param filename the dependency file name + */ + public static void foundConversionDependency(String filename) { + if (conversionDepsListeners != null) + { + conversionDepsListeners.forEach(l -> l.accept(filename)); + } + } /** * Create a Configuration instance. @@ -1417,11 +1467,14 @@ // always start with P2J_HOME parameter; this is reserved config.parmMap.put(PROP_HOME_DIR, home()); - InputStream cfgStream; + InputStream cfgStream = null; - // attempt to load from jar first - ClassLoader cl = ClassLoader.getSystemClassLoader(); - cfgStream = cl.getResourceAsStream(CFG_DIR + "/" + DEF_CFG_FILE); + // runtime configuration attempt to load from jar first + if (isRuntimeConfig()) + { + ClassLoader cl = ClassLoader.getSystemClassLoader(); + cfgStream = cl.getResourceAsStream(CFG_DIR + "/" + DEF_CFG_FILE); + } if (cfgStream == null) { === modified file 'src/com/goldencode/p2j/convert/ConversionDriver.java' --- old/src/com/goldencode/p2j/convert/ConversionDriver.java 2024-03-19 16:28:46 +0000 +++ new/src/com/goldencode/p2j/convert/ConversionDriver.java 2024-06-07 10:29:14 +0000 @@ -142,7 +142,8 @@ ** CA 20220603 Allow the generation of proxy Java programs in the folder specified by ** 'proxy-output-root'. ** 047 OM 20240311 Do not generate the .meta.xml any more. The information is already -** present in DMO interface annotations. +** present in DMO interface annotations. +** 048 ME 20240604 Add support for automatic dependencies conversion when using file list. */ /* @@ -215,6 +216,7 @@ import com.goldencode.p2j.schema.*; import com.goldencode.p2j.uast.*; import com.goldencode.p2j.util.*; +import com.goldencode.util.StringHelper; import java.io.*; import java.util.*; @@ -343,6 +345,9 @@ /** The list of Progress source file specific P2O files. */ private FileList sp2os = null; + /** The list of Progress source files dependencies (used but not in convert list). */ + private Set dependencies = null; + /** * Creates an instance with a specific configuration. * @@ -583,6 +588,29 @@ brew(jasts, "Business Logic and Frames Classes"); } + + @Override + protected void executeJob(String title) + { + // add conversion dependency listener + Configuration.addConversionDependencyListener(file -> { + if (dependencies == null) + { + dependencies = new HashSet<>(); + } + + file = StringHelper.removeQuotes(file); + + if (dependencies.add(file)) + { + // remove old java ast if we need to convert it + zapFiles(new String[] { file }, new String[] { ".jast" }); + } + }); + + super.executeJob(title); + } + /** * Gather all SOAP operations from all files, regardless if they are included in the incremental conversion * or not, and generate the WSDLs. @@ -1080,6 +1108,38 @@ jasts = new ExplicitFileList(oldjasts.toArray(new String[0])); } + @Override + protected void runScanDriver(boolean preproc, boolean schema, boolean abortOnError, + int threads) throws Exception + { + // update source dependencies with database schema triggers before scan + updateSourceDependencies(); + + super.runScanDriver(preproc, schema, abortOnError, threads); + + // update source dependencies with those found during scan + updateSourceDependencies(); + } + + private void updateSourceDependencies () + { + if (dependencies != null) { + for (String src : source.listFilenames()) + { + dependencies.remove(src); + } + + if (!dependencies.isEmpty()) + { + dependencies.addAll(Arrays.asList(source.listFilenames())); + source = new ExplicitFileList(dependencies.toArray(new String[0])); + job.files = source; + } + + dependencies = null; + } + } + /** * Container class that aggregates a set of options to control a run of the conversion * driver. === modified file 'src/com/goldencode/p2j/schema/schema.g' --- old/src/com/goldencode/p2j/schema/schema.g 2023-05-12 10:25:56 +0000 +++ new/src/com/goldencode/p2j/schema/schema.g 2024-06-07 10:29:14 +0000 @@ -110,6 +110,7 @@ ** CA 20230321 A table's signature must include index information (this includes the index ** name, options, field position and type). ** 041 GBB 20230512 Logging methods replaced by CentralLogger/ConversionStatus. +** 042 ME 20240604 Add database schema trigger procedures as conversion dependencies. */ /* @@ -2064,7 +2065,10 @@ */ proc_clause : - KW_PROC^ STRING + KW_PROC^ s:STRING + { + Configuration.foundConversionDependency(#s.getText()); + } ; /** === modified file 'src/com/goldencode/p2j/uast/AstGenerator.java' --- old/src/com/goldencode/p2j/uast/AstGenerator.java 2023-05-10 06:23:45 +0000 +++ new/src/com/goldencode/p2j/uast/AstGenerator.java 2024-06-07 10:29:14 +0000 @@ -191,6 +191,7 @@ ** 060 GBB 20230512 Logging methods replaced by CentralLogger/ConversionStatus. ** 061 OM 20230115 Replaced absolutePath(), relativePath(), upPath() and downPath() with faster ** versions, based on node types. +** 062 ME 20240604 Automatic add OO dependencies found during conversion using file list. */ /* @@ -1638,6 +1639,17 @@ String qname = ref.getText(); ClassDefinition cdef = SymbolResolver.getClassDefinition(qname); cdef.parseFinished(false); + + if (!cdef.isBuiltIn()) + { + // flag non built-in OO elements as conversion dependencies + Configuration.foundConversionDependency(filename); + } + } + else + { + // flag procedures as conversion dependencies + Configuration.foundConversionDependency(filename); } // save off output if requested, THIS MUST BE DONE AFTER FIXUPS! if (dumpParser) === modified file 'src/com/goldencode/p2j/uast/SymbolResolver.java' --- old/src/com/goldencode/p2j/uast/SymbolResolver.java 2024-06-06 11:00:32 +0000 +++ new/src/com/goldencode/p2j/uast/SymbolResolver.java 2024-06-26 10:44:09 +0000 @@ -592,6 +592,7 @@ import com.goldencode.p2j.schema.*; import com.goldencode.p2j.security.*; import com.goldencode.p2j.util.*; +import com.goldencode.p2j.util.InternalEntry.Type; /** * Contains a dictionary for each type of language namespace and provides @@ -4073,7 +4074,20 @@ */ public int lookupProcedure(String name) { - return lookupWorkerExact(procDict, name); + int ret = lookupWorkerExact(procDict, name); + + if (ret == -1) + { + // if not resolved already parse the procedure + try + { + getAstGenerator().processFile(name, null, -1); + } catch (AstException e) { + // catch error for internal procedures call + } + } + + return ret; } /** @@ -4594,17 +4608,6 @@ // at this point found.filename must be valid } - if (generator == null) - { - generator = new AstGenerator(); - generator.setSilent(silent); - generator.setPreprocess(true); - generator.setCache(true); - generator.setDumpLexer(true); - generator.setDumpParser(true); - generator.setAstPersist(true); - } - String relative = Configuration.normalizeFilename(found.filename); if (wa.preScanPass == 0) @@ -4628,7 +4631,7 @@ } // the PROPATH is inherited from the caller - generator.preScanClass(relative, found.builtin, found.dotnet, this.propath); + getAstGenerator().preScanClass(relative, found.builtin, found.dotnet, this.propath); // save all referenced classes/interfaces except for the genesis object if (wa.preScanPass > 1) @@ -8752,7 +8755,7 @@ if (!cdef.isBuiltIn() && new File(file).exists()) { - generator.processFile(file, null, -1); + getAstGenerator().processFile(file, null, -1); // at this point we have been fully parsed and all parents have been fully parsed, so // it is safe to detect whether or not one of our ancestors is a .NET class @@ -9976,6 +9979,26 @@ } /** + * Lazy load the AST Generator when new class/procedure needs to be processed. + * + * @return the AST generator + */ + private AstGenerator getAstGenerator () { + if (generator == null) + { + generator = new AstGenerator(); + generator.setSilent(silent); + generator.setPreprocess(true); + generator.setCache(true); + generator.setDumpLexer(true); + generator.setDumpParser(true); + generator.setAstPersist(true); + } + + return generator; + } + + /** * Create a new {@link Variable}, with the specified details. * * @param name