mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
* spelling: accessibility Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: accessories Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: adjustments Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: all Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: ambiguous Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: arguments Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: assignment Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: associated Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: assumes Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: auxiliary 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: checking Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: clazz Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: compatibility Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: completely Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: completion Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: complicated Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: conformance Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: constrained Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: constraint Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: contextual Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: conversion Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: convertible Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: couldn't Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: declaration Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: defaultable Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: dependent Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: depending Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: describe Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: diagnostic Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: diagnostics Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: existential Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: expects Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: explicit Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: explicitly Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: expression Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: first Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: font Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: forward Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: generation Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: generic Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: given Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: global Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: guarantee Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: happened Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: hierarchy Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: identical Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: immediately Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: implicit Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: indicates Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: inferred Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: initialization Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: initialize Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: initializer Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: integrity Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: interpolation Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: introducing Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: involved Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: just Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: like Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: likewise Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: mismatch Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: missing Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: more Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: necessarily Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: noescape Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: nonetheless Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: occurrences Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: operators Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: optional Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: otherwise Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: outside Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: overload Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: overridden Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: override Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: parameter Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: parameters Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: penalize Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: platforms Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: precedence Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: preemptively Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: preliminary Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: preserve Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: propagate Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: propagated Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: qualifier Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: question Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: really Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: received Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: references Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: replaceable Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: replacement Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: representable Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: representative Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: requirement Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: requires Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: resolved Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: retrieve Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: rewriting Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: satisfied Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: semantics Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: signature Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: similar Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: simplest Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: simplification Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: solver Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: struct Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: structurally Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: success Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: sure Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: symmetric Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: syntactically Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: target Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: that Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: the Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: themselves Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: these Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: this Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: transform Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: transparent Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: tread Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: truncation Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: type Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: unconstructable Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: universally Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: unknown Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: unwrapped Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: versioned Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: visible Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> * spelling: where Signed-off-by: Josh Soref <jsoref@users.noreply.github.com> Co-authored-by: Josh Soref <jsoref@users.noreply.github.com>
128 lines
4.2 KiB
C++
128 lines
4.2 KiB
C++
//===--- CompletionContextFinder.h ----------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2022 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_SEMA_COMPLETIONCONTEXTFINDER_H
|
|
#define SWIFT_SEMA_COMPLETIONCONTEXTFINDER_H
|
|
|
|
#include "swift/AST/ASTNode.h"
|
|
#include "swift/AST/ASTWalker.h"
|
|
#include "swift/AST/Expr.h"
|
|
#include "swift/IDE/TypeCheckCompletionCallback.h"
|
|
|
|
namespace swift {
|
|
|
|
class CompletionContextFinder : public ASTWalker {
|
|
enum class ContextKind {
|
|
FallbackExpression,
|
|
StringInterpolation,
|
|
SingleStmtClosure,
|
|
MultiStmtClosure,
|
|
ErrorExpression
|
|
};
|
|
|
|
struct Context {
|
|
ContextKind Kind;
|
|
Expr *E;
|
|
};
|
|
|
|
/// Stack of all "interesting" contexts up to code completion expression.
|
|
llvm::SmallVector<Context, 4> Contexts;
|
|
|
|
/// If we are completing inside an expression, the \c CodeCompletionExpr that
|
|
/// represents the code completion token.
|
|
|
|
/// The AST node that represents the code completion token, either as a
|
|
/// \c CodeCompletionExpr or a \c KeyPathExpr which contains a code completion
|
|
/// component.
|
|
llvm::PointerUnion<CodeCompletionExpr *, const KeyPathExpr *> CompletionNode;
|
|
|
|
Expr *InitialExpr = nullptr;
|
|
DeclContext *InitialDC;
|
|
|
|
public:
|
|
/// Finder for completion contexts within the provided initial expression.
|
|
CompletionContextFinder(ASTNode initialNode, DeclContext *DC)
|
|
: InitialExpr(initialNode.dyn_cast<Expr *>()), InitialDC(DC) {
|
|
assert(DC);
|
|
initialNode.walk(*this);
|
|
};
|
|
|
|
/// Finder for completion contexts within the outermost non-closure context of
|
|
/// the code completion expression's direct context.
|
|
CompletionContextFinder(DeclContext *completionDC) : InitialDC(completionDC) {
|
|
while (auto *ACE = dyn_cast<AbstractClosureExpr>(InitialDC))
|
|
InitialDC = ACE->getParent();
|
|
InitialDC->walkContext(*this);
|
|
}
|
|
|
|
std::pair<bool, Expr *> walkToExprPre(Expr *E) override;
|
|
|
|
Expr *walkToExprPost(Expr *E) override;
|
|
|
|
/// Check whether code completion expression is located inside of a
|
|
/// multi-statement closure.
|
|
bool locatedInMultiStmtClosure() const {
|
|
return hasContext(ContextKind::MultiStmtClosure);
|
|
}
|
|
|
|
bool locatedInStringInterpolation() const {
|
|
return hasContext(ContextKind::StringInterpolation);
|
|
}
|
|
|
|
bool hasCompletionExpr() const {
|
|
return CompletionNode.dyn_cast<CodeCompletionExpr *>() != nullptr;
|
|
}
|
|
|
|
CodeCompletionExpr *getCompletionExpr() const {
|
|
assert(hasCompletionExpr());
|
|
return CompletionNode.get<CodeCompletionExpr *>();
|
|
}
|
|
|
|
bool hasCompletionKeyPathComponent() const {
|
|
return CompletionNode.dyn_cast<const KeyPathExpr *>() != nullptr;
|
|
}
|
|
|
|
/// If we are completing in a key path, returns the \c KeyPath that contains
|
|
/// the code completion component.
|
|
const KeyPathExpr *getKeyPathContainingCompletionComponent() const {
|
|
assert(hasCompletionKeyPathComponent());
|
|
return CompletionNode.get<const KeyPathExpr *>();
|
|
}
|
|
|
|
/// If we are completing in a key path, returns the index at which the key
|
|
/// path has the code completion component.
|
|
size_t getKeyPathCompletionComponentIndex() const;
|
|
|
|
struct Fallback {
|
|
Expr *E; ///< The fallback expression.
|
|
DeclContext *DC; ///< The fallback expression's decl context.
|
|
bool SeparatePrecheck; ///< True if the fallback may require prechecking.
|
|
};
|
|
|
|
/// As a fallback sometimes its useful to not only type-check
|
|
/// code completion expression directly but instead add some
|
|
/// of the enclosing context e.g. when completion is an argument
|
|
/// to a call.
|
|
Optional<Fallback> getFallbackCompletionExpr() const;
|
|
|
|
private:
|
|
bool hasContext(ContextKind kind) const {
|
|
return llvm::find_if(Contexts, [&kind](const Context &currContext) {
|
|
return currContext.Kind == kind;
|
|
}) != Contexts.end();
|
|
}
|
|
};
|
|
|
|
} // end namespace swift
|
|
|
|
#endif // SWIFT_SEMA_COMPLETIONCONTEXTFINDER_H
|