Files
swift-mirror/lib/AST/SearchPathOptions.cpp
Josh Soref 81d3ad76ac Spelling ast (#42463)
* spelling: accessor

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: accommodates

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: argument

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: associated

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: availability

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: available

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: belongs

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: bookkeeping

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: building

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: clazz

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: clonable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: closure

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: concatenated

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: conformance

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: context

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: conversion

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: correspondence

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: declarations

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: declared

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: defining

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: delayed

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: dependency

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: deployed

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: descendants

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: diagnose

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: diagnostic

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: equitable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: evaluation

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: exclusivity

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: existence

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: existential

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: explicit

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: expressed

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: for

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: foreign

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: function

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: identifier

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: implicit

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: indices

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: information

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: instance

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: interchangeable

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: interface

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: introduced

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: invalid

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: kind-in

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: least

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: library

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: location

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: namespace

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: necessary

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: nonexistent

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: not

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: number

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: obtains

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: occurs

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: opaque

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: overridden

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: parameter

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: precede

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: preceding

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: property

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: protocol

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: qualified

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: recognized

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: recursively

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: references

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: relaxing

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: represented

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: request

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: requirement

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: requirements

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: retrieve

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: returned

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: satisfied

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: satisfy

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: scanner

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: siblings

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: simplified

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: something

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: source

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: specializations

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: specially

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: statement

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: stripped

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: structure

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: substitution

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: the

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transform

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transformed

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transitively

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: transparent

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: typecheck

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: unknown

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: unlabeled

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: unqualified

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: whether

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: with

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

* spelling: scanner

Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>

Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
2022-04-21 12:57:16 -07:00

162 lines
6.5 KiB
C++

//===----------------------- SearchPathOptions.cpp ------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2021 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/SearchPathOptions.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/Support/Errc.h"
using namespace swift;
void ModuleSearchPathLookup::addFilesInPathToLookupTable(
llvm::vfs::FileSystem *FS, StringRef SearchPath, ModuleSearchPathKind Kind,
bool IsSystem, unsigned SearchPathIndex) {
std::error_code Error;
auto entryAlreadyExists = [this](ModuleSearchPathKind Kind,
unsigned SearchPathIndex) -> bool {
return llvm::any_of(LookupTable, [&](const auto &LookupTableEntry) {
return llvm::any_of(
LookupTableEntry.second, [&](ModuleSearchPathPtr ExistingSearchPath) {
return ExistingSearchPath->getKind() == Kind &&
ExistingSearchPath->getIndex() == SearchPathIndex;
});
});
};
assert(!entryAlreadyExists(Kind, SearchPathIndex) &&
"Search path with this kind and index already exists");
ModuleSearchPathPtr TableEntry =
new ModuleSearchPath(SearchPath, Kind, IsSystem, SearchPathIndex);
for (auto Dir = FS->dir_begin(SearchPath, Error);
!Error && Dir != llvm::vfs::directory_iterator(); Dir.increment(Error)) {
StringRef Filename = llvm::sys::path::filename(Dir->path());
LookupTable[Filename].push_back(TableEntry);
}
}
void ModuleSearchPathLookup::rebuildLookupTable(const SearchPathOptions *Opts,
llvm::vfs::FileSystem *FS,
bool IsOSDarwin) {
clearLookupTable();
for (auto Entry : llvm::enumerate(Opts->getImportSearchPaths())) {
addFilesInPathToLookupTable(FS, Entry.value(),
ModuleSearchPathKind::Import,
/*isSystem=*/false, Entry.index());
}
for (auto Entry : llvm::enumerate(Opts->getFrameworkSearchPaths())) {
addFilesInPathToLookupTable(FS, Entry.value().Path, ModuleSearchPathKind::Framework,
Entry.value().IsSystem, Entry.index());
}
// Apple platforms have extra implicit framework search paths:
// $SDKROOT/System/Library/Frameworks/ and $SDKROOT/Library/Frameworks/.
if (IsOSDarwin) {
for (auto Entry : llvm::enumerate(Opts->getDarwinImplicitFrameworkSearchPaths())) {
addFilesInPathToLookupTable(FS, Entry.value(),
ModuleSearchPathKind::DarwinImplicitFramework,
/*isSystem=*/true, Entry.index());
}
}
for (auto Entry : llvm::enumerate(Opts->getRuntimeLibraryImportPaths())) {
addFilesInPathToLookupTable(FS, Entry.value(),
ModuleSearchPathKind::RuntimeLibrary,
/*isSystem=*/true, Entry.index());
}
State.FileSystem = FS;
State.IsOSDarwin = IsOSDarwin;
State.Opts = Opts;
State.IsPopulated = true;
}
SmallVector<const ModuleSearchPath *, 4>
ModuleSearchPathLookup::searchPathsContainingFile(
const SearchPathOptions *Opts, llvm::ArrayRef<std::string> Filenames,
llvm::vfs::FileSystem *FS, bool IsOSDarwin) {
if (!State.IsPopulated || State.FileSystem != FS ||
State.IsOSDarwin != IsOSDarwin || State.Opts != Opts) {
rebuildLookupTable(Opts, FS, IsOSDarwin);
}
// Gather all search paths that include a file whose name is in Filenames.
// To make sure that we don't include the same search paths twice, keep track
// of which search paths have already been added to Result by their kind and
// Index in ResultIds.
// Note that if a search path is specified twice by including it twice in
// compiler arguments or by specifying it as different kinds (e.g. once as
// import and once as framework search path), these search paths are
// considered different (because they have different indices/kinds and may
// thus still be included twice.
llvm::SmallVector<const ModuleSearchPath *, 4> Result;
llvm::SmallSet<std::pair<ModuleSearchPathKind, unsigned>, 4> ResultIds;
for (auto &Filename : Filenames) {
for (auto &Entry : LookupTable[Filename]) {
if (ResultIds.insert(std::make_pair(Entry->getKind(), Entry->getIndex()))
.second) {
Result.push_back(Entry.get());
}
}
}
// Make sure we maintain the same search paths order that we had used in
// populateLookupTableIfNecessary after merging results from
// different filenames.
llvm::sort(Result, [](const ModuleSearchPath *Lhs,
const ModuleSearchPath *Rhs) { return *Lhs < *Rhs; });
return Result;
}
/// Loads a VFS YAML file located at \p File using \p BaseFS and adds it to
/// \p OverlayFS. Returns an error if either loading the \p File failed or it
/// is invalid.
static llvm::Error loadAndValidateVFSOverlay(
const std::string &File,
const llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> &BaseFS,
const llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> &OverlayFS) {
auto Buffer = BaseFS->getBufferForFile(File);
if (!Buffer)
return llvm::createFileError(File, Buffer.getError());
auto VFS = llvm::vfs::getVFSFromYAML(std::move(Buffer.get()), nullptr, File);
if (!VFS)
return llvm::createFileError(File, llvm::errc::invalid_argument);
OverlayFS->pushOverlay(std::move(VFS));
return llvm::Error::success();
}
llvm::Expected<llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>>
SearchPathOptions::makeOverlayFileSystem(
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS) const {
// TODO: This implementation is different to how Clang reads overlays in.
// Expose a helper in Clang rather than doing this ourselves.
auto OverlayFS =
llvm::makeIntrusiveRefCnt<llvm::vfs::OverlayFileSystem>(BaseFS);
llvm::Error AllErrors = llvm::Error::success();
bool hasOverlays = false;
for (const auto &File : VFSOverlayFiles) {
hasOverlays = true;
if (auto Err = loadAndValidateVFSOverlay(File, BaseFS, OverlayFS))
AllErrors = llvm::joinErrors(std::move(AllErrors), std::move(Err));
}
if (AllErrors)
return std::move(AllErrors);
if (hasOverlays)
return OverlayFS;
return BaseFS;
}