Skip to content

Commit 13afe0b

Browse files
committed
Check that explicitly defined context is present in the file name
1 parent af89810 commit 13afe0b

3 files changed

Lines changed: 39 additions & 22 deletions

File tree

core/src/main/java/io/timeandspace/jpsg/Context.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,25 @@
2121

2222
public final class Context implements Iterable<Map.Entry<String, Option>> {
2323

24+
static boolean stringIncludesOption(String s, Option option) {
25+
String replacedString = option.intermediateReplace(s, "dummy");
26+
return !s.equals(replacedString);
27+
}
28+
2429
static Builder builder() {
2530
return new Builder();
2631
}
2732

2833
static class Builder {
29-
private final LinkedHashMap<String, Option> options = new LinkedHashMap<String, Option>();
34+
private final LinkedHashMap<String, Option> options = new LinkedHashMap<>();
3035

3136
Builder put(String dim, Option option) {
3237
options.put(dim, option);
3338
return this;
3439
}
3540

3641
Context makeContext() {
37-
// noinspection unchecked
38-
return new Context(new LinkedHashMap<String, Option>(options));
42+
return new Context(new LinkedHashMap<>(options));
3943
}
4044
}
4145

@@ -52,8 +56,7 @@ public Iterator<Map.Entry<String, Option>> iterator() {
5256
}
5357

5458
public Context join(Context additionalContext) {
55-
// noinspection unchecked
56-
LinkedHashMap<String, Option> newOptions = new LinkedHashMap<String, Option>(options);
59+
LinkedHashMap<String, Option> newOptions = new LinkedHashMap<>(options);
5760
for ( Map.Entry<String, Option> e : additionalContext.options.entrySet() ) {
5861
newOptions.put(e.getKey(), e.getValue());
5962
}

core/src/main/java/io/timeandspace/jpsg/Generator.kt

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -306,12 +306,11 @@ class Generator {
306306
defaultContext = defaultContext!!.join(contexts[0])
307307
}
308308

309-
excludedTypes = never
310-
.flatMap({ options -> Dimensions.Parser.parseOptions(options) }).toList()
309+
excludedTypes = never.flatMap { options -> parseOptions(options) }.toList()
311310

312-
permissiveConditions = included.map({ dimensionsParser!!.parse(it) }).toList()
311+
permissiveConditions = included.map { dimensionsParser!!.parse(it) }.toList()
313312

314-
prohibitingConditions = excluded.map({ dimensionsParser!!.parse(it) }).toList()
313+
prohibitingConditions = excluded.map { dimensionsParser!!.parse(it) }.toList()
315314

316315
initProcessors()
317316
}
@@ -333,16 +332,16 @@ class Generator {
333332
setCurrentSourceFile(sourceFile)
334333
log.info("Processing file: {}", sourceFile)
335334
val sourceFileName = sourceFile.name
336-
var targetDims = dimensionsParser!!.parseClassName(sourceFileName)
335+
var targetDims: Dimensions = dimensionsParser!!.parseClassName(sourceFileName)
337336
var rawContent = sourceFile.readText()
338337
val fileDimsM = CONTEXT_START_P.matcher(rawContent)
339338
if (fileDimsM.find() && fileDimsM.start() == 0) {
340-
targetDims = dimensionsParser!!.parseForContext(
341-
getBlockGroup(fileDimsM.group(), CONTEXT_START_BLOCK_P, "dimensions"))
342-
rawContent = rawContent.substring(fileDimsM.end()).trim({ it <= ' ' }) + "\n"
339+
val explicitContext = fileDimsM.group()
340+
targetDims = parseAndCheckExplicitContext(explicitContext, sourceFile)
341+
rawContent = rawContent.substring(fileDimsM.end()).trim { it <= ' ' } + "\n"
343342
}
344343
log.info("Target dimensions: {}", targetDims)
345-
val targetContexts = targetDims.generateContexts()
344+
val targetContexts: List<Context> = targetDims.generateContexts()
346345
val mainContext = defaultContext!!.join(targetContexts[0])
347346
val fileCondM = COND_START_P.matcher(rawContent)
348347
var fileCond: Condition? = null
@@ -351,7 +350,7 @@ class Generator {
351350
getBlockGroup(fileCondM.group(), COND_START_BLOCK_P, "condition"),
352351
dimensionsParser!!, mainContext,
353352
rawContent, fileCondM.start())
354-
rawContent = rawContent.substring(fileCondM.end()).trim({ it <= ' ' }) + "\n"
353+
rawContent = rawContent.substring(fileCondM.end()).trim { it <= ' ' } + "\n"
355354
}
356355
val content = rawContent
357356

@@ -404,6 +403,21 @@ class Generator {
404403
ForkJoinTasks.invokeAll(contextGenerationTasks)
405404
}
406405

406+
private fun parseAndCheckExplicitContext(explicitContext: String, sourceFile: File):
407+
Dimensions {
408+
val targetDims: Dimensions = dimensionsParser!!.parseForContext(
409+
getBlockGroup(explicitContext, CONTEXT_START_BLOCK_P, "dimensions"))
410+
val mainExplicitContext: Context = targetDims.generateContexts()[0]
411+
for ((dim, option) in mainExplicitContext) {
412+
if (!Context.stringIncludesOption(sourceFile.name, option)) {
413+
throw RuntimeException(
414+
"Dimension $dim with options ${targetDims.dimensions[dim]} specified " +
415+
"explicitly in $sourceFile is not found in the file name")
416+
}
417+
}
418+
return targetDims
419+
}
420+
407421
@Throws(IOException::class)
408422
internal fun writeFile(file: File, content: String) {
409423
file.writeText(content)
@@ -420,7 +434,7 @@ class Generator {
420434
}
421435
if (!checkPermissive(target))
422436
return false
423-
if (!prohibitingConditions!!.isEmpty()) {
437+
if (prohibitingConditions!!.isNotEmpty()) {
424438
for (prohibitingCondition in prohibitingConditions!!) {
425439
if (prohibitingCondition.checkAsCondition(target))
426440
return false
@@ -430,7 +444,7 @@ class Generator {
430444
}
431445

432446
private fun checkPermissive(target: Context): Boolean {
433-
if (!permissiveConditions!!.isEmpty()) {
447+
if (permissiveConditions!!.isNotEmpty()) {
434448
for (permissiveCondition in permissiveConditions!!) {
435449
if (permissiveCondition.checkAsCondition(target))
436450
return true

core/src/main/java/io/timeandspace/jpsg/MalformedTemplateException.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@ class MalformedTemplateException private constructor(message: String) : RuntimeE
3131
}
3232

3333
internal fun lines(s: String): List<String> {
34-
val ls = s.split("\\n".toRegex()).dropLastWhile({ it.isEmpty() }).toTypedArray()
35-
return ls.map({ l -> l + '\n' }).toList()
34+
val ls = s.split("\\n".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
35+
return ls.map { l -> l + '\n' }.toList()
3636
}
3737

3838
private fun makeMessageNear(input: CharSequence, pos: Int, message: String): String {
3939
val messageNear = StringBuilder()
4040

41-
messageNear.append("Source file: " + Generator.currentSourceFile() + "\n")
41+
messageNear.append("Source file: ${Generator.currentSourceFile()}\n")
4242
messageNear.append("$message:\n")
4343

4444
val s = input.toString()
@@ -54,11 +54,11 @@ class MalformedTemplateException private constructor(message: String) : RuntimeE
5454
charCount += line.length
5555
}
5656
val firstLine = max(targetLine - 2, 0)
57-
lines.subList(firstLine, targetLine + 1).forEach({ messageNear.append(it) })
57+
lines.subList(firstLine, targetLine + 1).forEach { messageNear.append(it) }
5858
val pointer = String(CharArray(pos - charCount)).replace('\u0000', ' ') + "^\n"
5959
messageNear.append(pointer)
6060
val lastLine = min(targetLine + 3, lines.size)
61-
lines.subList(targetLine + 1, lastLine).forEach({ messageNear.append(it) })
61+
lines.subList(targetLine + 1, lastLine).forEach { messageNear.append(it) }
6262
return messageNear.toString()
6363
}
6464
}

0 commit comments

Comments
 (0)