ssc_codegen 0.13.4__tar.gz → 0.15.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of ssc_codegen might be problematic. Click here for more details.
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/PKG-INFO +11 -11
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/README.md +10 -10
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/pyproject.toml +1 -1
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/__init__.py +4 -3
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/ast_/__init__.py +4 -1
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/ast_/nodes_core.py +41 -3
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/ast_build/builder.py +39 -1
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/cli/code_callbacks.py +0 -2
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/cli/main.py +0 -2
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/converters/go_goquery.py +31 -12
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/converters/js_pure.py +32 -3
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/converters/lua_htmlparser.py +32 -1
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/converters/py_base.py +59 -31
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/converters/py_bs4.py +30 -2
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/converters/py_lxml.py +38 -27
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/converters/py_parsel.py +30 -2
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/converters/py_selectolax.py +29 -1
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/converters/templates/py_base.py +12 -5
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/document.py +34 -1
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/schema.py +15 -1
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/tokens.py +6 -0
- ssc_codegen-0.15.0/ssc_codegen/transform.py +95 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/.gitignore +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/LICENSE +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/_compat.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/ast_/base.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/ast_/nodes_array.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/ast_/nodes_cast.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/ast_/nodes_filter.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/ast_/nodes_selectors.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/ast_/nodes_string.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/ast_/nodes_validate.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/ast_build/__init__.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/ast_build/main.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/ast_build/utils.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/ast_grep_rules/js_rules.yml +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/ast_grep_rules/py_drop_prefix_suffix_backport.yml +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/ast_grep_rules/py_rules.yml +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/cli/__init__.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/cli/ast_grep.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/cli/cli_callbacks.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/cli/cli_utils.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/cli/consts.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/cli/runtime_parse_runners.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/compiler.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/converters/__init__.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/converters/base.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/converters/helpers.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/converters/templates/__init__.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/converters/templates/go_goquery.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/converters/templates/js_pure.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/converters/templates/lua_base.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/converters/templates/lua_css_compat.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/converters/templates/lua_re_compat.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/document_utlis.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/json_struct.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/json_to_scc.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/logs.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/pseudo_selectors.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/selector_utils.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/static_checker/__init__.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/static_checker/base.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/static_checker/callbacks.py +0 -0
- {ssc_codegen-0.13.4 → ssc_codegen-0.15.0}/ssc_codegen/str_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ssc_codegen
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.15.0
|
|
4
4
|
Summary: Python-dsl code converter to html parser for web scraping
|
|
5
5
|
Project-URL: Documentation, https://github.com/vypivshiy/selector_schema_codegen#readme
|
|
6
6
|
Project-URL: Issues, https://github.com/vypivshiy/selector_schema_codegen/issues
|
|
@@ -58,15 +58,15 @@ ssc-gen - a python-based DSL to describe parsers for html documents, which is tr
|
|
|
58
58
|
|
|
59
59
|
Current support converters
|
|
60
60
|
|
|
61
|
-
| Language | HTML parser lib + dependencies
|
|
62
|
-
| ---------------------------------------- |
|
|
63
|
-
| Python (3.8
|
|
64
|
-
| ... | parsel
|
|
65
|
-
| ... | selectolax (lexbor)
|
|
66
|
-
| ... | lxml
|
|
67
|
-
| js (ES6)`2` | pure (firefox/chrome extension/nodejs)
|
|
68
|
-
| go (1.10+) **(UNSTABLE)** | goquery, gjson (`4`)
|
|
69
|
-
| lua (5.2+), luajit(2+) **(UNSTABLE)**`5` | lua-htmlparser, lrexlib(opt), dkjson
|
|
61
|
+
| Language | HTML parser lib + dependencies | XPath | CSS3 | CSS4 | Generated annotations, types, structs | formatter dependency |
|
|
62
|
+
| ---------------------------------------- | ------------------------------------------------------ | ----- | ---- | ---- | ------------------------------------- | -------------------- |
|
|
63
|
+
| Python (3.8-3.13) | bs4, lxml ( typing_extensions if py < 3.10 ) | N | Y | Y | TypedDict`1`, list, dict | ruff |
|
|
64
|
+
| ... | parsel ( typing_extensions if py < 3.10 ) | Y | Y | N | ... | ... |
|
|
65
|
+
| ... | selectolax (lexbor) ( typing_extensions if py < 3.10 ) | N | Y | N | ... | ... |
|
|
66
|
+
| ... | lxml ( typing_extensions if py < 3.10 ) | Y | Y | N | ... | ... |
|
|
67
|
+
| js (ES6)`2` | pure (firefox/chrome extension/nodejs) | Y | Y | Y | JSDoc | prettier |
|
|
68
|
+
| go (1.10+) **(UNSTABLE)** | goquery, gjson (`4`) | N | Y | N | struct(+json anchors), array, map | gofmt |
|
|
69
|
+
| lua (5.2+), luajit(2+) **(UNSTABLE)**`5` | lua-htmlparser, lrexlib(opt), dkjson | N | Y | N | EmmyLua | LuaFormatter |
|
|
70
70
|
|
|
71
71
|
- **CSS3** means support next selectors:
|
|
72
72
|
- basic: (`tag`, `.class`, `#id`, `tag1,tag2`)
|
|
@@ -99,6 +99,7 @@ For maximum portability of the configuration to the target language:
|
|
|
99
99
|
Check the html parser lib documentation aboud CSS selectors before implement code. Examples:
|
|
100
100
|
1. Several libs not support `+` operations (eg: [selectolax(modest)](https://github.com/rushter/selectolax), [dart.universal_html](https://pub.dev/packages/universal_html))
|
|
101
101
|
2. For research purpose, lua_htmlparser include converter for unsupported CSS3 query syntax
|
|
102
|
+
|
|
102
103
|
2. HTML parser libs maybe not supports attribute selectors: `*=`, `~=`, `|=`, `^=`, `$=`
|
|
103
104
|
3. Several libs not support pseudo classes (eg: standard [dart.html](https://dart.dev/libraries/dart-html) lib miss this feature).
|
|
104
105
|
|
|
@@ -245,7 +246,6 @@ You can use any html source:
|
|
|
245
246
|
|
|
246
247
|
## See also
|
|
247
248
|
|
|
248
|
-
|
|
249
249
|
- [Brief](docs/briefing.md) about css selectors and regular expressions
|
|
250
250
|
- [Explain](docs/explain.md) short document on how to understand DSL syntax
|
|
251
251
|
- [LLM](llm.md) experimental prompt for generate code
|
|
@@ -23,15 +23,15 @@ ssc-gen - a python-based DSL to describe parsers for html documents, which is tr
|
|
|
23
23
|
|
|
24
24
|
Current support converters
|
|
25
25
|
|
|
26
|
-
| Language | HTML parser lib + dependencies
|
|
27
|
-
| ---------------------------------------- |
|
|
28
|
-
| Python (3.8
|
|
29
|
-
| ... | parsel
|
|
30
|
-
| ... | selectolax (lexbor)
|
|
31
|
-
| ... | lxml
|
|
32
|
-
| js (ES6)`2` | pure (firefox/chrome extension/nodejs)
|
|
33
|
-
| go (1.10+) **(UNSTABLE)** | goquery, gjson (`4`)
|
|
34
|
-
| lua (5.2+), luajit(2+) **(UNSTABLE)**`5` | lua-htmlparser, lrexlib(opt), dkjson
|
|
26
|
+
| Language | HTML parser lib + dependencies | XPath | CSS3 | CSS4 | Generated annotations, types, structs | formatter dependency |
|
|
27
|
+
| ---------------------------------------- | ------------------------------------------------------ | ----- | ---- | ---- | ------------------------------------- | -------------------- |
|
|
28
|
+
| Python (3.8-3.13) | bs4, lxml ( typing_extensions if py < 3.10 ) | N | Y | Y | TypedDict`1`, list, dict | ruff |
|
|
29
|
+
| ... | parsel ( typing_extensions if py < 3.10 ) | Y | Y | N | ... | ... |
|
|
30
|
+
| ... | selectolax (lexbor) ( typing_extensions if py < 3.10 ) | N | Y | N | ... | ... |
|
|
31
|
+
| ... | lxml ( typing_extensions if py < 3.10 ) | Y | Y | N | ... | ... |
|
|
32
|
+
| js (ES6)`2` | pure (firefox/chrome extension/nodejs) | Y | Y | Y | JSDoc | prettier |
|
|
33
|
+
| go (1.10+) **(UNSTABLE)** | goquery, gjson (`4`) | N | Y | N | struct(+json anchors), array, map | gofmt |
|
|
34
|
+
| lua (5.2+), luajit(2+) **(UNSTABLE)**`5` | lua-htmlparser, lrexlib(opt), dkjson | N | Y | N | EmmyLua | LuaFormatter |
|
|
35
35
|
|
|
36
36
|
- **CSS3** means support next selectors:
|
|
37
37
|
- basic: (`tag`, `.class`, `#id`, `tag1,tag2`)
|
|
@@ -64,6 +64,7 @@ For maximum portability of the configuration to the target language:
|
|
|
64
64
|
Check the html parser lib documentation aboud CSS selectors before implement code. Examples:
|
|
65
65
|
1. Several libs not support `+` operations (eg: [selectolax(modest)](https://github.com/rushter/selectolax), [dart.universal_html](https://pub.dev/packages/universal_html))
|
|
66
66
|
2. For research purpose, lua_htmlparser include converter for unsupported CSS3 query syntax
|
|
67
|
+
|
|
67
68
|
2. HTML parser libs maybe not supports attribute selectors: `*=`, `~=`, `|=`, `^=`, `$=`
|
|
68
69
|
3. Several libs not support pseudo classes (eg: standard [dart.html](https://dart.dev/libraries/dart-html) lib miss this feature).
|
|
69
70
|
|
|
@@ -210,7 +211,6 @@ You can use any html source:
|
|
|
210
211
|
|
|
211
212
|
## See also
|
|
212
213
|
|
|
213
|
-
|
|
214
214
|
- [Brief](docs/briefing.md) about css selectors and regular expressions
|
|
215
215
|
- [Explain](docs/explain.md) short document on how to understand DSL syntax
|
|
216
216
|
- [LLM](llm.md) experimental prompt for generate code
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
from ssc_codegen.document import DocumentElementsFilter, HTMLDocument, ClassVarDocument, StringDocument, ArrayDocument, AssertDocument, NestedDocument, \
|
|
2
2
|
DefaultDocument, \
|
|
3
|
-
NumericDocument, JsonDocument, BooleanDocument, DocumentFilter
|
|
3
|
+
NumericDocument, JsonDocument, BooleanDocument, DocumentFilter, TransformDocument
|
|
4
4
|
from ssc_codegen.json_struct import Json
|
|
5
5
|
from ssc_codegen.logs import setup_logger
|
|
6
6
|
from ssc_codegen.schema import ItemSchema, DictSchema, ListSchema, FlatListSchema, AccUniqueListSchema
|
|
7
7
|
|
|
8
8
|
setup_logger()
|
|
9
9
|
|
|
10
|
-
VERSION = "0.
|
|
10
|
+
VERSION = "0.15.0"
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class __MISSING(object):
|
|
@@ -26,7 +26,8 @@ class Document(
|
|
|
26
26
|
DefaultDocument,
|
|
27
27
|
NumericDocument,
|
|
28
28
|
JsonDocument,
|
|
29
|
-
BooleanDocument
|
|
29
|
+
BooleanDocument,
|
|
30
|
+
TransformDocument
|
|
30
31
|
):
|
|
31
32
|
"""Special Common Document or Element marker manipulations"""
|
|
32
33
|
pass
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
from dataclasses import dataclass, field
|
|
2
|
-
from typing import Sequence, TypedDict, ClassVar, TypeVar
|
|
2
|
+
from typing import Sequence, TypedDict, ClassVar, TypeVar, TYPE_CHECKING
|
|
3
3
|
|
|
4
4
|
from ssc_codegen.ast_.base import T_EMPTY_KWARGS, BaseAstNode
|
|
5
5
|
from ssc_codegen.ast_.base import (
|
|
@@ -14,6 +14,9 @@ from ssc_codegen.tokens import (
|
|
|
14
14
|
VariableType,
|
|
15
15
|
)
|
|
16
16
|
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from ssc_codegen.transform import BaseTransform
|
|
19
|
+
|
|
17
20
|
KW_DOCSTRING = TypedDict("KW_DOCSTRING", {"value": str})
|
|
18
21
|
|
|
19
22
|
|
|
@@ -34,11 +37,32 @@ class Docstring(_DisableRepr, BaseAstNode[KW_DOCSTRING, tuple[str]]):
|
|
|
34
37
|
"""
|
|
35
38
|
|
|
36
39
|
kind: ClassVar[TokenType] = TokenType.DOCSTRING
|
|
37
|
-
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# push transform for resolve imports (dependencies)
|
|
43
|
+
KW_MODULE_IMPORTS = TypedDict(
|
|
44
|
+
"KW_MODULE_IMPORTS", {"transforms": list["BaseTransform"]}
|
|
45
|
+
)
|
|
46
|
+
ARGS_MODULE_IMPORTS = tuple[list["BaseTransform"]]
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@dataclass(kw_only=True)
|
|
50
|
+
class ModuleTransformImports(
|
|
51
|
+
BaseAstNode[KW_MODULE_IMPORTS, ARGS_MODULE_IMPORTS]
|
|
52
|
+
):
|
|
53
|
+
"""AST node representing module import transfrom dependencies.
|
|
54
|
+
|
|
55
|
+
This node contains import statements that will be added to the
|
|
56
|
+
generated module to ensure required dependencies are available.
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
kind: ClassVar[TokenType] = TokenType.TRANSFORM_IMPORTS
|
|
38
60
|
|
|
39
61
|
|
|
40
62
|
@dataclass(kw_only=True)
|
|
41
|
-
class ModuleImports(
|
|
63
|
+
class ModuleImports(
|
|
64
|
+
_DisableRepr, BaseAstNode[KW_MODULE_IMPORTS, ARGS_MODULE_IMPORTS]
|
|
65
|
+
):
|
|
42
66
|
"""AST node representing module import statements.
|
|
43
67
|
|
|
44
68
|
This node contains import statements that will be added to the
|
|
@@ -551,3 +575,17 @@ class CodeEnd(_DisableRepr, BaseAstNode):
|
|
|
551
575
|
"""
|
|
552
576
|
|
|
553
577
|
kind: ClassVar[TokenType] = TokenType.CODE_END
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
KW_TRANSFORM = TypedDict("KW_TRANSFORM", {"transform": "BaseTransform"})
|
|
581
|
+
ARGS_TRANSFORM = tuple["BaseTransform"]
|
|
582
|
+
|
|
583
|
+
|
|
584
|
+
@dataclass(kw_only=True)
|
|
585
|
+
class ExprTransform(BaseAstNode[KW_TRANSFORM, ARGS_TRANSFORM]):
|
|
586
|
+
kind: ClassVar[TokenType] = TokenType.TRANSFORM
|
|
587
|
+
|
|
588
|
+
|
|
589
|
+
@dataclass(kw_only=True)
|
|
590
|
+
class ModuleUtilities(_DisableRepr, BaseAstNode):
|
|
591
|
+
kind: ClassVar[TokenType] = TokenType.UTILITIES
|
|
@@ -3,6 +3,7 @@ from typing import MutableSequence, Type, cast
|
|
|
3
3
|
import warnings
|
|
4
4
|
from typing_extensions import Self
|
|
5
5
|
|
|
6
|
+
from ssc_codegen.ast_ import ModuleTransformImports, ModuleUtilities
|
|
6
7
|
from ssc_codegen.ast_.base import BaseAstNode
|
|
7
8
|
from ssc_codegen.ast_.nodes_cast import ExprJsonify, ExprNested
|
|
8
9
|
from ssc_codegen.ast_.nodes_core import (
|
|
@@ -113,7 +114,16 @@ class AstBuilder:
|
|
|
113
114
|
Docstring(kwargs={"value": module_doc}, parent=self.module)
|
|
114
115
|
)
|
|
115
116
|
# import node
|
|
116
|
-
|
|
117
|
+
# fallback add ModuleImports.kwargs["transform"] if target language not allowed use multiple import directives
|
|
118
|
+
self.module.body.append(
|
|
119
|
+
ModuleImports(parent=self.module, kwargs={"transforms": []})
|
|
120
|
+
)
|
|
121
|
+
self.module.body.append(
|
|
122
|
+
ModuleTransformImports(
|
|
123
|
+
parent=self.module, kwargs={"transforms": []}
|
|
124
|
+
)
|
|
125
|
+
)
|
|
126
|
+
self.module.body.append(ModuleUtilities(parent=self.module))
|
|
117
127
|
# CodeStart hook node
|
|
118
128
|
self.module.body.append(CodeStart(parent=self.module))
|
|
119
129
|
return self
|
|
@@ -398,10 +408,23 @@ class AstBuilder:
|
|
|
398
408
|
# generate typedef as annotation node
|
|
399
409
|
return st
|
|
400
410
|
|
|
411
|
+
@staticmethod
|
|
412
|
+
def is_collected_type_transform(transforms: list, target: object) -> bool:
|
|
413
|
+
for t in transforms:
|
|
414
|
+
if isinstance(t, type(target)):
|
|
415
|
+
return True
|
|
416
|
+
return False
|
|
417
|
+
|
|
401
418
|
def add_struct_parsers(self, *struct_parsers: Type[BaseSchema]) -> Self:
|
|
402
419
|
ssc_structs = []
|
|
403
420
|
ssc_typedefs = []
|
|
421
|
+
ssc_transforms = []
|
|
404
422
|
for schema in struct_parsers:
|
|
423
|
+
if schema.__SSC_TRANSFORMS__:
|
|
424
|
+
# check current used transforms for avoid generate duplicate imports
|
|
425
|
+
for t in schema.__SSC_TRANSFORMS__:
|
|
426
|
+
if not any(isinstance(i, type(t)) for i in ssc_transforms):
|
|
427
|
+
ssc_transforms.append(t)
|
|
405
428
|
if is_literals_only_schema(schema):
|
|
406
429
|
if schema.__SCHEMA_TYPE__ != StructType.ITEM:
|
|
407
430
|
raise TypeError(
|
|
@@ -420,6 +443,21 @@ class AstBuilder:
|
|
|
420
443
|
continue
|
|
421
444
|
ssc_typedefs.append(typedef)
|
|
422
445
|
# assembly
|
|
446
|
+
|
|
447
|
+
# insert transforms imports (in high-level API provide insert dependencies)
|
|
448
|
+
|
|
449
|
+
node_transform_import = self.module.find_node_by_token(
|
|
450
|
+
ModuleTransformImports.kind
|
|
451
|
+
)
|
|
452
|
+
node_transform_import = cast(
|
|
453
|
+
ModuleTransformImports, node_transform_import
|
|
454
|
+
)
|
|
455
|
+
node_transform_import.kwargs["transforms"] = ssc_transforms.copy()
|
|
456
|
+
|
|
457
|
+
node_import = self.module.find_node_by_token(ModuleImports.kind)
|
|
458
|
+
node_import = cast(ModuleImports, node_import)
|
|
459
|
+
node_import.kwargs["transform"] = ssc_transforms.copy()
|
|
460
|
+
|
|
423
461
|
self.module.body.extend(ssc_typedefs)
|
|
424
462
|
self.module.body.extend(ssc_structs)
|
|
425
463
|
self.module.body.append(CodeEnd(parent=self.module))
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
from typing import Callable
|
|
4
4
|
from ssc_codegen.str_utils import (
|
|
5
5
|
go_unimport_naive,
|
|
6
|
-
py_remove_unused_none_type_import,
|
|
7
6
|
)
|
|
8
7
|
|
|
9
8
|
|
|
@@ -28,7 +27,6 @@ class BaseCodeCallback:
|
|
|
28
27
|
return code
|
|
29
28
|
|
|
30
29
|
|
|
31
|
-
CB_PY_CODE = BaseCodeCallback(py_remove_unused_none_type_import)
|
|
32
30
|
CB_GO_CODE = BaseCodeCallback(go_unimport_naive, remove_empty_lines=True)
|
|
33
31
|
CB_DART_CODE = BaseCodeCallback(remove_empty_lines=True)
|
|
34
32
|
CB_JS_CODE = BaseCodeCallback(remove_empty_lines=True)
|
|
@@ -25,7 +25,6 @@ from ssc_codegen.cli.cli_utils import (
|
|
|
25
25
|
suggest_class_name,
|
|
26
26
|
)
|
|
27
27
|
from ssc_codegen.cli.code_callbacks import (
|
|
28
|
-
CB_PY_CODE,
|
|
29
28
|
CB_GO_CODE,
|
|
30
29
|
CB_JS_CODE,
|
|
31
30
|
)
|
|
@@ -208,7 +207,6 @@ def gen_py(
|
|
|
208
207
|
xpath_to_css=to_css,
|
|
209
208
|
css_to_xpath=to_xpath,
|
|
210
209
|
debug_instructions=debug,
|
|
211
|
-
code_cb=CB_PY_CODE,
|
|
212
210
|
gen_docstring=docstring,
|
|
213
211
|
)
|
|
214
212
|
|
|
@@ -51,6 +51,9 @@ from typing_extensions import assert_never
|
|
|
51
51
|
|
|
52
52
|
from ssc_codegen.ast_ import (
|
|
53
53
|
Docstring,
|
|
54
|
+
ExprTransform,
|
|
55
|
+
ModuleTransformImports,
|
|
56
|
+
ModuleUtilities,
|
|
54
57
|
StructParser,
|
|
55
58
|
ExprReturn,
|
|
56
59
|
ExprNoReturn,
|
|
@@ -393,21 +396,37 @@ def pre_docstring(node: Docstring) -> str:
|
|
|
393
396
|
|
|
394
397
|
@CONVERTER(ModuleImports.kind)
|
|
395
398
|
def pre_module_imports(_node: ModuleImports) -> str:
|
|
399
|
+
# TODO: resolve imports
|
|
400
|
+
return IMPORTS.replace("$PACKAGE$", CONVERTER.PACKAGE)
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
@CONVERTER(ModuleTransformImports.kind)
|
|
404
|
+
def pre_transform_imports(node: ModuleTransformImports) -> str:
|
|
405
|
+
transforms, *_ = node.unpack_args()
|
|
406
|
+
if transforms:
|
|
407
|
+
for t in transforms:
|
|
408
|
+
if t.collect_dependencies("go_goquery"):
|
|
409
|
+
raise NotImplementedError(
|
|
410
|
+
"Current converter implementation not support pass extra import dependencies"
|
|
411
|
+
)
|
|
412
|
+
return ""
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
@CONVERTER(ExprTransform.kind)
|
|
416
|
+
def pre_transform(node: ExprTransform) -> str:
|
|
417
|
+
prv, nxt = prev_next_var(node)
|
|
418
|
+
transform, *_ = node.unpack_args()
|
|
419
|
+
parts = transform.emit("go_goquery", prv, nxt)
|
|
420
|
+
return "\n" + "\n".join(parts)
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
@CONVERTER(ModuleUtilities.kind)
|
|
424
|
+
def pre_module_utilities(_: ModuleUtilities) -> str:
|
|
396
425
|
# HACK:
|
|
397
|
-
# golang not allowed override functions, check loaded helper functions by flag
|
|
398
|
-
helper_functions = (
|
|
399
|
-
HELPER_FUNCTIONS if not CONVERTER.HELPER_FUNCS_IMPORTED else ""
|
|
400
|
-
)
|
|
401
|
-
code = (
|
|
402
|
-
# magic constant
|
|
403
|
-
IMPORTS.replace("$PACKAGE$", CONVERTER.PACKAGE)
|
|
404
|
-
# HACK: push helper functions to ModuleImports token:
|
|
405
|
-
# its generated second after module docstring
|
|
406
|
-
+ helper_functions
|
|
407
|
-
)
|
|
426
|
+
# golang not allowed override or duplicate functions, check loaded helper functions by flag
|
|
408
427
|
if not CONVERTER.HELPER_FUNCS_IMPORTED:
|
|
409
428
|
CONVERTER.HELPER_FUNCS_IMPORTED = True
|
|
410
|
-
return
|
|
429
|
+
return HELPER_FUNCTIONS if not CONVERTER.HELPER_FUNCS_IMPORTED else ""
|
|
411
430
|
|
|
412
431
|
|
|
413
432
|
def get_typedef_field_by_name(node: TypeDef, field_name: str) -> str:
|
|
@@ -23,6 +23,9 @@ from typing import cast
|
|
|
23
23
|
|
|
24
24
|
from ssc_codegen.ast_ import (
|
|
25
25
|
Docstring,
|
|
26
|
+
ExprTransform,
|
|
27
|
+
ModuleTransformImports,
|
|
28
|
+
ModuleUtilities,
|
|
26
29
|
StructParser,
|
|
27
30
|
ExprReturn,
|
|
28
31
|
ExprNoReturn,
|
|
@@ -173,7 +176,11 @@ DOCSTR_START = "/**"
|
|
|
173
176
|
DOCSTR_END = "*/"
|
|
174
177
|
DOCSTR_SEP = "* "
|
|
175
178
|
CONVERTER = BaseCodeConverter(debug_comment_prefix="// ")
|
|
176
|
-
|
|
179
|
+
CONVERTER.TEST_EXCLUDE_NODES.extend(
|
|
180
|
+
[
|
|
181
|
+
ModuleImports.kind, # not use imports
|
|
182
|
+
]
|
|
183
|
+
)
|
|
177
184
|
|
|
178
185
|
|
|
179
186
|
# TODO: move to string_utils
|
|
@@ -213,8 +220,30 @@ def py_sequence_to_js_array(values: tuple[str, ...] | list[str]) -> str:
|
|
|
213
220
|
return "[" + val_arr[1:-1] + "]"
|
|
214
221
|
|
|
215
222
|
|
|
216
|
-
@CONVERTER(
|
|
217
|
-
def
|
|
223
|
+
@CONVERTER(ModuleTransformImports.kind)
|
|
224
|
+
def pre_transform_imports(node: ModuleTransformImports) -> str:
|
|
225
|
+
transforms, *_ = node.unpack_args()
|
|
226
|
+
|
|
227
|
+
if not transforms:
|
|
228
|
+
return ""
|
|
229
|
+
|
|
230
|
+
code_imports = []
|
|
231
|
+
for t in transforms:
|
|
232
|
+
if deps := t.collect_dependencies("js_pure"):
|
|
233
|
+
code_imports.append("\n".join(deps))
|
|
234
|
+
return "\n".join(code_imports)
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
@CONVERTER(ExprTransform.kind)
|
|
238
|
+
def pre_transform(node: ExprTransform) -> str:
|
|
239
|
+
# extend transform search provide py_bs4 module
|
|
240
|
+
prv, nxt = prev_next_var(node)
|
|
241
|
+
transform, *_ = node.unpack_args()
|
|
242
|
+
return "\n".join(f"{i};" for i in transform.emit("js_pure", prv, nxt))
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
@CONVERTER(ModuleUtilities.kind)
|
|
246
|
+
def pre_imports(_: ModuleUtilities) -> str:
|
|
218
247
|
return HELPER_FUNCTIONS
|
|
219
248
|
|
|
220
249
|
|
|
@@ -28,6 +28,9 @@ from typing import Any, cast
|
|
|
28
28
|
|
|
29
29
|
from ssc_codegen.ast_ import (
|
|
30
30
|
Docstring,
|
|
31
|
+
ExprTransform,
|
|
32
|
+
ModuleTransformImports,
|
|
33
|
+
ModuleUtilities,
|
|
31
34
|
StructParser,
|
|
32
35
|
ExprReturn,
|
|
33
36
|
ExprNoReturn,
|
|
@@ -187,6 +190,7 @@ CONVERTER.TEST_EXCLUDE_NODES.extend(
|
|
|
187
190
|
FilterDocHasText.kind,
|
|
188
191
|
FilterDocIsRegexText.kind,
|
|
189
192
|
FilterDocIsRegexRaw.kind,
|
|
193
|
+
# NOT IMPLEMENTED
|
|
190
194
|
]
|
|
191
195
|
)
|
|
192
196
|
|
|
@@ -291,7 +295,34 @@ def py_regex_to_lua_rex_pcre(
|
|
|
291
295
|
|
|
292
296
|
@CONVERTER(ModuleImports.kind)
|
|
293
297
|
def pre_imports(_: ModuleImports) -> str:
|
|
294
|
-
return IMPORTS
|
|
298
|
+
return IMPORTS
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
@CONVERTER(ModuleTransformImports.kind)
|
|
302
|
+
def pre_transform_imports(node: ModuleTransformImports) -> str:
|
|
303
|
+
transforms, *_ = node.unpack_args()
|
|
304
|
+
|
|
305
|
+
if not transforms:
|
|
306
|
+
return ""
|
|
307
|
+
|
|
308
|
+
code_imports = []
|
|
309
|
+
for t in transforms:
|
|
310
|
+
if deps := t.collect_dependencies("lua_htmlparser"):
|
|
311
|
+
code_imports.append("\n".join(deps))
|
|
312
|
+
return "\n".join(code_imports)
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
@CONVERTER(ModuleUtilities.kind)
|
|
316
|
+
def pre_utilities(_: ModuleUtilities) -> str:
|
|
317
|
+
return HELPER_FUNCTIONS
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
@CONVERTER(ExprTransform.kind)
|
|
321
|
+
def pre_transform(node: ExprTransform) -> str:
|
|
322
|
+
prv, nxt = prev_next_var(node)
|
|
323
|
+
transform, *_ = node.unpack_args()
|
|
324
|
+
parts = transform.emit("lua_htmlparser", prv, nxt)
|
|
325
|
+
return "\n" + "\n".join(parts)
|
|
295
326
|
|
|
296
327
|
|
|
297
328
|
@CONVERTER(Docstring.kind)
|