llvm/clang-tools-extra/clang-tidy/NoLintDirectiveHandler.cpp

//===-- clang-tools-extra/clang-tidy/NoLintDirectiveHandler.cpp -----------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
///  \file This file implements the NoLintDirectiveHandler class, which is used
///  to locate NOLINT comments in the file being analyzed, to decide whether a
///  diagnostic should be suppressed.
///
//===----------------------------------------------------------------------===//

#include "NoLintDirectiveHandler.h"
#include "GlobList.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Tooling/Core/Diagnostic.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringSwitch.h"
#include <cassert>
#include <cstddef>
#include <iterator>
#include <optional>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>

namespace clang::tidy {

//===----------------------------------------------------------------------===//
// NoLintType
//===----------------------------------------------------------------------===//

// The type - one of NOLINT[NEXTLINE/BEGIN/END].
enum class NoLintType {};

// Convert a string like "NOLINTNEXTLINE" to its enum `Type::NoLintNextLine`.
// Return `std::nullopt` if the string is unrecognized.
static std::optional<NoLintType> strToNoLintType(StringRef Str) {}

//===----------------------------------------------------------------------===//
// NoLintToken
//===----------------------------------------------------------------------===//

// Whitespace within a NOLINT's check list shall be ignored.
// "NOLINT( check1, check2 )" is equivalent to "NOLINT(check1,check2)".
// Return the check list with all extraneous whitespace removed.
static std::string trimWhitespace(StringRef Checks) {}

namespace {

// Record the presence of a NOLINT comment - its type, location, checks -
// as parsed from the file's character contents.
class NoLintToken {};

} // namespace

// Consume the entire buffer and return all `NoLintToken`s that were found.
static SmallVector<NoLintToken> getNoLints(StringRef Buffer) {}

//===----------------------------------------------------------------------===//
// NoLintBlockToken
//===----------------------------------------------------------------------===//

namespace {

// Represents a source range within a pair of NOLINT(BEGIN/END) comments.
class NoLintBlockToken {};

} // namespace

// Match NOLINTBEGINs with their corresponding NOLINTENDs and move them into
// `NoLintBlockToken`s. If any BEGINs or ENDs are left over, they are moved to
// `UnmatchedTokens`.
static SmallVector<NoLintBlockToken>
formNoLintBlocks(SmallVector<NoLintToken> NoLints,
                 SmallVectorImpl<NoLintToken> &UnmatchedTokens) {}

//===----------------------------------------------------------------------===//
// NoLintDirectiveHandler::Impl
//===----------------------------------------------------------------------===//

class NoLintDirectiveHandler::Impl {};

bool NoLintDirectiveHandler::Impl::shouldSuppress(
    DiagnosticsEngine::Level DiagLevel, const Diagnostic &Diag,
    StringRef DiagName, SmallVectorImpl<tooling::Diagnostic> &NoLintErrors,
    bool AllowIO, bool EnableNoLintBlocks) {}

// Look at the macro's spelling location for a NOLINT. If none is found, keep
// looking up the call stack.
bool NoLintDirectiveHandler::Impl::diagHasNoLintInMacro(
    const Diagnostic &Diag, StringRef DiagName,
    SmallVectorImpl<tooling::Diagnostic> &NoLintErrors, bool AllowIO,
    bool EnableNoLintBlocks) {}

// Look behind and ahead for '\n' characters. These mark the start and end of
// this line.
static std::pair<size_t, size_t> getLineStartAndEnd(StringRef Buffer,
                                                    size_t From) {}

// Whether the line has a NOLINT of type = `Type` that can suppress the
// diagnostic `DiagName`.
static bool lineHasNoLint(StringRef Buffer,
                          std::pair<size_t, size_t> LineStartAndEnd,
                          NoLintType Type, StringRef DiagName) {}

// Whether the provided diagnostic is located within and is suppressible by a
// block of NOLINT(BEGIN/END) comments.
static bool withinNoLintBlock(ArrayRef<NoLintBlockToken> NoLintBlocks,
                              size_t DiagPos, StringRef DiagName) {}

// Get the file contents as a string.
static std::optional<StringRef> getBuffer(const SourceManager &SrcMgr,
                                          FileID File, bool AllowIO) {}

// We will check for NOLINTs and NOLINTNEXTLINEs first. Checking for these is
// not so expensive (just need to parse the current and previous lines). Only if
// that fails do we look for NOLINT(BEGIN/END) blocks (which requires reading
// the entire file).
bool NoLintDirectiveHandler::Impl::diagHasNoLint(
    StringRef DiagName, SourceLocation DiagLoc, const SourceManager &SrcMgr,
    SmallVectorImpl<tooling::Diagnostic> &NoLintErrors, bool AllowIO,
    bool EnableNoLintBlocks) {}

// Construct a [clang-tidy-nolint] diagnostic to do with the unmatched
// NOLINT(BEGIN/END) pair.
static tooling::Diagnostic makeNoLintError(const SourceManager &SrcMgr,
                                           FileID File,
                                           const NoLintToken &NoLint) {}

// Find all NOLINT(BEGIN/END) blocks in a file and store in the cache.
void NoLintDirectiveHandler::Impl::generateCache(
    const SourceManager &SrcMgr, StringRef FileName, FileID File,
    StringRef Buffer, SmallVectorImpl<tooling::Diagnostic> &NoLintErrors) {}

//===----------------------------------------------------------------------===//
// NoLintDirectiveHandler
//===----------------------------------------------------------------------===//

NoLintDirectiveHandler::NoLintDirectiveHandler()
    :{}

NoLintDirectiveHandler::~NoLintDirectiveHandler() = default;

bool NoLintDirectiveHandler::shouldSuppress(
    DiagnosticsEngine::Level DiagLevel, const Diagnostic &Diag,
    StringRef DiagName, SmallVectorImpl<tooling::Diagnostic> &NoLintErrors,
    bool AllowIO, bool EnableNoLintBlocks) {}

} // namespace clang::tidy