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