Skip to content
This repository was archived by the owner on Jan 19, 2025. It is now read-only.

Commit 7ef5be1

Browse files
committed
Reformatting and Cleanup for #441
1 parent 1284bff commit 7ef5be1

File tree

8 files changed

+254
-443
lines changed

8 files changed

+254
-443
lines changed

package-parser/package_parser/commands/generate_annotations/_combine.py

-102
This file was deleted.

package-parser/package_parser/commands/generate_annotations/_generate_annotations.py

+121-83
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
import json
22
from io import TextIOWrapper
3-
from pathlib import Path
4-
from typing import Any
5-
6-
from package_parser.commands.find_usages import (
7-
ClassUsage,
8-
FunctionUsage,
9-
UsageStore,
10-
ValueUsage,
11-
)
3+
4+
from package_parser.commands.find_usages import UsageStore
125
from package_parser.commands.get_api import API
136
from package_parser.utils import parent_qname
147

158

16-
def generate_annotations(
17-
api_file: TextIOWrapper, usages_file: TextIOWrapper, out_dir: Path
18-
):
9+
def generate_annotations(api_file: TextIOWrapper, usages_file: TextIOWrapper, output_file: TextIOWrapper) -> None:
10+
# TODO: Make this a command line function?
11+
"""
12+
Generates an annotation file from the given API and UsageStore files, and writes it to the given output file.
13+
Annotations that are generated are: constant, unused,
14+
:param api_file: API file
15+
:param usages_file: UsageStore file
16+
:param output_file: Output file
17+
:return: None
18+
"""
19+
if api_file is None or usages_file is None or output_file is None:
20+
raise ValueError("api_file, usages_file, and output_file must be specified.")
21+
1922
with api_file:
2023
api_json = json.load(api_file)
2124
api = API.from_json(api_json)
@@ -24,12 +27,114 @@ def generate_annotations(
2427
usages_json = json.load(usages_file)
2528
usages = UsageStore.from_json(usages_json)
2629

27-
# out_dir.mkdir(parents=True, exist_ok=True)
28-
# base_file_name = api_file.name.replace("__api.json", "")
30+
annotation_functions = [__get_unused_annotations, __get_constant_annotations]
31+
32+
annotations_dict = __generate_annotation_dict(api, usages, annotation_functions)
2933

34+
json.dump(annotations_dict, output_file, indent=2)
35+
36+
37+
def __generate_annotation_dict(api: API, usages: UsageStore, functions: list[callable]):
3038
__preprocess_usages(usages, api)
31-
constant_parameters = __find_constant_parameters(usages, api)
32-
return constant_parameters
39+
40+
annotations_dict = {function(usages, api) for function in functions}
41+
42+
return annotations_dict
43+
44+
45+
def __get_constant_annotations(usages: UsageStore, api: API) -> dict[str, dict[str, dict[str, str]]]:
46+
"""
47+
Returns all parameters that are only ever assigned a single value.
48+
:param usages: UsageStore object
49+
:param api: API object for usages
50+
:return: {"constant": dict[str, dict[str, str]]}
51+
"""
52+
result: dict[str, dict[str, str]] = {}
53+
54+
for parameter_qname in list(usages.parameter_usages.keys()):
55+
56+
if len(usages.value_usages[parameter_qname].values()) == 0:
57+
continue
58+
59+
if len(usages.value_usages[parameter_qname].keys()) == 1:
60+
if usages.most_common_value(parameter_qname) is None:
61+
continue
62+
63+
target_name = __qname_to_target_name(api, parameter_qname)
64+
65+
default_type, default_value = __get_default_type_from_value(
66+
str(usages.most_common_value(parameter_qname))
67+
)
68+
69+
result[target_name] = {
70+
"target": target_name,
71+
"defaultType": default_type,
72+
"defaultValue": default_value,
73+
}
74+
75+
return {"constant": result}
76+
77+
78+
def __get_unused_annotations(usages: UsageStore, api: API) -> dict[str, dict[str, dict[str, str]]]:
79+
"""
80+
Returns all parameters that are never used.
81+
:param usages: UsageStore object
82+
:param api: API object for usages
83+
:return: {"unused": dict[str, dict[str, str]]}
84+
"""
85+
unuseds: dict[str, dict[str, str]] = {}
86+
87+
for parameter_name in list(usages.parameter_usages.keys()):
88+
if usages.parameter_usages.get(parameter_name) == 0:
89+
formatted_name = __qname_to_target_name(api, parameter_name)
90+
unuseds[formatted_name] = {"target": formatted_name}
91+
92+
return {"unused": unuseds}
93+
94+
95+
def __qname_to_target_name(api: API, qname: str) -> str:
96+
"""
97+
Formats the given name to the wanted format. This method is to be removed as soon as the UsageStore is updated to
98+
use the new format.
99+
:param api: API object
100+
:param qname: Name pre-formatting
101+
:return: Formatted name
102+
"""
103+
if qname is None or api is None:
104+
raise ValueError("qname and api must be specified.")
105+
106+
target_elements = qname.split(".")
107+
108+
package_name = api.package
109+
module_name = class_name = function_name = parameter_name = ""
110+
111+
if ".".join(target_elements) in api.parameters().keys():
112+
parameter_name = "/" + target_elements.pop()
113+
if ".".join(target_elements) in api.functions.keys():
114+
function_name = f"/{target_elements.pop()}"
115+
if ".".join(target_elements) in api.classes.keys():
116+
class_name = f"/{target_elements.pop()}"
117+
if ".".join(target_elements) in api.modules.keys():
118+
module_name = "/" + ".".join(target_elements)
119+
120+
return package_name + module_name + class_name + function_name + parameter_name
121+
122+
123+
def __get_default_type_from_value(default_value: str) -> tuple[str, str]:
124+
default_value = str(default_value)[1:-1]
125+
126+
if default_value == "null":
127+
default_type = "none"
128+
elif default_value == "True" or default_value == "False":
129+
default_type = "boolean"
130+
elif default_value.isnumeric():
131+
default_type = "number"
132+
default_value = default_value
133+
else:
134+
default_type = "string"
135+
default_value = default_value
136+
137+
return default_type, default_value
33138

34139

35140
def __preprocess_usages(usages: UsageStore, api: API) -> None:
@@ -121,70 +226,3 @@ def __add_implicit_usages_of_default_value(usages: UsageStore, api: API) -> None
121226

122227
for location in locations_of_implicit_usages_of_default_value:
123228
usages.add_value_usage(parameter_qname, default_value, location)
124-
125-
126-
def __find_constant_parameters(
127-
usages: UsageStore, api: API
128-
) -> dict[str, dict[str, str]]:
129-
"""
130-
Returns all parameters that are only ever assigned a single value.
131-
132-
:param usages: Usage store
133-
"""
134-
135-
result = {}
136-
137-
for parameter_qname in list(usages.parameter_usages.keys()):
138-
139-
if len(usages.value_usages[parameter_qname].values()) == 0:
140-
continue
141-
142-
if len(usages.value_usages[parameter_qname].keys()) == 1:
143-
target_name = __qname_to_target_name(api, parameter_qname)
144-
default_type, default_value = __get_default_type_from_value(
145-
str(usages.most_common_value(parameter_qname))
146-
)
147-
print(target_name)
148-
result[target_name] = {
149-
"target": target_name,
150-
"defaultType": default_type,
151-
"defaultValue": default_value,
152-
}
153-
154-
print(json.dumps(result))
155-
return result
156-
157-
158-
def __qname_to_target_name(api: API, qname: str) -> str:
159-
target_elements = qname.split(".")
160-
161-
package_name = api.package
162-
module_name = class_name = function_name = parameter_name = ""
163-
164-
if ".".join(target_elements) in api.parameters().keys():
165-
parameter_name = "/" + target_elements.pop()
166-
if ".".join(target_elements) in api.functions.keys():
167-
function_name = f"/{target_elements.pop()}"
168-
if ".".join(target_elements) in api.classes.keys():
169-
class_name = f"/{target_elements.pop()}"
170-
if ".".join(target_elements) in api.modules.keys():
171-
module_name = "/" + ".".join(target_elements)
172-
173-
return package_name + module_name + class_name + function_name + parameter_name
174-
175-
176-
def __get_default_type_from_value(default_value: str) -> tuple[str, str]:
177-
default_value = str(default_value)[1:-1]
178-
179-
if default_value == "null":
180-
default_type = "none"
181-
elif default_value == "True" or default_value == "False":
182-
default_type = "boolean"
183-
elif default_value.isnumeric():
184-
default_type = "number"
185-
default_value = default_value
186-
else:
187-
default_type = "string"
188-
default_value = default_value
189-
190-
return default_type, default_value

package-parser/package_parser/commands/generate_annotations/_generate_unused_annotations.py

-44
This file was deleted.

0 commit comments

Comments
 (0)