Skip to content

[5.1][IDE/SourceKit] New SourceKit request for filtered method list #22762

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions include/swift/IDE/ConformingMethodList.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//===--- ConformingMethodList.h --- -----------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2019 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_IDE_CONFORMINGMETHODLIST_H
#define SWIFT_IDE_CONFORMINGMETHODLIST_H

#include "swift/AST/Type.h"
#include "swift/Basic/LLVM.h"

namespace swift {
class CodeCompletionCallbacksFactory;

namespace ide {

/// A result item for context info query.
class ConformingMethodListResult {
public:
/// The decl context of the parsed expression.
DeclContext *DC;

/// The resolved type of the expression.
Type ExprType;

/// Methods which satisfy the criteria.
SmallVector<ValueDecl *, 0> Members;

ConformingMethodListResult(DeclContext *DC, Type ExprType)
: DC(DC), ExprType(ExprType) {}
};

/// An abstract base class for consumers of context info results.
class ConformingMethodListConsumer {
public:
virtual ~ConformingMethodListConsumer() {}
virtual void handleResult(const ConformingMethodListResult &result) = 0;
};

/// Printing consumer
class PrintingConformingMethodListConsumer
: public ConformingMethodListConsumer {
llvm::raw_ostream &OS;

public:
PrintingConformingMethodListConsumer(llvm::raw_ostream &OS) : OS(OS) {}

void handleResult(const ConformingMethodListResult &result) override;
};

/// Create a factory for code completion callbacks.
CodeCompletionCallbacksFactory *makeConformingMethodListCallbacksFactory(
ArrayRef<const char *> expectedTypeNames,
ConformingMethodListConsumer &Consumer);

} // namespace ide
} // namespace swift

#endif // SWIFT_IDE_CONFORMINGMETHODLIST_H
64 changes: 32 additions & 32 deletions include/swift/Parse/CodeCompletionCallbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,114 +117,114 @@ class CodeCompletionCallbacks {

/// Complete the whole expression. This is a fallback that should
/// produce results when more specific completion methods failed.
virtual void completeExpr() = 0;
virtual void completeExpr() {};

/// Complete expr-dot after we have consumed the dot.
virtual void completeDotExpr(Expr *E, SourceLoc DotLoc) = 0;
virtual void completeDotExpr(Expr *E, SourceLoc DotLoc) {};

/// Complete the beginning of a statement or expression.
virtual void completeStmtOrExpr() = 0;
virtual void completeStmtOrExpr() {};

/// Complete the beginning of expr-postfix -- no tokens provided
/// by user.
virtual void completePostfixExprBeginning(CodeCompletionExpr *E) = 0;
virtual void completePostfixExprBeginning(CodeCompletionExpr *E) {};

/// Complete the beginning of expr-postfix in a for-each loop sequqence
/// -- no tokens provided by user.
virtual void completeForEachSequenceBeginning(CodeCompletionExpr *E) = 0;
virtual void completeForEachSequenceBeginning(CodeCompletionExpr *E) {};

/// Complete a given expr-postfix.
virtual void completePostfixExpr(Expr *E, bool hasSpace) = 0;
virtual void completePostfixExpr(Expr *E, bool hasSpace) {};

/// Complete a given expr-postfix, given that there is a following
/// left parenthesis.
virtual void completePostfixExprParen(Expr *E, Expr *CodeCompletionE) = 0;
virtual void completePostfixExprParen(Expr *E, Expr *CodeCompletionE) {};

/// Complete expr-super after we have consumed the 'super' keyword.
virtual void completeExprSuper(SuperRefExpr *SRE) = 0;
virtual void completeExprSuper(SuperRefExpr *SRE) {};

/// Complete expr-super after we have consumed the 'super' keyword and
/// a dot.
virtual void completeExprSuperDot(SuperRefExpr *SRE) = 0;
virtual void completeExprSuperDot(SuperRefExpr *SRE) {};

/// Complete the argument to an Objective-C #keyPath
/// expression.
///
/// \param KPE A partial #keyPath expression that can be used to
/// provide context. This will be \c NULL if no components of the
/// #keyPath argument have been parsed yet.
virtual void completeExprKeyPath(KeyPathExpr *KPE, SourceLoc DotLoc) = 0;
virtual void completeExprKeyPath(KeyPathExpr *KPE, SourceLoc DotLoc) {};

/// Complete the beginning of type-simple -- no tokens provided
/// by user.
virtual void completeTypeSimpleBeginning() = 0;
virtual void completeTypeSimpleBeginning() {};

/// Complete a given type-identifier after we have consumed the dot.
virtual void completeTypeIdentifierWithDot(IdentTypeRepr *ITR) = 0;
virtual void completeTypeIdentifierWithDot(IdentTypeRepr *ITR) {};

/// Complete a given type-identifier when there is no trailing dot.
virtual void completeTypeIdentifierWithoutDot(IdentTypeRepr *ITR) = 0;
virtual void completeTypeIdentifierWithoutDot(IdentTypeRepr *ITR) {};

/// Complete at the beginning of a case stmt pattern.
virtual void completeCaseStmtBeginning() = 0;
virtual void completeCaseStmtBeginning() {};

/// Complete a case stmt pattern that starts with a dot.
virtual void completeCaseStmtDotPrefix() = 0;
virtual void completeCaseStmtDotPrefix() {};

/// Complete at the beginning of member of a nominal decl member -- no tokens
/// provided by user.
virtual void completeNominalMemberBeginning(
SmallVectorImpl<StringRef> &Keywords) = 0;
SmallVectorImpl<StringRef> &Keywords) {};

