in Sources/LLBNinja/NinjaBuild.swift [94:166]
func lookupFunction(forKey rawKey: LLBKey, _ ctx: Context) -> LLBFuture<LLBFunction> {
guard let key = rawKey as? String else {
return ctx.group.next().makeFailedFuture(
NinjaEngineDelegateError.unexpectedKeyType(String(describing: type(of: rawKey)))
)
}
guard let code = key.first else {
return ctx.group.next().makeFailedFuture(NinjaEngineDelegateError.invalidKey(key))
}
switch code {
// A top-level target build request (expected to always be a valid target).
case "T":
// Must be a target.
let target = String(key.dropFirst(1))
guard let i = self.commandMap[target] else {
return ctx.group.next().makeFailedFuture(NinjaEngineDelegateError.commandNotFound(target))
}
return ctx.group.next().makeSucceededFuture(
LLBSimpleFunction { (fi, key, ctx) in
return fi.request("C" + String(i), ctx)
}
)
// A build node.
case "N":
// If this is a command output, build the command (note that there
// must be a level of indirection here, because the same command may
// produce multiple outputs).
let path = String(key.dropFirst(1))
if let i = self.commandMap[path] {
return ctx.group.next().makeSucceededFuture(
LLBSimpleFunction { (fi, key, ctx) in
return fi.request("C" + String(i), ctx)
}
)
}
// Otherwise, it is an input file.
return ctx.group.next().makeSucceededFuture(
LLBSimpleFunction { (fi, key, ctx) in
return self.delegate.build(group: ctx.group, path: path).map { $0 as LLBValue }
}
)
// A build command.
case "C":
let commandIndexStr = String(key.dropFirst(1))
guard let i = Int(commandIndexStr) else {
return ctx.group.next().makeFailedFuture(NinjaEngineDelegateError.unexpectedCommandKey(key))
}
return ctx.group.next().makeSucceededFuture(
LLBSimpleFunction { (fi, key, ctx) in
// Get the command.
let command = self.manifest.statements[i]
// FIXME: For now, we just merge all the inputs. This isn't
// really in keeping with the Ninja semantics, but is strong.
var inputs = command.explicitInputs.map{ fi.request("N" + $0, ctx).asNinjaValue() }
inputs += command.implicitInputs.map{ fi.request("N" + $0, ctx).asNinjaValue() }
inputs += command.orderOnlyInputs.map{ fi.request("N" + $0, ctx).asNinjaValue() }
return LLBFuture.whenAllSucceed(inputs, on: ctx.group.next()).flatMap { inputs in
return self.delegate.build(group: ctx.group.next(), command: command, inputs: inputs).map { $0 as LLBValue }
}
}
)
default:
return ctx.group.next().makeFailedFuture(NinjaEngineDelegateError.unexpectedKey(key))
}
}