From 56b294d52052f8c844c1d2dbd316f00cc570e9b1 Mon Sep 17 00:00:00 2001 From: paulklint Date: Thu, 19 Feb 2026 11:57:08 +0100 Subject: [PATCH 1/4] Improved message for outdated TPL and removed possibly confusing println --- .../compiler/lang/rascalcore/check/CheckerCommon.rsc | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CheckerCommon.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CheckerCommon.rsc index 2fc22129a7..5c2c2b2b70 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CheckerCommon.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CheckerCommon.rsc @@ -420,7 +420,7 @@ tuple[bool, TModel, ModuleStatus] getTModelForModule(MODID moduleId, ModuleStatu while(size(ms.tmodels) >= tmodelCacheSize && size(ms.tmodelLIFO) > 0 && ms.tmodelLIFO[-1] != moduleId){ ms = removeOldestTModelFromCache(ms); } - + qualifiedModuleName = moduleId2moduleName(moduleId); = getTPLReadLoc(moduleId, pcfg); if(found){ if(traceTPL) println("*** reading tmodel "); @@ -440,14 +440,11 @@ tuple[bool, TModel, ModuleStatus] getTModelForModule(MODID moduleId, ModuleStatu return ; } } catch e: { - qualifiedModuleName = moduleId2moduleName(moduleId); return : ", tplLoc)]), ms>; } - msg = " has outdated Rascal TPL version (required: )"; - println("INFO: )"); + msg = " for has outdated Rascal TPL version (required: )"; throw rascalTplVersionError(msg); } - qualifiedModuleName = moduleId2moduleName(moduleId); return ", tplLoc)]), ms>; } From cf71690cdbdcf59da39467d52755b03180ee5268 Mon Sep 17 00:00:00 2001 From: paulklint Date: Thu, 19 Feb 2026 19:15:38 +0100 Subject: [PATCH 2/4] Reorganized the reporting of TPL version errors --- .../lang/rascalcore/check/ADTandGrammar.rsc | 2 +- .../lang/rascalcore/check/Checker.rsc | 16 ++++++-- .../lang/rascalcore/check/CheckerCommon.rsc | 17 ++++++--- .../compiler/lang/rascalcore/check/Import.rsc | 13 ++++++- .../check/tests/BinaryDependencyTests.rsc | 38 ++++++++++++++++++- .../rascalcore/compile/CompileTimeError.rsc | 2 +- 6 files changed, 73 insertions(+), 15 deletions(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/ADTandGrammar.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/ADTandGrammar.rsc index 46578396ce..52ecb2d560 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/ADTandGrammar.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/ADTandGrammar.rsc @@ -177,7 +177,7 @@ tuple[TModel, ModuleStatus] addGrammar(MODID moduleId, set[MODID] imports, set[M } else { = getTModelForModule(m, ms); if(!found) { - msg = error("Cannot add grammar, tmodel for not found", ms.moduleLocs[moduleId] ? |unknown:///|); + msg = error("Cannot add grammar or tmodel since `` is not found", ms.moduleLocs[moduleId] ? |unknown:///|); ms.messages[moduleId] ? {} += { msg }; tm1 = tmodel(modelName=qualifiedModuleName, messages=[msg]); return ; diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/Checker.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/Checker.rsc index 052543bd35..b39e55919d 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/Checker.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/Checker.rsc @@ -279,7 +279,10 @@ ModuleStatus rascalTModelForLocs( ms.status[m] += {tpl_uptodate(), checked(), bom_update_needed()}; } } - } catch rascalTplVersionError(e): ;// m_compatible remains false + } catch rascalTplVersionError(_,_,_,_): { + ms.status[m] += { tpl_version_error() }; + // m_compatible remains false + }; compatible_with_all_imports = compatible_with_all_imports && m_compatible; } @@ -328,6 +331,9 @@ ModuleStatus rascalTModelForLocs( if(!ms.status[inameId]?){ ms.status[inameId] = {}; } + if({tpl_version_error(), rsc_not_found()} <= ms.status[inameId]){ + imsgs += error("Rascal TPL version error for ``, no source found", imod@\loc); + } if(inameId notin usedModules){ if(iname == "ParseTree" && implicitlyUsesParseTree(ms.moduleLocs[m].path, tm)){ continue check_imports; @@ -389,9 +395,13 @@ ModuleStatus rascalTModelForLocs( for(MODID mid <- topModuleIds){ ms.messages[mid] = { error("Parse error", src) }; } - } catch rascalTplVersionError(str txt):{ + } catch rascalTplVersionError(str moduleName, loc tpl, str version, str txt):{ for(MODID mid <- topModuleIds){ - ms.messages[mid] = { error("", ms.moduleLocs[mid] ? |unknown:///|) }; + causes = [ info("Module `` has outdated Rascal TPL version , no source found", tpl) ]; + ms.messages[mid] ? {} += { error("Import/extend of `` has ", + ms.moduleLocs[mid] ? |unknown:///|, + causes= causes) + }; } } catch Message msg: { for(MODID mid <- topModuleIds){ diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CheckerCommon.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CheckerCommon.rsc index 5c2c2b2b70..fc06cfaacc 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CheckerCommon.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CheckerCommon.rsc @@ -73,6 +73,7 @@ void checkSupportedByParserGenerator(Tree t, Collector c){ data MStatus = rsc_not_found() | tpl_not_found() + | tpl_version_error() | rsc_changed() | parsed() | parse_error() @@ -263,7 +264,7 @@ tuple[bool, Module, ModuleStatus] getModuleParseTree(MODID moduleId, ModuleStatu } } catch e: { println(e); - ms.messages[moduleId] ? {} += {error("Module not found", mloc)}; + ms.messages[moduleId] ? {} += {error("Module `` not found", mloc)}; ms.moduleLocs[moduleId] = mloc; return ; } @@ -427,8 +428,8 @@ tuple[bool, TModel, ModuleStatus] getTModelForModule(MODID moduleId, ModuleStatu tmVersion = "0.0.0"; try { tm = readBinaryValueFile(ReifiedTModel, tplLoc); - if(tm.rascalTplVersion? && isValidRascalTplVersion(tm.rascalTplVersion)){ - tmVersion = tm.rascalTplVersion; + tmVersion = tm.rascalTplVersion; + if(isValidRascalTplVersion(tmVersion)){ ms.tmodels[moduleId] = tm; mloc = getRascalModuleLocation(moduleId, ms); if(isModuleLocationInLibs(mloc, pcfg)){ @@ -442,10 +443,14 @@ tuple[bool, TModel, ModuleStatus] getTModelForModule(MODID moduleId, ModuleStatu } catch e: { return : ", tplLoc)]), ms>; } - msg = " for has outdated Rascal TPL version (required: )"; - throw rascalTplVersionError(msg); + msg = "outdated Rascal TPL version (required: )"; + throw rascalTplVersionError(qualifiedModuleName, tplLoc, tmVersion, msg); } - return ", tplLoc)]), ms>; + mloc = tplLoc; + try { + mloc = getRascalModuleLocation(moduleId, ms); + } catch _: /* ignore when this fails */; + return ", mloc)]), ms>; } rel[loc from, PathRole r, loc to] getPaths(rel[MODID from, PathRole r, MODID to] paths, ModuleStatus ms){ diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/Import.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/Import.rsc index 0449b7b670..aabd8d4fa9 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/Import.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/Import.rsc @@ -241,10 +241,19 @@ ModuleStatus getImportAndExtendGraph(MODID moduleId, ModuleStatus ms){ return completeModuleStatus(ms); } } - } catch rascalTplVersionError(_): - ; // Need to recheck since TModel uses incompatible TPL version + } catch rascalTplVersionError(str moduleName, loc tplLoc, str version, str txt):{ + ms.status[moduleName2moduleId(moduleName)] += { tpl_version_error() }; + // Need to recheck since TModel uses incompatible TPL version + } if(rsc_not_found() in ms.status[moduleId]){ + if(tpl_version_error() in ms.status[moduleId]){ + iName = moduleId2moduleName(moduleId); + for( <- ms.paths){ + mName = moduleId2moduleName(m); + ms.messages[m] ? {} += { error("For import/extend `` of `` is no source available and TPL has wrong version", m) }; + } + } return ms; } diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/BinaryDependencyTests.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/BinaryDependencyTests.rsc index ea04b1007c..086a8a74b3 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/BinaryDependencyTests.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/BinaryDependencyTests.rsc @@ -130,6 +130,11 @@ Project removeSourceOfModule(str mname, Project pd){ return pd; } +Project removeTPLOfModule(str mname, Project pd){ + remove(bin(pd.name) + "rascal/$.tpl", recursive=true); + return pd; +} + Project setTPLVersionOfProject(str v, Project pd){ try { for(loc f <- find(bin(pd.name), "tpl")){ @@ -175,6 +180,7 @@ bool checkExpectNoErrors(str mname, PathConfig pcfg, list[Project] remove = []){ } bool expectErrors(list[ModuleMessages] modMsgs, list[str] expected){ + if(verbose) iprintln(modMsgs); errors = {e | /e:error(_,_) := modMsgs}; for(e <- errors){ @@ -382,7 +388,35 @@ test bool incompatibleWithBinaryLibraryDueToTPLVersion(){ lib = removeSourceOfModule("M1", lib); // remove source of M1 completely, to be sure - lib = setTPLVersionOfProject("0.0.0", lib); // set rascalTplVersion to incompatible version number + lib = setTPLVersionOfProject("0.0.1", lib); // set rascalTplVersion to incompatible version number + + // Create project "client" and module "M2" and then compile "M2" + // "client" uses "lib" as binary library + clientName = "client"; + client = createProject(clientName, + ("M2": "import M1; // binary import + 'int main() = f(42); // compatible call fo f + "), + createPathConfig(clientName) + [libs = [bin(libName)] ] + ); + return checkExpectErrors("M2", ["outdated Rascal TPL version"], client.pcfg, remove = [lib, client]); +} + + + +test bool removedTPLInBinaryLibrary(){ + // Create project "lib" and module "M1" and then compile "M1" + libName = "lib"; + lib = createProject(libName, + ("M1": "int f(int n) = n;"), + createPathConfig(libName) + ); + assert checkExpectNoErrors("M1", lib.pcfg); + + + lib = removeSourceOfModule("M1", lib); // remove source of M1 completely, to be sure + lib = removeTPLOfModule("M1", lib); // remove M1's tpl file // Create project "client" and module "M2" and then compile "M2" // "client" uses "lib" as binary library @@ -394,7 +428,7 @@ test bool incompatibleWithBinaryLibraryDueToTPLVersion(){ createPathConfig(clientName) [libs = [bin(libName)] ] ); - return checkExpectErrors("M2", ["has outdated Rascal TPL version"], client.pcfg, remove = [lib, client]); + return checkExpectErrors("M2", ["Module M1 not found"], client.pcfg, remove = [lib, client]); } // Scenarios with outdated TPL versions diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/compile/CompileTimeError.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/compile/CompileTimeError.rsc index 14875ac352..1b597e6fef 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/compile/CompileTimeError.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/compile/CompileTimeError.rsc @@ -31,5 +31,5 @@ import Message; data Exception = CompileTimeError(Message msg) | InternalCompilerError(Message msg) - | rascalTplVersionError(str txt) + | rascalTplVersionError(str moduleName, loc tpl, str version, str txt) ; \ No newline at end of file From ded2b881bb57a554582c3f3e9abb6fd02d80be86 Mon Sep 17 00:00:00 2001 From: paulklint Date: Thu, 19 Feb 2026 20:03:33 +0100 Subject: [PATCH 3/4] Removed println --- .../rascalmpl/compiler/lang/rascalcore/check/CheckerCommon.rsc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CheckerCommon.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CheckerCommon.rsc index fc06cfaacc..6395d816b8 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CheckerCommon.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CheckerCommon.rsc @@ -263,7 +263,6 @@ tuple[bool, Module, ModuleStatus] getModuleParseTree(MODID moduleId, ModuleStatu throw "No src or library module"; } } catch e: { - println(e); ms.messages[moduleId] ? {} += {error("Module `` not found", mloc)}; ms.moduleLocs[moduleId] = mloc; return ; From 74eb35ae168a319037d03a3b773ee68a62f33421 Mon Sep 17 00:00:00 2001 From: paulklint Date: Thu, 19 Feb 2026 20:03:57 +0100 Subject: [PATCH 4/4] Fixed quotes --- .../lang/rascalcore/check/tests/BinaryDependencyTests.rsc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/BinaryDependencyTests.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/BinaryDependencyTests.rsc index 086a8a74b3..2adc954d83 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/BinaryDependencyTests.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/BinaryDependencyTests.rsc @@ -428,7 +428,7 @@ test bool removedTPLInBinaryLibrary(){ createPathConfig(clientName) [libs = [bin(libName)] ] ); - return checkExpectErrors("M2", ["Module M1 not found"], client.pcfg, remove = [lib, client]); + return checkExpectErrors("M2", ["Module `M1` not found"], client.pcfg, remove = [lib, client]); } // Scenarios with outdated TPL versions