Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(340)

Side by Side Diff: third_party/WebKit/Source/bindings/scripts/generate_idl_diff.py

Issue 1363203003: Make a dictionary that expresses a diff between two json files including AST. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright 2015 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 """generate_idl_diff.py is a script that generates a diff of two given IDL files .
7 Usage: generate_idl_diff.py old_file.json new_file.json diff_file.json
8 old_file.json: An input json file including idl data of old Chrome version
9 new_file.json: An input json file including idl data of new Chrome version
10 diff_file.json: An output json file expressing a diff between old_file.json
11 and new_file.json
12 """
13
14 import json
15 import os
16 import sys
17
18
19 """Data structure of input files of this script.
20 The format of the json files is as follows. Each json file contains multiple
21 "interface"s. Each "interface" contains 'ExtAttributes', 'Consts', 'Attributes'
22 and 'Operations'. Each item in them are called a "member".
23 {'InterfaceName': {
Yuki 2015/09/25 03:55:59 nit: Better to add 'Name' key in the example.
shimadaa 2015/09/25 05:13:25 Done.
24 'ExtAttributes': [{'Name': '...'},
25 ...,
26 ],
27 'Consts': [{'Type': '...',
28 'Name': '...',
29 'Value': '...'
30 },
31 ...,
32 ],
33 'Attributes': [{'Type': '...',
34 'Name': '...',
35 'ExtAttributes':[{'Name': '...'},
36 ...,
37 ]
38 },
39 ...,
40 ],
41 'Operations': [{'Type': '...',
42 'Name': '...',
43 'ExtAttributes': [{'Name': '...'},
44 ...,
45 ]
46 'Arguments': [{'Type': '...',
47 'Name': '...'},
48 ...,
49 ]
50 },
51 ...,
52 ]
53 },
54 ...,
55 }
56 """
57
58
59 EXTATTRIBUTES_AND_MEMBER_TYPES = ['ExtAttributes', 'Consts', 'Attributes', 'Oper ations']
60 DIFF_INSENSITIVE_FIELDS = ['Name']
61 DIFF_TAG = 'diff_tag'
62 DIFF_TAG_ADDED = 'added'
63 DIFF_TAG_DELETED = 'deleted'
64
65
66 def load_json_file(filepath):
67 """Load a json file into a dictionary.
68 Args:
69 filepath: A json file path of a json file that we want to load
70 Returns:
71 An "interfaces" object loaded from the json file
72 """
73 with open(filepath, 'r') as f:
74 return json.load(f)
75
76
77 def members_diff(old_interface, new_interface):
78 """Create a diff between two "interface" objects by adding annotations to
79 "member" objects that are not common in them.
80 Args:
81 old_interface: An "interface" object
82 new_interface: An "interface" object
83 Returns:
84 (annotated, is_changed) where
85 annotated: An annotated "interface" object
86 is_changed: True if two interfaces are not identical, otherwise False
87 """
88 annotated = {}
89 is_changed = False
90 for member_type in EXTATTRIBUTES_AND_MEMBER_TYPES:
91 annotated_members = []
92 unannotated_members = []
93 for member in new_interface[member_type]:
94 if member in old_interface[member_type]:
95 unannotated_members.append(member)
96 old_interface[member_type].remove(member)
97 else:
98 is_changed = True
99 member[DIFF_TAG] = DIFF_TAG_ADDED
100 annotated_members.append(member)
101 annotated[member_type] = annotated_members
102 annotated[member_type].extend(unannotated_members)
103 for member_type in EXTATTRIBUTES_AND_MEMBER_TYPES:
104 for member in old_interface[member_type]:
105 is_changed = True
106 member[DIFF_TAG] = DIFF_TAG_DELETED
107 annotated[member_type].extend(old_interface[member_type])
108 for field in DIFF_INSENSITIVE_FIELDS:
109 annotated[field] = old_interface[field]
110 return (annotated, is_changed)
111
112
113 def annotate_all_members(interface, diff_tag):
114 """Add annotations to all "member" objects of |interface|.
115 Args:
116 interface: An "interface" object whose members should be annotated with
117 |diff_tag|.
118 diff_tag: DIFF_TAG_ADDED or DIFF_TAG_DELETED
119 Returns:
120 Annotated "interface" object
121 """
122 for member_type in EXTATTRIBUTES_AND_MEMBER_TYPES:
123 for member in interface[member_type]:
124 member[DIFF_TAG] = diff_tag
125 return interface
126
127
128 def interfaces_diff(old_interfaces, new_interfaces):
129 """Compare two "interfaces" objects and create a diff between them by
130 adding annotations (DIFF_TAG_ADDED or DIFF_TAG_DELETED) to each member
131 and/or interface.
132 Args:
133 old_interfaces: An "interfaces" object
134 new_interfaces: An "interfaces" object
135 Returns:
136 An "interfaces" object representing diff between |old_interfaces| and
137 |new_interfaces|
138 """
139 annotated = {}
140 for interface_name, interface in new_interfaces.items():
141 if interface_name in old_interfaces:
142 annotated_interface, is_changed = members_diff(old_interfaces[interf ace_name], interface)
143 if is_changed:
144 annotated[interface_name] = annotated_interface
145 del old_interfaces[interface_name]
146 else:
147 interface = annotate_all_members(interface, DIFF_TAG_ADDED)
148 interface[DIFF_TAG] = DIFF_TAG_ADDED
149 annotated[interface_name] = interface
150 for interface_name, interface in old_interfaces.items():
151 interface = annotate_all_members(interface, DIFF_TAG_DELETED)
152 interface[DIFF_TAG] = DIFF_TAG_DELETED
153 annotated.update(old_interfaces)
154 return annotated
155
156
157 def write_diff(diff, filepath):
158 """Write a diff dictionary to a json file.
159 Args:
160 diff: An "interfaces" object that represents a diff
161 filepath: An output file path
162 """
163 with open(filepath, 'w') as f:
164 json.dump(diff, f, indent=4)
165
166
167 def main(argv):
168 if len(argv) != 3:
169 sys.stdout.write(
170 'Usage: make_diff.py <old_file.json> <new_file.json> '
171 '<diff_file.jsson>\n')
172 exit(1)
173 old_json_file = argv[0]
174 new_json_file = argv[1]
175 output_file = argv[2]
176 old_interfaces = load_json_file(old_json_file)
177 new_interfaces = load_json_file(new_json_file)
178 diff = interfaces_diff(old_interfaces, new_interfaces)
179 write_diff(diff, output_file)
180
181
182 if __name__ == '__main__':
183 main(sys.argv[1:])
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698