// Copyright 2026 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_REGEXP_REGEXP_PRINTER_H_
#define V8_REGEXP_REGEXP_PRINTER_H_
#ifdef V8_ENABLE_REGEXP_DIAGNOSTICS
#include <iostream>
#include <map>
#include <memory>
#include "irregexp/RegExpShim.h"
namespace v8 {
namespace internal {
class Zone;
namespace regexp {
class GraphPrinter;
class Node;
template <typename T>
class NodePrinter;
class TraceTreeScope;
class Tree;
template <typename T>
class GraphLabeller {
public :
auto RegisterNode(const T* node) {
auto result = nodes_.emplace(node, next_node_label_);
if (result.second) {
next_node_label_++;
}
return result.first;
}
int NodeId(const T* node) {
auto it = nodes_.find(node);
if (it == nodes_.end()) {
it = RegisterNode(node);
DCHECK_NE(it, nodes_.end());
}
return it->second;
}
int NodeId(const T* node) const {
auto it = nodes_.find(node);
if (it == nodes_.end()) {
return -1 ;
}
return it->second;
}
private :
std::map<const T*, int > nodes_;
int next_node_label_ = 1 ;
};
class PrinterBase {
public :
enum class Color : int {
kDefault = 0 ,
kRed = 31 ,
kGreen = 32 ,
kYellow = 33 ,
kBlue = 34 ,
kMagenta = 35 ,
kCyan = 36 ,
kWhite = 37
};
PrinterBase(std::ostream& os, Zone* zone) : os_(os), zone_(zone) {}
PrinterBase(const PrinterBase& other) V8_NOEXCEPT = default ;
int color() const { return color_; }
void set_color(Color color) {
if (!v8_flags.log_colour) return ;
color_ = static_cast <int >(color);
os() << "\033[" << color_ << "m" ;
}
void set_bold(bool bold) {
if (!v8_flags.log_colour) return ;
os() << "\033[" << (bold ? "1" : "0" ) << ";" << color() << "m" ;
}
std::ostream& os() { return os_; }
Zone* zone() { return zone_; }
private :
std::ostream& os_;
Zone* zone_;
int color_ = 0 ;
};
template <typename T>
class NodePrinterBase : public PrinterBase {
public :
NodePrinterBase(std::ostream& os, GraphLabeller<T>* labeller, Zone* zone,
char prefix)
: PrinterBase(os, zone), labeller_(labeller), prefix_(prefix) {}
NodePrinterBase(const PrinterBase& other, GraphLabeller<T>* labeller,
char prefix)
: PrinterBase(other), labeller_(labeller), prefix_(prefix) {}
GraphLabeller<T>* labeller() { return labeller_; }
const GraphLabeller<T>* labeller() const { return labeller_; }
void PrintNodeLabel(const T* node) {
if (!labeller_) return ;
int id = labeller_->NodeId(node);
DCHECK_NE(id, 0 );
set_bold(true );
os() << prefix_ << id;
set_bold(false );
}
void RegisterNode(const T* node) {
if (!labeller_) return ;
labeller_->RegisterNode(node);
}
protected :
GraphLabeller<T>* labeller_;
const char prefix_;
};
class V8_EXPORT_PRIVATE Diagnostics {
public :
Diagnostics(std::ostream& os, Zone* zone);
~Diagnostics();
std::ostream& os() const { return os_; }
Zone* zone() const { return zone_; }
bool has_graph_labeller() const { return !!graph_labeller_; }
GraphLabeller<Node>* graph_labeller() const {
DCHECK(has_graph_labeller());
return graph_labeller_.get();
}
void set_graph_labeller(std::unique_ptr<GraphLabeller<Node>> graph_labeller);
bool has_tree_labeller() const { return !!tree_labeller_; }
GraphLabeller<Tree>* tree_labeller() const {
DCHECK(has_tree_labeller());
return tree_labeller_.get();
}
void set_tree_labeller(std::unique_ptr<GraphLabeller<Tree>> tree_labeller);
bool has_graph_printer() const { return !!graph_printer_; }
GraphPrinter* graph_printer() const {
DCHECK(has_graph_printer());
return graph_printer_.get();
}
void set_graph_printer(std::unique_ptr<GraphPrinter> graph_printer);
bool has_ast_printer() const { return !!ast_printer_; }
NodePrinter<Tree>* ast_printer() const {
DCHECK(has_ast_printer());
return ast_printer_.get();
}
void set_ast_printer(std::unique_ptr<NodePrinter<Tree>> ast_printer);
TraceTreeScope* trace_tree_scope() { return trace_tree_scope_; }
void set_trace_tree_scope(TraceTreeScope* scope) {
trace_tree_scope_ = scope;
}
private :
std::unique_ptr<GraphLabeller<Node>> graph_labeller_;
std::unique_ptr<GraphLabeller<Tree>> tree_labeller_;
std::unique_ptr<GraphPrinter> graph_printer_;
std::unique_ptr<NodePrinter<Tree>> ast_printer_;
TraceTreeScope* trace_tree_scope_ = nullptr;
std::ostream& os_;
Zone* zone_;
};
} // namespace regexp
} // namespace internal
} // namespace v8
#endif // V8_ENABLE_REGEXP_DIAGNOSTICS
#endif // V8_REGEXP_REGEXP_PRINTER_H_
Messung V0.5 in Prozent C=98 H=100 G=98
[Dauer der Verarbeitung: 0.10 Sekunden, vorverarbeitet 2026-09-29]