in src/main/groovy/groovy/util/ConfigSlurper.groovy [186:296]
ConfigObject parse(Script script, URL location) {
Stack<String> currentConditionalBlock = new Stack<String>()
def config = location ? new ConfigObject(location) : new ConfigObject()
GroovySystem.metaClassRegistry.removeMetaClass(script.class)
def mc = script.class.metaClass
def prefix = ''
LinkedList stack = new LinkedList()
stack << [config: config, scope: [:]]
def pushStack = { co ->
stack << [config: co, scope: stack.last.scope.clone()]
}
def assignName = { name, co ->
def current = stack.last
current.config[name] = co
current.scope[name] = co
}
mc.getProperty = { String name ->
def current = stack.last
def result
if (current.config.get(name)) {
result = current.config.get(name)
} else if (current.scope[name]) {
result = current.scope[name]
} else {
try {
result = InvokerHelper.getProperty(this, name)
} catch (GroovyRuntimeException e) {
result = new ConfigObject()
assignName.call(name, result)
}
}
result
}
ConfigObject overrides = new ConfigObject()
mc.invokeMethod = { String name, args ->
def result
if (args.length == 1 && args[0] instanceof Closure) {
if (name in conditionValues.keySet()) {
try {
currentConditionalBlock.push(name)
conditionalBlocks.push([:])
args[0].call()
} finally {
currentConditionalBlock.pop()
for (entry in conditionalBlocks.pop().entrySet()) {
def c = stack.last.config
(c != config? c : overrides).merge(entry.value)
}
}
} else if (currentConditionalBlock.size() > 0) {
String conditionalBlockKey = currentConditionalBlock.peek()
if (name == conditionValues[conditionalBlockKey]) {
def co = new ConfigObject()
conditionalBlocks.peek()[conditionalBlockKey] = co
pushStack.call(co)
try {
currentConditionalBlock.pop()
args[0].call()
} finally {
currentConditionalBlock.push(conditionalBlockKey)
}
stack.removeLast()
}
} else {
def co
if (stack.last.config.get(name) instanceof ConfigObject) {
co = stack.last.config.get(name)
} else {
co = new ConfigObject()
}
assignName.call(name, co)
pushStack.call(co)
args[0].call()
stack.removeLast()
}
} else if (args.length == 2 && args[1] instanceof Closure) {
try {
prefix = name + '.'
assignName.call(name, args[0])
args[1].call()
} finally { prefix = '' }
} else {
MetaMethod mm = mc.getMetaMethod(name, args)
if (mm) {
result = mm.invoke(delegate, args)
} else {
throw new MissingMethodException(name, getClass(), args)
}
}
result
}
script.metaClass = mc
def setProperty = { String name, value ->
assignName.call(prefix + name, value)
}
def binding = new ConfigBinding(setProperty)
if (this.bindingVars) {
binding.variables.putAll(this.bindingVars)
}
script.binding = binding
script.run()
config.merge(overrides)
config
}