| // Copyright 2020 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "gn/swift_values.h" |
| |
| #include <algorithm> |
| |
| #include "gn/deps_iterator.h" |
| #include "gn/err.h" |
| #include "gn/settings.h" |
| #include "gn/substitution_writer.h" |
| #include "gn/target.h" |
| #include "gn/tool.h" |
| |
| SwiftValues::SwiftValues() = default; |
| |
| SwiftValues::~SwiftValues() = default; |
| |
| // static |
| bool SwiftValues::OnTargetResolved(Target* target, Err* err) { |
| if (!target->builds_swift_module()) |
| return true; |
| |
| return target->swift_values().FillModuleOutputFile(target, err); |
| } |
| |
| const Tool* SwiftValues::GetTool(const Target* target) const { |
| DCHECK(target->builds_swift_module()); |
| return target->toolchain()->GetToolForSourceType(SourceFile::SOURCE_SWIFT); |
| } |
| |
| void SwiftValues::GetOutputs(const Target* target, |
| std::vector<OutputFile>* result) const { |
| const Tool* tool = GetTool(target); |
| |
| // Expand tool's outputs(). |
| SubstitutionWriter::ApplyListToLinkerAsOutputFile(target, tool, |
| tool->outputs(), result); |
| |
| // Expand tool's partial_outputs() for each .swift source file. |
| for (const SourceFile& source : target->sources()) { |
| if (!source.IsSwiftType()) { |
| continue; |
| } |
| |
| SubstitutionWriter::ApplyListToCompilerAsOutputFile( |
| target, source, tool->partial_outputs(), result); |
| } |
| } |
| |
| void SwiftValues::GetOutputsAsSourceFiles( |
| const Target* target, |
| std::vector<SourceFile>* result) const { |
| std::vector<OutputFile> outputs; |
| GetOutputs(target, &outputs); |
| |
| result->reserve(outputs.size()); |
| |
| const BuildSettings* build_settings = target->settings()->build_settings(); |
| for (const OutputFile& output : outputs) { |
| result->push_back(output.AsSourceFile(build_settings)); |
| } |
| } |
| |
| bool SwiftValues::FillModuleOutputFile(Target* target, Err* err) { |
| std::vector<OutputFile> outputs; |
| GetOutputs(target, &outputs); |
| |
| // Keep only .swiftmodule output files. |
| const BuildSettings* build_settings = target->settings()->build_settings(); |
| const auto iter = std::remove_if( |
| outputs.begin(), outputs.end(), |
| [build_settings](const OutputFile& output) -> bool { |
| SourceFile output_as_source_file = output.AsSourceFile(build_settings); |
| return !output_as_source_file.IsSwiftModuleType(); |
| }); |
| outputs.erase(iter, outputs.end()); |
| |
| // A target should generate exactly one .swiftmodule file. |
| if (outputs.size() != 1) { |
| const Tool* tool = GetTool(target); |
| *err = Err(tool->defined_from(), "Incorrect outputs for tool", |
| "The outputs of tool " + std::string(tool->name()) + |
| " must list exactly one .swiftmodule file"); |
| return false; |
| } |
| |
| module_output_file_ = outputs.front(); |
| module_output_dir_ = |
| module_output_file_.AsSourceFile(build_settings).GetDir(); |
| |
| return true; |
| } |