1
1
mirror of https://github.com/github/semantic.git synced 2024-12-20 21:31:48 +03:00
semantic/test/fixtures/python/matching/docstrings_nested.py

11 lines
144 B
Python
Raw Normal View History

Give Control.Matching API better ergonomics. Given that @tclem and I have found the matcher API frustrating, I've taken a stab at improving its ergonomics, and I've found some success in separating composition of matchers from predicate-based narrowing thereof. The biggest change here is the elimination of the old `match` combinator, which proved to be clumsy in that it complected narrowing and composition. Top-down matching combinators are now written with the `need` combinator and the `>>>` combinator, which is more readable and more versatile. Here's a matcher that accepts functions with Python docstrings: ```haskell docstringMatcher :: ( Decl.Function :< fs , [] :< fs , Lit.TextElement :< fs , term ~ Term (Sum fs) ann ) => Matcher term term docstringMatcher = target <* (need Decl.functionBody >>> narrow @[] >>> mhead >>> narrow @Lit.TextElement >>> ensure Lit.isTripleQuoted)) ``` Pretty readable, right? Each step of the tree regular expression - choosing function bodies, ensuring said bodies are lists, examining the first element, and choosing only TextElements containing triple-quoted strings - is made implicit. The old way would have looked something like this: ```haskell docstringMatcher = target <* match Decl.functionBody $ narrow $ matchM listToMaybe $ target <* ensure Lit.isTripleQuoted ``` which is a good deal more disorganized and less flexible in the quite-common case of applying functions during a matching pass. Separating the act of composition from function application is a big win here. Further comments are inline.
2018-11-03 02:25:29 +03:00
def foo():
"""here's a docstring"""
pass
def bar():
"""and another"""
def dang():
"""and a nested one"""
pass