Commit graph

47 commits

Author SHA1 Message Date
Venkat Subramaniam
f162b37b9c Changing data provider to accept dictionaries in testAssign
Currently, a lot of libcst node tests use data providers that use tuples
instead of dictionaries. This just makes the tests unreadable, so this
is one of several diffs aiming to solve this issue.
2019-07-22 20:04:37 -07:00
Venkat Subramaniam
9874534789 AssertTest fix
Changing all tests to accept kwargs instead of regular arguments.
2019-07-22 20:04:37 -07:00
Ray Zeng
0b0ffb8824 Fix batched vistor dependency resolution
Adds logic to gather metadata dependencies from `BatchableCSTVisitors`
when constructing a batched visitor.
2019-07-22 20:04:37 -07:00
Ray Zeng
36cfb512ea Refactor metadata runner
Refactors various metadata related classes to better reflect intended
usage of the API.

The metadata runner now deep clones the module and returns a copy
containing the metadata information. Metadata providers also return the
tree to enforce the idea that the tree is immutable (even though no
copying is actually done and providers write directly to the original
tree).
2019-07-22 20:04:37 -07:00
Venkat Subramaniam
e452bd3a55 Changing data provider to accept dictionaries in testAssert
Currently, a lot of libcst node tests use data providers that use tuples
instead of dictionaries. This just makes the tests unreadable, so this
is one of several diffs aiming to solve this issue.
2019-07-22 20:04:37 -07:00
Benjamin Woodruff
a6aee836b0 Fix parsing of ConcatenatedString with mixed f-strings and simple strings
Previously, while `f"abc" f"def"` and `"abc" "def"` would parse as a
ConcatenatedString, `f"" ""` wouldn't because it mixes f-strings and
simple strings.

This joins `atom_string` and `atom_fstring` into a single `atom_string`
rule, which has an added benefit of simplifying the code.
2019-07-22 20:04:37 -07:00
Ray Zeng
f1232d9190 Record syntactic position of more expressions
Update codegen and tests to cover list, list comprehension and generator
expressions. Also cleans up some extraneous position tracking code in
codegen.
2019-07-22 20:04:37 -07:00
Jennifer Taylor
3b3f52673a Rework 'pass' on removal behavior
Instead of generating Pass nodes on removal, allow empty IndentedBlock,
SimpleStatementLine and SimpleStatementSuite nodes. Have them insert a
'pass' token manually when they encounter having nothing inside of
them. This allows us to more easily figure out when we should keep a
node around, and means that we no longer construct new nodes with
surprising subnodes based on somewhat-related user input. It also
matches how we do MaybeSentinel support for the rest of Python's
syntactic sugar. As a bonus (well, the point of this diff actually), we
no longer add a pass statement every time we remove another statement,
only when we actually need to.
2019-07-22 20:04:37 -07:00
Benjamin Woodruff
656f61b810 Implement nodes and parser logic for Set and SetComp
This supports the syntax:

```
myset = {1, 2, 3}
```

and

```
myset = {i + 1 for i in range(3)}
```
2019-07-22 20:04:37 -07:00
Jennifer Taylor
f9f7a202f7 Remove Number
Remove Number wrapper node and go back to just having UnaryOperation.
2019-07-22 20:04:37 -07:00
Ray Zeng
4b5a6a969e Change entry point to metadata runner
Changes `CSTNode.visit()` to `CSTNode._visit_impl()` and uses `visit()`
as a public entry point to prevent users from running visitors with
metadata dependencies on nodes other than Modules.
2019-07-22 20:04:37 -07:00
Ray Zeng
7c51249ec8 Convert metadata computation to use batched visitors
Converts metadata providers to extend from either CSTVisitor or from
BatchableCSTVisitor and updates the runner to batch providers when
possible. There is a known issue in this diff where metadata may be
computed multiple times on the same pass which is addressed in
a later diff. There should be no correctness issues in this diff as
metadata computation should have no side effects.
2019-07-22 20:04:37 -07:00
Ray Zeng
9e622ac74e Define batchable visitors
Defines a batchable visitor API for libcst.
2019-07-22 20:04:37 -07:00
Ray Zeng
64e7ba4e9a Define mutating/non-mutating visitors for the CST
Defines two new visitor base classes for libcst:

- `CSTTransformer` provides an visitor that can be used to create a new
  tree. This is a drop in replacement for the old `CSTVisitor` in
  `_base_visitor.py`.
- `CSTVisitor` provides a visitor that does not allow the user to mutate
  the tree by restricting access to the updated_node in `on_leave`.
2019-07-22 20:04:37 -07:00
Benjamin Woodruff
3e941cbc89 Fix some holes/bugs around validation of cst.Comparision
I noticed that this had some bugs when I was reading through it. Let's
fix it!

- It's safe to use a Comparison with a word operator as long as it's
  first or last child is safe. Previously, this would incorrectly fail
  validation on an expression like `a if(b) < (c)else d`
- We have to validate every comparator against it's next operator's
  leading whitespace, not just the first comparator (`self.left`).
