diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/Lex/Preprocessor.h | 16 | ||||
-rw-r--r-- | clang/include/clang/Sema/CodeCompleteConsumer.h | 9 | ||||
-rw-r--r-- | clang/lib/Lex/Lexer.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Lex/Preprocessor.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Sema/CodeCompleteConsumer.cpp | 25 | ||||
-rw-r--r-- | clang/test/CodeCompletion/objc-message.mm | 4 | ||||
-rw-r--r-- | clang/test/Index/complete-method-decls.m | 2 | ||||
-rw-r--r-- | clang/test/Index/complete-objc-message-id.m | 4 | ||||
-rw-r--r-- | clang/test/Index/complete-objc-message.m | 8 | ||||
-rw-r--r-- | clang/test/Index/complete-recovery.m | 2 | ||||
-rw-r--r-- | clang/test/Index/complete-super.m | 4 |
11 files changed, 75 insertions, 14 deletions
diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 30cc37f6f88..c9b712504e1 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -265,6 +265,10 @@ class Preprocessor : public RefCountedBase<Preprocessor> { /// \brief True if we hit the code-completion point. bool CodeCompletionReached; + /// \brief The code completion token containing the information + /// on the stem that is to be code completed. + IdentifierInfo *CodeCompletionII; + /// \brief The directory that the main file should be considered to occupy, /// if it does not correspond to a real file (as happens when building a /// module). @@ -984,6 +988,18 @@ public: /// completion point. void CodeCompleteNaturalLanguage(); + /// \brief Set the code completion token for filtering purposes. + void setCodeCompletionIdentifierInfo(IdentifierInfo *Filter) { + CodeCompletionII = Filter; + } + + /// \brief Get the code completion token for filtering purposes. + StringRef getCodeCompletionFilter() { + if (CodeCompletionII) + return CodeCompletionII->getName(); + return {}; + } + /// \brief Retrieve the preprocessing record, or NULL if there is no /// preprocessing record. PreprocessingRecord *getPreprocessingRecord() const { return Record; } diff --git a/clang/include/clang/Sema/CodeCompleteConsumer.h b/clang/include/clang/Sema/CodeCompleteConsumer.h index 014ea5d61df..4ad1b017032 100644 --- a/clang/include/clang/Sema/CodeCompleteConsumer.h +++ b/clang/include/clang/Sema/CodeCompleteConsumer.h @@ -913,6 +913,13 @@ public: /// \brief Deregisters and destroys this code-completion consumer. virtual ~CodeCompleteConsumer(); + /// \name Code-completion filtering + /// \brief Check if the result should be filtered out. + virtual bool isResultFilteredOut(StringRef Filter, + CodeCompletionResult Results) { + return false; + } + /// \name Code-completion callbacks //@{ /// \brief Process the finalized code-completion results. @@ -966,6 +973,8 @@ public: OverloadCandidate *Candidates, unsigned NumCandidates) override; + bool isResultFilteredOut(StringRef Filter, CodeCompletionResult Results) override; + CodeCompletionAllocator &getAllocator() override { return CCTUInfo.getAllocator(); } diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index 9c2a0163ace..9f7638d8329 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -1533,7 +1533,15 @@ FinishIdentifier: // preprocessor, which may macro expand it or something. if (II->isHandleIdentifierCase()) return PP->HandleIdentifier(Result); - + + if (II->getTokenID() == tok::identifier && isCodeCompletionPoint(CurPtr) + && II->getPPKeywordID() == tok::pp_not_keyword + && II->getObjCKeywordID() == tok::objc_not_keyword) { + // Return the code-completion token. + Result.setKind(tok::code_completion); + cutOffLexing(); + return true; + } return true; } diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index 3654ba080d4..8832c7f80c4 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -74,7 +74,7 @@ Preprocessor::Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts, IncrementalProcessing(false), TUKind(TUKind), CodeComplete(nullptr), CodeCompletionFile(nullptr), CodeCompletionOffset(0), LastTokenWasAt(false), ModuleImportExpectsIdentifier(false), - CodeCompletionReached(0), MainFileDir(nullptr), + CodeCompletionReached(0), CodeCompletionII(0), MainFileDir(nullptr), SkipMainFilePreamble(0, true), CurPPLexer(nullptr), CurDirLookup(nullptr), CurLexerKind(CLK_Lexer), CurSubmodule(nullptr), Callbacks(nullptr), CurSubmoduleState(&NullSubmoduleState), MacroArgCache(nullptr), @@ -744,6 +744,9 @@ void Preprocessor::Lex(Token &Result) { } } while (!ReturnedToken); + if (Result.is(tok::code_completion)) + setCodeCompletionIdentifierInfo(Result.getIdentifierInfo()); + LastTokenWasAt = Result.is(tok::at); } diff --git a/clang/lib/Sema/CodeCompleteConsumer.cpp b/clang/lib/Sema/CodeCompleteConsumer.cpp index 9a4f0d921bf..e4f0e397f01 100644 --- a/clang/lib/Sema/CodeCompleteConsumer.cpp +++ b/clang/lib/Sema/CodeCompleteConsumer.cpp @@ -17,6 +17,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/Sema/Scope.h" #include "clang/Sema/Sema.h" +#include "clang/Lex/Preprocessor.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" @@ -428,6 +429,26 @@ CodeCompleteConsumer::OverloadCandidate::getFunctionType() const { CodeCompleteConsumer::~CodeCompleteConsumer() { } +bool PrintingCodeCompleteConsumer::isResultFilteredOut(StringRef Filter, + CodeCompletionResult Result) { + switch (Result.Kind) { + case CodeCompletionResult::RK_Declaration: { + return !(Result.Declaration->getIdentifier() && + Result.Declaration->getIdentifier()->getName().startswith(Filter)); + } + case CodeCompletionResult::RK_Keyword: { + return !StringRef(Result.Keyword).startswith(Filter); + } + case CodeCompletionResult::RK_Macro: { + return !Result.Macro->getName().startswith(Filter); + } + case CodeCompletionResult::RK_Pattern: { + return !StringRef(Result.Pattern->getAsString()).startswith(Filter); + } + default: llvm_unreachable("Unknown code completion result Kind."); + } +} + void PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef, CodeCompletionContext Context, @@ -435,8 +456,12 @@ PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef, unsigned NumResults) { std::stable_sort(Results, Results + NumResults); + StringRef Filter = SemaRef.getPreprocessor().getCodeCompletionFilter(); + // Print the results. for (unsigned I = 0; I != NumResults; ++I) { + if(!Filter.empty() && isResultFilteredOut(Filter, Results[I])) + continue; OS << "COMPLETION: "; switch (Results[I].Kind) { case CodeCompletionResult::RK_Declaration: diff --git a/clang/test/CodeCompletion/objc-message.mm b/clang/test/CodeCompletion/objc-message.mm index 352a18e0da9..7a503097e07 100644 --- a/clang/test/CodeCompletion/objc-message.mm +++ b/clang/test/CodeCompletion/objc-message.mm @@ -38,9 +38,9 @@ void func(const RetainPtr<id <FooTestProtocol>>& ptr) [ptr instanceMethod1]; } -// RUN: %clang_cc1 -fsyntax-only -std=c++11 -code-completion-at=%s:33:7 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -code-completion-at=%s:33:8 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s // CHECK-CC1: categoryInstanceMethod : [#id#]categoryInstanceMethod // CHECK-CC1: instanceMethod1 : [#id#]instanceMethod1 // CHECK-CC1: protocolInstanceMethod : [#id#]protocolInstanceMethod -// RUN: %clang_cc1 -fsyntax-only -std=c++11 -code-completion-at=%s:38:7 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -code-completion-at=%s:38:8 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s // CHECK-CC2: protocolInstanceMethod : [#id#]protocolInstanceMethod diff --git a/clang/test/Index/complete-method-decls.m b/clang/test/Index/complete-method-decls.m index 41134081e15..8a171422666 100644 --- a/clang/test/Index/complete-method-decls.m +++ b/clang/test/Index/complete-method-decls.m @@ -195,7 +195,7 @@ typedef A *MyObjectRef; // CHECK-CCG: NotImplemented:{TypedText void} (50) // CHECK-CCG: NotImplemented:{TypedText volatile} (50) // RUN: c-index-test -code-completion-at=%s:60:24 %s | FileCheck -check-prefix=CHECK-CCF %s -// RUN: c-index-test -code-completion-at=%s:60:26 %s | FileCheck -check-prefix=CHECK-CCH %s +// RUN: c-index-test -code-completion-at=%s:60:27 %s | FileCheck -check-prefix=CHECK-CCH %s // CHECK-CCH: ObjCInterfaceDecl:{TypedText A} (50) // CHECK-CCH: ObjCInterfaceDecl:{TypedText B} (50) // CHECK-CCH: NotImplemented:{TypedText bycopy} (40) diff --git a/clang/test/Index/complete-objc-message-id.m b/clang/test/Index/complete-objc-message-id.m index 415e0ff0219..044c82851d9 100644 --- a/clang/test/Index/complete-objc-message-id.m +++ b/clang/test/Index/complete-objc-message-id.m @@ -68,7 +68,7 @@ void message_qualified_id(id<P2> ip2) { // CHECK-SELECTOR-PREF: ObjCClassMethodDecl:{ResultType id}{TypedText new} (35) // CHECK-SELECTOR-PREF: ObjCClassMethodDecl:{ResultType Class}{TypedText superclass} (35) -// RUN: c-index-test -code-completion-at=%s:46:7 %s | FileCheck -check-prefix=CHECK-INSTANCE-QUAL-ID %s -// RUN: c-index-test -code-completion-at=%s:47:7 %s | FileCheck -check-prefix=CHECK-INSTANCE-QUAL-ID %s +// RUN: c-index-test -code-completion-at=%s:46:8 %s | FileCheck -check-prefix=CHECK-INSTANCE-QUAL-ID %s +// RUN: c-index-test -code-completion-at=%s:47:8 %s | FileCheck -check-prefix=CHECK-INSTANCE-QUAL-ID %s // CHECK-INSTANCE-QUAL-ID: ObjCInstanceMethodDecl:{ResultType int}{TypedText P1_method1} (37) // CHECK-INSTANCE-QUAL-ID: ObjCInstanceMethodDecl:{ResultType int}{TypedText P2_method1} (35) diff --git a/clang/test/Index/complete-objc-message.m b/clang/test/Index/complete-objc-message.m index 193f1f8bf22..e3fce6bc20f 100644 --- a/clang/test/Index/complete-objc-message.m +++ b/clang/test/Index/complete-objc-message.m @@ -218,13 +218,13 @@ void test_Nullability(Nullability *n, A* a) { // CHECK-CC2-NEXT: Container Kind: ObjCInterfaceDecl // CHECK-CC2-NEXT: Container is complete // CHECK-CC2-NEXT: Container USR: c:objc(cs)Foo -// RUN: c-index-test -code-completion-at=%s:61:16 %s | FileCheck -check-prefix=CHECK-CC3 %s +// RUN: c-index-test -code-completion-at=%s:61:17 %s | FileCheck -check-prefix=CHECK-CC3 %s // CHECK-CC3: ObjCClassMethodDecl:{ResultType int}{TypedText MyClassMethod:}{Placeholder (id)} // CHECK-CC3: ObjCClassMethodDecl:{ResultType int}{TypedText MyPrivateMethod} -// RUN: c-index-test -code-completion-at=%s:65:16 %s | FileCheck -check-prefix=CHECK-CC4 %s +// RUN: c-index-test -code-completion-at=%s:65:17 %s | FileCheck -check-prefix=CHECK-CC4 %s // CHECK-CC4: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyInstMethod:}{Placeholder (id)}{HorizontalSpace }{TypedText second:}{Placeholder (id)} // CHECK-CC4: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyPrivateInstMethod} -// RUN: c-index-test -code-completion-at=%s:74:9 %s | FileCheck -check-prefix=CHECK-CC5 %s +// RUN: c-index-test -code-completion-at=%s:74:10 %s | FileCheck -check-prefix=CHECK-CC5 %s // CHECK-CC5: ObjCInstanceMethodDecl:{ResultType int}{TypedText MyInstMethod:}{Placeholder (id)}{HorizontalSpace }{TypedText second:}{Placeholder (id)} // CHECK-CC5: ObjCInstanceMethodDecl:{ResultType int}{TypedText MySubInstMethod} // RUN: c-index-test -code-completion-at=%s:82:8 %s | FileCheck -check-prefix=CHECK-CC6 %s @@ -311,7 +311,7 @@ void test_Nullability(Nullability *n, A* a) { // CHECK-CCI: ObjCInstanceMethodDecl:{ResultType void}{TypedText method1} (37) // CHECK-CCI: ObjCInstanceMethodDecl:{ResultType void}{TypedText method2} (35) -// RUN: c-index-test -code-completion-at=%s:150:5 %s | FileCheck -check-prefix=CHECK-REDUNDANT %s +// RUN: c-index-test -code-completion-at=%s:150:6 %s | FileCheck -check-prefix=CHECK-REDUNDANT %s // CHECK-REDUNDANT: ObjCInstanceMethodDecl:{ResultType void}{TypedText method2} (35) // CHECK-REDUNDANT-NOT: ObjCInstanceMethodDecl:{ResultType void}{TypedText method2} // CHECK-REDUNDANT: ObjCInstanceMethodDecl:{ResultType void}{TypedText method3} (35) diff --git a/clang/test/Index/complete-recovery.m b/clang/test/Index/complete-recovery.m index ec5bf8af6ab..bd920eb3ac6 100644 --- a/clang/test/Index/complete-recovery.m +++ b/clang/test/Index/complete-recovery.m @@ -26,7 +26,7 @@ // Test case for fix committed in r145441. // RUN: env CINDEXTEST_CODE_COMPLETE_PATTERNS=1 c-index-test -code-completion-at=%s:9:20 %s -fms-compatibility | FileCheck -check-prefix=CHECK-CC1 %s -// RUN: env CINDEXTEST_CODE_COMPLETE_PATTERNS=1 c-index-test -code-completion-at=%s:10:24 %s | FileCheck -check-prefix=CHECK-CC2 %s +// RUN: env CINDEXTEST_CODE_COMPLETE_PATTERNS=1 c-index-test -code-completion-at=%s:10:25 %s | FileCheck -check-prefix=CHECK-CC2 %s // CHECK-CC2: NotImplemented:{ResultType char[]}{TypedText @encode}{LeftParen (}{Placeholder type-name}{RightParen )} // CHECK-CC2: NotImplemented:{TypedText _Bool} // CHECK-CC2: VarDecl:{ResultType A *}{TypedText a} diff --git a/clang/test/Index/complete-super.m b/clang/test/Index/complete-super.m index be7edfdef83..952ffbc6fd0 100644 --- a/clang/test/Index/complete-super.m +++ b/clang/test/Index/complete-super.m @@ -60,7 +60,7 @@ typedef int Bool; // RUN: c-index-test -code-completion-at=%s:20:16 %s | FileCheck -check-prefix=CHECK-ADD-TO %s // CHECK-ADD-TO: ObjCInstanceMethodDecl:{ResultType void}{Informative add:}{TypedText to:}{Placeholder b} (20) -// RUN: c-index-test -code-completion-at=%s:24:28 %s | FileCheck -check-prefix=CHECK-SELECTOR-FIRST %s +// RUN: c-index-test -code-completion-at=%s:24:29 %s | FileCheck -check-prefix=CHECK-SELECTOR-FIRST %s // CHECK-SELECTOR-FIRST: ObjCClassMethodDecl:{ResultType void}{Informative select:}{TypedText first:}{Placeholder a}{HorizontalSpace }{Text second:}{Placeholder b} (20) // Check "super" completion at the third identifier @@ -69,7 +69,7 @@ typedef int Bool; // Check "super" completion with missing '['. // RUN: c-index-test -code-completion-at=%s:25:10 %s | FileCheck -check-prefix=CHECK-SELECTOR-SELECTOR %s -// RUN: c-index-test -code-completion-at=%s:25:28 %s | FileCheck -check-prefix=CHECK-SELECTOR-FIRST %s +// RUN: c-index-test -code-completion-at=%s:25:29 %s | FileCheck -check-prefix=CHECK-SELECTOR-FIRST %s // RUN: c-index-test -code-completion-at=%s:25:37 %s | FileCheck -check-prefix=CHECK-SELECTOR-SECOND %s // Check "super" completion for a method declared in a category. |