1 //===--- FileExtensionsUtils.cpp - clang-tidy -------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "FileExtensionsUtils.h"
10 #include "clang/Basic/CharInfo.h"
11 #include "llvm/Support/Path.h"
12 
13 namespace clang {
14 namespace tidy {
15 namespace utils {
16 
isExpansionLocInHeaderFile(SourceLocation Loc,const SourceManager & SM,const FileExtensionsSet & HeaderFileExtensions)17 bool isExpansionLocInHeaderFile(SourceLocation Loc, const SourceManager &SM,
18                                 const FileExtensionsSet &HeaderFileExtensions) {
19   SourceLocation ExpansionLoc = SM.getExpansionLoc(Loc);
20   return isFileExtension(SM.getFilename(ExpansionLoc), HeaderFileExtensions);
21 }
22 
isPresumedLocInHeaderFile(SourceLocation Loc,SourceManager & SM,const FileExtensionsSet & HeaderFileExtensions)23 bool isPresumedLocInHeaderFile(SourceLocation Loc, SourceManager &SM,
24                                const FileExtensionsSet &HeaderFileExtensions) {
25   PresumedLoc PresumedLocation = SM.getPresumedLoc(Loc);
26   return isFileExtension(PresumedLocation.getFilename(), HeaderFileExtensions);
27 }
28 
isSpellingLocInHeaderFile(SourceLocation Loc,SourceManager & SM,const FileExtensionsSet & HeaderFileExtensions)29 bool isSpellingLocInHeaderFile(SourceLocation Loc, SourceManager &SM,
30                                const FileExtensionsSet &HeaderFileExtensions) {
31   SourceLocation SpellingLoc = SM.getSpellingLoc(Loc);
32   return isFileExtension(SM.getFilename(SpellingLoc), HeaderFileExtensions);
33 }
34 
parseFileExtensions(StringRef AllFileExtensions,FileExtensionsSet & FileExtensions,StringRef Delimiters)35 bool parseFileExtensions(StringRef AllFileExtensions,
36                          FileExtensionsSet &FileExtensions,
37                          StringRef Delimiters) {
38   SmallVector<StringRef, 5> Suffixes;
39   for (char Delimiter : Delimiters) {
40     if (AllFileExtensions.contains(Delimiter)) {
41       AllFileExtensions.split(Suffixes, Delimiter);
42       break;
43     }
44   }
45 
46   FileExtensions.clear();
47   for (StringRef Suffix : Suffixes) {
48     StringRef Extension = Suffix.trim();
49     if (!llvm::all_of(Extension, isAlphanumeric))
50       return false;
51     FileExtensions.insert(Extension);
52   }
53   return true;
54 }
55 
56 llvm::Optional<StringRef>
getFileExtension(StringRef FileName,const FileExtensionsSet & FileExtensions)57 getFileExtension(StringRef FileName, const FileExtensionsSet &FileExtensions) {
58   StringRef Extension = llvm::sys::path::extension(FileName);
59   if (Extension.empty())
60     return llvm::None;
61   // Skip "." prefix.
62   if (!FileExtensions.count(Extension.substr(1)))
63     return llvm::None;
64   return Extension;
65 }
66 
isFileExtension(StringRef FileName,const FileExtensionsSet & FileExtensions)67 bool isFileExtension(StringRef FileName,
68                      const FileExtensionsSet &FileExtensions) {
69   return getFileExtension(FileName, FileExtensions).hasValue();
70 }
71 
72 } // namespace utils
73 } // namespace tidy
74 } // namespace clang
75