2019-07-22 20:04:37 -07:00
Benjamin Woodruff
435f36a097 Convert checks for an empty SimpleWhitespace to use .empty
It's more readable and compatible with parenthesizable whitespace.
2019-07-22 20:04:37 -07:00
Benjamin Woodruff
11349acdea Fix parsing of nested parenthesis around Number nodes
The parser would lose track of nested parenthesis, because it was
reading the wrong lpar/rpar value.

Thanks for reporting this, @rayjzeng!
2019-07-22 20:04:37 -07:00
Benjamin Woodruff
a8ca94691e Add parser support for ListComp and GeneratorExp
Using the nodes I defined previously, this adds support for parsing

```
(a for b in c if d)
```

and

```
[a for b in c if d]
```
2019-07-22 20:04:37 -07:00
Benjamin Woodruff
2295d062fc Add node classes for ListComp
This adds support for

```
[a for b in c if d]
```

I added support for GeneratorExp in a previous commit, so this is a
simple extension of that.
2019-07-22 20:04:37 -07:00
Benjamin Woodruff
6557122db6 Add node classes for GeneratorExp
This adds support for

```
(a for b in c if d)
```

As well as various nested versions of the expression.

This does not include nodes for other comprehension types, they'll come
in later diffs.
2019-07-22 20:04:37 -07:00
Ray Zeng
dbbe3d1927 Add metadata dependencies to CSTVisitor and add metadata runner
Add metadata access and dependency logic in `CSTVisitor` and
`Module.visit` to generate all metadata dependencies before performing a
visit pass over a tree and validate access to metadata.
2019-07-22 19:53:49 -07:00
Benjamin Woodruff
a293787f8c Add node class and parser implementation for List
This is based heavily on the implementation of Tuple, and was pretty
straightforward as a result.
2019-07-22 19:53:49 -07:00
Benjamin Woodruff
edd8496f19 Add parser logic for cst.Tuple
There's a lot of different places tuples can get used, and
`Element`/`StarredElement` require some tricky handling of commas, so
this took a while.

Hopefully, this work should make `List` easy to implement.
`dictsetmaker` and comprehensions are still going to be a pain though...

Along the way, I found out that `Element`/`StarredElement`'s
`whitespace_after` wasn't needed, because the tuple's parenthesis (if
they exist) or parent node would be a better owner anyways, so that's
removed in this commit.
2019-07-22 19:53:49 -07:00
Ray Zeng
39e4e433d8 Refactor CodePosition
Renames `CodePosition` to `CodeRange` and stores start and end position
as a `CodePosition` dataclass to avoid the ambiguity of using tuples.
2019-07-22 19:53:49 -07:00
Ray Zeng
d0ecb018e1 Port line and column numbers to metadata framework
Refactors codegen to write position information to the `__metadata__`
fields in nodes keyed by `BasicPositionProvider` and
`SyntacticPositionProvider` as defined in position_metadata.py.

This commit also updates `deep_equals` to ignore dataclass fields that
are marked `compare=False` to avoid comparing metadata when doing
equality checks.
2019-07-22 19:53:49 -07:00
Benjamin Woodruff
8fba418f2c Add runtime type validation support
This ports `CSTNode.validate_types_shallow` and
`CSTNode.validate_types_deep`, as well as `libcst._type_enforce` to the
open-source release.

These are useful if someone wants to use LibCST without a static type
checker.

These weren't originally included because `libcst._type_enforce` wasn't
3.7 compatible.
2019-07-22 19:53:49 -07:00
Ray Zeng
a19fa41780 Define metadata base class and provider
Define base classes for metadata API in libcst/metadata and adds the
`__metadata__` field to `CSTNode` and `get_metadata()` method to
`CSTVisitor`.
2019-07-22 19:53:49 -07:00
Ray Zeng
8984ce45b2 Semantic position of expression nodes
Updates codegen to also track semantic position of expression nodes
(found in _expression.py).
2019-07-22 19:53:49 -07:00
Benjamin Woodruff
670ece1e91 pyre-strict libcst/__init__.py and libcst/tool.py 2019-07-22 19:53:49 -07:00
Ray Zeng
f2f2510297 Define a context manager that can be used to track "semantic" start and end positions for nodes
Created a context manager `record_semantic_position()` in `CodegenState`
to be used for tracking semantic positions of nodes in the CodegenState.
2019-07-22 19:53:49 -07:00
Ray Zeng
d3544824fc Wrap _codegen methods in a helper function to track where nodes start and end.
Converts `_codegen` methods into `_codegen_impl` to wrap implementations
to calls to update the position of each node in the `CodegenState`. The
stored position is the syntactic position of a node (that includes any
whitespace attached to that particular node).

Also updates implementation of tool and `CSTNode.__repr__` to not print
fields of `CSTNode` objects prefixed with "_".
2019-07-22 19:53:49 -07:00
Ray Zeng
65cea1ce21 Rename indent to indent_tokens in CodegenState
Follow-up to previous commits.
2019-07-22 19:53:49 -07:00
Ray Zeng
85e2d7171e Convert _codegen methods in nodes to use the new CodegenState methods
Converts all nodes to use new CodegenState methods as defined in the
previous commit.

