Skip to content

[CodeCompletion] Migrate postfix expr completion to solver-based #42280

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

Closed
11 changes: 9 additions & 2 deletions include/swift/IDE/CompletionLookup.h
Original file line number Diff line number Diff line change
Expand Up @@ -503,7 +503,14 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {

void getPostfixKeywordCompletions(Type ExprType, Expr *ParsedExpr);

void getValueExprCompletions(Type ExprType, ValueDecl *VD = nullptr);
/// Add code completion results after an expression of type \p ExprType.
/// This includes members as well as call patterns if \p ExprType is a
/// function type.
/// If \p IsDeclUnapplied is \c true, we are completing after a refernce to
/// \p VD that hasn't been called yet. Thus, \p VD has type \p ExprType and we
/// can use \p VD to enrich call pattern completions of \p ExprType.
void getValueExprCompletions(Type ExprType, ValueDecl *VD = nullptr,
bool IsDeclUnapplied = false);

void collectOperators(SmallVectorImpl<OperatorDecl *> &results);

Expand All @@ -513,7 +520,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {

void tryPostfixOperator(Expr *expr, PostfixOperatorDecl *op);

void addAssignmentOperator(Type RHSType, Type resultType);
void addAssignmentOperator(Type RHSType);

void addInfixOperatorCompletion(OperatorDecl *op, Type resultType,
Type RHSType);
Expand Down
65 changes: 0 additions & 65 deletions include/swift/IDE/DotExprCompletion.h

This file was deleted.

110 changes: 110 additions & 0 deletions include/swift/IDE/PostfixCompletion.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
//===--- DotExprCodeCompletion.h ------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 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_IDE_POSTFIXCOMPLETION_H
#define SWIFT_IDE_POSTFIXCOMPLETION_H

#include "swift/IDE/CodeCompletionConsumer.h"
#include "swift/IDE/CodeCompletionContext.h"
#include "swift/IDE/TypeCheckCompletionCallback.h"

namespace swift {
namespace ide {

/// Used to collect and store information needed to perform postfix completion
/// (either <base>.#^COMPLETE^# or <base>#^COMPLETE^#).
class PostfixCompletionCallback : public TypeCheckCompletionCallback {
struct Result {
/// The type that we are completing on. Will never be null.
Type BaseTy;

/// The we were able to determine it, the decl that we are completing on.
/// Is \c nullptr if we are completing on an expression.
ValueDecl *BaseDecl;

/// Whether \c BaseDecl refers to a function that has not been called yet.
/// In such cases, we know that \p BaseTy is the type of \p BaseDecl and we
/// can use \p BaseDecl for more detailed call pattern completions.
bool IsBaseDeclUnapplied;

/// If the expression we are completing on statically refers to a metatype,
/// that is if it's something like 'MyType'. In such cases we want to offer
/// constructor call pattern completions and don't want to suggested
/// operators that work on metatypes.
bool BaseIsStaticMetaType;

/// The types that the completion is expected to produce.
SmallVector<Type, 4> ExpectedTypes;

/// Whether results that produce 'Void' should be disfavored. This happens
/// if the context is requiring a value. Once a completion produces 'Void',
/// we know that we can't retrieve a value from it anymore.
bool ExpectsNonVoid;

/// If the code completion expression occurrs as a single statement in a
/// single-expression closure. In such cases we don't want to disfavor
/// results that produce 'Void' because the user might intend to make the
/// closure a multi-statment closure, in which case this expression is no
/// longer implicitly returned.
bool IsImplicitSingleExpressionReturn;

/// Whether the surrounding context is async and thus calling async
/// functions is supported.
bool IsInAsyncContext;

/// Checks whether this result has the same \c BaseTy and \c BaseDecl as
/// \p Other and if the two can thus be merged to be one value lookup in
/// \c deliverResults.
bool canBeMergedWith(const Result &Other) const;

/// Merge this result with \p Other. Assumes that they can be merged.
void merge(const Result &Other);
};

CodeCompletionExpr *CompletionExpr;
DeclContext *DC;

SmallVector<Result, 4> Results;

/// Add a result to \c Results, merging it with an existing result, if
/// possible.
void addResult(const Result &Res);

void sawSolutionImpl(const constraints::Solution &solution) override;

public:
PostfixCompletionCallback(CodeCompletionExpr *CompletionExpr, DeclContext *DC)
: CompletionExpr(CompletionExpr), DC(DC) {}

/// Typecheck the code completion expression in isolation, calling
/// \c sawSolution for each solution formed.
void fallbackTypeCheck(DeclContext *DC) override;

/// Deliver code completion results that were discoverd by \c sawSolution to
/// \p Consumer.
/// \param DotLoc If we are completing after a dot, the location of the dot,
/// otherwise an invalid SourceLoc.
/// \param IsInSelector Whether we are completing in an Objective-C selector.
/// \param IncludeOperators If operators should be suggested. Assumes that
/// \p DotLoc is invalid
/// \param HasLeadingSpace Whether there is a space separating the exiting
/// expression and the code completion token.
void deliverResults(SourceLoc DotLoc, bool IsInSelector,
bool IncludeOperators, bool HasLeadingSpace,
CodeCompletionContext &CompletionCtx,
CodeCompletionConsumer &Consumer);
};

} // end namespace ide
} // end namespace swift

#endif // SWIFT_IDE_POSTFIXCOMPLETION_H
5 changes: 3 additions & 2 deletions include/swift/Parse/CodeCompletionCallbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,9 @@ class CodeCompletionCallbacks {
/// -- no tokens provided by user.
virtual void completeForEachSequenceBeginning(CodeCompletionExpr *E) {};

/// Complete a given expr-postfix.
virtual void completePostfixExpr(Expr *E, bool hasSpace) {};
/// Complete a expr-postfix. The \c CodeCompletionExpr has the expression it
/// is completing after set as its base.
virtual void completePostfixExpr(CodeCompletionExpr *E, bool hasSpace){};

/// Complete a given expr-postfix, given that there is a following
/// left parenthesis.
Expand Down
6 changes: 6 additions & 0 deletions include/swift/Sema/IDETypeChecking.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#ifndef SWIFT_SEMA_IDETYPECHECKING_H
#define SWIFT_SEMA_IDETYPECHECKING_H

#include "swift/AST/Expr.h"
#include "swift/AST/ASTNode.h"
#include "swift/AST/Identifier.h"
#include "swift/AST/TypeCheckRequests.h"
Expand Down Expand Up @@ -164,6 +165,11 @@ namespace swift {
constraints::SolutionApplicationTarget &target, bool needsPrecheck,
llvm::function_ref<void(const constraints::Solution &)> callback);

/// Thunk around \c TypeChecker::resolveDeclRefExpr to make it
/// available to \c swift::ide.
Expr *resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE, DeclContext *Context,
bool replaceInvalidRefsWithErrors);

LookupResult
lookupSemanticMember(DeclContext *DC, Type ty, DeclName name);

Expand Down
20 changes: 10 additions & 10 deletions lib/IDE/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@

add_swift_host_library(swiftIDE STATIC
AfterPoundExprCompletion.cpp
APIDigesterData.cpp
ArgumentCompletion.cpp
CodeCompletion.cpp
CodeCompletionCache.cpp
CodeCompletionContext.cpp
CodeCompletionConsumer.cpp
CodeCompletionContext.cpp
CodeCompletionDiagnostics.cpp
CodeCompletionResult.cpp
CodeCompletionResultBuilder.cpp
CodeCompletionResultPrinter.cpp
CodeCompletionResult.cpp
CodeCompletionResultType.cpp
CodeCompletionString.cpp
CodeCompletionStringPrinter.cpp
Expand All @@ -20,26 +21,25 @@ add_swift_host_library(swiftIDE STATIC
CompletionOverrideLookup.cpp
ConformingMethodList.cpp
DependencyChecking.cpp
DotExprCompletion.cpp
ExprCompletion.cpp
ExprContextAnalysis.cpp
Formatting.cpp
FuzzyStringMatcher.cpp
Refactoring.cpp
IDERequests.cpp
IDETypeChecking.cpp
ImportDepth.cpp
KeyPathCompletion.cpp
ModuleInterfacePrinting.cpp
PostfixCompletion.cpp
Refactoring.cpp
REPLCodeCompletion.cpp
SourceEntityWalker.cpp
SwiftSourceDocInfo.cpp
SyntaxModel.cpp
TypeCheckCompletionCallback.cpp
TypeContextInfo.cpp
UnresolvedMemberCompletion.cpp
Utils.cpp
IDETypeChecking.cpp
ImportDepth.cpp
APIDigesterData.cpp
SourceEntityWalker.cpp
TypeContextInfo.cpp
IDERequests.cpp
)
target_link_libraries(swiftIDE PRIVATE
swiftAST
Expand Down
Loading