diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/Checker.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/Checker.rsc index d3eeda94e39..98ec75730d4 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/Checker.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/Checker.rsc @@ -183,7 +183,7 @@ ModuleStatus rascalTModelForLocs( mloc = mlocs[i]; mname = mnames[i]; if(isModuleLocationInLibs(mloc, pcfg)){ - ms.status[mloc] ? {} += {rsc_not_found()}; + ms = addProperty(mloc, ms, tpl_from_library()); } ms.moduleLocs[mid] = mloc; @@ -241,18 +241,15 @@ ModuleStatus rascalTModelForLocs( jobStep(jobName, intercalate(" + ", [*componentNames]), work=size(componentNames)); - recheck = !all(m <- component, m in ms.status, (tpl_uptodate() in ms.status[m] || checked() in ms.status[m])); + recheck = !all(m <- component, hasAnyProperty(m, ms, tpl_uptodate(), checked())); for(m <- component){ - if(m notin ms.status){ - ms.status[m] = {}; - } mi += 1; if(!recheck){ - if(tpl_uptodate() notin ms.status[m]){ + if(hasNotProperty(m, ms, tpl_uptodate())){ = getTModelForModule(m, ms); if(found){ - ms.status[m] += {tpl_uptodate(), checked()}; + ms = addProperty(m, ms, tpl_uptodate(), checked()); } } } @@ -262,8 +259,7 @@ ModuleStatus rascalTModelForLocs( any_tpl_outdated = any(m <- component, tplOutdated(m, pcfg)); if(any_tpl_outdated){ for(m <- component){ - ms.status[m] -= {tpl_uptodate(), checked()}; - ms.status[m] += {rsc_changed()}; + ms = deleteProperty(m, ms, tpl_uptodate(), checked()); } } else { for(m <- component){ @@ -275,11 +271,11 @@ ModuleStatus rascalTModelForLocs( = importsAndExtendsAreBinaryCompatible(tm, imports_extends_m, ms); if(m_compatible){ - ms.status[m] += {tpl_uptodate(), checked(), bom_update_needed()}; + ms = addProperty(m, ms, tpl_uptodate(), checked(), bom_update_needed()); } } } catch rascalTplVersionError(_,_,_,_): { - ms.status[m] += { tpl_version_error() }; + ms = addProperty(m, ms, tpl_version_error()); // m_compatible remains false }; @@ -287,14 +283,15 @@ ModuleStatus rascalTModelForLocs( } } - any_rsc_changed = any(m <- component, rsc_changed() in ms.status[m]); - any_from_lib = any(m <- component, rsc_not_found() in ms.status[m]); + any_rsc_changed = any(m <- component, hasProperty(m, ms, rsc_changed())); + all_rsc_found = all(m <- component, hasNotProperty(m, ms, rsc_not_found())); + any_from_lib = any(m <- component, hasProperty(m, ms, tpl_from_library())); all_tmodels_uptodate = true; for(m <- component){ - if(tpl_uptodate() notin ms.status[m] && checked() notin ms.status[m]) + if(hasNotProperty(m, ms, tpl_uptodate(), checked())) all_tmodels_uptodate = false; } - recheckCond = !any_from_lib && (!compatible_with_all_imports || any_rsc_changed || !all_tmodels_uptodate); + recheckCond = !any_from_lib && all_rsc_found && (!compatible_with_all_imports || any_rsc_changed || !all_tmodels_uptodate); if(recheckCond){ // if(ms.compilerConfig.verbose){ @@ -306,16 +303,16 @@ ModuleStatus rascalTModelForLocs( map[str,TModel] tmodels_for_component = (); map[MODID,set[MODID]] m_imports = (); map[MODID,set[MODID]] m_extends = (); - for(m <- component, rsc_not_found() notin ms.status[m], MStatus::ignored() notin ms.status[m]){ - imports = { imp | <- ms.paths, m1 == m, MStatus::ignored() notin ms.status[imp]}; + for(m <- component, hasNotProperty(m, ms, rsc_not_found(), ModuleProperty::ignored())){ + imports = { imp | <- ms.paths, m1 == m, hasNotProperty(imp, ms, ModuleProperty::ignored())}; m_imports[m] = imports; - extends = { ext | <- ms.paths, m1 == m, MStatus::ignored() notin ms.status[ext] }; + extends = { ext | <- ms.paths, m1 == m, hasNotProperty(ext, ms, ModuleProperty::ignored()) }; m_extends[m] = extends; invertedExtends = ms.paths<2,0>; if(compilerConfig.warnUnused){ // Look for unused imports or extends //usedModules = {path2module[l.path] | loc l <- range(tm.useDef), tm.definitions[l].idRole == moduleId(), path2module[l.path]?}; - usedModules = {l | loc l <- range(tm.useDef), tm.definitions[l].idRole == moduleId()}; + usedModules = {l | loc l <- range(tm.useDef), l in tm.definitions, tm.definitions[l].idRole == moduleId()}; usedModules += {*invertedExtends[um] | um <- usedModules}; // use of an extended module via import list[Message] imsgs = []; = getModuleParseTree(m, ms); @@ -327,10 +324,7 @@ ModuleStatus rascalTModelForLocs( for(imod <- pt.header.imports, imod has \module){ iname = unescape(""); inameId = moduleName2moduleId(iname); - if(!ms.status[inameId]?){ - ms.status[inameId] = {}; - } - if({tpl_version_error(), rsc_not_found()} <= ms.status[inameId]){ + if(hasProperty(inameId, ms, tpl_version_error(), rsc_not_found())){ imsgs += error("Rascal TPL version error for ``, no source found", imod@\loc); } if(inameId notin usedModules){ @@ -343,8 +337,8 @@ ModuleStatus rascalTModelForLocs( if(ms.moduleLocs[inameId]? && ms.moduleLocs[m]? && usesOrExtendsADT(ms.moduleLocs[m].path, ms.moduleLocs[inameId].path, tm)){ continue check_imports; } - if((inameId in component || checked() in ms.status[inameId]) && rsc_not_found() notin ms.status[inameId]){ - if(imod is \default){ + if((inameId in component || hasProperty(inameId, ms, checked())) && hasNotProperty(inameId, ms, rsc_not_found())){ + if(imod is \default){ imsgs += warning("Unused import of ``", imod@\loc); } //else { //TODO: maybe add option to turn off info messages? //imsgs += info("Extended module `` is unused in the current module", imod@\loc); @@ -360,9 +354,9 @@ ModuleStatus rascalTModelForLocs( } ms.messages[m] ? {} += toSet(tm.messages); - ms.status[m] += {tpl_uptodate(), checked()}; + ms = addProperty(m, ms, tpl_uptodate(), checked()); if(errorsPresent(ms.messages[m])){ - ms.status[m] += {check_error()}; + ms = addProperty(m, ms, check_error()); } } // prepare the TModels of the modules in this component for compilation @@ -370,24 +364,19 @@ ModuleStatus rascalTModelForLocs( = prepareForCompilation(component, m_imports, m_extends, ms, tm); // generate code for the modules in this component - - for(MODID m <- component, MStatus::ignored() notin ms.status[m]){ + for(MODID m <- component, hasNotProperty(m, ms, ModuleProperty::ignored())){ = getModuleParseTree(m, ms); if(success){ lmsgs = codgen(m, pt, transient_tms, ms, compilerConfig); ms.messages[m] += toSet(lmsgs); - ms.status[m] += errorsPresent(lmsgs) ? {code_generation_error()} : {code_generated()}; + ms = addProperty(m, ms, errorsPresent(lmsgs) ? code_generation_error() : code_generated()); } } ms = doSaveModule(component, m_imports, m_extends, ms, transient_tms, compilerConfig); for(m <- component){ - ms.status[m] -= {rsc_changed()}; - ms.status[m] += {tpl_uptodate()}; + ms = deleteProperty(m, ms, rsc_changed()); + ms = addProperty(m, ms, tpl_uptodate()); } - } else { - ;// for(m <- component){ - // ms.status[m] += bom_update_needed(); - // } } } } catch ParseError(loc src): { @@ -433,7 +422,7 @@ tuple[set[MODID], ModuleStatus] loadImportsAndExtends(set[MODID] moduleIds, Modu pcfg = ms.pathConfig; for( <- ms.paths, from in moduleIds){ if(imp notin added, imp notin moduleIds){ - if(tpl_uptodate() in ms.status[imp]){ + if(hasProperty(imp, ms, tpl_uptodate())){ added += imp; = getTModelForModule(imp, ms); try { @@ -458,15 +447,16 @@ tuple[TModel, ModuleStatus] rascalTModelComponent(set[MODID] moduleIds, ModuleSt map[MODID, Module] idTrees = (); for(MODID mid <- moduleIds){ mname = moduleId2moduleName(mid); - //ms.status[mid] = {}; - //ms.messages[mid] = {}; ms = removeTModel(mid, ms); mloc = |unknown:///|(0,0,<0,0>,<0,0>); try { mloc = getRascalModuleLocation(mid, ms); + if(endsWith(mloc.path, "tpl")){ + ms = addProperty(mid, ms, tpl_from_library()); + } } catch Message err: { ms.messages[mid] = { err }; - ms.status[mid] += { rsc_not_found() }; + ms = addProperty(mid, ms, rsc_not_found()); tm = tmodel(modelName=mname, messages=[ err ]); ms = addTModel(mid, tm, ms); return ; @@ -480,7 +470,7 @@ tuple[TModel, ModuleStatus] rascalTModelComponent(set[MODID] moduleIds, ModuleSt if(hasIgnoreCompilerTag(tagsMap)) { ms.messages[mid] ? {} += { Message::info("Ignoring module ", pt.header.name@\loc) }; - ms.status[mid] += MStatus::ignored(); + ms = addProperty(mid, ms, ModuleProperty::ignored()); } idTrees[mid] = pt; } @@ -522,8 +512,8 @@ tuple[TModel, ModuleStatus] rascalTModelComponent(set[MODID] moduleIds, ModuleSt return ; } else { oneOfComponent = getOneFrom(moduleIds); - ms.status[oneOfComponent]? {} += { tpl_saved() }; // TODO check this, when is this executed? - = getTModelForModule(oneOfComponent, ms); + ms = addProperty(oneOfComponent, ms, tpl_saved()); + = getTModelForModule(oneOfComponent, ms); return ; } } @@ -565,7 +555,7 @@ tuple[bool, ModuleStatus] libraryDependenciesAreCompatible(list[MODID] candidate try { = getTModelForModule(candidate, ms); if(found){ // TODO: needed? - imports_and_extends = ms.paths<0,2>[candidate]; + imports_and_extends = tm.paths<0,2>[candidate]; // ms.paths<0,2>[candidate]; = importsAndExtendsAreBinaryCompatible(tm, imports_and_extends, ms); if(!compatible){ return ; diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/CheckerCommon.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/CheckerCommon.rsc index b8f89b62721..391ef186eef 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/CheckerCommon.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/CheckerCommon.rsc @@ -68,14 +68,10 @@ void checkSupportedByParserGenerator(Tree t, Collector c){ }); } - - -data MStatus = +data ModuleProperty = rsc_not_found() - | tpl_not_found() - | tpl_version_error() | rsc_changed() - | parsed() + // | parsed() | parse_error() | module_dependencies_extracted() | checked() @@ -83,7 +79,10 @@ data MStatus = | code_generated() | code_generation_error() | tpl_uptodate() + | tpl_from_library() | tpl_saved() + | tpl_not_found() + | tpl_version_error() | ignored() | bom_update_needed() ; @@ -99,11 +98,46 @@ data ModuleStatus = map[MODID,loc] moduleLocs, map[MODID,datetime] moduleLastModified, map[MODID, set[Message]] messages, - map[MODID, set[MStatus]] status, + map[MODID, set[ModuleProperty]] status, PathConfig pathConfig, RascalCompilerConfig compilerConfig ); +// p1 in status && p2 in status ... +bool hasProperty(MODID mid, ModuleStatus ms, ModuleProperty properties...){ + if(mid notin ms.status) return false; + mstatus = ms.status[mid]; + return !isEmpty(mstatus) && all(p <- properties, p in mstatus); +} + +// p1 in status || p2 in status ... +bool hasAnyProperty(MODID mid, ModuleStatus ms, ModuleProperty properties...){ + if(mid notin ms.status) return false; + mstatus = ms.status[mid]; + return !isEmpty(mstatus) && any(p <- properties, p in mstatus); +} + +// p1 notin status && p2 notin status ... +bool hasNotProperty(MODID mid, ModuleStatus ms, ModuleProperty properties...){ + if(mid notin ms.status) return true; + mstatus = ms.status[mid]; + return isEmpty(mstatus) || all(ModuleProperty p <- properties, p notin mstatus); +} + +ModuleStatus addProperty(MODID mid, ModuleStatus ms, ModuleProperty properties...){ + mstatus = mid notin ms.status ? {} : ms.status[mid]; + mstatus += toSet(properties); + ms.status[mid] = mstatus; + return ms; +} + +ModuleStatus deleteProperty(MODID mid, ModuleStatus ms, ModuleProperty properties...){ + mstatus = mid notin ms.status ? {} : ms.status[mid]; + mstatus -= toSet(properties); + ms.status[mid] = mstatus; + return ms; +} + ModuleStatus moduleStatus( // TEMPORARY FOR COMPATIBILITY BETWEEN VERSIONS rel[str, PathRole, str] _strPaths, rel[MODID, PathRole, MODID] _paths, @@ -115,7 +149,7 @@ ModuleStatus moduleStatus( // TEMPORARY FOR COMPATIBILITY BETWEEN VERSI map[MODID,loc] _moduleLocs, map[MODID,datetime] _moduleLastModified, map[MODID, set[Message]] _messages, - map[MODID, set[MStatus]] _status, + map[MODID, set[ModuleProperty]] _status, PathConfig pathConfig, RascalCompilerConfig compilerConfig) = newModuleStatus(pathConfig, compilerConfig); @@ -221,6 +255,7 @@ bool tplOutdated(MODID moduleId, PathConfig pcfg){ try { qualifiedModuleName = moduleId2moduleName(moduleId); mloc = getRascalModuleLocation(qualifiedModuleName, pcfg); + if(endsWith(mloc.path, "tpl")) return false; = getTPLReadLoc(qualifiedModuleName, pcfg); lmMloc = lastModified(mloc); lmTpl = lastModified(tpl); @@ -244,10 +279,7 @@ tuple[bool, Module, ModuleStatus] getModuleParseTree(MODID moduleId, ModuleStatu if(traceParseTreeCache) println("*** using cached parse tree for "); return ; } else { - if(!ms.status[moduleId]?){ - ms.status[moduleId] = {}; - } - if(parse_error() notin ms.status[moduleId]){ + if(hasNotProperty(moduleId, ms, parse_error())){ if(size(ms.parseTreeLIFO) >= parseTreeCacheSize){ ms.parseTrees = delete(ms.parseTrees, ms.parseTreeLIFO[-1]); if(traceParseTreeCache) println("*** deleting parse tree "); @@ -259,7 +291,7 @@ tuple[bool, Module, ModuleStatus] getModuleParseTree(MODID moduleId, ModuleStatu mloc = getRascalModuleLocation(moduleId, ms); // Make sure we found a real source module (as opposed to a tpl module in a library if(isModuleLocationInLibs(mloc, pcfg)) { - ms.status[moduleId] += {rsc_not_found()}; + ms = addProperty(moduleId, ms, tpl_from_library()); throw "No src or library module"; } } catch e: { @@ -273,12 +305,11 @@ tuple[bool, Module, ModuleStatus] getModuleParseTree(MODID moduleId, ModuleStatu ms.parseTrees[moduleId] = pt; newLoc = getLoc(pt); ms.moduleLocs[moduleId] = newLoc; - ms.status[moduleId] ? {} += {parsed()}; return ; } catch ParseError(loc src): { ms.messages[moduleId] ? {} = {error("Parse error in ", src)}; ms.moduleLocs[moduleId] = mloc; - ms.status[moduleId] += parse_error(); + ms = addProperty(moduleId, ms, parse_error()); return ; } } @@ -307,14 +338,14 @@ loc getRascalModuleLocation(MODID moduleId, ModuleStatus ms){ int tmodelCacheSize = 30; // should be > 0 ModuleStatus clearTModelCache(ModuleStatus ms){ - todo = { mname | mname <- ms.status, bom_update_needed() in ms.status[mname]}; + todo = { mname | mname <- ms.status, hasProperty(mname, ms, bom_update_needed())}; for(candidate <- ms.tmodelLIFO){ ms = removeOldestTModelFromCache(ms/*, updateBOMneeded=true*/); todo -= candidate; } for(candidate <- todo){ ms = removeTModel(candidate, ms/*, updateBOMneeded=true*/); - ms.status[candidate] -= bom_update_needed(); + ms = deleteProperty(candidate, ms, bom_update_needed()); } return ms; } @@ -330,7 +361,7 @@ rel[str,datetime,PathRole] makeBom(MODID moduleId, ModuleStatus ms){ } ModuleStatus updateBOM(MODID moduleId, ModuleStatus ms){ - if(rsc_not_found() in ms.status[moduleId]){ + if(hasAnyProperty(moduleId, ms, rsc_not_found(), tpl_from_library())){ return ms; } = getTModelForModule(moduleId, ms); @@ -339,7 +370,7 @@ ModuleStatus updateBOM(MODID moduleId, ModuleStatus ms){ newBom = makeBom(moduleId, ms); if(newBom != tm.store[key_bom]){ tm.store[key_bom] = newBom; - ms.status[moduleId] -= {tpl_saved(), bom_update_needed()}; + ms = deleteProperty(moduleId, ms, tpl_saved(), bom_update_needed()); ms = addTModel(moduleId, tm, ms); if(ms.compilerConfig.logWrittenFiles) println("Updated BOM: "); @@ -353,20 +384,18 @@ ModuleStatus updateBOM(MODID moduleId, ModuleStatus ms){ ModuleStatus removeTModel(MODID candidate, ModuleStatus ms, bool updateBOMneeded = false){ assert isModuleId(candidate) : "removeTModel: "; if( updateBOMneeded - || ( candidate in ms.tmodels - && candidate in ms.status - && tpl_saved() notin ms.status[candidate] - && rsc_not_found() notin ms.status[candidate]) + || candidate in ms.tmodels + && !hasAnyProperty(candidate, ms, tpl_saved(), rsc_not_found(), tpl_from_library()) ){ pcfg = ms.pathConfig; if(updateBOMneeded){ ms = updateBOM(candidate, ms); } - ms.status[candidate] -= bom_update_needed(); + ms = deleteProperty(candidate, ms, bom_update_needed()); = getTPLWriteLoc(candidate, pcfg); tm = ms.tmodels[candidate]; //tm.messages = toList(toSet(tm.messages) + ms.messages[candidate]); // TODO needed ? - ms.status[candidate] += tpl_saved(); + ms = addProperty(candidate, ms, tpl_saved()); if(ms.compilerConfig.verbose) println("Saving tmodel for before removing from cache"); try { writeBinaryValueFile(tplLoc, tm); @@ -432,9 +461,9 @@ tuple[bool, TModel, ModuleStatus] getTModelForModule(MODID moduleId, ModuleStatu ms.tmodels[moduleId] = tm; mloc = getRascalModuleLocation(moduleId, ms); if(isModuleLocationInLibs(mloc, pcfg)){ - ms.status[moduleId] ? {} += {rsc_not_found()}; + ms = addProperty(moduleId, ms, tpl_from_library()); } - ms.status[moduleId] ? {} += {tpl_uptodate(), tpl_saved()}; + ms = addProperty(moduleId, ms, tpl_uptodate(), tpl_saved()); //do not include errors from tm in ModuleStatus to avoid that they become persistent ms.tmodelLIFO = [moduleId, *ms.tmodelLIFO]; return ; diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/Import.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/Import.rsc index 103f5c28c85..9c1e54df3f9 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/Import.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/Import.rsc @@ -57,7 +57,7 @@ ModuleStatus reportSelfImport(rel[loc, PathRole, loc] paths, ModuleStatus ms){ for( <- paths){ // mname = getRascalModuleName(from, ms.pathConfig); ms.messages[from] ? {} += {error("Self import not allowed", from)}; - ms.status[from] ? {} += {check_error()}; + ms = addProperty(from, ms, check_error()); } return ms; } @@ -69,7 +69,7 @@ ModuleStatus reportCycles(rel[MODID, PathRole, MODID]paths, rel[MODID,MODID] ext mname = getRascalModuleName(mid, ms.pathConfig); causes = [ info("Part of extend cycle ", emid) | emid <- extendCycle ]; ms.messages[mid] ? {} += {error("Extend cycle not allowed", mid, causes=causes)}; - ms.status[mid] ? {} += {check_error()}; + ms = addProperty(mid, ms, check_error()); } } pathsPlus = { | <- paths}+; @@ -88,7 +88,7 @@ ModuleStatus reportCycles(rel[MODID, PathRole, MODID]paths, rel[MODID,MODID] ext causes = [ info("Part of mixed import/extend cycle ", eloc) | eloc <- cycle ]; ms.messages[mid] ? {} += { error("Mixed import/extend cycle not allowed", mid, causes=causes) }; - ms.status[mid] ? {} += {check_error()}; + ms = addProperty(mid, ms, check_error()); } } return ms; @@ -113,7 +113,7 @@ ModuleStatus completeModuleStatus(ModuleStatus ms){ | < MODID c, MODID b> <- imports }; - ms.paths = paths; + ms.paths = paths; return ms; } @@ -134,14 +134,10 @@ ModuleStatus getImportAndExtendGraph(MODID moduleId, ModuleStatus ms){ pcfg = ms.pathConfig; qualifiedModuleName = moduleId2moduleName(moduleId); - if(!ms.status[moduleId]?){ - ms.status[moduleId] = {}; - } - - if(module_dependencies_extracted() in ms.status[moduleId]){ + if(hasProperty(moduleId, ms, module_dependencies_extracted())){ return ms; } - ms.status[moduleId] += module_dependencies_extracted(); + ms = addProperty(moduleId, ms, module_dependencies_extracted()); try { = getTModelForModule(moduleId, ms); @@ -156,9 +152,6 @@ ModuleStatus getImportAndExtendGraph(MODID moduleId, ModuleStatus ms){ if(tm.store[key_bom]? && rel[str,datetime,PathRole] bom := tm.store[key_bom]){ for( <- bom){ mid = moduleName2moduleId(m); - if(!ms.status[mid]?){ - ms.status[mid] = {}; - } if(mid != moduleId){ localImportsAndExtends += ; } @@ -168,9 +161,9 @@ ModuleStatus getImportAndExtendGraph(MODID moduleId, ModuleStatus ms){ = isModuleModified(mid, timestampInBom, pathRole, ms); if(dependencyChanged || mchanged){ allImportsAndExtendsValid = false; - ms.status[mid] += rsc_changed(); - ms.status[mid] -= {tpl_uptodate(), checked()}; - ms.status[moduleId] -= tpl_saved(); + ms = addProperty(mid, ms, rsc_changed()); + ms = deleteProperty(mid, ms, tpl_uptodate(), checked()); + ms = deleteProperty(moduleId, ms, tpl_saved()); ms.messages[moduleId] = {}; if(ms.compilerConfig.verbose){ println("--- using (most recent) version of , @@ -187,11 +180,14 @@ ModuleStatus getImportAndExtendGraph(MODID moduleId, ModuleStatus ms){ try { try { mloc = getRascalModuleLocation(moduleId, ms); + if(endsWith(mloc.path, "tpl")){ + ms = addProperty(moduleId, ms, tpl_from_library()); + } } catch Message err: { ms.messages[moduleId] = { err }; tm = tmodel(modelName=moduleId2moduleName(moduleId), messages=[ err ]); ms = addTModel(moduleId, tm, ms); - ms.status[moduleId] += { rsc_not_found() }; + ms = addProperty(moduleId, ms, rsc_not_found()); return ms; } if(!isRascalLogicalLoc(mloc) && (mloc.extension != "rsc" || isModuleLocationInLibs(mloc, pcfg))) throw "No src or library module 1"; //There is only a tpl file available @@ -225,25 +221,23 @@ ModuleStatus getImportAndExtendGraph(MODID moduleId, ModuleStatus ms){ } } if(allImportsAndExtendsValid){ - ms.status[moduleId] += {tpl_uptodate(), checked(), tpl_saved()}; //TODO: maybe check existence of generated java files + ms = addProperty(moduleId, ms, tpl_uptodate(), checked(), tpl_saved(), module_dependencies_extracted()); //TODO: maybe check existence of generated java files ms.moduleLocs += (moduleName2moduleId(mname) : tm.moduleLocs[mname] | mname <- tm.moduleLocs); // TODO: or not? ms.paths += tm.paths; - ms.status[moduleId] += module_dependencies_extracted(); ms.messages[moduleId] ? {} += toSet(tm.messages); - for( <- localImportsAndExtends, isEmpty({module_dependencies_extracted()} & ms.status[imp]) ){ - ms.status[imp] -= tpl_saved(); + for( <- localImportsAndExtends, hasNotProperty(imp, ms, module_dependencies_extracted()) ){ + ms = deleteProperty(imp, ms, tpl_saved()); ms = getImportAndExtendGraph(imp, ms); } return completeModuleStatus(ms); } } } catch rascalTplVersionError(str moduleName, loc tplLoc, str version, str txt):{ - ms.status[moduleName2moduleId(moduleName)] += { tpl_version_error() }; + ms = addProperty(moduleName2moduleId(moduleName), ms, 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]){ + if(hasAnyProperty(moduleId, ms, rsc_not_found(), tpl_from_library())){ + if(hasProperty(moduleId, ms, tpl_version_error())){ iName = moduleId2moduleName(moduleId); for( <- ms.paths){ mName = moduleId2moduleName(m); @@ -257,11 +251,11 @@ ModuleStatus getImportAndExtendGraph(MODID moduleId, ModuleStatus ms){ if(success){ = getModulePaths(pt, ms); - for(<_, _, imp> <- imports_and_extends, rsc_not_found() notin ms.status[imp]){ + for(<_, _, imp> <- imports_and_extends, hasNotProperty(imp, ms, rsc_not_found())){ ms = getImportAndExtendGraph(imp, ms); } } else { - ms.status[moduleId] += rsc_not_found(); + ms = addProperty(moduleId, ms, rsc_not_found()); } return completeModuleStatus(ms); @@ -360,15 +354,6 @@ tuple[ModuleStatus, rel[loc, PathRole, loc]] getModulePaths(Module m, ModuleStat iname = unescape(""); inameId = moduleName2moduleId(iname); imports_and_extends += ; - ms.status[inameId] = ms.status[inameId] ? {}; - // try { - // // mloc = getRascalModuleLocation(iname, ms); - // ms.paths += {}; - // } catch Message err: { - // err.at = imod@\loc; - // ms.messages[moduleId] ? {} += { err }; - // ms.status[inameId] += { rsc_not_found() }; - // } } ms.paths += imports_and_extends; return ; @@ -396,15 +381,14 @@ tuple[map[MODID,TModel], ModuleStatus] prepareForCompilation(set[MODID] componen pcfg = ms.pathConfig; dependencies_ok = true; - for(m <- component, rsc_not_found() notin ms.status[m], MStatus::ignored() notin ms.status[m]){ - if(parse_error() in ms.status[m]){ + for(m <- component, hasNotProperty(m, ms, rsc_not_found(), ModuleProperty::ignored())){ + if(hasProperty(m, ms, parse_error())){ return <(m : tmodel(modelName=moduleId2moduleName(m),messages=toList(ms.messages[m]))) ,ms>; } - for(imp <- m_imports[m] + m_extends[m], rsc_not_found() notin ms.status[imp], MStatus::ignored() notin ms.status[m]){ - imp_status = ms.status[imp]; - if(parse_error() in imp_status || checked() notin imp_status){ + for(imp <- m_imports[m] + m_extends[m], hasNotProperty(imp, ms, rsc_not_found()), hasNotProperty(m, ms, ModuleProperty::ignored())){ + if(hasProperty(imp, ms, parse_error()) || hasNotProperty(imp, ms, checked())){ dependencies_ok = false; - cause = (rsc_not_found() in imp_status) ? "module not found" : "due to syntax error"; + cause = hasProperty(imp, ms, rsc_not_found()) ? "module not found" : "due to syntax error"; ms.messages[m] = (ms.messages[imp] ? {}) + error(" module could not be checked ()", m); } } @@ -414,7 +398,7 @@ tuple[map[MODID,TModel], ModuleStatus] prepareForCompilation(set[MODID] componen } transient_tms = (m : tm | m <- component); org_tm = tm; - for(MODID m <- component, rsc_not_found() notin ms.status[m], MStatus::ignored() notin ms.status[m]){ + for(MODID m <- component, hasNotProperty(m, ms, rsc_not_found(), ModuleProperty::ignored())){ tm = org_tm; mname = moduleId2moduleName(m); tm.modelName = mname; @@ -433,7 +417,7 @@ tuple[map[MODID,TModel], ModuleStatus] prepareForCompilation(set[MODID] componen ModuleStatus doSaveModule(set[MODID] component, map[MODID,set[MODID]] m_imports, map[MODID,set[MODID]] m_extends, ModuleStatus ms, map[MODID, TModel] transient_tms, RascalCompilerConfig compilerConfig){ pcfg = ms.pathConfig; - component = { m | m <- component, MStatus::ignored() notin ms.status[m] }; + component = { m | m <- component, hasNotProperty(m, ms, ModuleProperty::ignored()) }; if(isEmpty(component)) return ms; //println("doSaveModule: , , , "); @@ -459,9 +443,9 @@ ModuleStatus doSaveModule(set[MODID] component, map[MODID,set[MODID]] m_imports, bom = makeBom(currentModule, ms); - extendedModuleScopes = {m | MODID m <- extends, checked() in ms.status[m]}; + extendedModuleScopes = {m | MODID m <- extends, hasProperty(m, ms, checked())}; extendedModuleScopes += {*tm.paths[ems,importPath()] | MODID ems <- extendedModuleScopes}; // add imports of extended modules - filteredModuleScopes = {m | MODID m <- (currentModule + imports), checked() in ms.status[m]} + extendedModuleScopes; + filteredModuleScopes = {m | MODID m <- (currentModule + imports), hasProperty(m, ms, checked())} + extendedModuleScopes; TModel m1 = tmodel(); m1.version = getCurrentTplVersion(); @@ -531,7 +515,7 @@ ModuleStatus doSaveModule(set[MODID] component, map[MODID,set[MODID]] m_imports, case loc l : if(!isEmpty(l.fragment)) insert l[fragment=""]; }; m1.logical2physical = tm.logical2physical; - ms.status[currentModule] -= {tpl_saved()}; + ms = deleteProperty(currentModule, ms, tpl_saved()); ms = addTModel(currentModule, m1, ms); // println("TModel for :"); iprintln(m1); } diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/TestConfigs.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/TestConfigs.rsc index 55fadfad48e..52c8618e7ba 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/TestConfigs.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/TestConfigs.rsc @@ -50,6 +50,7 @@ public loc RASCAL = |mvn://org.rascalmpl--rascal--0.41.0-RC15/|; public loc RASCAL42 = |mvn://org.rascalmpl--rascal--0.42.0-RC2/|; loc TYPEPAL = |mvn://org.rascalmpl--typepal--0.14.8/|; loc OUTDATED_TYPEPAL = |mvn://org.rascalmpl--typepal--0.14.1/|; +loc TYPEPAL166 = |mvn://org.rascalmpl--typepal--0.16.6-RC1/|; loc DRAMBIGUITY = |mvn://org.rascalmpl--drambiguity--0.1.2/|; loc FLYBYTES = |mvn://org.rascalmpl--flybytes--0.1.5/|; diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/ChangeScenarioTests.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/ChangeScenarioTests.rsc index cef2ace5073..28d9b0f1ca0 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/ChangeScenarioTests.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/ChangeScenarioTests.rsc @@ -775,6 +775,47 @@ test bool onlyChangedModulesAreReChecked2(){ return true; } +loc TYPEPAL166 = |mvn://org.rascalmpl--typepal--0.16.6-RC1/|; +test bool changeMultipleTimes() { // ht @toinehartman + loc projDir = |memory:///incremental-test/proj|; + loc checkerModule = projDir + "src" + "Checker.rsc"; + + PathConfig pcfg = pathConfig( + projectRoot = projDir, + srcs = [projDir + "src"], + bin = projDir + "target", + // There might be incompatibility here, since Rascal uses typepal--0.16.6-RC2 at the time of writing. + // However, I would still expect that errors caused by that appear on the first type-check. + libs = [TYPEPAL166, RASCAL42] + ); + iprintln(pcfg); + + // Clean + remove(projDir); + writeFile(checkerModule, " + module Checker + extend analysis::typepal::TypePal; + void collect(Collector c) { ; } + "); + + // First check + println("Initial check"); + if (!checkModuleOK(checkerModule, pathConfig = pcfg)) { + throw "First check failed; supposed to be OK."; + } + int N_TRIES = 10; + // Since this seems sporadically succeed, we run this a couple of times until it fails + for (i <- [1..N_TRIES + 1]) { + // Follow-up check + println("Follow-up check #"); + touch(checkerModule); + if (!checkModuleOK(checkerModule, pathConfig = pcfg)) { + return false; + } + } + return true; +} + // Benchmarks for incremental type checking void benchmark(str title, lrel[str, void()] cases){ diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/StaticTestingUtils.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/StaticTestingUtils.rsc index 7df51994e74..641121e9b30 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/StaticTestingUtils.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/StaticTestingUtils.rsc @@ -107,11 +107,11 @@ void removeModule(str mname){ void printModules(){ println("\<\<\<\<"); - for(f <- find(|memory:///test-modules/|, "rsc")){ + for(f <- find(|memory:///|, "rsc")){ println(" : '"); } - for(f <- find(|memory:///test-modules/|, "tpl")){ + for(f <- find(|memory:///|, "tpl")){ println(": "); } println("\>\>\>\>"); diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/download-test-jars.sh b/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/download-test-jars.sh index de70619a004..84f0a0d91b0 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/download-test-jars.sh +++ b/src/org/rascalmpl/compiler/lang/rascalcore/check/tests/download-test-jars.sh @@ -11,6 +11,7 @@ download "org.rascalmpl" "rascal" "0.41.0-RC15" download "org.rascalmpl" "rascal" "0.42.0-RC2" download "org.rascalmpl" "typepal" "0.14.8" download "org.rascalmpl" "typepal" "0.14.1" +download "org.rascalmpl" "typepal" "0.16.6-RC1" download "org.rascalmpl" "drambiguity" "0.1.2" download "org.rascalmpl" "flybytes" "0.1.5" download "org.rascalmpl" "salix-core" "0.2.7" diff --git a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Compile.rsc b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Compile.rsc index f70913380eb..8946aeb5af2 100644 --- a/src/org/rascalmpl/compiler/lang/rascalcore/compile/Compile.rsc +++ b/src/org/rascalmpl/compiler/lang/rascalcore/compile/Compile.rsc @@ -90,7 +90,7 @@ list[Message] compile1(MODID moduleId, lang::rascal::\syntax::Rascal::Module M, imports = { imp | <- ms.paths, m1 == moduleId }; extends = { ext | <- ms.paths, m1 == moduleId }; tmodels = (); - for(m <- imports + extends, tpl_uptodate() in ms.status[m]){ + for(m <- imports + extends, hasProperty(m, ms, tpl_uptodate())){ if(m in transient_tms){ tmodels[m] = transient_tms[m]; } else {