Author: dgoldman Date: Wed Feb 27 09:40:33 2019 New Revision: 355008 URL: http://llvm.org/viewvc/llvm-project?rev=355008&view=rev Log: Support framework import/include auto-completion
Frameworks filesystem representations: UIKit.framework/Headers/%header% Framework import format: #import <UIKit/%header%> Thus the completion code must map the input format of <UIKit/> to the path of UIKit.framework/Headers as well as strip the ".framework" suffix when auto-completing the framework name. Added: cfe/trunk/test/CodeCompletion/included-frameworks.m Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=355008&r1=355007&r2=355008&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original) +++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Wed Feb 27 09:40:33 2019 @@ -8404,10 +8404,23 @@ void Sema::CodeCompleteIncludedFile(llvm }; // Helper: scans IncludeDir for nice files, and adds results for each. - auto AddFilesFromIncludeDir = [&](StringRef IncludeDir, bool IsSystem) { + auto AddFilesFromIncludeDir = [&](StringRef IncludeDir, + bool IsSystem, + DirectoryLookup::LookupType_t LookupType) { llvm::SmallString<128> Dir = IncludeDir; - if (!NativeRelDir.empty()) - llvm::sys::path::append(Dir, NativeRelDir); + if (!NativeRelDir.empty()) { + if (LookupType == DirectoryLookup::LT_Framework) { + // For a framework dir, #include <Foo/Bar/> actually maps to + // a path of Foo.framework/Headers/Bar/. + auto Begin = llvm::sys::path::begin(NativeRelDir); + auto End = llvm::sys::path::end(NativeRelDir); + + llvm::sys::path::append(Dir, *Begin + ".framework", "Headers"); + llvm::sys::path::append(Dir, ++Begin, End); + } else { + llvm::sys::path::append(Dir, NativeRelDir); + } + } std::error_code EC; unsigned Count = 0; @@ -8418,6 +8431,12 @@ void Sema::CodeCompleteIncludedFile(llvm StringRef Filename = llvm::sys::path::filename(It->path()); switch (It->type()) { case llvm::sys::fs::file_type::directory_file: + // All entries in a framework directory must have a ".framework" suffix, + // but the suffix does not appear in the source code's include/import. + if (LookupType == DirectoryLookup::LT_Framework && + NativeRelDir.empty() && !Filename.consume_back(".framework")) + break; + AddCompletion(Filename, /*IsDirectory=*/true); break; case llvm::sys::fs::file_type::regular_file: @@ -8446,10 +8465,12 @@ void Sema::CodeCompleteIncludedFile(llvm // header maps are not (currently) enumerable. break; case DirectoryLookup::LT_NormalDir: - AddFilesFromIncludeDir(IncludeDir.getDir()->getName(), IsSystem); + AddFilesFromIncludeDir(IncludeDir.getDir()->getName(), IsSystem, + DirectoryLookup::LT_NormalDir); break; case DirectoryLookup::LT_Framework: - AddFilesFromIncludeDir(IncludeDir.getFrameworkDir()->getName(), IsSystem); + AddFilesFromIncludeDir(IncludeDir.getFrameworkDir()->getName(), IsSystem, + DirectoryLookup::LT_Framework); break; } }; @@ -8463,7 +8484,8 @@ void Sema::CodeCompleteIncludedFile(llvm // The current directory is on the include path for "quoted" includes. auto *CurFile = PP.getCurrentFileLexer()->getFileEntry(); if (CurFile && CurFile->getDir()) - AddFilesFromIncludeDir(CurFile->getDir()->getName(), false); + AddFilesFromIncludeDir(CurFile->getDir()->getName(), false, + DirectoryLookup::LT_NormalDir); for (const auto &D : make_range(S.quoted_dir_begin(), S.quoted_dir_end())) AddFilesFromDirLookup(D, false); } Added: cfe/trunk/test/CodeCompletion/included-frameworks.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeCompletion/included-frameworks.m?rev=355008&view=auto ============================================================================== --- cfe/trunk/test/CodeCompletion/included-frameworks.m (added) +++ cfe/trunk/test/CodeCompletion/included-frameworks.m Wed Feb 27 09:40:33 2019 @@ -0,0 +1,29 @@ +// RUN: rm -rf %t && mkdir -p %t/Foo.framework/Headers/SubFolder && mkdir %t/NotAFramework/ +// RUN: touch %t/Foo.framework/Headers/Foo.h && touch %t/Foo.framework/Headers/FOOClass.h +// RUN: touch %t/Foo.framework/Headers/SubFolder/FOOInternal.h + +#import <Foo/Foo.h> + +#import <Foo/SubFolder/FOOInternal.h> + +// Note: the run lines follow their respective tests, since line/column +// matter in this test. + +// Autocomplete frameworks without the ".framework" extension. +// +// RUN: %clang -fsyntax-only -F %t -Xclang -code-completion-at=%s:5:10 %s -o - | FileCheck -check-prefix=CHECK-1 %s +// CHECK-1-NOT: Foo.framework/ +// CHECK-1-NOT: NotAFramework/ +// CHECK-1: Foo/ + +// Autocomplete for frameworks inside its Headers folder. +// +// RUN: %clang -fsyntax-only -F %t -Xclang -code-completion-at=%s:5:14 %s -o - | FileCheck -check-prefix=CHECK-2 %s +// CHECK-2: Foo.h> +// CHECK-2: FOOClass.h> +// CHECK-2: SubFolder/ + +// Autocomplete for folders inside of a frameworks. +// +// RUN: %clang -fsyntax-only -F %t -Xclang -code-completion-at=%s:7:24 %s -o - | FileCheck -check-prefix=CHECK-3 %s +// CHECK-3: FOOInternal.h> _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits