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

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

Issue 2756993003: [WebAgentsAPI]: Remove OverloadSetAdapter. (Closed)
Patch Set: Added a note about diverging from spec. 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 unified diff | Download patch
« no previous file with comments | « no previous file | third_party/WebKit/Source/bindings/scripts/overload_set_algorithm_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2017 The Chromium Authors. All rights reserved. 1 # Copyright 2017 The Chromium Authors. All rights reserved.
2 # coding=utf-8 2 # coding=utf-8
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 from collections import Counter 6 from collections import Counter
7 import itertools 7 import itertools
8 from operator import itemgetter 8 from operator import itemgetter
9 9
10 10
11 def sort_and_groupby(list_to_sort, key=None): 11 def sort_and_groupby(list_to_sort, key=None):
12 """Returns a generator of (key, list), sorting and grouping list by key.""" 12 """Returns a generator of (key, list), sorting and grouping list by key."""
13 list_to_sort.sort(key=key) 13 list_to_sort.sort(key=key)
14 return ((k, list(g)) for k, g in itertools.groupby(list_to_sort, key)) 14 return ((k, list(g)) for k, g in itertools.groupby(list_to_sort, key))
15 15
16 16
17 class OverloadSetAdapter(object): 17 def effective_overload_set(F): # pylint: disable=invalid-name
18 """Base class for the second effective_overload_set argument. Python is
19 a type-lax language, so this is mostly documentation of the expected
20 interface."""
21
22 def arguments(self, operation):
23 """Given an operation, return the list of its arguments."""
24 raise NotImplementedError
25
26 def type(self, argument):
27 """Given an argument, return its type."""
28 raise NotImplementedError
29
30 def is_optional(self, argument):
31 """Given an argument, return whether it is optional."""
32 raise NotImplementedError
33
34 def is_variadic(self, argument):
35 """"Given an argument, return whether it is variadic."""
36 raise NotImplementedError
37
38
39 class MethodContextAdapter(OverloadSetAdapter):
40 def arguments(self, operation):
41 return operation['arguments']
42
43 def type(self, argument):
44 return argument['idl_type_object']
45
46 def is_optional(self, argument):
47 return argument['is_optional']
48
49 def is_variadic(self, argument):
50 return argument['is_variadic']
51
52
53 def effective_overload_set(F, adapter): # pylint: disable=invalid-name
54 """Returns the effective overload set of an overloaded function. 18 """Returns the effective overload set of an overloaded function.
55 19
56 An effective overload set is the set of overloaded functions + signatures 20 An effective overload set is the set of overloaded functions + signatures
57 (type list of arguments, with optional and variadic arguments included or 21 (type list of arguments, with optional and variadic arguments included or
58 not), and is used in the overload resolution algorithm. 22 not), and is used in the overload resolution algorithm.
59 23
60 For example, given input [f1(optional long x), f2(DOMString s)], the output 24 For example, given input [f1(optional long x), f2(DOMString s)], the output
61 is informally [f1(), f1(long), f2(DOMString)], and formally 25 is informally [f1(), f1(long), f2(DOMString)], and formally
62 [(f1, [], []), (f1, [long], [optional]), (f2, [DOMString], [required])]. 26 [(f1, [], []), (f1, [long], [optional]), (f2, [DOMString], [required])].
63 27
(...skipping 30 matching lines...) Expand all
94 S = [] # pylint: disable=invalid-name 58 S = [] # pylint: disable=invalid-name
95 59
96 # 2. Let F be a set with elements as follows, according to the kind of 60 # 2. Let F be a set with elements as follows, according to the kind of
97 # effective overload set: 61 # effective overload set:
98 # (Passed as argument, nothing to do.) 62 # (Passed as argument, nothing to do.)
99 63
100 # 3. & 4. (maxarg, m) are only needed for variadics, not used. 64 # 3. & 4. (maxarg, m) are only needed for variadics, not used.
101 65
102 # 5. For each operation, extended attribute or callback function X in F: 66 # 5. For each operation, extended attribute or callback function X in F:
103 for X in F: # X is the "callable". pylint: disable=invalid-name 67 for X in F: # X is the "callable". pylint: disable=invalid-name
104 arguments = adapter.arguments(X) # pylint: disable=invalid-name 68 arguments = X['arguments'] # pylint: disable=invalid-name
105 # 1. Let n be the number of arguments X is declared to take. 69 # 1. Let n be the number of arguments X is declared to take.
106 n = len(arguments) # pylint: disable=invalid-name 70 n = len(arguments) # pylint: disable=invalid-name
107 # 2. Let t0..n−1 be a list of types, where ti is the type of X’s 71 # 2. Let t0..n−1 be a list of types, where ti is the type of X’s
108 # argument at index i. 72 # argument at index i.
109 # (“type list”) 73 # (“type list”)
110 t = tuple(adapter.type(argument) # pylint: disable=invalid-name 74 t = tuple(argument['idl_type_object'] # pylint: disable=invalid-name
111 for argument in arguments) 75 for argument in arguments)
112 # 3. Let o0..n−1 be a list of optionality values, where oi is “variadic” 76 # 3. Let o0..n−1 be a list of optionality values, where oi is “variadic”
113 # if X’s argument at index i is a final, variadic argument, “optional” 77 # if X’s argument at index i is a final, variadic argument, “optional”
114 # if the argument is optional, and “required” otherwise. 78 # if the argument is optional, and “required” otherwise.
115 # (“optionality list”) 79 # (“optionality list”)
116 # (We’re just using a boolean for optional/variadic vs. required.) 80 # (We’re just using a boolean for optional/variadic vs. required.)
117 o = tuple(adapter.is_optional(argument) # pylint: disable=invalid-name 81 o = tuple(argument['is_optional'] # pylint: disable=invalid-name
118 or adapter.is_variadic(argument) 82 or argument['is_variadic']
119 for argument in arguments) 83 for argument in arguments)
120 # 4. Add to S the tuple <X, t0..n−1, o0..n−1>. 84 # 4. Add to S the tuple <X, t0..n−1, o0..n−1>.
121 S.append((X, t, o)) 85 S.append((X, t, o))
122 # 5. If X is declared to be variadic, then: 86 # 5. If X is declared to be variadic, then:
123 # (Not used, so not implemented.) 87 # (Not used, so not implemented.)
124 # 6. Initialize i to n−1. 88 # 6. Initialize i to n−1.
125 i = n - 1 89 i = n - 1
126 # 7. While i ≥ 0: 90 # 7. While i ≥ 0:
127 # Spec bug (fencepost error); should be “While i > 0:” 91 # Spec bug (fencepost error); should be “While i > 0:”
128 # https://www.w3.org/Bugs/Public/show_bug.cgi?id=25590 92 # https://www.w3.org/Bugs/Public/show_bug.cgi?id=25590
(...skipping 12 matching lines...) Expand all
141 # 6. The effective overload set is S. 105 # 6. The effective overload set is S.
142 return S 106 return S
143 107
144 108
145 def effective_overload_set_by_length(overloads): 109 def effective_overload_set_by_length(overloads):
146 def type_list_length(entry): 110 def type_list_length(entry):
147 # Entries in the effective overload set are 3-tuples: 111 # Entries in the effective overload set are 3-tuples:
148 # (callable, type list, optionality list) 112 # (callable, type list, optionality list)
149 return len(entry[1]) 113 return len(entry[1])
150 114
151 effective_overloads = effective_overload_set(overloads, 115 effective_overloads = effective_overload_set(overloads)
152 MethodContextAdapter())
153 return list(sort_and_groupby(effective_overloads, type_list_length)) 116 return list(sort_and_groupby(effective_overloads, type_list_length))
154 117
155 118
156 def method_overloads_by_name(methods): 119 def method_overloads_by_name(methods):
157 """Returns generator of overloaded methods by name: [name, [method]]""" 120 """Returns generator of overloaded methods by name: [name, [method]]"""
158 # Filter to only methods that are actually overloaded 121 # Filter to only methods that are actually overloaded
159 method_counts = Counter(method['name'] for method in methods) 122 method_counts = Counter(method['name'] for method in methods)
160 overloaded_method_names = set(name 123 overloaded_method_names = set(name
161 for name, count in method_counts.iteritems() 124 for name, count in method_counts.iteritems()
162 if count > 1) 125 if count > 1)
163 overloaded_methods = [method for method in methods 126 overloaded_methods = [method for method in methods
164 if method['name'] in overloaded_method_names] 127 if method['name'] in overloaded_method_names]
165 128
166 # Group by name (generally will be defined together, but not necessarily) 129 # Group by name (generally will be defined together, but not necessarily)
167 return sort_and_groupby(overloaded_methods, itemgetter('name')) 130 return sort_and_groupby(overloaded_methods, itemgetter('name'))
OLDNEW
« no previous file with comments | « no previous file | third_party/WebKit/Source/bindings/scripts/overload_set_algorithm_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698