Skip to content

Commit 4f93399

Browse files
committed
[skiplang/skc] Fix #env() variable invalidation.
1 parent 575ac19 commit 4f93399

File tree

6 files changed

+108
-70
lines changed

6 files changed

+108
-70
lines changed

skiplang/compiler/src/SkipParser.sk

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ mutable class SkipParser{
3333
lazy: Bool,
3434
tokenLexer: mutable SkipLexer.SkipCoreLexer,
3535
templateLexer: mutable SkipLexer.TemplateLexer,
36+
accessedEnvVars: mutable Set<String> = mutable Set[],
3637
} extends Parser.Parser {
3738
static fun create(source: String, lazy: Bool): mutable this {
3839
lexingPosition = Lexer.LexingPosition::create(source);
@@ -54,6 +55,10 @@ mutable class SkipParser{
5455
};
5556
}
5657

58+
readonly fun getAccessedEnvVars(): SortedSet<String> {
59+
SortedSet::createFromIterator(this.accessedEnvVars.values())
60+
}
61+
5762
mutable fun createPeekParser(): mutable this {
5863
mutable static{
5964
lazy => this.lazy,
@@ -4791,6 +4796,8 @@ mutable class SkipParser{
47914796
};
47924797
closeParen = this.eatTree(TokenKind.CLOSE_PAREN());
47934798

4799+
this.accessedEnvVars.insert(varName.getToken().stringLiteralValue());
4800+
47944801
ParseTree.EnvMacroTree{
47954802
range => this.createRange(start),
47964803
envKeyword,
@@ -5108,7 +5115,7 @@ fun parseSource(
51085115
source: String,
51095116
isLazy: Bool,
51105117
filename: String = "",
5111-
): Parser.ParseResults {
5118+
): (Parser.ParseResults, SortedSet<String>) {
51125119
parser = SkipParser::create(source, isLazy);
51135120
tree = parser.parseSourceUnit();
51145121
allErrors = parser.getErrors();
@@ -5124,7 +5131,11 @@ fun parseSource(
51245131
if (errors.isEmpty() && !isLazy) {
51255132
Parser.validateParse(tokens, tree, filename);
51265133
};
5127-
Parser.ParseResults{tokens, comments => parser.getComments(), tree, errors};
5134+
5135+
(
5136+
Parser.ParseResults{tokens, comments => parser.getComments(), tree, errors},
5137+
parser.getAccessedEnvVars(),
5138+
)
51285139
}
51295140

51305141
fun getNamedParameterDefaultValue(tree: ParseTree): ParseTree {

skiplang/compiler/src/compile.sk

Lines changed: 15 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -247,28 +247,7 @@ fun getOrInitializeBackend(context: mutable SKStore.Context): SKStore.EagerDir {
247247
};
248248

249249
if (conf.emit == "sklib") {
250-
accessed_env_vars = context.getGlobal(
251-
FileCache.kEnvAccessGlobal,
252-
) match {
253-
| None() -> SortedSet[]
254-
| Some(envMapFile) ->
255-
FileCache.EnvMapFile::type(envMapFile)
256-
.value.maybeGet(conf.lib_name)
257-
.default(SortedSet[])
258-
};
259-
env_dir = SKStore.EHandle(
260-
SKStore.SID::keyType,
261-
SKStore.StringFile::type,
262-
SKStore.DirName::create(
263-
`/packageEnv/${conf.lib_name.default("_default")}/`,
264-
),
265-
);
266-
env = SortedMap::createFromIterator(
267-
accessed_env_vars
268-
.map(v -> (v, env_dir.unsafeGet(context, SKStore.SID(v)).value))
269-
.iterator(),
270-
);
271-
compile_sklib(conf, env);
250+
compile_sklib(context, conf);
272251
return void
273252
};
274253

@@ -425,11 +404,21 @@ fun compile_binary(
425404
})
426405
}
427406

428-
fun compile_sklib(
429-
conf: Config.Config,
430-
env_vars: SortedMap<String, String>,
431-
): void {
407+
fun compile_sklib(context: mutable SKStore.Context, conf: Config.Config): void {
432408
runCompilerPhase("native/write_sklib", () -> {
409+
accessed_env_vars = SortedSet::createFromItems(
410+
FileCache.packageEnvAccessDir.getArray(
411+
context,
412+
SKStore.SID(conf.lib_name.fromSome()),
413+
).map(v -> v.value),
414+
);
415+
env_dir = FileCache.packageEnvDir(conf.lib_name);
416+
env_vars = SortedMap::createFromIterator(
417+
accessed_env_vars
418+
.map(v -> (v, env_dir.unsafeGet(context, SKStore.SID(v)).value))
419+
.iterator(),
420+
);
421+
433422
// NOTE: Static libraries (`.a` archives) provided as input files are
434423
// bundled into the `sklib`.
435424
sklib = mutable SklibBuilder(

skiplang/compiler/src/skfmt.sk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ fun prettyPrint(
1111
contents: String,
1212
filename: String,
1313
): Result<String, SkipError.Error> {
14-
parsed = SkipParser.parseSource(contents, false);
14+
(parsed, _) = SkipParser.parseSource(contents, false);
1515
if (parsed.errors.size() > 0) {
1616
// Parse errors are expected. Exceptions are bugs.
1717
Failure(

skiplang/compiler/src/skipMain.sk

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ fun type_program(
1515
): SKStore.EHandle<SKStore.SID, SkipTyping.DefFile> {
1616
parsed_program = FileCache.fileDir.map(
1717
FileCache.InputSource::keyType,
18-
SkipParse.DefsFile::type,
18+
SkipParse.DefsWithAccessedEnvVarsFile::type,
1919
context,
20-
SkipParse.astDirName,
20+
SKStore.DirName::create("/astAndAccessedEnvVarsCache/"),
2121
(context, writer, key, sources) ~> {
2222
source = sources.first;
2323
SkipError.catchErrors(0, context, () -> {
@@ -26,7 +26,35 @@ fun type_program(
2626
},
2727
);
2828

29-
(defsDir, childDir) = SkipExpand.program(context, parsed_program);
29+
_ = parsed_program.map(
30+
SKStore.SID::keyType,
31+
SKStore.StringFile::type,
32+
context,
33+
FileCache.packageEnvAccessDirName,
34+
(_context, writer, key, values) ~> {
35+
writer.setArray(
36+
SKStore.SID(key.pkg_opt.default(FileCache.kAnonymousPackageName)),
37+
values
38+
.getUnique()
39+
.fromSome()
40+
.accessed_env_vars.values()
41+
.map(v -> SKStore.StringFile(v))
42+
.collect(Array),
43+
)
44+
},
45+
);
46+
47+
ast = parsed_program.map(
48+
FileCache.InputSource::keyType,
49+
SkipParse.DefsFile::type,
50+
context,
51+
SkipParse.astDirName,
52+
(_context, writer, key, values) ~> {
53+
writer.set(key, SkipParse.DefsFile(values.getUnique().fromSome().defs))
54+
},
55+
);
56+
57+
(defsDir, childDir) = SkipExpand.program(context, ast);
3058
inhDir = SkipInherit.populateClassesDir(context);
3159
SkipNaming.populateClasses(context, defsDir, inhDir, childDir);
3260
SkipNaming.populateFuns(context, defsDir);

skiplang/compiler/src/skipNaming.sk

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3662,32 +3662,13 @@ fun expandForEachMacro(
36623662

36633663
fun expandEnvMacro(context: mutable SKStore.Context, varName: A.Name): N.Expr_ {
36643664
(pos, name) = varName;
3665-
pkg_env = SKStore.EHandle(
3666-
SKStore.SID::keyType,
3667-
SKStore.StringFile::type,
3668-
// FIXME: Ensure package names cannot start with an underscore to avoid clash with `_default`.
3669-
SKStore.DirName::create(
3670-
`/packageEnv/${pos.file.pkg_opt.default("_default")}/`,
3671-
),
3672-
);
3673-
value = pkg_env.maybeGet(context, SKStore.SID(name)) match {
3665+
value = FileCache.packageEnvDir(pos.file.pkg_opt).maybeGet(
3666+
context,
3667+
SKStore.SID(name),
3668+
) match {
36743669
| None() -> SkipError.error(pos, `Environment variable ${name} is not set.`)
36753670
| Some(v) -> v.value
36763671
};
3677-
// Record access to env variable.
3678-
cur_env_map = context.getGlobal(FileCache.kEnvAccessGlobal) match {
3679-
| None() -> SortedMap[]
3680-
| Some(envMapFile) -> FileCache.EnvMapFile::type(envMapFile).value
3681-
};
3682-
context.setGlobal(
3683-
FileCache.kEnvAccessGlobal,
3684-
FileCache.EnvMapFile(
3685-
cur_env_map.set(
3686-
pos.file.pkg_opt,
3687-
cur_env_map.maybeGet(pos.file.pkg_opt).default(SortedSet[]).set(name),
3688-
),
3689-
),
3690-
);
36913672
N.Literal(A.StringLiteral(value))
36923673
}
36933674

skiplang/compiler/src/skipParse.sk

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,18 @@ const packageDir: SKStore.EHandle<
6868
packageDirName,
6969
);
7070

71+
const packageEnvAccessDirName: SKStore.DirName = SKStore.DirName::create(
72+
"/packageEnvAccess/",
73+
);
74+
const packageEnvAccessDir: SKStore.EHandle<
75+
SKStore.SID,
76+
SKStore.StringFile,
77+
> = SKStore.EHandle(
78+
SKStore.SID::keyType,
79+
SKStore.StringFile::type,
80+
packageEnvAccessDirName,
81+
);
82+
7183
fun pkgDelta(
7284
old_pkg: InputPackageFiles,
7385
new_pkg: InputPackageFiles,
@@ -205,17 +217,33 @@ fun writeFiles(
205217
}
206218
}
207219

220+
// FIXME: Ensure package names cannot start with an underscore to avoid clash with `_anonymous`.
221+
const kAnonymousPackageName: String = "_anonymous";
222+
223+
fun packageEnvDirName(pkg_opt: ?String): SKStore.DirName {
224+
SKStore.DirName::create(
225+
`/packageEnv/${pkg_opt.default(kAnonymousPackageName)}/`,
226+
)
227+
}
228+
229+
fun packageEnvDir(
230+
pkg_opt: ?String,
231+
): SKStore.EHandle<SKStore.SID, SKStore.StringFile> {
232+
SKStore.EHandle(
233+
SKStore.SID::keyType,
234+
SKStore.StringFile::type,
235+
packageEnvDirName(pkg_opt),
236+
)
237+
}
238+
208239
fun updatePackageEnv(
209240
context: mutable SKStore.Context,
210241
pkg_opt: ?String,
211242
env: Array<(String, String)>,
212243
): void {
213-
envDirName = SKStore.DirName::create(
214-
`/packageEnv/${pkg_opt.default("_default")}/`,
215-
);
244+
envDirName = packageEnvDirName(pkg_opt);
216245
envDir = context.unsafeMaybeGetEagerDir(envDirName) match {
217-
| Some _ ->
218-
SKStore.EHandle(SKStore.SID::keyType, SKStore.StringFile::type, envDirName)
246+
| Some _ -> packageEnvDir(pkg_opt)
219247
| None _ ->
220248
context.mkdir(SKStore.SID::keyType, SKStore.StringFile::type, envDirName)
221249
};
@@ -236,12 +264,6 @@ fun updatePackageEnv(
236264
};
237265
}
238266

239-
const kEnvAccessGlobal: String = "ACCESSED_ENV_MAP";
240-
241-
class EnvMapFile(
242-
value: SortedMap<?String, SortedSet<String>>,
243-
) extends SKStore.File
244-
245267
module end;
246268

247269
module SkipParse;
@@ -254,11 +276,18 @@ const astDir: SKStore.EHandle<SKStore.SID, DefsFile> = SKStore.EHandle(
254276
);
255277

256278
class DefsFile(value: List<SkipAst.Definition>) extends SKStore.File
279+
class DefsWithAccessedEnvVarsFile(
280+
defs: List<SkipAst.Definition>,
281+
accessed_env_vars: SortedSet<String>,
282+
) extends SKStore.File
257283

258-
fun parseFile(file: FileCache.InputSource, source: String): DefsFile {
259-
fileResult = SkipParser.parseSource(source, true);
260-
ast = parseToAst(file, fileResult);
261-
DefsFile(ast)
284+
fun parseFile(
285+
file: FileCache.InputSource,
286+
source: String,
287+
): DefsWithAccessedEnvVarsFile {
288+
(fileResult, accessed_env_vars) = SkipParser.parseSource(source, true);
289+
defs = parseToAst(file, fileResult);
290+
DefsWithAccessedEnvVarsFile(defs, accessed_env_vars)
262291
}
263292

264293
fun parseToAst(

0 commit comments

Comments
 (0)