Ran codemods:

    codemod -d libcst 'state.tokens.append\((.*)\)' 'state.add_token(\1)'
    codemod -d libcst 'state.tokens.extend\(state.indent\)' 'state.add_indent_tokens()'
    codemod -d libcst 'state.indent.pop()' 'state.decrease_indent()'
    codemod -d libcst 'state.indent.append\((.*)\)' 'state.increase_indent(\1)'

Where `codemod` refers to https://github.com/facebook/codemod
2019-07-22 19:53:49 -07:00
Ray Zeng
d6bda7e69a Add hooks to CodegenState for line/column tracking
Adds methods to CodegenState for common indentation change operations to
allow for tracking of line and column numbers.
2019-07-22 19:53:49 -07:00
Jennifer Taylor
a0bfc90339 Make ParserSyntaxError picklable 2019-07-22 19:53:49 -07:00
Benjamin Woodruff
76b5ac0de2 Add config files to make tools easier to use
- `pyproject.toml` is supported by isort and black, and lets us call
  those tools without supplying a ton of arguments.
- `.editorconfig` is supported by a wide range of editors, and can
  automatically set per-project configuration.
- `.pyre_configuration` is used by pyre.
- I added test discovery to the `setup.py` file, which required some
  extra `__init__.py` files.
2019-07-22 19:53:49 -07:00
Benjamin Woodruff
7c069518a5 Make libcst/tests/test_tool.py pyre-strict 2019-07-22 19:53:49 -07:00
Benjamin Woodruff
31c0ee65a2 Export maybe and removal sentinels from __init__
Otherwise, these aren't exposed publicly anywhere.

This was @DragonMinded's change, I'm just importing it to github.
2019-07-22 19:53:49 -07:00
Benjamin Woodruff
1dab051ddb Remove Starred element type
We decided to merge this functionality into StarredElement.
2019-07-22 19:53:49 -07:00
Benjamin Woodruff
d4551da477 Improve setup.py compatibility
- Add `libcst/__init__.py` back which I accidentally deleted in another
  commit.
- Add `*.egg-info/` to the gitignore, because `libcst.egg-info` is it's
  created by pip/setuptools when locally installing libcst, and it's
  annoying.
- Changed the version number from `0.1.dev` to `0.1.dev0`, since pip was
  warning that it was normalizing the version number from the former to
  the later.
- Add a `python_requires` field, since we know that libcst only works on
  3.6+.
- Add an `install_requires`. Pip uses this to find dependencies, and
  ignores `requirements.txt` (since `requirements.txt` is really only
  intended to be a freeze file).
- Add the dataclasses backport as a dependency for Python 3.6. I
  validated that installing and using libcst works in both 3.6 and 3.7.

**Test Plan:**

```
$ python3 -m venv libcst-install-test  # my system python is 3.7

$ libcst-install-test/bin/pip install --upgrade pip ipython
Cache entry deserialization failed, entry ignored
Collecting pip
  Using cached
  be401c0032/pip-19.1.1-py2.py3-none-any.whl
Collecting ipython
...  # lots of output

$ ~/libcst-install-test/bin/pip install ~/libcst/
Processing ./libcst
Requirement already satisfied: parso in
./libcst-install-test/lib/python3.7/site-packages (from
libcst==0.1.dev0) (0.4.0)
Collecting typing_extensions (from libcst==0.1.dev0)
  Using cached
  c66e553258/typing_extensions-3.7.2-py3-none-any.whl
Installing collected packages: typing-extensions, libcst
  Running setup.py install for libcst ... done
  Successfully installed libcst-0.1.dev0 typing-extensions-3.7.2

$ ~/libcst-install-test/bin/ipython
Python 3.7.3 (default, Apr  3 2019, 05:39:12)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.5.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from libcst import parser

In [2]: parser.parse_expression("None")
Out[2]:
Name(
    value='None',
    lpar=[],
    rpar=[],
)

In [3]:
```

I then repeated the same with a copy of CPython 3.6 that I built from
source.
2019-06-06 15:37:27 -07:00
Benjamin Woodruff
ca15eb2685 Add nodedefs (no parsing yet) needed for Tuple
This ended up being pretty complicated, so the parser stuff will come in
another diff.

Hopefully this should set up up nicely for dicts, sets, and lists too.
2019-06-05 15:23:22 -07:00
Jennifer Taylor
21ace9df33 Fix comment ownership around IndentedBlock 2019-06-05 14:31:04 -07:00
Jennifer Taylor
bb72c70a3b Hand-roll print instead of using implicit repr, allowing us to filter
most irrelevant node attributes out.
2019-06-05 14:25:29 -07:00
Jennifer Taylor
3888c31835 Use .empty property on BaseParenthesizableWhitespace 2019-06-03 15:44:10 -07:00
Jennifer Taylor
e5938df16a Better serialization for MaybeSentinel 2019-06-03 15:43:55 -07:00
Jennifer Taylor
8ff42de3c5 Fix issue with @add_slots and py3.7 2019-06-03 15:43:28 -07:00
Jennifer Taylor
0719faa198 Initial export of LibCST to github. 2019-05-31 14:16:53 -07:00