This PR converts the syntax highlighters to plugins. Previously, the highlighters were part of the Language plugin, using a library shared by the C-like languages. The Highlighters already had a plugin-like design, with a clang and default highlighter. This PR takes them out of the language plugin and into their own highlighter plugin. They are still accessed thought he HighlightManager. This change is motivated by #170250. It will allow us to have both a clang and tree-sitter based highlighter, as well as make it possible to have a highlighter for a language that doesn't have an upstream language plugin, like Swift or Rust.
201 lines
6.8 KiB
C++
201 lines
6.8 KiB
C++
//===-- ObjCLanguage.h ------------------------------------------*- C++ -*-===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_OBJCLANGUAGE_H
|
|
#define LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_OBJCLANGUAGE_H
|
|
|
|
#include <cstring>
|
|
#include <vector>
|
|
|
|
#include "lldb/Target/Language.h"
|
|
#include "lldb/Utility/ConstString.h"
|
|
#include "lldb/lldb-private.h"
|
|
|
|
namespace lldb_private {
|
|
|
|
class ObjCLanguage : public Language {
|
|
public:
|
|
class ObjCMethodName {
|
|
public:
|
|
/// The static factory method for creating a ObjCMethodName.
|
|
///
|
|
/// \param[in] name
|
|
/// The name of the method.
|
|
///
|
|
/// \param[in] strict
|
|
/// Control whether or not the name parser is strict about +/- in the
|
|
/// front of the name.
|
|
///
|
|
/// \return If the name failed to parse as a valid Objective-C method name,
|
|
/// returns std::nullopt. Otherwise returns a const ObjCMethodName.
|
|
static std::optional<const ObjCMethodName> Create(llvm::StringRef name,
|
|
bool strict);
|
|
|
|
/// Determines if this method is a class method
|
|
///
|
|
/// \return Returns true if the method is a class method. False otherwise.
|
|
bool IsClassMethod() const { return m_type == eTypeClassMethod; }
|
|
|
|
/// Determines if this method is an instance method
|
|
///
|
|
/// \return Returns true if the method is an instance method. False
|
|
/// otherwise.
|
|
bool IsInstanceMethod() const { return m_type == eTypeInstanceMethod; }
|
|
|
|
/// Returns the full name of the method.
|
|
///
|
|
/// This includes the class name, the category name (if applicable), and the
|
|
/// selector name.
|
|
///
|
|
/// \return The name of the method in the form of a const std::string
|
|
/// reference.
|
|
const std::string &GetFullName() const { return m_full; }
|
|
|
|
/// Creates a variation of this method without the category.
|
|
/// If this method has no category, it returns an empty string.
|
|
///
|
|
/// Example:
|
|
/// Full name: "+[NSString(my_additions) myStringWithCString:]"
|
|
/// becomes "+[NSString myStringWithCString:]"
|
|
///
|
|
/// \return The method name without the category or an empty string if there
|
|
/// was no category to begin with.
|
|
std::string GetFullNameWithoutCategory() const;
|
|
|
|
/// Returns a reference to the class name.
|
|
///
|
|
/// Example:
|
|
/// Full name: "+[NSString(my_additions) myStringWithCString:]"
|
|
/// will give you "NSString"
|
|
///
|
|
/// \return A StringRef to the class name of this method.
|
|
llvm::StringRef GetClassName() const;
|
|
|
|
/// Returns a reference to the class name with the category.
|
|
///
|
|
/// Example:
|
|
/// Full name: "+[NSString(my_additions) myStringWithCString:]"
|
|
/// will give you "NSString(my_additions)"
|
|
///
|
|
/// Note: If your method has no category, this will give the same output as
|
|
/// `GetClassName`.
|
|
///
|
|
/// \return A StringRef to the class name (including the category) of this
|
|
/// method. If there was no category, returns the same as `GetClassName`.
|
|
llvm::StringRef GetClassNameWithCategory() const;
|
|
|
|
/// Returns a reference to the category name.
|
|
///
|
|
/// Example:
|
|
/// Full name: "+[NSString(my_additions) myStringWithCString:]"
|
|
/// will give you "my_additions"
|
|
/// \return A StringRef to the category name of this method. If no category
|
|
/// is present, the StringRef is empty.
|
|
llvm::StringRef GetCategory() const;
|
|
|
|
/// Returns a reference to the selector name.
|
|
///
|
|
/// Example:
|
|
/// Full name: "+[NSString(my_additions) myStringWithCString:]"
|
|
/// will give you "myStringWithCString:"
|
|
/// \return A StringRef to the selector of this method.
|
|
llvm::StringRef GetSelector() const;
|
|
|
|
protected:
|
|
enum Type { eTypeUnspecified, eTypeClassMethod, eTypeInstanceMethod };
|
|
|
|
ObjCMethodName(llvm::StringRef name, Type type)
|
|
: m_full(name.str()), m_type(type) {}
|
|
|
|
const std::string m_full;
|
|
Type m_type;
|
|
};
|
|
|
|
ObjCLanguage() = default;
|
|
|
|
~ObjCLanguage() override = default;
|
|
|
|
lldb::LanguageType GetLanguageType() const override {
|
|
return lldb::eLanguageTypeObjC;
|
|
}
|
|
|
|
llvm::StringRef GetUserEntryPointName() const override { return "main"; }
|
|
|
|
// Get all possible names for a method. Examples:
|
|
// If method_name is "+[NSString(my_additions) myStringWithCString:]"
|
|
// variant_names[0] => "+[NSString myStringWithCString:]"
|
|
// If name is specified without the leading '+' or '-' like
|
|
// "[NSString(my_additions) myStringWithCString:]"
|
|
// variant_names[0] => "+[NSString(my_additions) myStringWithCString:]"
|
|
// variant_names[1] => "-[NSString(my_additions) myStringWithCString:]"
|
|
// variant_names[2] => "+[NSString myStringWithCString:]"
|
|
// variant_names[3] => "-[NSString myStringWithCString:]"
|
|
// Also returns the FunctionNameType of each possible name.
|
|
std::vector<Language::MethodNameVariant>
|
|
GetMethodNameVariants(ConstString method_name) const override;
|
|
|
|
std::pair<lldb::FunctionNameType, std::optional<ConstString>>
|
|
GetFunctionNameInfo(ConstString name) const override;
|
|
|
|
bool SymbolNameFitsToLanguage(const Mangled &mangled) const override;
|
|
|
|
lldb::TypeCategoryImplSP GetFormatters() override;
|
|
|
|
std::vector<FormattersMatchCandidate>
|
|
GetPossibleFormattersMatches(ValueObject &valobj,
|
|
lldb::DynamicValueType use_dynamic) override;
|
|
|
|
std::unique_ptr<TypeScavenger> GetTypeScavenger() override;
|
|
|
|
std::pair<llvm::StringRef, llvm::StringRef>
|
|
GetFormatterPrefixSuffix(llvm::StringRef type_hint) override;
|
|
|
|
bool IsNilReference(ValueObject &valobj) override;
|
|
|
|
llvm::StringRef GetNilReferenceSummaryString() override { return "nil"; }
|
|
|
|
bool IsSourceFile(llvm::StringRef file_path) const override;
|
|
|
|
// Static Functions
|
|
static void Initialize();
|
|
|
|
static void Terminate();
|
|
|
|
static lldb_private::Language *CreateInstance(lldb::LanguageType language);
|
|
|
|
static llvm::StringRef GetPluginNameStatic() { return "objc"; }
|
|
|
|
static bool IsPossibleObjCMethodName(llvm::StringRef name);
|
|
|
|
static bool IsPossibleObjCSelector(const char *name) {
|
|
if (!name)
|
|
return false;
|
|
|
|
if (strchr(name, ':') == nullptr)
|
|
return true;
|
|
else if (name[strlen(name) - 1] == ':')
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
llvm::StringRef GetInstanceVariableName() override { return "self"; }
|
|
|
|
virtual std::optional<bool>
|
|
GetBooleanFromString(llvm::StringRef str) const override;
|
|
|
|
bool SupportsExceptionBreakpointsOnThrow() const override { return true; }
|
|
|
|
// PluginInterface protocol
|
|
llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
|
|
};
|
|
|
|
} // namespace lldb_private
|
|
|
|
#endif // LLDB_SOURCE_PLUGINS_LANGUAGE_OBJC_OBJCLANGUAGE_H
|