Ví dụ DSL Python

Chúng tôi đã bắt đầu phát triển Ngôn ngữ dành riêng cho miền [DSL] mô hình có thể được sử dụng để giải quyết nhiều vấn đề tương tự như trình tạo mô hình, trong khi vẫn giữ thông tin mô hình trong tệp

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
name.matches["foo.*"]
],
model = ...
]
8. DSL nhằm mục đích cung cấp một cách nhỏ gọn để tạo các mô hình cho tất cả các mã phù hợp với một truy vấn nhất định. Điều này cho phép người dùng tránh viết hàng trăm hoặc hàng nghìn mô hình

Khái niệm cơ bản

Hình thức cơ bản nhất để truy vấn DSL của Pysa là tạo các mô hình dựa trên tên hàm. Để làm như vậy, hãy thêm

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
name.matches["foo.*"]
],
model = ...
]
9 vào tệp
ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
name.matches["foo.*"]
],
model = ...
]
8 của bạn

ModelQuery[
# Indicates the name of the query
name = "get_foo_sources",
# Indicates that this query is looking for functions
find = "functions",
# Indicates those functions should be called 'foo'
where = [name.matches["foo"]],
# Indicates that matched function should be modeled as returning 'Test' taint
model = [
Returns[TaintSource[Test]],
],
# Indicates that the generated models should include the 'foo' and 'foo2' functions
expected_models = [
"def file.foo[] -> TaintSource[Test]: ...",
"def file.foo2[] -> TaintSource[Test]: ..."
],
# Indicates that the generated models should not include the 'bar' function
unexpected_models = [
"def file.bar[] -> TaintSource[Test]: ..."
]
]

Những điều cần lưu ý trong ví dụ này

  1. Mệnh đề
    ModelQuery[
    name = "get_foo",
    find = ...,
    where = [
    name.equals["foo"]
    ],
    model = ...
    ]
    1 là tên truy vấn của bạn
  2. Mệnh đề
    ModelQuery[
    name = "get_foo",
    find = ...,
    where = [
    name.equals["foo"]
    ],
    model = ...
    ]
    2 cho phép bạn chọn xem bạn muốn mô hình hóa các hàm, phương thức hay thuộc tính
  3. Mệnh đề
    ModelQuery[
    name = "get_foo",
    find = ...,
    where = [
    name.equals["foo"]
    ],
    model = ...
    ]
    3 là cách bạn tinh chỉnh tiêu chí của mình khi mô hình sẽ được tạo - trong ví dụ này, chúng tôi đang lọc các hàm có tên chứa
    ModelQuery[
    name = "get_foo",
    find = ...,
    where = [
    name.equals["foo"]
    ],
    model = ...
    ]
    4
  4. Mệnh đề
    ModelQuery[
    name = "get_foo",
    find = ...,
    where = [
    name.equals["foo"]
    ],
    model = ...
    ]
    5 là danh sách các mô hình để tạo. Ở đây, cú pháp có nghĩa là các hàm khớp với mệnh đề where sẽ được mô hình hóa khi trả về
    ModelQuery[
    name = "get_foo",
    find = ...,
    where = [
    name.equals["foo"]
    ],
    model = ...
    ]
    6
  5. Các mệnh đề
    ModelQuery[
    name = "get_foo",
    find = ...,
    where = [
    name.equals["foo"]
    ],
    model = ...
    ]
    7 và
    ModelQuery[
    name = "get_foo",
    find = ...,
    where = [
    name.equals["foo"]
    ],
    model = ...
    ]
    8 là tùy chọn và cho phép bạn chỉ định các mô hình nên hoặc không nên được tạo bởi truy vấn của bạn

