Skip to content

Commit a9750e2

Browse files
committed
Fix #50: error when modules loaded twice
1 parent 5e5fd29 commit a9750e2

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

spaghetti-core/src/main/groovy/com/prezi/spaghetti/config/ModuleConfigurationParser.groovy

+14-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.prezi.spaghetti.config
22

33
import com.prezi.spaghetti.ast.ModuleNode
4+
import com.prezi.spaghetti.ast.parser.AstParserException
45
import com.prezi.spaghetti.ast.parser.MissingTypeResolver
56
import com.prezi.spaghetti.ast.parser.ModuleParser
67
import com.prezi.spaghetti.ast.parser.ModuleTypeResolver
@@ -15,19 +16,27 @@ class ModuleConfigurationParser {
1516
Collection<ModuleDefinitionSource> localModuleSources,
1617
Collection<ModuleDefinitionSource> dependentModuleSources,
1718
Collection<ModuleDefinitionSource> transitiveModuleSources) {
19+
Set<String> parsedModules = []
1820
def configNode = new DefaultModuleConfiguration()
19-
def transitiveResolver = resolveModules(MissingTypeResolver.INSTANCE, transitiveModuleSources, configNode.transitiveDependentModules)
20-
def directResolver = resolveModules(transitiveResolver, dependentModuleSources, configNode.directDependentModules)
21-
resolveModules(directResolver, localModuleSources, configNode.localModules)
21+
def transitiveResolver = parseModules(MissingTypeResolver.INSTANCE, transitiveModuleSources, configNode.transitiveDependentModules, parsedModules)
22+
def directResolver = parseModules(transitiveResolver, dependentModuleSources, configNode.directDependentModules, parsedModules)
23+
parseModules(directResolver, localModuleSources, configNode.localModules, parsedModules)
2224
return configNode
2325
}
2426

25-
static TypeResolver resolveModules(TypeResolver parentResolver, Collection<ModuleDefinitionSource> sources, Set<ModuleNode> moduleNodes) {
27+
static TypeResolver parseModules(TypeResolver parentResolver, Collection<ModuleDefinitionSource> sources, Set<ModuleNode> moduleNodes, Set<String> allModuleNames) {
2628
List<ModuleParser> parsers = sources.collect { ModuleParser.create(it) }
2729
def resolver = parsers.inject(parentResolver) {
2830
TypeResolver resolver, parser -> new ModuleTypeResolver(resolver, parser.module)
2931
}
30-
moduleNodes.addAll parsers*.parse(resolver)
32+
parsers.each { parser ->
33+
def module = parser.parse(resolver)
34+
if (allModuleNames.contains(module.name)) {
35+
throw new AstParserException(module.source, ": module loaded multiple times: ${module.name}")
36+
}
37+
allModuleNames.add(module.name)
38+
moduleNodes.add module
39+
}
3140
return resolver
3241
}
3342
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package com.prezi.spaghetti.config
2+
3+
import com.prezi.spaghetti.ast.parser.AstParserException
4+
import com.prezi.spaghetti.definition.ModuleDefinitionSource
5+
import spock.lang.Specification
6+
7+
/**
8+
* Created by lptr on 01/06/14.
9+
*/
10+
class ModuleConfigurationParserTest extends Specification {
11+
def "Loaded multiple times"() {
12+
when:
13+
ModuleConfigurationParser.parse(
14+
[new ModuleDefinitionSource("C:\\test1.module", "module com.example.test")],
15+
[],
16+
[new ModuleDefinitionSource("C:\\test2.module", "module com.example.test")]
17+
)
18+
19+
then:
20+
def ex = thrown AstParserException
21+
ex.message == "Parse error in C:\\test1.module: module loaded multiple times: com.example.test"
22+
}
23+
}

0 commit comments

Comments
 (0)