/// Complete at the beginning of accessor in a accessor block.
virtual void completeAccessorBeginning() = 0;
virtual void completeAccessorBeginning() {};

/// Complete the keyword in attribute, for instance, @available.
virtual void completeDeclAttrKeyword(Decl *D, bool Sil, bool Param) = 0;
virtual void completeDeclAttrKeyword(Decl *D, bool Sil, bool Param) {};

/// Complete the parameters in attribute, for instance, version specifier for
/// @available.
virtual void completeDeclAttrParam(DeclAttrKind DK, int Index) = 0;
virtual void completeDeclAttrParam(DeclAttrKind DK, int Index) {};

/// Complete within a precedence group decl or after a colon in an
/// operator decl.
virtual void completeInPrecedenceGroup(SyntaxKind SK) = 0;
virtual void completeInPrecedenceGroup(SyntaxKind SK) {};

/// Complete the platform names inside #available statements.
virtual void completePoundAvailablePlatform() = 0;
virtual void completePoundAvailablePlatform() {};

/// Complete the import decl with importable modules.
virtual void
completeImportDecl(std::vector<std::pair<Identifier, SourceLoc>> &Path) = 0;
completeImportDecl(std::vector<std::pair<Identifier, SourceLoc>> &Path) {};

/// Complete unresolved members after dot.
virtual void completeUnresolvedMember(CodeCompletionExpr *E,
SourceLoc DotLoc) = 0;
SourceLoc DotLoc) {};

virtual void completeAssignmentRHS(AssignExpr *E) = 0;
virtual void completeAssignmentRHS(AssignExpr *E) {};

virtual void completeCallArg(CodeCompletionExpr *E) = 0;
virtual void completeCallArg(CodeCompletionExpr *E) {};

virtual void completeReturnStmt(CodeCompletionExpr *E) = 0;
virtual void completeReturnStmt(CodeCompletionExpr *E) {};

/// Complete a yield statement. A missing yield index means that the
/// completion immediately follows the 'yield' keyword; it may be either
/// an expresion or a parenthesized expression list. A present yield
/// index means that the completion is within the parentheses and is
/// for a specific yield value.
virtual void completeYieldStmt(CodeCompletionExpr *E,
Optional<unsigned> yieldIndex) = 0;
Optional<unsigned> yieldIndex) {};

virtual void completeAfterPoundExpr(CodeCompletionExpr *E,
Optional<StmtKind> ParentKind) = 0;
Optional<StmtKind> ParentKind) {};

virtual void completeAfterPoundDirective() = 0;
virtual void completeAfterPoundDirective() {};

virtual void completePlatformCondition() = 0;
virtual void completePlatformCondition() {};

virtual void completeAfterIfStmt(bool hasElse) = 0;
virtual void completeAfterIfStmt(bool hasElse) {};

virtual void completeGenericParams(TypeLoc TL) = 0;
virtual void completeGenericParams(TypeLoc TL) {};

/// Signals that the AST for the all the delayed-parsed code was
/// constructed. No \c complete*() callbacks will be done after this.
Expand Down
1 change: 1 addition & 0 deletions lib/IDE/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ add_swift_host_library(swiftIDE STATIC
CodeCompletion.cpp
CodeCompletionCache.cpp
CommentConversion.cpp
ConformingMethodList.cpp
ExprContextAnalysis.cpp
Formatting.cpp
Refactoring.cpp
Expand Down
42 changes: 0 additions & 42 deletions lib/IDE/CodeCompletion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -374,48 +374,6 @@ static Stmt *findNearestStmt(const DeclContext *DC, SourceLoc Loc,
const_cast<DeclContext *>(DC)->walkContext(Finder);
return Finder.getFoundStmt();
}
/// Prepare the given expression for type-checking again, prinicipally by
/// erasing any ErrorType types on the given expression, allowing later
/// type-checking to make progress.
///
/// FIXME: this is fundamentally a workaround for the fact that we may end up
/// typechecking parts of an expression more than once - first for checking
/// the context, and later for checking more-specific things like unresolved
/// members. We should restructure code-completion type-checking so that we
/// never typecheck more than once (or find a more principled way to do it).
static void prepareForRetypechecking(Expr *E) {
assert(E);
struct Eraser : public ASTWalker {
std::pair<bool, Expr *> walkToExprPre(Expr *expr) override {
if (expr && expr->getType() && (expr->getType()->hasError() ||
expr->getType()->hasUnresolvedType()))
expr->setType(Type());
if (auto *ACE = dyn_cast_or_null<AutoClosureExpr>(expr)) {
return { true, ACE->getSingleExpressionBody() };
}
return { true, expr };
}
bool walkToTypeLocPre(TypeLoc &TL) override {
if (TL.getType() && (TL.getType()->hasError() ||
TL.getType()->hasUnresolvedType()))
TL.setType(Type());
return true;
}

std::pair<bool, Pattern*> walkToPatternPre(Pattern *P) override {
if (P && P->hasType() && (P->getType()->hasError() ||
P->getType()->hasUnresolvedType())) {
P->setType(Type());
}
return { true, P };
}
std::pair<bool, Stmt *> walkToStmtPre(Stmt *S) override {
return { false, S };
}
};

E->walk(Eraser());
}

CodeCompletionString::CodeCompletionString(ArrayRef<Chunk> Chunks) {
std::uninitialized_copy(Chunks.begin(), Chunks.end(),
Expand Down
Loading