Khi gọi Pysa, nếu bạn thêm cờ

ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
9 vào lệnh gọi của mình, các mô hình đã tạo, được sắp xếp theo ModelQuery tương ứng đã tạo ra chúng, sẽ được ghi vào một tệp ở định dạng JSON

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`

Sau đó, bạn có thể xem tệp này để xem các mô hình đã tạo

mệnh đề tên

Mệnh đề

ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
1 mô tả ý nghĩa của truy vấn để tìm. Thông thường, nó tuân theo định dạng
ModelQuery[
name = "get_return_HttpRequest_sources",
find = "functions",
where = [
return_annotation.equals["django.http.HttpRequest"],
],
model = Returns[TaintSource[UserControlled, Via[http_request]]]
]
1 + [câu truy vấn phù hợp với điều gì trong mệnh đề
ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
3] + [
ModelQuery[
name = "get_return_HttpRequest_sources",
find = "functions",
where = [
return_annotation.equals["django.http.HttpRequest"],
],
model = Returns[TaintSource[UserControlled, Via[http_request]]]
]
3,
ModelQuery[
name = "get_return_HttpRequest_sources",
find = "functions",
where = [
return_annotation.equals["django.http.HttpRequest"],
],
model = Returns[TaintSource[UserControlled, Via[http_request]]]
]
4 và/hoặc
ModelQuery[
name = "get_return_HttpRequest_sources",
find = "functions",
where = [
return_annotation.equals["django.http.HttpRequest"],
],
model = Returns[TaintSource[UserControlled, Via[http_request]]]
]
5]. Mệnh đề này phải là duy nhất cho mọi ModelQuery trong một tệp

Tìm mệnh đề

Mệnh đề

ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
2 chỉ định những thực thể cần lập mô hình và hiện hỗ trợ
ModelQuery[
name = "get_return_HttpRequest_sources",
find = "functions",
where = [
return_annotation.equals["django.http.HttpRequest"],
],
model = Returns[TaintSource[UserControlled, Via[http_request]]]
]
7,
ModelQuery[
name = "get_return_HttpRequest_sources",
find = "functions",
where = [
return_annotation.equals["django.http.HttpRequest"],
],
model = Returns[TaintSource[UserControlled, Via[http_request]]]
]
8,
ModelQuery[
name = "get_return_HttpRequest_sources",
find = "functions",
where = [
return_annotation.equals["django.http.HttpRequest"],
],
model = Returns[TaintSource[UserControlled, Via[http_request]]]
]
9 và
ModelQuery[
name = "get_return_Request_sources",
find = "methods",
where = [
return_annotation.matches[".*Request"],
],
model = Returns[TaintSource[UserControlled, Via[http_request]]]
]
0.
ModelQuery[
name = "get_return_HttpRequest_sources",
find = "functions",
where = [
return_annotation.equals["django.http.HttpRequest"],
],
model = Returns[TaintSource[UserControlled, Via[http_request]]]
]
7 cho biết rằng bạn đang truy vấn các hàm miễn phí,
ModelQuery[
name = "get_return_HttpRequest_sources",
find = "functions",
where = [
return_annotation.equals["django.http.HttpRequest"],
],
model = Returns[TaintSource[UserControlled, Via[http_request]]]
]
8 cho biết rằng bạn chỉ đang truy vấn các phương thức của lớp,
ModelQuery[
name = "get_return_HttpRequest_sources",
find = "functions",
where = [
return_annotation.equals["django.http.HttpRequest"],
],
model = Returns[TaintSource[UserControlled, Via[http_request]]]
]
9 cho biết rằng bạn đang truy vấn các thuộc tính trên các lớp và
ModelQuery[
name = "get_return_Request_sources",
find = "methods",
where = [
return_annotation.matches[".*Request"],
],
model = Returns[TaintSource[UserControlled, Via[http_request]]]
]
0 cho biết rằng bạn đang truy vấn các tên có sẵn trong phạm vi toàn cầu

Lưu ý rằng

ModelQuery[
name = "get_return_HttpRequest_sources",
find = "functions",
where = [
return_annotation.equals["django.http.HttpRequest"],
],
model = Returns[TaintSource[UserControlled, Via[http_request]]]
]
9 cũng bao gồm các thuộc tính do hàm tạo khởi tạo, chẳng hạn như
ModelQuery[
name = "get_return_Request_sources",
find = "methods",
where = [
return_annotation.matches[".*Request"],
],
model = Returns[TaintSource[UserControlled, Via[http_request]]]
]
6 trong trường hợp sau

class C:
x = ...

def __init__[self]:
self.y = ...

Lưu ý rằng

ModelQuery[
name = "get_return_Request_sources",
find = "methods",
where = [
return_annotation.matches[".*Request"],
],
model = Returns[TaintSource[UserControlled, Via[http_request]]]
]
0 hiện không suy ra chú thích loại của giá trị của chúng, vì vậy việc truy vấn sẽ hiệu quả hơn khi chúng được chú thích đúng cách

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int

mệnh đề ở đâu

ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
3 mệnh đề là một danh sách các vị từ, tất cả các vị từ này phải khớp với một thực thể được mô hình hóa. Lưu ý rằng một số vị ngữ chỉ tương thích với các loại mệnh đề tìm kiếm cụ thể

ModelQuery[
name = "get_return_Request_sources",
find = "methods",
where = [
return_annotation.matches[".*Request"],
],
model = Returns[TaintSource[UserControlled, Via[http_request]]]
]
9

Vị từ truy vấn cơ bản nhất là đối sánh tên - tên bạn đang tìm kiếm được biên dịch dưới dạng biểu thức chính quy và tên đủ điều kiện của thực thể được so sánh với tên đó. Tên đủ điều kiện bao gồm mô-đun và lớp - ví dụ: đối với phương pháp

ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
4 trong lớp
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
01 là một phần của mô-đun
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
02, tên đủ điều kiện là
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
03

Thí dụ

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
fully_qualified_name.matches["foo.*"]
],
model = ...
]

thận trọng

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
04 thực hiện khớp một phần. Chẳng hạn,
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
05 sẽ khớp với một hàm có tên là
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
06. Để thực hiện một trận đấu đầy đủ, hãy sử dụng
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
07 và
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
08. Ví dụ.
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
09

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
10

Mệnh đề này sẽ khớp khi tên đủ điều kiện của thực thể hoàn toàn giống với chuỗi đã chỉ định

Thí dụ

ModelQuery[
name = "get_bar_C_foo",
find = ...,
where = [
fully_qualified_name.equals["bar.C.foo"]
],
model = ...
]

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
11

Mệnh đề

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
11 tương tự như mệnh đề
ModelQuery[
name = "get_return_Request_sources",
find = "methods",
where = [
return_annotation.matches[".*Request"],
],
model = Returns[TaintSource[UserControlled, Via[http_request]]]
]
9, nhưng khớp với tên thực của thực thể, không bao gồm tên mô-đun và tên lớp

Thí dụ

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
name.matches["foo.*"]
],
model = ...
]

thận trọng

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
04 thực hiện khớp một phần. Chẳng hạn,
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
05 sẽ khớp với một hàm có tên là
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
16. Để thực hiện một trận đấu đầy đủ, hãy sử dụng
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
07 và
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
08. Ví dụ.
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
19

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
20

Mệnh đề

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
20 tương tự như mệnh đề
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
10, nhưng khớp với tên thực của thực thể, ngoại trừ tên mô-đun và tên lớp

ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
23 mệnh đề

Các truy vấn mô hình cho phép truy vấn dựa trên chú thích trả về của một hàm có thể gọi được. Lưu ý rằng mệnh đề

ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
3 này không hoạt động khi mệnh đề
ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
2 chỉ định
ModelQuery[
name = "get_return_HttpRequest_sources",
find = "functions",
where = [
return_annotation.equals["django.http.HttpRequest"],
],
model = Returns[TaintSource[UserControlled, Via[http_request]]]
]
9

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
27

Mệnh đề sẽ khớp khi tên đủ điều kiện của loại trả về có thể gọi được khớp chính xác với giá trị đã chỉ định

ModelQuery[
name = "get_return_HttpRequest_sources",
find = "functions",
where = [
return_annotation.equals["django.http.HttpRequest"],
],
model = Returns[TaintSource[UserControlled, Via[http_request]]]
]

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
28

Điều này tương tự như mệnh đề trước, nhưng sẽ khớp khi tên đủ điều kiện của loại trả về có thể gọi được khớp với mẫu đã chỉ định

ModelQuery[
name = "get_return_Request_sources",
find = "methods",
where = [
return_annotation.matches[".*Request"],
],
model = Returns[TaintSource[UserControlled, Via[http_request]]]
]

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
29

Điều này sẽ khớp khi loại trả về có thể gọi được chú thích bằng. Đây là một loại được sử dụng để trang trí các loại hiện có với siêu dữ liệu theo ngữ cảnh cụ thể, e. g

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
0

Thí dụ

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
1

Truy vấn này sẽ phù hợp với các chức năng như truy vấn được hiển thị ở trên

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
31 mệnh đề

Các truy vấn mô hình cho phép truy vấn dựa trên chú thích loại của một

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
32. Lưu ý rằng điều này tương tự như các mệnh đề được hiển thị trước đây. Xem thêm.
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
34 mệnh đề mẫu

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
36

Mệnh đề sẽ khớp khi tên đủ điều kiện của loại được chú thích rõ ràng của toàn cầu khớp chính xác với giá trị đã chỉ định

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
2

Ví dụ: truy vấn trên khi chạy trên đoạn mã sau

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
3

sẽ dẫn đến một mô hình cho

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
37

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
38

Điều này tương tự như mệnh đề trước, nhưng sẽ khớp khi tên đủ điều kiện của chú thích loại rõ ràng của toàn cục khớp với mẫu đã chỉ định

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
4

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
39

Điều này sẽ khớp khi loại toàn cầu được chú thích bằng. Đây là một loại được sử dụng để trang trí các loại hiện có với siêu dữ liệu theo ngữ cảnh cụ thể, e. g

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
5

Thí dụ

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
6

Truy vấn này sẽ phù hợp với các chức năng như truy vấn được hiển thị ở trên

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
41 mệnh đề

Các truy vấn mô hình cho phép kết hợp các cuộc gọi trong đó bất kỳ tham số nào khớp với một mệnh đề nhất định. Hiện tại, mệnh đề duy nhất chúng tôi hỗ trợ cho các tham số là chỉ định các điều kiện trên chú thích loại của các tham số có thể gọi được. Chúng có thể được sử dụng cùng với mệnh đề mô hình

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
34 [xem ] để làm mờ các tham số cụ thể. Lưu ý rằng mệnh đề
ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
3 này không hoạt động khi mệnh đề
ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
2 chỉ định
ModelQuery[
name = "get_return_HttpRequest_sources",
find = "functions",
where = [
return_annotation.equals["django.http.HttpRequest"],
],
model = Returns[TaintSource[UserControlled, Via[http_request]]]
]
9

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
47

Mệnh đề này sẽ khớp với tất cả các lệnh gọi có ít nhất một tham số trong đó tên đủ điều kiện của loại tham số khớp chính xác với giá trị đã chỉ định

Thí dụ

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
7

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
48

Mệnh đề này sẽ khớp với tất cả các lệnh gọi có ít nhất một tham số trong đó tên đủ điều kiện của loại tham số khớp với mẫu đã chỉ định

Thí dụ

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
8

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
49

Mệnh đề này sẽ khớp với tất cả các callables có ít nhất một tham số với loại

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
30

Thí dụ

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
9

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
51 mệnh đề

Có những trường hợp khi chúng ta muốn lập mô hình các thực thể khớp với bất kỳ tập hợp mệnh đề nào. Mệnh đề

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
51 thể hiện chính xác trường hợp này

Thí dụ

class C:
x = ...

def __init__[self]:
self.y = ...
0

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
53 mệnh đề

Có những trường hợp chúng ta muốn mô hình hóa các thực thể khớp với tất cả các mệnh đề. Mệnh đề

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
53 có thể được sử dụng trong trường hợp này

Thí dụ

class C:
x = ...

def __init__[self]:
self.y = ...
1

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
55 mệnh đề

Mệnh đề

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
55 được sử dụng để tìm các vật gọi được được trang trí bằng các vật trang trí phù hợp với một mẫu. Mệnh đề này lấy mệnh đề trang trí làm đối số

Điều khoản trang trí
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
57

Mệnh đề trang trí

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
57 được sử dụng để khớp tên với tên đủ điều kiện của một người trang trí. Các mệnh đề tên được hỗ trợ giống như các mệnh đề đã thảo luận ở trên đối với các ràng buộc truy vấn mô hình, tôi. e.
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
59, sẽ khớp khi trình trang trí khớp với mẫu biểu thức chính quy được chỉ định dưới dạng chuỗi và
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
60 sẽ khớp khi tên đủ điều kiện của trình trang trí bằng chính xác chuỗi đã chỉ định

Ví dụ: nếu bạn muốn tìm tất cả các chức năng được trang trí bởi

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
61, một trình trang trí được nhập từ
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
62, bạn có thể viết

class C:
x = ...

def __init__[self]:
self.y = ...
2

hoặc là

class C:
x = ...

def __init__[self]:
self.y = ...
3

Mệnh đề trang trí
ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
1

Mệnh đề

ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
1 tương tự như mệnh đề
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
57, nhưng khớp với tên thực của thực thể, ngoại trừ tên mô-đun và tên lớp

Mệnh đề trang trí
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
66

Các mệnh đề

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
66 được sử dụng để khớp với các đối số được cung cấp cho trình trang trí. Các mệnh đề đối số được hỗ trợ là
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
68, sẽ khớp khi các đối số được chỉ định là một tập hợp con của các đối số của trình trang trí và
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
69, sẽ khớp khi trình trang trí có chính xác các đối số đã chỉ định

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
70 hỗ trợ cả đối số vị trí và từ khóa. Đối với các đối số vị trí, danh sách các đối số vị trí được cung cấp cho mệnh đề
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
70 phải là tiền tố của danh sách các đối số vị trí trên bộ trang trí thực tế, i. e. giá trị của đối số ở mỗi vị trí phải giống nhau. Ví dụ với đoạn mã Python sau

class C:
x = ...

def __init__[self]:
self.y = ...
4

Truy vấn này sẽ khớp với cả

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
72 và
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
73, nhưng không khớp với
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
74, vì giá trị của các đối số vị trí không khớp

class C:
x = ...

def __init__[self]:
self.y = ...
5

Đối với các đối số từ khóa trong

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
70, các đối số từ khóa đã chỉ định phải là tập hợp con của các đối số từ khóa của trình trang trí, nhưng có thể được chỉ định theo bất kỳ thứ tự nào. Ví dụ với đoạn mã Python sau

class C:
x = ...

def __init__[self]:
self.y = ...
6

Truy vấn này sẽ khớp với cả

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
72 và
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
73

class C:
x = ...

def __init__[self]:
self.y = ...
7

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
78 hoạt động tương tự, nhưng sẽ chỉ khớp nếu các đối số được chỉ định khớp chính xác với các đối số của trình trang trí. Điều này có nghĩa là đối với các đối số vị trí, tất cả các đối số ở mỗi vị trí phải khớp chính xác theo giá trị. Các đối số từ khóa có thể được chỉ định theo một thứ tự khác, nhưng tập hợp các đối số từ khóa đã chỉ định và tập hợp các đối số từ khóa thực của trình trang trí phải giống nhau. Ví dụ với đoạn mã Python sau

class C:
x = ...

def __init__[self]:
self.y = ...
8

Truy vấn này sẽ khớp với cả

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
72 và
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
73, nhưng không khớp với
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
81 hoặc
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
82

class C:
x = ...

def __init__[self]:
self.y = ...
9

Mệnh đề trang trí
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
83,
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
53 và
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
51

Các mệnh đề

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
83,
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
53 và
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
51 có thể được sử dụng trong mệnh đề trang trí giống như cách chúng được sử dụng trong mệnh đề chính
ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
3 của truy vấn mô hình

Điều khoản
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
90

Bạn có thể sử dụng mệnh đề

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
91 để chỉ định các vị từ trong lớp. Vị ngữ này chỉ có thể được sử dụng khi mệnh đề find chỉ định các phương thức hoặc thuộc tính

Mệnh đề

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
90 được sử dụng để mô hình hóa các thực thể khi tên đủ điều kiện của lớp khớp chính xác với chuỗi đã chỉ định

Thí dụ

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
0

Điều khoản
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
93

Mệnh đề

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
93 được sử dụng để mô hình hóa các thực thể khi tên đủ điều kiện của lớp khớp với biểu thức chính quy được cung cấp

Thí dụ

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
1

Điều khoản
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
95

Mệnh đề

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
95 tương tự như mệnh đề
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
93, nhưng khớp với tên thực của lớp, không bao gồm các mô-đun

Điều khoản
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
98

Mệnh đề

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
98 tương tự như mệnh đề
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
90, nhưng khớp với tên thực của lớp, không bao gồm các mô-đun

Điều khoản
class C:
x = ...

def __init__[self]:
self.y = ...
01

Mệnh đề

class C:
x = ...

def __init__[self]:
self.y = ...
01 được sử dụng để mô hình hóa các thực thể khi lớp này là lớp con của tên lớp được cung cấp

Thí dụ

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
2

Hành vi mặc định là nó sẽ chỉ khớp nếu lớp là một thể hiện của hoặc một lớp con trực tiếp của lớp đã chỉ định. Ví dụ, với các lớp

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
3

truy vấn trên sẽ chỉ mô hình hóa các thuộc tính

class C:
x = ...

def __init__[self]:
self.y = ...
03 và
class C:
x = ...

def __init__[self]:
self.y = ...
04, vì
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
01 được coi là mở rộng chính nó và
class C:
x = ...

def __init__[self]:
self.y = ...
06 là lớp con trực tiếp của
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
01. Tuy nhiên, nó sẽ không mô hình hóa
class C:
x = ...

def __init__[self]:
self.y = ...
08, vì
class C:
x = ...

def __init__[self]:
self.y = ...
09 là một phân lớp con của
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
01

Nếu bạn muốn mô hình hóa một lớp và tất cả các lớp con một cách chuyển tiếp, bạn có thể sử dụng cờ

class C:
x = ...

def __init__[self]:
self.y = ...
11

Thí dụ

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
4

Truy vấn này sẽ mô hình

class C:
x = ...

def __init__[self]:
self.y = ...
12,
class C:
x = ...

def __init__[self]:
self.y = ...
04 và
class C:
x = ...

def __init__[self]:
self.y = ...
08

Nếu bạn không muốn so khớp trên chính lớp đó, bạn có thể sử dụng cờ

class C:
x = ...

def __init__[self]:
self.y = ...
15

Thí dụ

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
5

Truy vấn này sẽ mô hình

class C:
x = ...

def __init__[self]:
self.y = ...
04 và
class C:
x = ...

def __init__[self]:
self.y = ...
08

Điều khoản
class C:
x = ...

def __init__[self]:
self.y = ...
18

Mệnh đề

class C:
x = ...

def __init__[self]:
self.y = ...
18 được sử dụng để chỉ định các ràng buộc đối với một trình trang trí lớp, vì vậy bạn có thể chọn mô hình hóa các thực thể trên các lớp chỉ khi lớp mà nó là một phần của trình trang trí được chỉ định

Các đối số cho mệnh đề này giống hệt với ràng buộc không thuộc lớp

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
55, để biết thêm thông tin, vui lòng xem phần

Thí dụ

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
6

Ví dụ: truy vấn trên khi chạy trên đoạn mã sau

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
7

sẽ dẫn đến một mô hình cho

class C:
x = ...

def __init__[self]:
self.y = ...
22

Điều khoản
class C:
x = ...

def __init__[self]:
self.y = ...
23

Mệnh đề

class C:
x = ...

def __init__[self]:
self.y = ...
23 được sử dụng để mô hình hóa các thực thể khi bất kỳ phần tử con nào của lớp hiện tại đáp ứng các ràng buộc đã chỉ định

Các đối số cho mệnh đề này là bất kỳ sự kết hợp nào của các ràng buộc lớp hợp lệ [

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
98,
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
95,
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
90,
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
93,
class C:
x = ...

def __init__[self]:
self.y = ...
01,
class C:
x = ...

def __init__[self]:
self.y = ...
18] và các mệnh đề logic [
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
51,
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
53,
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
83], cùng với các mệnh đề tùy chọn
class C:
x = ...

def __init__[self]:
self.y = ...
11 và
class C:
x = ...

def __init__[self]:
self.y = ...
15

Thí dụ

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
8

Tương tự như ràng buộc

class C:
x = ...

def __init__[self]:
self.y = ...
01, hành vi mặc định là nó sẽ chỉ khớp nếu lớp hiện tại bằng hoặc là lớp con trực tiếp của lớp đã chỉ định. Ví dụ, với các lớp

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
9

Truy vấn trên sẽ chỉ mô hình hóa các phương thức

class C:
x = ...

def __init__[self]:
self.y = ...
37 và
class C:
x = ...

def __init__[self]:
self.y = ...
38, vì
class C:
x = ...

def __init__[self]:
self.y = ...
39 là cha mẹ trực tiếp của
class C:
x = ...

def __init__[self]:
self.y = ...
40 và
class C:
x = ...

def __init__[self]:
self.y = ...
40 được coi là tự mở rộng. Tuy nhiên, nó sẽ không mô hình hóa
class C:
x = ...

def __init__[self]:
self.y = ...
42, vì
class C:
x = ...

def __init__[self]:
self.y = ...
39 là phân lớp con của
class C:
x = ...

def __init__[self]:
self.y = ...
44

Nếu bạn muốn mô hình hóa một lớp và tất cả các lớp con một cách chuyển tiếp, bạn có thể sử dụng cờ

class C:
x = ...

def __init__[self]:
self.y = ...
11

Thí dụ

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
fully_qualified_name.matches["foo.*"]
],
model = ...
]
0

Truy vấn này sẽ mô hình

class C:
x = ...

def __init__[self]:
self.y = ...
42,
class C:
x = ...

def __init__[self]:
self.y = ...
37 và
class C:
x = ...

def __init__[self]:
self.y = ...
38

Nếu bạn muốn mô hình hóa tất cả các lớp con của một lớp ngoại trừ chính nó, bạn có thể sử dụng cờ

class C:
x = ...

def __init__[self]:
self.y = ...
15

Thí dụ

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
fully_qualified_name.matches["foo.*"]
],
model = ...
]
1

Truy vấn này sẽ mô hình

class C:
x = ...

def __init__[self]:
self.y = ...
42,
class C:
x = ...

def __init__[self]:
self.y = ...
37 nhưng KHÔNG PHẢI
class C:
x = ...

def __init__[self]:
self.y = ...
38

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
83 mệnh đề

Mệnh đề

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
83 phủ nhận bất kỳ mệnh đề hiện có nào hợp lệ đối với thực thể được lập mô hình

Thí dụ

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
fully_qualified_name.matches["foo.*"]
],
model = ...
]
2

Các mô hình đã tạo [Mệnh đề mô hình]

Phần cuối cùng của truy vấn mô hình thực sự tạo ra các mô hình cho tất cả các thực thể khớp với mệnh đề where được cung cấp. Đối với các hàm có thể gọi được, chúng tôi hỗ trợ tạo mô hình cho các tham số theo tên hoặc vị trí, cũng như tạo mô hình cho tất cả các tham số. Ngoài ra, chúng tôi hỗ trợ tạo các mô hình cho chú thích trả lại

trở lại vết bẩn

Taint được trả về có dạng

class C:
x = ...

def __init__[self]:
self.y = ...
55, trong đó
class C:
x = ...

def __init__[self]:
self.y = ...
56 là một chú thích taint hoặc một danh sách các chú thích taint

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
fully_qualified_name.matches["foo.*"]
],
model = ...
]
3

tham số taint

Các tham số có thể bị làm hỏng bằng cách sử dụng mệnh đề

class C:
x = ...

def __init__[self]:
self.y = ...
57. Theo mặc định, tất cả các tham số sẽ được xử lý bằng thông số taint được cung cấp. Nếu bạn chỉ muốn làm mờ các tham số cụ thể phù hợp với các điều kiện nhất định, thì có thể chỉ định mệnh đề
ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
3 tùy chọn để thực hiện điều này, cho phép các ràng buộc về tên tham số, loại chú thích của tham số hoặc vị trí tham số. Ví dụ

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
fully_qualified_name.matches["foo.*"]
],
model = ...
]
4

ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
1 mệnh đề

Để chỉ định một ràng buộc về tên tham số, có thể sử dụng các mệnh đề

class C:
x = ...

def __init__[self]:
self.y = ...
60 hoặc
class C:
x = ...

def __init__[self]:
self.y = ...
61. Như trong mệnh đề chính
ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
3 của truy vấn mô hình,
class C:
x = ...

def __init__[self]:
self.y = ...
63 tìm kiếm một kết quả khớp chính xác trên chuỗi đã chỉ định, trong khi
class C:
x = ...

def __init__[self]:
self.y = ...
64 cho phép cung cấp biểu thức chính quy dưới dạng mẫu để khớp với

Thí dụ

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
fully_qualified_name.matches["foo.*"]
],
model = ...
]
5

Điều khoản
class C:
x = ...

def __init__[self]:
self.y = ...
65

Để chỉ định một ràng buộc về vị trí tham số, có thể sử dụng mệnh đề

class C:
x = ...

def __init__[self]:
self.y = ...
66. Phải mất một số nguyên biểu thị vị trí của tham số

Thí dụ

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
fully_qualified_name.matches["foo.*"]
],
model = ...
]
6

Điều khoản
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
31

Mệnh đề này được sử dụng để chỉ định một ràng buộc đối với chú thích loại tham số. Hiện tại các mệnh đề được hỗ trợ là.

class C:
x = ...

def __init__[self]:
self.y = ...
68, lấy tên đủ điều kiện của một loại hoặc lớp Python và khớp khi có khớp chính xác,
class C:
x = ...

def __init__[self]:
self.y = ...
69, lấy một mẫu biểu thức chính quy để khớp với các chú thích loại và
class C:
x = ...

def __init__[self]:
self.y = ...
70, sẽ khớp với các tham số của loại

Thí dụ

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
fully_qualified_name.matches["foo.*"]
],
model = ...
]
7

Để khớp với phần chú thích của các loại

class C:
x = ...

def __init__[self]:
self.y = ...
72, hãy xem xét ví dụ sau. Giả sử mã này là trong
class C:
x = ...

def __init__[self]:
self.y = ...
73

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
fully_qualified_name.matches["foo.*"]
],
model = ...
]
8

Lưu ý rằng tên loại cần đối chiếu là tên đủ điều kiện của nó, cũng bao gồm tên đủ điều kiện của bất kỳ loại nào khác được tham chiếu [ví dụ:

class C:
x = ...

def __init__[self]:
self.y = ...
74 thay vì chỉ
class C:
x = ...

def __init__[self]:
self.y = ...
75]. Khi nhiều đối số được cung cấp cho loại, chúng được coi là nằm trong một bộ dữ liệu

Dưới đây là một số ví dụ về mệnh đề

ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
3 có thể được sử dụng để chỉ định các mô hình cho các thuộc tính được chú thích trong trường hợp này

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
fully_qualified_name.matches["foo.*"]
],
model = ...
]
9

Truy vấn này sẽ tạo ra các mô hình sau

ModelQuery[
name = "get_bar_C_foo",
find = ...,
where = [
fully_qualified_name.equals["bar.C.foo"]
],
model = ...
]
0

Các mệnh đề
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
83,
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
53 và
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
51

Các mệnh đề

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
83,
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
53 và
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
51 có thể được sử dụng giống như cách chúng được sử dụng trong mệnh đề chính
ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
3 của truy vấn mô hình.
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
83 có thể được sử dụng để phủ định bất kỳ mệnh đề hiện có nào,
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
53 để khớp khi tất cả các mệnh đề được cung cấp khớp với nhau và
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
51 có thể được sử dụng để khớp khi bất kỳ một trong số các mệnh đề được cung cấp khớp

Thí dụ

ModelQuery[
name = "get_bar_C_foo",
find = ...,
where = [
fully_qualified_name.equals["bar.C.foo"]
],
model = ...
]
1

Sử dụng
class C:
x = ...

def __init__[self]:
self.y = ...
87 với mệnh đề
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
34

Thông thường, khi chỉ định một

class C:
x = ...

def __init__[self]:
self.y = ...
87, đối số mà bạn muốn nắm bắt giá trị hoặc loại của sẽ được chỉ định. Tuy nhiên, khi viết các truy vấn mô hình và cố gắng tìm tất cả các tham số phù hợp với một số điều kiện nhất định, chúng ta có thể không biết chính xác tên của các tham số sẽ được mô hình hóa. Ví dụ

ModelQuery[
name = "get_bar_C_foo",
find = ...,
where = [
fully_qualified_name.equals["bar.C.foo"]
],
model = ...
]
2

Giả sử chúng ta muốn lập mô hình tất cả các tham số có tiền tố

class C:
x = ...

def __init__[self]:
self.y = ...
90 ở đây và đính kèm một
class C:
x = ...

def __init__[self]:
self.y = ...
87 cho chúng. Trong trường hợp này, vẫn có thể đính kèm các tính năng này vào mô hình tham số, bằng cách sử dụng một
class C:
x = ...

def __init__[self]:
self.y = ...
87 độc lập như sau

ModelQuery[
name = "get_bar_C_foo",
find = ...,
where = [
fully_qualified_name.equals["bar.C.foo"]
],
model = ...
]
3

Điều này sẽ tạo ra các mô hình tương đương như sau

ModelQuery[
name = "get_bar_C_foo",
find = ...,
where = [
fully_qualified_name.equals["bar.C.foo"]
],
model = ...
]
4

Mô hình cho các thuộc tính

Taint cho các mô hình thuộc tính yêu cầu mệnh đề mô hình

class C:
x = ...

def __init__[self]:
self.y = ...
93, mệnh đề này chỉ có thể được sử dụng khi mệnh đề find chỉ định các thuộc tính

Thí dụ

ModelQuery[
name = "get_bar_C_foo",
find = ...,
where = [
fully_qualified_name.equals["bar.C.foo"]
],
model = ...
]
5

Mô hình cho toàn cầu

Taint cho các mô hình toàn cục yêu cầu mệnh đề mô hình

class C:
x = ...

def __init__[self]:
self.y = ...
94, mệnh đề này chỉ có thể được sử dụng khi mệnh đề find chỉ định các mô hình toàn cầu

Thí dụ

ModelQuery[
name = "get_bar_C_foo",
find = ...,
where = [
fully_qualified_name.equals["bar.C.foo"]
],
model = ...
]
6

Mô hình cho các chế độ cài đặt

Mệnh đề mô hình này khác với các mệnh đề khác trong phần này theo nghĩa là nó không tạo vết bẩn cho các mô hình mà nó nhắm mục tiêu, nhưng cập nhật các mô hình của chúng bằng các chế độ cụ thể để thay đổi hành vi của chúng bằng phân tích vết bẩn

Các chế độ có sẵn là

    • Ngăn không cho một hàm hoặc phương thức bị đánh dấu là tối nghĩa
    • Bỏ qua suy luận của chức năng hoặc mô hình được nhắm mục tiêu và buộc sử dụng các mô hình do người dùng xác định cho luồng dữ liệu
    • Ngăn chặn sự lan truyền vết bẩn từ mô hình được nhắm mục tiêu vào và từ các phương thức bị ghi đè trên các lớp con
    • Chỉ định các hàm hoặc phương thức sẽ được sử dụng làm điểm vào để phân tích, vì vậy chỉ các lệnh gọi chuyển tiếp từ hàm đó mới được phân tích
    • Ngăn không cho trình trang trí đã chọn được nội tuyến trong quá trình phân tích
    • Ghi chú. chế độ này sẽ không hoạt động, vì các truy vấn mô hình được tạo sau khi các bộ trang trí được nội tuyến

Chẳng hạn, thay vì chú thích riêng từng chức năng, như trong tệp

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
name.matches["foo.*"]
],
model = ...
]
8 sau đây

ModelQuery[
name = "get_bar_C_foo",
find = ...,
where = [
fully_qualified_name.equals["bar.C.foo"]
],
model = ...
]
7

Thay vào đó, người ta có thể sử dụng truy vấn mô hình sau

ModelQuery[
name = "get_bar_C_foo",
find = ...,
where = [
fully_qualified_name.equals["bar.C.foo"]
],
model = ...
]
8

Lợi ích là bất kỳ chức năng mới nào khớp với tên đó cũng sẽ được coi là điểm vào

Lưu ý rằng cũng có thể bao gồm nhiều chế độ trong mệnh đề mô hình

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
01 bằng cách mở rộng danh sách [e. g
def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
02

mệnh đề Mô hình mong đợi và không mong đợi

Các mệnh đề

ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
7 và
ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
8 tùy chọn cho phép bạn chỉ định các mô hình mà ModelQuery của bạn nên hoặc không nên tạo tương đương với. Các mô hình trong các mệnh đề này phải là các mô hình Pysa đúng về mặt cú pháp [xem hướng dẫn về cách viết mô hình Pysa]. Nếu truy vấn của bạn không tạo ra một mô hình trong
ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
7 hoặc nếu nó tạo ra một mô hình trong
ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
8, một lỗi sẽ xuất hiện

Thí dụ

ModelQuery[
name = "get_bar_C_foo",
find = ...,
where = [
fully_qualified_name.equals["bar.C.foo"]
],
model = ...
]
9

Điều này sẽ không tạo ra bất kỳ lỗi nào, vì các mô hình mà ModelQuery tạo ra sẽ chứa

ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
7 chứ không phải
ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
8

Truy vấn bộ đệm

Tạo mô hình cho một số lượng lớn truy vấn có thể khá chậm. Các truy vấn bộ đệm cho phép tăng tốc độ tạo mô hình bằng cách tách các truy vấn có mệnh đề

ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
3 tương tự thành một truy vấn duy nhất, truy vấn này xây dựng ánh xạ từ một tên tùy ý đến một tập hợp các thực thể phù hợp. Sau đó, các truy vấn khác có thể đọc từ bộ đệm này, giúp chúng thực thi nhanh chóng

Chẳng hạn, hãy tưởng tượng có các truy vấn sau

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
name.matches["foo.*"]
],
model = ...
]
0

Chúng ta có thể đưa mệnh đề where đắt tiền vào một truy vấn duy nhất ghi vào bộ đệm khóa-giá trị, sử dụng mệnh đề

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
10

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
name.matches["foo.*"]
],
model = ...
]
1

Tất cả các phương thức so khớp sẽ được lưu trữ trong bộ đệm có tên là

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
11, dưới khóa là
def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
12

Sau khi thực hiện truy vấn, chúng tôi có thể nhận được bộ đệm sau

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
11

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
name.matches["foo.*"]
],
model = ...
]
2

Sau đó, chúng ta có thể đọc từ bộ đệm bằng mệnh đề where

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
14

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
name.matches["foo.*"]
],
model = ...
]
3

Điều này sẽ tạo ra các mô hình giống như ví dụ đầu tiên, nhưng việc tạo mô hình sẽ nhanh hơn rất nhiều

Xét về độ phức tạp về thời gian, nếu số lượng thực thể [các phương pháp ở đây] là

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
15, số lượng truy vấn là
def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
16 và chi phí trung bình để đánh giá mệnh đề where là
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
01, thì ví dụ đầu tiên sẽ có độ phức tạp
def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
18. Sử dụng các truy vấn bộ đệm, điều này biến thành
def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
19, điều này tốt hơn nhiều

mệnh đề WriteToCache

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
10 là một mệnh đề mô hình được sử dụng để lưu trữ các thực thể vào bộ đệm. Nó có các đối số sau

  • A
    def fun[x: int, y: str] -> int:
    return x + int[y]

    a = fun[1, "2"] # -> typing.Any
    b: int = fun[1, "2"] # -> int
    21, là tên của bộ đệm
  • Một
    ModelQuery[
    name = "get_foo",
    find = ...,
    where = [
    name.equals["foo"]
    ],
    model = ...
    ]
    1 dưới dạng chuỗi f, sẽ là khóa cho thực thể trong bộ đệm

Tên có thể sử dụng các biến sau

  • def fun[x: int, y: str] -> int:
    return x + int[y]

    a = fun[1, "2"] # -> typing.Any
    b: int = fun[1, "2"] # -> int
    23. Tên [không đủ điều kiện] của chức năng
  • def fun[x: int, y: str] -> int:
    return x + int[y]

    a = fun[1, "2"] # -> typing.Any
    b: int = fun[1, "2"] # -> int
    24. Tên [không đủ điều kiện] của phương thức
  • def fun[x: int, y: str] -> int:
    return x + int[y]

    a = fun[1, "2"] # -> typing.Any
    b: int = fun[1, "2"] # -> int
    25. Tên [không đủ điều kiện] của lớp
  • def fun[x: int, y: str] -> int:
    return x + int[y]

    a = fun[1, "2"] # -> typing.Any
    b: int = fun[1, "2"] # -> int
    26. Nhóm nắm bắt biểu thức chính quy có tên là
    def fun[x: int, y: str] -> int:
    return x + int[y]

    a = fun[1, "2"] # -> typing.Any
    b: int = fun[1, "2"] # -> int
    27. Xem tài liệu bên dưới

Ví dụ

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
name.matches["foo.*"]
],
model = ...
]
4

Lưu ý rằng bạn có thể viết nhiều thực thể dưới cùng một tên. Chẳng hạn, điều này xảy ra nếu bạn sử dụng

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
28 và nhiều phương thức của cùng một lớp khớp với mệnh đề where

mệnh đề read_from_cache

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
14 là mệnh đề where sẽ chỉ khớp với các thực thể có tên đã cho trong bộ đệm. Nó có các đối số sau

  • A
    def fun[x: int, y: str] -> int:
    return x + int[y]

    a = fun[1, "2"] # -> typing.Any
    b: int = fun[1, "2"] # -> int
    21, là tên của bộ đệm
  • Một
    ModelQuery[
    name = "get_foo",
    find = ...,
    where = [
    name.equals["foo"]
    ],
    model = ...
    ]
    1 dưới dạng một chuỗi, là khóa cho các thực thể trong bộ đệm

Ví dụ

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
name.matches["foo.*"]
],
model = ...
]
5

Lưu ý rằng bạn có thể sử dụng

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
14 kết hợp với các mệnh đề where khác, miễn là có ít nhất một mệnh đề
def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
14 đang hoạt động trên tất cả các nhánh

Ví dụ, điều này là không được phép

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
name.matches["foo.*"]
],
model = ...
]
6

Chụp biểu thức chính quy

Mệnh đề

$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
11 và
$ pyre analyze --dump-model-query-results /path/to/output/file.txt
...
> Emitting the model query results to `/my/home/dir/.pyre/model_query_results.pysa`
95 có thể sử dụng các nhóm bắt giữ được đặt tên, có thể được sử dụng trong mệnh đề
ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
1 của
def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
10

Ví dụ

ModelQuery[
name = "get_starting_with_foo",
find = ...,
where = [
name.matches["foo.*"]
],
model = ...
]
7

Đối với chức năng

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
38, điều này sẽ tạo bộ đệm cho khóa
ModelQuery[
name = "get_foo",
find = ...,
where = [
name.equals["foo"]
],
model = ...
]
4

thận trọng

Hãy cẩn thận khi sử dụng chụp biểu thức chính quy. Nếu không tìm thấy nhóm chụp [e. g, lỗi đánh máy],

def fun[x: int, y: str] -> int:
return x + int[y]

a = fun[1, "2"] # -> typing.Any
b: int = fun[1, "2"] # -> int
10 sẽ sử dụng chuỗi rỗng

Ví dụ về DSL là gì?

Một ví dụ điển hình về DSL là HTML . Nó là một ngôn ngữ cho miền ứng dụng web. Chẳng hạn, nó không thể được sử dụng để xử lý số liệu, nhưng rõ ràng HTML được sử dụng rộng rãi như thế nào trên web. Người tạo GPL không biết ngôn ngữ có thể được sử dụng ở đâu hoặc các vấn đề mà người dùng dự định giải quyết với ngôn ngữ đó.

DSL trong Python là gì?

Ngôn ngữ dành riêng cho miền hay viết tắt là DSL, là ngôn ngữ dành riêng cho một miền ứng dụng cụ thể . Nói cách khác, đó là ngôn ngữ lập trình được sử dụng cho một ứng dụng hoặc trường hợp sử dụng cụ thể hơn là ngôn ngữ có mục đích chung như Python. Ví dụ, biểu thức chính quy là một DSL.

Cú pháp DSL là gì?

Ngôn ngữ dành riêng cho miền là ngôn ngữ lập trình có mức độ trừu tượng cao hơn được tối ưu hóa cho một loại vấn đề cụ thể. DSL sử dụng các khái niệm và quy tắc từ trường hoặc miền .

Khi nào tôi nên tạo DSL?

Đầu tiên, tôi sẽ sử dụng DSL khi miền có vấn đề mà bạn đang phát triển là một miền nổi tiếng rộng rãi và một số chuyên gia kinh doanh của miền đó .

Chủ Đề