Skip to content

Commit

Permalink
[IDE/CodeComplete] Add CallParameterClosureType chunk, which resolves
Browse files Browse the repository at this point in the history
optional & alias types for closure type parameters.

This allows code completion placeholder expansion to properly expand
closure parameters utilizing a typealias, e.g. dispatch_block_t.

Update and add test for the above.

Work for <rdar://problem/15860693>.

Swift SVN r20206
  • Loading branch information
sonnyfalk committed Jul 19, 2014
1 parent 993b822 commit efa1ff8
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 2 deletions.
4 changes: 4 additions & 0 deletions include/swift/IDE/CodeCompletion.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ class CodeCompletionString {
CallParameterColon,
/// Required parameter type.
CallParameterType,
/// Desugared closure parameter type. This can be used to get the
/// closure type if CallParameterType is a NameAliasType.
CallParameterClosureType,

/// A placeholder for \c ! or \c ? in a call to a method found by dynamic
/// lookup.
Expand Down Expand Up @@ -159,6 +162,7 @@ class CodeCompletionString {
Kind == ChunkKind::CallParameterInternalName ||
Kind == ChunkKind::CallParameterColon ||
Kind == ChunkKind::CallParameterType ||
Kind == ChunkKind::CallParameterClosureType ||
Kind == ChunkKind::GenericParameterName ||
Kind == ChunkKind::DynamicLookupMethodCallTail ||
Kind == ChunkKind::OptionalMethodCallTail ||
Expand Down
4 changes: 4 additions & 0 deletions lib/IDE/CodeCompletion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,14 @@ void CodeCompletionString::print(raw_ostream &OS) const {
case Chunk::ChunkKind::CallParameterInternalName:
case Chunk::ChunkKind::CallParameterColon:
case Chunk::ChunkKind::CallParameterType:
case Chunk::ChunkKind::CallParameterClosureType:
case CodeCompletionString::Chunk::ChunkKind::GenericParameterName:
if (AnnotatedTextChunk)
OS << "['";
else if (C.getKind() == Chunk::ChunkKind::CallParameterInternalName)
OS << "(";
else if (C.getKind() == Chunk::ChunkKind::CallParameterClosureType)
OS << "##";
for (char Ch : C.getText()) {
if (Ch == '\n')
OS << "\\n";
Expand Down Expand Up @@ -648,6 +651,7 @@ Optional<unsigned> CodeCompletionString::getFirstTextChunkIndex() const {
case CodeCompletionString::Chunk::ChunkKind::CallParameterInternalName:
case CodeCompletionString::Chunk::ChunkKind::CallParameterColon:
case CodeCompletionString::Chunk::ChunkKind::CallParameterType:
case CodeCompletionString::Chunk::ChunkKind::CallParameterClosureType:
case CodeCompletionString::Chunk::ChunkKind::OptionalBegin:
case CodeCompletionString::Chunk::ChunkKind::CallParameterBegin:
case CodeCompletionString::Chunk::ChunkKind::GenericParameterBegin:
Expand Down
18 changes: 18 additions & 0 deletions lib/IDE/CodeCompletionResultBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,24 @@ class CodeCompletionResultBuilder {

addChunkWithText(CodeCompletionString::Chunk::ChunkKind::CallParameterType,
Ty->getString());

// Resolve optional and alias to find out if we have function/closure
// parameter type.
auto *ParamType = Ty.getPointer();
if (auto OTy = ParamType->getOptionalObjectType())
ParamType = OTy.getPointer();
if (auto *NATy = dyn_cast<NameAliasType>(ParamType))
ParamType = NATy->getSinglyDesugaredType();

if (ParamType && isa<AnyFunctionType>(ParamType)) {
// If this is a closure type, add ChunkKind::CallParameterClosureType.
PrintOptions PO;
PO.PrintFunctionRepresentationAttrs = false;
addChunkWithText(
CodeCompletionString::Chunk::ChunkKind::CallParameterClosureType,
ParamType->getString(PO));
}

if (IsVarArg)
addEllipsis();
CurrentNestingLevel--;
Expand Down
1 change: 1 addition & 0 deletions lib/IDE/REPLCodeCompletion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ static std::string toInsertableString(CodeCompletionResult *Result) {
case CodeCompletionString::Chunk::ChunkKind::CallParameterInternalName:
case CodeCompletionString::Chunk::ChunkKind::CallParameterColon:
case CodeCompletionString::Chunk::ChunkKind::CallParameterType:
case CodeCompletionString::Chunk::ChunkKind::CallParameterClosureType:
case CodeCompletionString::Chunk::ChunkKind::OptionalBegin:
case CodeCompletionString::Chunk::ChunkKind::CallParameterBegin:
case CodeCompletionString::Chunk::ChunkKind::GenericParameterBegin:
Expand Down
4 changes: 2 additions & 2 deletions test/IDE/complete_from_clang_framework.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ func testSwiftCompletions(foo: SwiftStruct) {
// CLANG_FOO-DAG: Decl[FreeFunction]/OtherModule: fooFunc1({#(a): Int32#})[#Int32#]{{$}}
// CLANG_FOO-DAG: Decl[FreeFunction]/OtherModule: fooFunc1AnonymousParam({#Int32#})[#Int32#]{{$}}
// CLANG_FOO-DAG: Decl[FreeFunction]/OtherModule: fooFunc3({#(a): Int32#}, {#(b): Float#}, {#(c): Double#}, {#(d): UnsafePointer<Int32>#})[#Int32#]{{$}}
// CLANG_FOO-DAG: Decl[FreeFunction]/OtherModule: fooFuncWithBlock({#(blk): ((Float) -> Int32)?#})[#Void#]{{$}}
// CLANG_FOO-DAG: Decl[FreeFunction]/OtherModule: fooFuncWithBlock({#(blk): ((Float) -> Int32)?##(Float) -> Int32#})[#Void#]{{$}}
// CLANG_FOO-DAG: Decl[FreeFunction]/OtherModule: fooFuncWithComment1()[#Void#]{{$}}
// CLANG_FOO-DAG: Decl[FreeFunction]/OtherModule: fooFuncWithComment2()[#Void#]{{$}}
// CLANG_FOO-DAG: Decl[FreeFunction]/OtherModule: fooFuncWithComment3()[#Void#]{{$}}
Expand Down Expand Up @@ -159,7 +159,7 @@ func testCompleteModuleQualifiedFoo2() {
// CLANG_QUAL_FOO_2-DAG: Decl[FreeFunction]/OtherModule: .fooFunc3({#(a): Int32#}, {#(b): Float#}, {#(c): Double#}, {#(d): UnsafePointer<Int32>#})[#Int32#]{{$}}
// CLANG_QUAL_FOO_2-DAG: Decl[FreeFunction]/OtherModule: .fooFuncNoreturn1()[#Void#]{{$}}
// CLANG_QUAL_FOO_2-DAG: Decl[FreeFunction]/OtherModule: .fooFuncNoreturn2()[#Void#]{{$}}
// CLANG_QUAL_FOO_2-DAG: Decl[FreeFunction]/OtherModule: .fooFuncWithBlock({#(blk): ((Float) -> Int32)?#})[#Void#]{{$}}
// CLANG_QUAL_FOO_2-DAG: Decl[FreeFunction]/OtherModule: .fooFuncWithBlock({#(blk): ((Float) -> Int32)?##(Float) -> Int32#})[#Void#]{{$}}
// CLANG_QUAL_FOO_2-DAG: Decl[FreeFunction]/OtherModule: .fooFuncWithFunctionPointer({#(fptr): CFunctionPointer<((Float) -> Int32)>#})[#Void#]{{$}}
// CLANG_QUAL_FOO_2-DAG: Decl[FreeFunction]/OtherModule: .fooFuncWithComment1()[#Void#]{{$}}
// CLANG_QUAL_FOO_2-DAG: Decl[FreeFunction]/OtherModule: .fooFuncWithComment2()[#Void#]{{$}}
Expand Down
18 changes: 18 additions & 0 deletions test/IDE/complete_with_closure_param.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// RUN: %swift-ide-test -code-completion -source-filename %s -code-completion-token=COMPLETE | FileCheck %s

typealias TestAl = (Int, Int) -> Bool

class Bar {
func foo1(callback: (Int, Int) -> Void) {
}
func foo2(callback: TestAl) {
}
}

Bar().#^COMPLETE^#


// CHECK: Begin completions, 2 items
// CHECK-DAG: Decl[InstanceMethod]/CurrNominal: foo1({#(callback): (Int, Int) -> Void##(Int, Int) -> Void#})[#Void#]
// CHECK-DAG: Decl[InstanceMethod]/CurrNominal: foo2({#(callback): TestAl##(Int, Int) -> Bool#})[#Void#]
// CHECK: End completions

0 comments on commit efa1ff8

Please sign in to comment.