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

Commit 8ad8e6a

Browse files
authored
feat: migrate @CalledAfter annotations (#1152)
Closes #1150. ### Summary of Changes - Migration of `@CalledAfter` annotations through a mapping from old api elements to new api elements for the two function called before or after. If there is no mapping from the function called before to another function in the class of the apiv2 element, an unsure `@CalledAfter` annotation will be created with the same name as the function called before. Else, a `@CalledAfter` annotation will be created, if the called before function is mapped to only one other function and the annotated apiv2 element is a function. Otherwise, mark the mapped apiv2 elements with a `@todo` annotation. ### Testing Instructions run the migrate command or view and run the `test_migration.py` file Co-authored-by: Aclrian <[email protected]>
1 parent 36026ea commit 8ad8e6a

File tree

9 files changed

+620
-30
lines changed

9 files changed

+620
-30
lines changed

package-parser/package_parser/processing/migration/_migrate.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,14 @@
77
from package_parser.processing.api.model import Attribute, Result
88
from package_parser.processing.migration.annotations import (
99
migrate_boundary_annotation,
10+
migrate_called_after_annotation,
1011
migrate_enum_annotation,
12+
migrate_move_annotation,
13+
migrate_remove_annotation,
1114
migrate_rename_annotation,
1215
migrate_todo_annotation,
1316
migrate_value_annotation,
1417
)
15-
from package_parser.processing.migration.annotations._migrate_move_annotation import (
16-
migrate_move_annotation,
17-
)
18-
from package_parser.processing.migration.annotations._migrate_remove_annotation import (
19-
migrate_remove_annotation,
20-
)
2118
from package_parser.processing.migration.model import Mapping
2219

2320

@@ -45,6 +42,14 @@ def migrate_annotations(
4542
for annotation in migrate_boundary_annotation(boundary_annotation, mapping):
4643
migrated_annotation_store.add_annotation(annotation)
4744

45+
for called_after_annotation in annotationsv1.calledAfterAnnotations:
46+
mapping = _get_mapping_from_annotation(called_after_annotation, mappings)
47+
if mapping is not None:
48+
for annotation in migrate_called_after_annotation(
49+
called_after_annotation, mapping, mappings
50+
):
51+
migrated_annotation_store.add_annotation(annotation)
52+
4853
for enum_annotation in annotationsv1.enumAnnotations:
4954
mapping = _get_mapping_from_annotation(enum_annotation, mappings)
5055
if mapping is not None:
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
from ._constants import migration_author
22
from ._get_migration_text import get_migration_text
33
from ._migrate_boundary_annotation import migrate_boundary_annotation
4+
from ._migrate_called_after_annotation import migrate_called_after_annotation
45
from ._migrate_enum_annotation import migrate_enum_annotation
6+
from ._migrate_move_annotation import migrate_move_annotation
7+
from ._migrate_remove_annotation import migrate_remove_annotation
58
from ._migrate_rename_annotation import migrate_rename_annotation
69
from ._migrate_todo_annotation import migrate_todo_annotation
710
from ._migrate_value_annotation import migrate_value_annotation

package-parser/package_parser/processing/migration/annotations/_get_migration_text.py

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from typing import Any, Sequence
2+
13
from package_parser.processing.annotations.model import (
24
AbstractAnnotation,
35
BoundaryAnnotation,
@@ -15,6 +17,13 @@
1517
TodoAnnotation,
1618
ValueAnnotation,
1719
)
20+
from package_parser.processing.api.model import (
21+
Attribute,
22+
Class,
23+
Function,
24+
Parameter,
25+
Result,
26+
)
1827
from package_parser.processing.migration import Mapping
1928

2029

@@ -75,7 +84,9 @@ def _get_further_information(annotation: AbstractAnnotation) -> str:
7584
return " with the data '" + str(annotation.to_json()) + "'"
7685

7786

78-
def get_migration_text(annotation: AbstractAnnotation, mapping: Mapping) -> str:
87+
def get_migration_text(
88+
annotation: AbstractAnnotation, mapping: Mapping, additional_information: Any = None
89+
) -> str:
7990
class_name = str(annotation.__class__.__name__)
8091
if class_name.endswith("Annotation"):
8192
class_name = class_name[:-10]
@@ -89,13 +100,29 @@ def get_migration_text(annotation: AbstractAnnotation, mapping: Mapping) -> str:
89100
" from the previous version was at '"
90101
+ annotation.target
91102
+ "' and the possible alternatives in the new version of the api are: "
92-
+ ", ".join(
93-
map(
94-
lambda api_element: api_element.id
95-
if hasattr(api_element, "id")
96-
else api_element.name,
97-
mapping.get_apiv2_elements(),
103+
+ _list_api_elements(mapping.get_apiv2_elements())
104+
)
105+
if additional_information is not None and isinstance(additional_information, list):
106+
functions = [
107+
function
108+
for function in additional_information
109+
if isinstance(function, Function)
110+
]
111+
if len(functions) > 0:
112+
migrate_text += (
113+
" and the possible replacements (" + _list_api_elements(functions) + ")"
98114
)
115+
return migrate_text
116+
117+
118+
def _list_api_elements(
119+
api_elements: Sequence[Attribute | Class | Function | Parameter | Result],
120+
) -> str:
121+
return ", ".join(
122+
map(
123+
lambda api_element: api_element.id
124+
if hasattr(api_element, "id")
125+
else api_element.name,
126+
api_elements,
99127
)
100128
)
101-
return migrate_text
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
from copy import deepcopy
2+
3+
from package_parser.processing.annotations.model import (
4+
AbstractAnnotation,
5+
CalledAfterAnnotation,
6+
EnumReviewResult,
7+
TodoAnnotation,
8+
)
9+
from package_parser.processing.api.model import Attribute, Function, Result
10+
from package_parser.processing.migration.model import Mapping
11+
12+
from ._constants import migration_author
13+
from ._get_migration_text import get_migration_text
14+
15+
16+
def migrate_called_after_annotation(
17+
called_after_annotation: CalledAfterAnnotation,
18+
mapping: Mapping,
19+
mappings: list[Mapping],
20+
) -> list[AbstractAnnotation]:
21+
called_after_annotation = deepcopy(called_after_annotation)
22+
authors = called_after_annotation.authors
23+
authors.append(migration_author)
24+
called_after_annotation.authors = authors
25+
26+
migrated_annotations: list[AbstractAnnotation] = []
27+
for element in mapping.get_apiv2_elements():
28+
if not isinstance(element, Function):
29+
if not isinstance(element, (Attribute, Result)):
30+
migrated_annotations.append(
31+
TodoAnnotation(
32+
element.id,
33+
authors,
34+
called_after_annotation.reviewers,
35+
called_after_annotation.comment,
36+
called_after_annotation.reviewResult,
37+
get_migration_text(called_after_annotation, mapping),
38+
)
39+
)
40+
continue
41+
42+
called_before_functions = _get_function_called_before_replacements(
43+
called_after_annotation, mappings, element
44+
)
45+
migrate_text = get_migration_text(
46+
called_after_annotation,
47+
mapping,
48+
additional_information=called_before_functions,
49+
)
50+
if len(called_before_functions) == 0:
51+
migrated_annotations.append(
52+
CalledAfterAnnotation(
53+
element.id,
54+
authors,
55+
called_after_annotation.reviewers,
56+
called_after_annotation.comment,
57+
EnumReviewResult.UNSURE,
58+
called_after_annotation.calledAfterName,
59+
)
60+
)
61+
elif (
62+
len(called_before_functions) == 1 and called_before_functions[0] != element
63+
):
64+
migrated_annotations.append(
65+
CalledAfterAnnotation(
66+
element.id,
67+
authors,
68+
called_after_annotation.reviewers,
69+
called_after_annotation.comment,
70+
called_after_annotation.reviewResult,
71+
called_before_functions[0].name,
72+
)
73+
)
74+
else:
75+
migrated_annotations.append(
76+
TodoAnnotation(
77+
element.id,
78+
authors,
79+
called_after_annotation.reviewers,
80+
called_after_annotation.comment,
81+
EnumReviewResult.NONE,
82+
migrate_text,
83+
)
84+
)
85+
return migrated_annotations
86+
87+
88+
def _get_function_called_before_replacements(
89+
called_after_annotation: CalledAfterAnnotation,
90+
mappings: list[Mapping],
91+
functionv2: Function,
92+
) -> list[Function]:
93+
called_before_idv1 = (
94+
"/".join(called_after_annotation.target.split("/")[:-1])
95+
+ "/"
96+
+ called_after_annotation.calledAfterName
97+
)
98+
called_before_idv2_prefix = "/".join(functionv2.id.split("/")[:-1]) + "/"
99+
functions_in_same_class: list[Function] = []
100+
for mapping in mappings:
101+
found_mapped_function_in_same_class = False
102+
for element in mapping.get_apiv1_elements():
103+
if isinstance(element, Function) and called_before_idv1 == element.id:
104+
found_mapped_function_in_same_class = True
105+
break
106+
107+
if found_mapped_function_in_same_class:
108+
for replacement in mapping.get_apiv2_elements():
109+
if isinstance(replacement, Function) and replacement.id.startswith(
110+
called_before_idv2_prefix
111+
):
112+
functions_in_same_class.append(replacement)
113+
break
114+
return functions_in_same_class

package-parser/tests/processing/migration/annotations/test_boundary_migration.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def migrate_boundary_annotation_data_one_to_one_mapping() -> Tuple[
3030
parameterv1 = Parameter(
3131
id_="test/test.boundary.test1.testA",
3232
name="testA",
33-
qname="test.enum.test1.testA",
33+
qname="test.boundary.test1.testA",
3434
default_value="1",
3535
assigned_by=ParameterAssignment.POSITION_OR_NAME,
3636
is_public=True,
@@ -39,7 +39,7 @@ def migrate_boundary_annotation_data_one_to_one_mapping() -> Tuple[
3939
parameterv2 = Parameter(
4040
id_="test/test.boundary.test1.testB",
4141
name="testB",
42-
qname="test.enum.test1.testB",
42+
qname="test.boundary.test1.testB",
4343
default_value="1",
4444
assigned_by=ParameterAssignment.POSITION_OR_NAME,
4545
is_public=True,
@@ -88,7 +88,7 @@ def migrate_boundary_annotation_data_one_to_one_mapping_int_to_float() -> Tuple[
8888
parameterv1 = Parameter(
8989
id_="test/test.boundary.test2.testA",
9090
name="testA",
91-
qname="test.enum.test2.testA",
91+
qname="test.boundary.test2.testA",
9292
default_value="1",
9393
assigned_by=ParameterAssignment.POSITION_OR_NAME,
9494
is_public=True,
@@ -97,7 +97,7 @@ def migrate_boundary_annotation_data_one_to_one_mapping_int_to_float() -> Tuple[
9797
parameterv2 = Parameter(
9898
id_="test/test.boundary.test2.testB",
9999
name="testB",
100-
qname="test.enum.test2.testB",
100+
qname="test.boundary.test2.testB",
101101
default_value="1.0",
102102
assigned_by=ParameterAssignment.POSITION_OR_NAME,
103103
is_public=True,
@@ -152,7 +152,7 @@ def migrate_boundary_annotation_data_one_to_one_mapping_float_to_int() -> Tuple[
152152
parameterv1 = Parameter(
153153
id_="test/test.boundary.test3.testA",
154154
name="testA",
155-
qname="test.enum.test3.testA",
155+
qname="test.boundary.test3.testA",
156156
default_value="1.0",
157157
assigned_by=ParameterAssignment.POSITION_OR_NAME,
158158
is_public=True,
@@ -163,7 +163,7 @@ def migrate_boundary_annotation_data_one_to_one_mapping_float_to_int() -> Tuple[
163163
parameterv2 = Parameter(
164164
id_="test/test.boundary.test3.testB",
165165
name="testB",
166-
qname="test.enum.test3.testB",
166+
qname="test.boundary.test3.testB",
167167
default_value="1",
168168
assigned_by=ParameterAssignment.POSITION_OR_NAME,
169169
is_public=True,
@@ -215,7 +215,7 @@ def migrate_boundary_annotation_data_one_to_many_mapping() -> Tuple[
215215
parameterv1 = Parameter(
216216
id_="test/test.boundary.test4.testv1",
217217
name="testA",
218-
qname="test.enum.test4.testA",
218+
qname="test.boundary.test4.testA",
219219
default_value="1",
220220
assigned_by=ParameterAssignment.POSITION_OR_NAME,
221221
is_public=True,
@@ -224,7 +224,7 @@ def migrate_boundary_annotation_data_one_to_many_mapping() -> Tuple[
224224
parameterv2_a = Parameter(
225225
id_="test/test.boundary.test4.testA",
226226
name="testA",
227-
qname="test.enum.test4.testA",
227+
qname="test.boundary.test4.testA",
228228
default_value="1",
229229
assigned_by=ParameterAssignment.POSITION_OR_NAME,
230230
is_public=True,
@@ -233,7 +233,7 @@ def migrate_boundary_annotation_data_one_to_many_mapping() -> Tuple[
233233
parameterv2_b = Parameter(
234234
id_="test/test.boundary.test4.testB",
235235
name="testB",
236-
qname="test.enum.test4.testB",
236+
qname="test.boundary.test4.testB",
237237
default_value="1.0",
238238
assigned_by=ParameterAssignment.POSITION_OR_NAME,
239239
is_public=True,
@@ -244,7 +244,7 @@ def migrate_boundary_annotation_data_one_to_many_mapping() -> Tuple[
244244
parameterv2_c = Parameter(
245245
id_="test/test.boundary.test4.testC",
246246
name="testC",
247-
qname="test.enum.test4.testC",
247+
qname="test.boundary.test4.testC",
248248
default_value="",
249249
assigned_by=ParameterAssignment.POSITION_OR_NAME,
250250
is_public=True,

0 commit comments

Comments
 (0)