@@ -113,9 +113,7 @@ class RegExpTerm extends Locatable, @regexpterm {
113113 /**
114114 * Holds if this is the root term of a regular expression.
115115 */
116- predicate isRootTerm ( ) {
117- not getParent ( ) instanceof RegExpTerm
118- }
116+ predicate isRootTerm ( ) { not getParent ( ) instanceof RegExpTerm }
119117
120118 /**
121119 * Gets the outermost term of this regular expression.
@@ -130,19 +128,15 @@ class RegExpTerm extends Locatable, @regexpterm {
130128 /**
131129 * Holds if this term occurs as part of a regular expression literal.
132130 */
133- predicate isPartOfRegExpLiteral ( ) {
134- exists ( getLiteral ( ) )
135- }
131+ predicate isPartOfRegExpLiteral ( ) { exists ( getLiteral ( ) ) }
136132
137133 /**
138134 * Holds if this term occurs as part of a string literal.
139135 *
140136 * This predicate holds regardless of whether the string literal is actually
141137 * used as a regular expression. See `isUsedAsRegExp`.
142138 */
143- predicate isPartOfStringLiteral ( ) {
144- getRootTerm ( ) .getParent ( ) instanceof StringLiteral
145- }
139+ predicate isPartOfStringLiteral ( ) { getRootTerm ( ) .getParent ( ) instanceof StringLiteral }
146140
147141 /**
148142 * Holds if this term is part of a regular expression literal, or a string literal
@@ -344,8 +338,7 @@ class RegExpAnchor extends RegExpTerm, @regexp_anchor {
344338 * ^
345339 * ```
346340 */
347- class RegExpCaret extends RegExpAnchor , @regexp_caret {
348- }
341+ class RegExpCaret extends RegExpAnchor , @regexp_caret { }
349342
350343/**
351344 * A dollar assertion `$` matching the end of a line.
@@ -356,8 +349,7 @@ class RegExpCaret extends RegExpAnchor, @regexp_caret {
356349 * $
357350 * ```
358351 */
359- class RegExpDollar extends RegExpAnchor , @regexp_dollar {
360- }
352+ class RegExpDollar extends RegExpAnchor , @regexp_dollar { }
361353
362354/**
363355 * A word boundary assertion.
@@ -940,3 +932,40 @@ private class StringRegExpPatternSource extends RegExpPatternSource {
940932
941933 override RegExpTerm getRegExpTerm ( ) { result = asExpr ( ) .( StringLiteral ) .asRegExp ( ) }
942934}
935+
936+ module RegExp {
937+ /** Gets the string `"?"` used to represent a regular expression whose flags are unknown. */
938+ string unknownFlag ( ) { result = "?" }
939+
940+ /** Holds `flags` includes the `m` flag. */
941+ bindingset [ flags]
942+ predicate isMultiline ( string flags ) { flags .matches ( "%m%" ) }
943+
944+ /** Holds `flags` includes the `g` flag. */
945+ bindingset [ flags]
946+ predicate isGlobal ( string flags ) { flags .matches ( "%g%" ) }
947+
948+ /** Holds `flags` includes the `i` flag. */
949+ bindingset [ flags]
950+ predicate isIgnoreCase ( string flags ) { flags .matches ( "%i%" ) }
951+
952+ /** Holds `flags` includes the `s` flag. */
953+ bindingset [ flags]
954+ predicate isDotAll ( string flags ) { flags .matches ( "%s%" ) }
955+
956+ /** Holds `flags` includes the `m` flag or is the unknown flag `?`. */
957+ bindingset [ flags]
958+ predicate maybeMultiline ( string flags ) { flags = unknownFlag ( ) or isMultiline ( flags ) }
959+
960+ /** Holds `flags` includes the `g` flag or is the unknown flag `?`. */
961+ bindingset [ flags]
962+ predicate maybeGlobal ( string flags ) { flags = unknownFlag ( ) or isGlobal ( flags ) }
963+
964+ /** Holds `flags` includes the `i` flag or is the unknown flag `?`. */
965+ bindingset [ flags]
966+ predicate maybeIgnoreCase ( string flags ) { flags = unknownFlag ( ) or isIgnoreCase ( flags ) }
967+
968+ /** Holds `flags` includes the `s` flag or is the unknown flag `?`. */
969+ bindingset [ flags]
970+ predicate maybeDotAll ( string flags ) { flags = unknownFlag ( ) or isDotAll ( flags ) }
971+ }
0 commit comments