mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[ModuleInterface] Add new TextualInterfaceOption flag, move TextualInterfaceGeneration.{h,cpp}
This commit is contained in:
97
lib/Frontend/ParseableInterfaceGeneration.cpp
Normal file
97
lib/Frontend/ParseableInterfaceGeneration.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
//===--- ParseableInterfaceGeneration.cpp - swiftinterface files ----------===//
|
||||
//
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2018 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "swift/AST/ASTContext.h"
|
||||
#include "swift/AST/Decl.h"
|
||||
#include "swift/AST/DiagnosticsFrontend.h"
|
||||
#include "swift/AST/Module.h"
|
||||
#include "swift/Frontend/ParseableInterfaceGeneration.h"
|
||||
#include "clang/Basic/Module.h"
|
||||
|
||||
using namespace swift;
|
||||
|
||||
/// Diagnose any scoped imports in \p imports, i.e. those with a non-empty
|
||||
/// access path. These are not yet supported by parseable interfaces, since the
|
||||
/// information about the declaration kind is not preserved through the binary
|
||||
/// serialization that happens as an intermediate step in non-whole-module
|
||||
/// builds.
|
||||
///
|
||||
/// These come from declarations like `import class FooKit.MainFooController`.
|
||||
static void diagnoseScopedImports(DiagnosticEngine &diags,
|
||||
ArrayRef<ModuleDecl::ImportedModule> imports){
|
||||
for (const ModuleDecl::ImportedModule &importPair : imports) {
|
||||
if (importPair.first.empty())
|
||||
continue;
|
||||
diags.diagnose(importPair.first.front().second,
|
||||
diag::parseable_interface_scoped_import_unsupported);
|
||||
}
|
||||
}
|
||||
|
||||
/// Prints the imported modules in \p M to \p out in the form of \c import
|
||||
/// source declarations.
|
||||
static void printImports(raw_ostream &out, ModuleDecl *M) {
|
||||
// FIXME: This is very similar to what's in Serializer::writeInputBlock, but
|
||||
// it's not obvious what higher-level optimization would be factored out here.
|
||||
SmallVector<ModuleDecl::ImportedModule, 8> allImports;
|
||||
M->getImportedModules(allImports, ModuleDecl::ImportFilter::All);
|
||||
ModuleDecl::removeDuplicateImports(allImports);
|
||||
diagnoseScopedImports(M->getASTContext().Diags, allImports);
|
||||
|
||||
// Collect the public imports as a subset so that we can mark them with
|
||||
// '@_exported'.
|
||||
SmallVector<ModuleDecl::ImportedModule, 8> publicImports;
|
||||
M->getImportedModules(publicImports, ModuleDecl::ImportFilter::Public);
|
||||
llvm::SmallSet<ModuleDecl::ImportedModule, 8,
|
||||
ModuleDecl::OrderImportedModules> publicImportSet;
|
||||
publicImportSet.insert(publicImports.begin(), publicImports.end());
|
||||
|
||||
for (auto import : allImports) {
|
||||
if (import.second->isStdlibModule() ||
|
||||
import.second->isOnoneSupportModule() ||
|
||||
import.second->isBuiltinModule()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (publicImportSet.count(import))
|
||||
out << "@_exported ";
|
||||
out << "import ";
|
||||
import.second->getReverseFullModuleName().printForward(out);
|
||||
|
||||
// Write the access path we should be honoring but aren't.
|
||||
// (See diagnoseScopedImports above.)
|
||||
if (!import.first.empty()) {
|
||||
out << "/*";
|
||||
for (const auto &accessPathElem : import.first)
|
||||
out << "." << accessPathElem.first;
|
||||
out << "*/";
|
||||
}
|
||||
|
||||
out << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
bool swift::emitParseableInterface(raw_ostream &out, ModuleDecl *M) {
|
||||
assert(M);
|
||||
|
||||
printImports(out, M);
|
||||
|
||||
const PrintOptions printOptions = PrintOptions::printParseableInterfaceFile();
|
||||
SmallVector<Decl *, 16> topLevelDecls;
|
||||
M->getTopLevelDecls(topLevelDecls);
|
||||
for (const Decl *D : topLevelDecls) {
|
||||
if (!D->shouldPrintInContext(printOptions))
|
||||
continue;
|
||||
D->print(out, printOptions);
|
||||
out << "\n";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
Reference in New Issue
Block a user