-
Notifications
You must be signed in to change notification settings - Fork 49
Untangle _RegexParser
from RegexBuilder
#299
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Untangle _RegexParser
from RegexBuilder
#299
Conversation
@swift-ci Please test |
let amount = amount._patternBase | ||
let kind = kind._patternBase | ||
let amount = amount.ast._patternBase | ||
let kind = (kind.ast ?? .eager)._patternBase |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this depend on options?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does in two ways:
- If this quantifier was written in the DSL, it can have a default value that gets drawn from the current options
- If this quantifier was written in syntax,
.eager
and.reluctant
can get flipped, depending on the options (the AST is just the syntax)
We defer both of those effects until byte code generation — we'd need to maintain option state in a similar way here.
case .default: | ||
return ".eager" | ||
} | ||
(ast ?? .eager)._patternBase |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this depend on options?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, see above.
@@ -134,6 +142,12 @@ extension DSLTree { | |||
self.isInverted = isInverted | |||
} | |||
|
|||
public static func generalCategory(_ category: Unicode.GeneralCategory) -> Self { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this API? What proposal is it in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's in the Unicode for String Processing proposal — we should provide more ways of making character classes over Unicode properties.
extension DSLTree { | ||
/// Presents a wrapped version of `DSLTree.Node` that can provide an internal | ||
/// `_TreeNode` conformance. | ||
struct _Tree: _TreeNode { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this used for? Why isn't this DSLTree
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is more or less a compiler limitation workaround. _TreeNode
is a protocol defined in _RegexParser
, and since DSLTree
is public (as SPI), its conformance to _TreeNode
is also public. However, _RegexParser
is imported as implementation only, so its symbols can't/shouldn't be included in the public interface of _StringProcessing
. So this type basically provides that DSLTree: _TreeNode
conformance by composition, and since it's internal, it doesn't cause the issue with exported implementation-only symbols.
} | ||
|
||
@_spi(RegexBuilder) | ||
public enum _AST { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is the AST relevant at all to DSLTree? Is it because we don't have or want to have versions of these enums?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are the things that we hadn't duplicated into the DSLTree layer, so we were just storing AST symbols in DSLTree nodes. My goal with this change was just to wrap those, not necessarily replace them wholesale. At some point it would be great to have better separation between the two modules.
@@ -294,7 +298,17 @@ extension _CharacterClassModel: CustomStringConvertible { | |||
} | |||
|
|||
extension _CharacterClassModel { | |||
public func makeAST() -> AST.Node? { | |||
public func makeDSLTreeCharacterClass() -> DSLTree.CustomCharacterClass? { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this public? Should it be SPI?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_CharacterClassModel
is SPI, so this is as well — I should probably at least add a comment so it isn't jarring to see this in an extension.
This makes the changes necessary for _RegexParser to be imported as an implementation-only dependency. The change provides _StringProcessing wrappers for all `AST` types that need to be publicly visible via SPI, and a DSLTree.Node wrapper for internal conformance to _TreeNode. Co-authored-by: Richard Wei <[email protected]>
This makes the changes necessary for _RegexParser to be imported as an implementation-only dependency. The change provides _StringProcessing wrappers for all `AST` types that need to be publicly visible via SPI, and a DSLTree.Node wrapper for internal conformance to _TreeNode. Co-authored-by: Richard Wei <[email protected]>
With the change to make
_StringProcessing
import_RegexParser
as implementation only, noAST
types can be used by theRegexBuilder
module. This adds wrapper types in_StringProcessing
to hide those types, particularly as associated values inDSLTree.Node
. It also provides a wrapper type forDSLTree.Node
that conforms to_TreeNode
for the purpose of building up the tree's capture structure. (It sure would be nice if implementation-only-imported protocols were just treated as internal.)