RegExpObject.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /*
  2. * Copyright (c) 2020, Matthew Olsson <mattco@serenityos.org>
  3. * Copyright (c) 2024, Andreas Kling <andreas@ladybird.org>
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #pragma once
  8. #include <AK/EnumBits.h>
  9. #include <AK/Optional.h>
  10. #include <AK/Result.h>
  11. #include <LibJS/Runtime/Object.h>
  12. #include <LibRegex/Regex.h>
  13. namespace JS {
  14. ThrowCompletionOr<GC::Ref<RegExpObject>> regexp_create(VM&, Value pattern, Value flags);
  15. ThrowCompletionOr<GC::Ref<RegExpObject>> regexp_alloc(VM&, FunctionObject& new_target);
  16. Result<regex::RegexOptions<ECMAScriptFlags>, ByteString> regex_flags_from_string(StringView flags);
  17. struct ParseRegexPatternError {
  18. ByteString error;
  19. };
  20. ErrorOr<ByteString, ParseRegexPatternError> parse_regex_pattern(StringView pattern, bool unicode, bool unicode_sets);
  21. ThrowCompletionOr<ByteString> parse_regex_pattern(VM& vm, StringView pattern, bool unicode, bool unicode_sets);
  22. class RegExpObject : public Object {
  23. JS_OBJECT(RegExpObject, Object);
  24. GC_DECLARE_ALLOCATOR(RegExpObject);
  25. public:
  26. // JS regexps are all 'global' by default as per our definition, but the "global" flag enables "stateful".
  27. // FIXME: Enable 'BrowserExtended' only if in a browser context.
  28. static constexpr regex::RegexOptions<ECMAScriptFlags> default_flags {
  29. (regex::ECMAScriptFlags)regex::AllFlags::SingleMatch
  30. | (regex::ECMAScriptFlags)regex::AllFlags::Global
  31. | (regex::ECMAScriptFlags)regex::AllFlags::SkipTrimEmptyMatches
  32. | regex::ECMAScriptFlags::BrowserExtended
  33. };
  34. enum class Flags {
  35. HasIndices = 1 << 0,
  36. Global = 1 << 1,
  37. IgnoreCase = 1 << 2,
  38. Multiline = 1 << 3,
  39. DotAll = 1 << 4,
  40. UnicodeSets = 1 << 5,
  41. Unicode = 1 << 6,
  42. Sticky = 1 << 7,
  43. };
  44. static GC::Ref<RegExpObject> create(Realm&);
  45. static GC::Ref<RegExpObject> create(Realm&, Regex<ECMA262> regex, ByteString pattern, ByteString flags);
  46. ThrowCompletionOr<GC::Ref<RegExpObject>> regexp_initialize(VM&, Value pattern, Value flags);
  47. ByteString escape_regexp_pattern() const;
  48. virtual void initialize(Realm&) override;
  49. virtual ~RegExpObject() override = default;
  50. ByteString const& pattern() const { return m_pattern; }
  51. ByteString const& flags() const { return m_flags; }
  52. Flags flag_bits() const { return m_flag_bits; }
  53. Regex<ECMA262> const& regex() { return *m_regex; }
  54. Regex<ECMA262> const& regex() const { return *m_regex; }
  55. Realm& realm() { return *m_realm; }
  56. Realm const& realm() const { return *m_realm; }
  57. bool legacy_features_enabled() const { return m_legacy_features_enabled; }
  58. void set_legacy_features_enabled(bool legacy_features_enabled) { m_legacy_features_enabled = legacy_features_enabled; }
  59. void set_realm(Realm& realm) { m_realm = &realm; }
  60. private:
  61. RegExpObject(Object& prototype);
  62. RegExpObject(Regex<ECMA262> regex, ByteString pattern, ByteString flags, Object& prototype);
  63. virtual void visit_edges(Visitor&) override;
  64. ByteString m_pattern;
  65. ByteString m_flags;
  66. Flags m_flag_bits { 0 };
  67. bool m_legacy_features_enabled { false }; // [[LegacyFeaturesEnabled]]
  68. // Note: This is initialized in RegExpAlloc, but will be non-null afterwards
  69. GC::Ptr<Realm> m_realm; // [[Realm]]
  70. Optional<Regex<ECMA262>> m_regex;
  71. };
  72. AK_ENUM_BITWISE_OPERATORS(RegExpObject::Flags);
  73. }