Skip to content

Commit

Permalink
Configuring the compiler made simpler
Browse files Browse the repository at this point in the history
The existing situation was that _and_ a TypePalConfig _and_ a
CompilerConfig were needed to configure the typechecker and compiler.

This has been replaced by a single RascalCompilerConfig (see
lang::rascalcore::check::RascalConfig) that contains all configuration
option both for the TypePal specific options and for the
compiler-specific options.

As a result, there is a single place for options, and the signatures of
several functions could be simplified.
  • Loading branch information
PaulKlint committed Mar 10, 2024
1 parent 53b0ffa commit 35a67f5
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 87 deletions.
10 changes: 4 additions & 6 deletions src/org/rascalmpl/core/library/CheckTestSources.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ void checkTestSources(PathConfig pcfg) {
println("PathConfig for type checking test sources:\n");
iprintln(testConfig);

testCompilerConfig = getRascalCompilerConfig();
testCompilerConfig = rascalCompilerConfig(testConfig);
total = 0;

println(readFile(|lib://rascal/META-INF/MANIFEST.MF|));
Expand Down Expand Up @@ -82,7 +82,7 @@ void checkTestSources(PathConfig pcfg) {
"analysis::m3::TypeSymbol"];

for (m <- libraryModules) {
<e,d> = safeCompile(m, testConfig, testCompilerConfig);
<e,d> = safeCompile(m, testCompilerConfig);
total += d;
}

Expand All @@ -101,7 +101,7 @@ void checkTestSources(PathConfig pcfg) {
for (i <- index(testModules)) {
m = testModules[i];
println("Checking test module <m> [<i>/<n>]");
<e, d> = safeCompile(m, testConfig, testCompilerConfig);
<e, d> = safeCompile(m, testCompilerConfig);
total += d;
if(!isEmpty(e)){
exceptions += e;
Expand All @@ -114,13 +114,11 @@ void checkTestSources(PathConfig pcfg) {
println("Time: <secs> seconds");
}
tuple[str, int] safeCompile(str \module, PathConfig pcfg, CompilerConfig compilerConfig) {
tuple[str, int] safeCompile(str \module, RascalCompilerConfig compilerConfig) {
start_time = cpuTime();
try {
println("checking <\module>");
ModuleStatus result = rascalTModelForNames([\module],
rascalTypePalConfig(pcfg),
compilerConfig,
dummy_compile1);
iprintln(result.tmodels[\module].messages);
Expand Down
13 changes: 6 additions & 7 deletions src/org/rascalmpl/core/library/CompileTestSources.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ void compileTestSources(PathConfig pcfg) {
println("PathConfig for compiling test sources:\n");
iprintln(testConfig);

testCompilerConfig = getRascalCompilerConfig();
testCompilerConfig = rascalCompilerConfig(testConfig);
total = 0;

println(readFile(|lib://rascal/META-INF/MANIFEST.MF|));
Expand Down Expand Up @@ -121,7 +121,7 @@ void compileTestSources(PathConfig pcfg) {


for (m <- libraryModules) {
<e, d> = safeCompile(m, testConfig, testCompilerConfig);
<e, d> = safeCompile(m, testCompilerConfig);
total += d;
}

Expand All @@ -145,7 +145,7 @@ void compileTestSources(PathConfig pcfg) {
for (i <- index(testModules)) {
m = testModules[i];
println("Compiling test module <m> [<i>/<n>]");
<e, d> = safeCompile(m, testConfig, testCompilerConfig);
<e, d> = safeCompile(m, testCompilerConfig);
total += d;
if(!isEmpty(e)){
exceptions += e;
Expand All @@ -158,11 +158,10 @@ void compileTestSources(PathConfig pcfg) {
println("Time: <secs> seconds");
}
tuple[str, int] safeCompile(str \module, PathConfig pcfg, CompilerConfig compilerConfig) {
tuple[str, int] safeCompile(str \module, RascalCompilerConfig compilerConfig) {
start_time = cpuTime();
try {
println("compiling <\module>");
compile(\module, pcfg, compilerConfig);
try {
compile(\module, compilerConfig);
return <"",cpuTime()-start_time>;
}
catch value exception: {
Expand Down
10 changes: 5 additions & 5 deletions src/org/rascalmpl/core/library/GenerateTestSources.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ void generateTestSources(PathConfig pcfg) {
libs = [ ]
);

testCompilerConfig = getRascalCompilerConfig();
testCompilerConfig = getRascalCompilerConfigForDev(testConfig);

map[str,int] durations = ();

Expand Down Expand Up @@ -118,7 +118,7 @@ void generateTestSources(PathConfig pcfg) {


for (m <- libraryModules) {
safeCompile(m, testConfig, testCompilerConfig, (int d) { durations[m] = d; });
safeCompile(m, testCompilerConfig, (int d) { durations[m] = d; });
}

//for (m <- checkerTestModules) {
Expand All @@ -140,7 +140,7 @@ void generateTestSources(PathConfig pcfg) {
for (i <- index(testModules)) {
m = testModules[i];
println("Compiling test module <m> [<i>/<n>]");
e = safeCompile(m, testConfig, testCompilerConfig, (int d) { durations[m] = d; });
e = safeCompile(m, testCompilerConfig, (int d) { durations[m] = d; });
if(!isEmpty(e)){
exceptions += e;
}
Expand All @@ -153,10 +153,10 @@ void generateTestSources(PathConfig pcfg) {
//iprintln(sort({ <m, durations[m] / 1000000000> | m <- durations}, bool (<_,int i>, <_, int j>) { return i < j; }));
}
str safeCompile(str \module, PathConfig pcfg, CompilerConfig compilerConfig, void (int duration) measure) {
str safeCompile(str \module, RascalCompilerConfig compilerConfig, void (int duration) measure) {
try {
measure(cpuTimeOf(() {
compile(\module, pcfg, compilerConfig);
compile(\module, compilerConfig);
}));
return "";
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,29 @@ public str key_grammar = "grammar";
public str key_ADTs = "ADTs";
public str key_common_keyword_fields = "CommonKeywordFields";

// Define alias for TypePalConfig

alias RascalCompilerConfig = TypePalConfig;

// Add keyword parameters to a TypePalConfig to represent compiler settings
// Also see lang::rascalcore::check::RascalConfig

data TypePalConfig(
bool logImports = true,
// Control message level
bool warnUnused = true,
bool warnUnusedFormals = true,
bool warnUnusedVariables = true,
bool warnUnusedPatternFormals = true,
bool warnDeprecated = false
bool warnDeprecated = false,

loc reloc = |noreloc:///|, // Unused

// Debugging options
bool verbose = true, // for each compiled module, print PathConfig, module name and compilation time
bool logImports = false, // log all imported files
bool logWrittenFiles = false, // log all files written by compiler

bool optimizeVisit = true, // Options for compiler developer
bool enableAsserts = true,
bool forceCompilationTopModule = false
);
66 changes: 33 additions & 33 deletions src/org/rascalmpl/core/library/lang/rascalcore/check/Checker.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@ data PathConfig(
loc resources = |unknown:///|,
loc testResources =|unknown:///|
);

Tree mkTree(int n) = [DecimalIntegerLiteral] "<for(int _ <- [0 .. n]){>6<}>"; // Create a unique tree to identify predefined names

void rascalPreCollectInitialization(map[str, Tree] namedTrees, Collector c){

Expand Down Expand Up @@ -130,6 +128,14 @@ public PathConfig getRascalCorePathConfig() {
libs = []
);
}

public RascalCompilerConfig getRascalCoreCompilerConfig(){
return rascalCompilerConfig(getRascalCorePathConfig())[verbose = true][forceCompilationTopModule = true][logWrittenFiles = true];
}

public RascalCompilerConfig getRascalCompilerConfigForDev(PathConfig pcfg){
return rascalCompilerConfig(pcfg);
}

@synopsis{a path config for testing type-checking of the standard library in the rascal project}
public PathConfig getRascalProjectPathConfig() {
Expand All @@ -142,9 +148,6 @@ public PathConfig getRascalProjectPathConfig() {
);
}

CompilerConfig getRascalCompilerConfig()
= cconfig();

list[Message] validatePathConfigForCompiler(PathConfig pcfg, loc mloc){
msgs = [];

Expand Down Expand Up @@ -187,14 +190,11 @@ list[Message] validatePathConfigForCompiler(PathConfig pcfg, loc mloc){
// rascalTModelForLocs is the basic work horse

ModuleStatus rascalTModelForLocs(
list[loc] mlocs,
TypePalConfig config,
CompilerConfig compilerConfig,
list[Message](str qualifiedModuleName, lang::rascal::\syntax::Rascal::Module M, ModuleStatus ms, CompilerConfig compilerConfig) codgen
){
bool forceCompilationTopModule = false; /***** for convenience, set to true during development of type checker *****/

pcfg = config.typepalPathConfig;
list[loc] mlocs,
RascalCompilerConfig compilerConfig,
list[Message](str qualifiedModuleName, lang::rascal::\syntax::Rascal::Module M, ModuleStatus ms, RascalCompilerConfig compilerConfig) codgen
){
pcfg = compilerConfig.typepalPathConfig;
if(compilerConfig.verbose) iprintln(pcfg);

msgs = validatePathConfigForCompiler(pcfg, mlocs[0]);
Expand All @@ -218,7 +218,7 @@ ModuleStatus rascalTModelForLocs(
try {
ms = getImportAndExtendGraph(topModuleNames, pcfg);

if(forceCompilationTopModule){
if(compilerConfig.forceCompilationTopModule){
for(str nm <- topModuleNames){
ms.status[nm] = {};
}
Expand Down Expand Up @@ -265,7 +265,7 @@ ModuleStatus rascalTModelForLocs(
}
}
if(!all(m <- component, tpl_uptodate() in ms.status[m] || checked() in ms.status[m])){
<tm, ms> = rascalTModelComponent(component, ms, config);
<tm, ms> = rascalTModelComponent(component, ms, compilerConfig);
moduleScopes += getModuleScopes(tm);
map[str,TModel] tmodels_for_component = ();
map[str,set[str]] m_imports = ();
Expand All @@ -276,7 +276,7 @@ ModuleStatus rascalTModelForLocs(
extends = { ext | <m1, extendPath(), ext > <- ms.strPaths, m1 == m };
m_extends[m] = extends;
invertedExtends = ms.strPaths<2,0>;
if(config.warnUnused){
if(compilerConfig.warnUnused){
// Look for unused imports or exports
usedModules = {path2module[l.path] | loc l <- range(tm.useDef), tm.definitions[l].idRole != moduleId(), path2module[l.path]?};
usedModules += {*invertedExtends[um] | um <- usedModules}; // use of an extended module via import
Expand Down Expand Up @@ -384,7 +384,7 @@ tuple[set[str], ModuleStatus] loadImportsAndExtends(str moduleName, ModuleStatus
return <added, ms>;
}

tuple[TModel, ModuleStatus] rascalTModelComponent(set[str] moduleNames, ModuleStatus ms, TypePalConfig config){
tuple[TModel, ModuleStatus] rascalTModelComponent(set[str] moduleNames, ModuleStatus ms, RascalCompilerConfig compilerConfig){

pcfg = ms.pathConfig;
modelName = intercalate(" + ", toList(moduleNames));
Expand All @@ -398,10 +398,10 @@ tuple[TModel, ModuleStatus] rascalTModelComponent(set[str] moduleNames, ModuleSt
}
}
jobStart("RascalCompiler");
jobStep("RascalCompiler", "Type checking <modelName>"); // TODO: monitor
if(config.verbose) println("Type checking <modelName>");
jobStep("RascalCompiler", "Checking <modelName>"); // TODO: monitor
if(compilerConfig.verbose) println("Checking <modelName>");

c = newCollector(modelName, namedTrees, config);
c = newCollector(modelName, namedTrees, compilerConfig);
c.push(key_pathconfig, pcfg);

rascalPreCollectInitialization(namedTrees, c);
Expand All @@ -428,12 +428,11 @@ tuple[TModel, ModuleStatus] rascalTModelComponent(set[str] moduleNames, ModuleSt
// ---- rascalTModelForName a checker version that works on module names

ModuleStatus rascalTModelForNames(list[str] moduleNames,
TypePalConfig config,
CompilerConfig compilerConfig,
list[Message] (str qualifiedModuleName, lang::rascal::\syntax::Rascal::Module M, ModuleStatus ms, CompilerConfig compilerConfig) codgen){
RascalCompilerConfig compilerConfig,
list[Message] (str qualifiedModuleName, lang::rascal::\syntax::Rascal::Module M, ModuleStatus ms, RascalCompilerConfig compilerConfig) codgen){


pcfg = config.typepalPathConfig;
pcfg = compilerConfig.typepalPathConfig;
mlocs = [];
for(moduleName <- moduleNames){
try {
Expand All @@ -445,32 +444,33 @@ ModuleStatus rascalTModelForNames(list[str] moduleNames,
return ms;
}
}
return rascalTModelForLocs(mlocs, config, compilerConfig, codgen);
return rascalTModelForLocs(mlocs, compilerConfig, codgen);
}

// ---- checker functions for IDE

// name of the production has to mirror the Kernel compile result
data ModuleMessages = program(loc src, set[Message] messages);

list[Message] dummy_compile1(str _qualifiedModuleName, lang::rascal::\syntax::Rascal::Module _M, ModuleStatus _ms, CompilerConfig _compilerConfig)
list[Message] dummy_compile1(str _qualifiedModuleName, lang::rascal::\syntax::Rascal::Module _M, ModuleStatus _ms, RascalCompilerConfig _compilerConfig)
= [];

list[ModuleMessages] check(list[loc] moduleLocs, PathConfig pcfg, CompilerConfig compilerConfig){
pcfg1 = pcfg; pcfg1.classloaders = []; pcfg1.javaCompilerPath = [];
list[ModuleMessages] check(list[loc] moduleLocs, RascalCompilerConfig compilerConfig){
pcfg1 = compilerConfig.typepalPathConfig; pcfg1.classloaders = []; pcfg1.javaCompilerPath = [];
compilerConfig.typepalPathConfig = pcfg1;
//println("=== check: <moduleLocs>"); iprintln(pcfg1);
ms = rascalTModelForLocs(moduleLocs, rascalTypePalConfig(pcfg), compilerConfig, dummy_compile1);
ms = rascalTModelForLocs(moduleLocs, compilerConfig, dummy_compile1);
return [ program(ms.moduleLocs[mname], toSet(ms.messages[mname])) | mname <- ms.messages ];
}

list[ModuleMessages] checkAll(loc root, PathConfig pcfg, CompilerConfig compilerConfig){
return check(toList(find(root, "rsc")), pcfg, compilerConfig);
list[ModuleMessages] checkAll(loc root, RascalCompilerConfig compilerConfig){
return check(toList(find(root, "rsc")), compilerConfig);
}

// ---- Convenience check function during development -------------------------

map[str, list[Message]] checkModules(list[str] moduleNames, TypePalConfig config, PathConfig pcfg, bool verbose=true) {
ModuleStatus ms = rascalTModelForNames(moduleNames, config, getRascalCompilerConfig()[verbose=verbose], dummy_compile1);
map[str, list[Message]] checkModules(list[str] moduleNames, RascalCompilerConfig compilerConfig) {
ModuleStatus ms = rascalTModelForNames(moduleNames, compilerConfig, dummy_compile1);
tmodels = ms.tmodels;
return (mname : tmodels[mname].messages | mname <- tmodels, !isEmpty(tmodels[mname].messages));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ tuple[bool, TModel, ModuleStatus] getTModelForModule(str qualifiedModuleName, Mo
ms.tmodels[qualifiedModuleName] = tpl;
ms.status[qualifiedModuleName] += {tpl_uptodate(), tpl_saved()};
return <true, tpl, ms>;
} catch _:
return <false, tmodel(modelName=qualifiedModuleName, messages=[error("Cannot read tpl", tplLoc)]), ms>;
} catch e:
return <false, tmodel(modelName=qualifiedModuleName, messages=[error("Cannot read .tpl for <qualifiedModuleName>: <e>", tplLoc)]), ms>;
//throw IO("Cannot read tpl for <qualifiedModuleName>: <e>");
}
//if(qualifiedModuleName notin hardwired){
Expand Down Expand Up @@ -439,7 +439,7 @@ ModuleStatus preSaveModule(set[str] component, map[str,set[str]] m_imports, map[
return ms;
}

ModuleStatus doSaveModule(set[str] component, map[str,set[str]] m_imports, map[str,set[str]] m_extends, ModuleStatus ms, map[str,loc] moduleScopes, CompilerConfig compilerConfig){
ModuleStatus doSaveModule(set[str] component, map[str,set[str]] m_imports, map[str,set[str]] m_extends, ModuleStatus ms, map[str,loc] moduleScopes, RascalCompilerConfig compilerConfig){
map[str,datetime] moduleLastModified = ms.moduleLastModified;
pcfg = ms.pathConfig;
//println("doSaveModule: <qualifiedModuleName>, <imports>, <extends>, <moduleScopes>");
Expand Down
Loading

0 comments on commit 35a67f5

Please sign in to comment.