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

Unified Diff: bindings/scripts/generate_idl_diff.py

Issue 2786203002: Roll 50: Copied IDLs, PYTHON scripts from WebKit removed deleted files in WebCore (Closed)
Patch Set: Created 3 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « bindings/scripts/generate_global_constructors.py ('k') | bindings/scripts/generate_idl_diff_test.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: bindings/scripts/generate_idl_diff.py
diff --git a/bindings/scripts/generate_idl_diff.py b/bindings/scripts/generate_idl_diff.py
new file mode 100644
index 0000000000000000000000000000000000000000..ae98695aa495fcc8895202d8f49a22d7aa9aeed7
--- /dev/null
+++ b/bindings/scripts/generate_idl_diff.py
@@ -0,0 +1,184 @@
+#!/usr/bin/env python
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""generate_idl_diff.py is a script that generates a diff of two given IDL files.
+Usage: generate_idl_diff.py old_file.json new_file.json diff_file.json
+ old_file.json: An input json file including idl data of old Chrome version
+ new_file.json: An input json file including idl data of new Chrome version
+ diff_file.json: An output json file expressing a diff between old_file.json
+ and new_file.json
+"""
+
+import json
+import os
+import sys
+
+
+"""Data structure of input files of this script.
+The format of the json files is as follows. Each json file contains multiple
+"interface"s. Each "interface" contains 'ExtAttributes', 'Consts', 'Attributes'
+and 'Operations'. Each item in them are called a "member".
+ {'InterfaceName': {
+ 'ExtAttributes': [{'Name': '...'},
+ ...,
+ ],
+ 'Consts': [{'Type': '...',
+ 'Name': '...',
+ 'Value': '...'
+ },
+ ...,
+ ],
+ 'Attributes': [{'Type': '...',
+ 'Name': '...',
+ 'ExtAttributes':[{'Name': '...'},
+ ...,
+ ]
+ },
+ ...,
+ ],
+ 'Operations': [{'Type': '...',
+ 'Name': '...',
+ 'ExtAttributes': [{'Name': '...'},
+ ...,
+ ]
+ 'Arguments': [{'Type': '...',
+ 'Name': '...'},
+ ...,
+ ]
+ },
+ ...,
+ ],
+ 'Name': '...'
+ },
+ ...,
+ }
+"""
+
+
+EXTATTRIBUTES_AND_MEMBER_TYPES = ['ExtAttributes', 'Consts', 'Attributes', 'Operations']
+DIFF_INSENSITIVE_FIELDS = ['Name']
+DIFF_TAG = 'diff_tag'
+DIFF_TAG_ADDED = 'added'
+DIFF_TAG_DELETED = 'deleted'
+
+
+def load_json_file(filepath):
+ """Load a json file into a dictionary.
+ Args:
+ filepath: A json file path of a json file that we want to load
+ Returns:
+ An "interfaces" object loaded from the json file
+ """
+ with open(filepath, 'r') as f:
+ return json.load(f)
+
+
+def members_diff(old_interface, new_interface):
+ """Create a diff between two "interface" objects by adding annotations to
+ "member" objects that are not common in them.
+ Args:
+ old_interface: An "interface" object
+ new_interface: An "interface" object
+ Returns:
+ (annotated, is_changed) where
+ annotated: An annotated "interface" object
+ is_changed: True if two interfaces are not identical, otherwise False
+ """
+ annotated = {}
+ is_changed = False
+ for member_type in EXTATTRIBUTES_AND_MEMBER_TYPES:
+ annotated_members = []
+ unannotated_members = []
+ for member in new_interface[member_type]:
+ if member in old_interface[member_type]:
+ unannotated_members.append(member)
+ old_interface[member_type].remove(member)
+ else:
+ is_changed = True
+ member[DIFF_TAG] = DIFF_TAG_ADDED
+ annotated_members.append(member)
+ annotated[member_type] = annotated_members
+ annotated[member_type].extend(unannotated_members)
+ for member_type in EXTATTRIBUTES_AND_MEMBER_TYPES:
+ for member in old_interface[member_type]:
+ is_changed = True
+ member[DIFF_TAG] = DIFF_TAG_DELETED
+ annotated[member_type].extend(old_interface[member_type])
+ for field in DIFF_INSENSITIVE_FIELDS:
+ annotated[field] = old_interface[field]
+ return (annotated, is_changed)
+
+
+def annotate_all_members(interface, diff_tag):
+ """Add annotations to all "member" objects of |interface|.
+ Args:
+ interface: An "interface" object whose members should be annotated with
+ |diff_tag|.
+ diff_tag: DIFF_TAG_ADDED or DIFF_TAG_DELETED
+ Returns:
+ Annotated "interface" object
+ """
+ for member_type in EXTATTRIBUTES_AND_MEMBER_TYPES:
+ for member in interface[member_type]:
+ member[DIFF_TAG] = diff_tag
+ return interface
+
+
+def interfaces_diff(old_interfaces, new_interfaces):
+ """Compare two "interfaces" objects and create a diff between them by
+ adding annotations (DIFF_TAG_ADDED or DIFF_TAG_DELETED) to each member
+ and/or interface.
+ Args:
+ old_interfaces: An "interfaces" object
+ new_interfaces: An "interfaces" object
+ Returns:
+ An "interfaces" object representing diff between |old_interfaces| and
+ |new_interfaces|
+ """
+ annotated = {}
+ for interface_name, interface in new_interfaces.items():
+ if interface_name in old_interfaces:
+ annotated_interface, is_changed = members_diff(old_interfaces[interface_name], interface)
+ if is_changed:
+ annotated[interface_name] = annotated_interface
+ del old_interfaces[interface_name]
+ else:
+ interface = annotate_all_members(interface, DIFF_TAG_ADDED)
+ interface[DIFF_TAG] = DIFF_TAG_ADDED
+ annotated[interface_name] = interface
+ for interface_name, interface in old_interfaces.items():
+ interface = annotate_all_members(interface, DIFF_TAG_DELETED)
+ interface[DIFF_TAG] = DIFF_TAG_DELETED
+ annotated.update(old_interfaces)
+ return annotated
+
+
+def write_diff(diff, filepath):
+ """Write a diff dictionary to a json file.
+ Args:
+ diff: An "interfaces" object that represents a diff
+ filepath: An output file path
+ """
+ with open(filepath, 'w') as f:
+ json.dump(diff, f, indent=4)
+
+
+def main(argv):
+ if len(argv) != 3:
+ sys.stdout.write(
+ 'Usage: make_diff.py <old_file.json> <new_file.json> '
+ '<diff_file.json>\n')
+ exit(1)
+ old_json_file = argv[0]
+ new_json_file = argv[1]
+ output_file = argv[2]
+ old_interfaces = load_json_file(old_json_file)
+ new_interfaces = load_json_file(new_json_file)
+ diff = interfaces_diff(old_interfaces, new_interfaces)
+ write_diff(diff, output_file)
+
+
+if __name__ == '__main__':
+ main(sys.argv[1:])
« no previous file with comments | « bindings/scripts/generate_global_constructors.py ('k') | bindings/scripts/generate_idl_diff_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698