xref: /llvm-project/clang-tools-extra/clang-tidy/utils/FileExtensionsUtils.cpp (revision 7d2ea6c422d3f5712b7253407005e1a465a76946)
13486cc01SJonathan Roelofs //===--- FileExtensionsUtils.cpp - clang-tidy -------------------*- C++ -*-===//
23486cc01SJonathan Roelofs //
33486cc01SJonathan Roelofs // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43486cc01SJonathan Roelofs // See https://llvm.org/LICENSE.txt for license information.
53486cc01SJonathan Roelofs // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63486cc01SJonathan Roelofs //
73486cc01SJonathan Roelofs //===----------------------------------------------------------------------===//
83486cc01SJonathan Roelofs 
93486cc01SJonathan Roelofs #include "FileExtensionsUtils.h"
103486cc01SJonathan Roelofs #include "clang/Basic/CharInfo.h"
113486cc01SJonathan Roelofs #include "llvm/Support/Path.h"
1271f55735SKazu Hirata #include <optional>
133486cc01SJonathan Roelofs 
14*7d2ea6c4SCarlos Galvez namespace clang::tidy::utils {
153486cc01SJonathan Roelofs 
isExpansionLocInHeaderFile(SourceLocation Loc,const SourceManager & SM,const FileExtensionsSet & HeaderFileExtensions)163486cc01SJonathan Roelofs bool isExpansionLocInHeaderFile(SourceLocation Loc, const SourceManager &SM,
173486cc01SJonathan Roelofs                                 const FileExtensionsSet &HeaderFileExtensions) {
183486cc01SJonathan Roelofs   SourceLocation ExpansionLoc = SM.getExpansionLoc(Loc);
193486cc01SJonathan Roelofs   return isFileExtension(SM.getFilename(ExpansionLoc), HeaderFileExtensions);
203486cc01SJonathan Roelofs }
213486cc01SJonathan Roelofs 
isPresumedLocInHeaderFile(SourceLocation Loc,SourceManager & SM,const FileExtensionsSet & HeaderFileExtensions)223486cc01SJonathan Roelofs bool isPresumedLocInHeaderFile(SourceLocation Loc, SourceManager &SM,
233486cc01SJonathan Roelofs                                const FileExtensionsSet &HeaderFileExtensions) {
243486cc01SJonathan Roelofs   PresumedLoc PresumedLocation = SM.getPresumedLoc(Loc);
253486cc01SJonathan Roelofs   return isFileExtension(PresumedLocation.getFilename(), HeaderFileExtensions);
263486cc01SJonathan Roelofs }
273486cc01SJonathan Roelofs 
isSpellingLocInHeaderFile(SourceLocation Loc,SourceManager & SM,const FileExtensionsSet & HeaderFileExtensions)283486cc01SJonathan Roelofs bool isSpellingLocInHeaderFile(SourceLocation Loc, SourceManager &SM,
293486cc01SJonathan Roelofs                                const FileExtensionsSet &HeaderFileExtensions) {
303486cc01SJonathan Roelofs   SourceLocation SpellingLoc = SM.getSpellingLoc(Loc);
313486cc01SJonathan Roelofs   return isFileExtension(SM.getFilename(SpellingLoc), HeaderFileExtensions);
323486cc01SJonathan Roelofs }
333486cc01SJonathan Roelofs 
parseFileExtensions(StringRef AllFileExtensions,FileExtensionsSet & FileExtensions,StringRef Delimiters)343486cc01SJonathan Roelofs bool parseFileExtensions(StringRef AllFileExtensions,
3547caa691SJonathan Roelofs                          FileExtensionsSet &FileExtensions,
3647caa691SJonathan Roelofs                          StringRef Delimiters) {
373486cc01SJonathan Roelofs   SmallVector<StringRef, 5> Suffixes;
3847caa691SJonathan Roelofs   for (char Delimiter : Delimiters) {
3947caa691SJonathan Roelofs     if (AllFileExtensions.contains(Delimiter)) {
403486cc01SJonathan Roelofs       AllFileExtensions.split(Suffixes, Delimiter);
4147caa691SJonathan Roelofs       break;
4247caa691SJonathan Roelofs     }
4347caa691SJonathan Roelofs   }
4447caa691SJonathan Roelofs 
453486cc01SJonathan Roelofs   FileExtensions.clear();
463486cc01SJonathan Roelofs   for (StringRef Suffix : Suffixes) {
473486cc01SJonathan Roelofs     StringRef Extension = Suffix.trim();
483486cc01SJonathan Roelofs     if (!llvm::all_of(Extension, isAlphanumeric))
493486cc01SJonathan Roelofs       return false;
503486cc01SJonathan Roelofs     FileExtensions.insert(Extension);
513486cc01SJonathan Roelofs   }
523486cc01SJonathan Roelofs   return true;
533486cc01SJonathan Roelofs }
543486cc01SJonathan Roelofs 
55f71ffd3bSKazu Hirata std::optional<StringRef>
getFileExtension(StringRef FileName,const FileExtensionsSet & FileExtensions)562c9cf9f4SJonathan Roelofs getFileExtension(StringRef FileName, const FileExtensionsSet &FileExtensions) {
57714466bfSNico Weber   StringRef Extension = llvm::sys::path::extension(FileName);
58714466bfSNico Weber   if (Extension.empty())
59cd8702efSKazu Hirata     return std::nullopt;
60714466bfSNico Weber   // Skip "." prefix.
612c9cf9f4SJonathan Roelofs   if (!FileExtensions.count(Extension.substr(1)))
62cd8702efSKazu Hirata     return std::nullopt;
632c9cf9f4SJonathan Roelofs   return Extension;
642c9cf9f4SJonathan Roelofs }
652c9cf9f4SJonathan Roelofs 
isFileExtension(StringRef FileName,const FileExtensionsSet & FileExtensions)662c9cf9f4SJonathan Roelofs bool isFileExtension(StringRef FileName,
672c9cf9f4SJonathan Roelofs                      const FileExtensionsSet &FileExtensions) {
68064a08cdSKazu Hirata   return getFileExtension(FileName, FileExtensions).has_value();
693486cc01SJonathan Roelofs }
703486cc01SJonathan Roelofs 
71*7d2ea6c4SCarlos Galvez } // namespace clang::tidy::utils
72