Remove unneeded declarations from JSCallee.h
[WebKit-https.git] / Source / WebKit2 / Scripts / webkit / parser.py
1 # Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions
5 # are met:
6 # 1.  Redistributions of source code must retain the above copyright
7 #     notice, this list of conditions and the following disclaimer.
8 # 2.  Redistributions in binary form must reproduce the above copyright
9 #     notice, this list of conditions and the following disclaimer in the
10 #     documentation and/or other materials provided with the distribution.
11 #
12 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
13 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15 # DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
16 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
17 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
18 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
19 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
20 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
21 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22
23 import re
24
25 from webkit import model
26
27
28 def combine_condition(conditions):
29     if conditions:
30         if len(conditions) == 1:
31             return conditions[0]
32         else:
33             return bracket_if_needed(' && '.join(map(bracket_if_needed, conditions)))
34     else:
35         return None
36
37
38 def bracket_if_needed(condition):
39     if re.match(r'.*(&&|\|\|).*', condition):
40         return '(%s)' % condition
41     else:
42         return condition
43
44
45 def parse(file):
46     receiver_attributes = None
47     destination = None
48     messages = []
49     conditions = []
50     master_condition = None
51     superclass = []
52     for line in file:
53         match = re.search(r'messages -> (?P<destination>[A-Za-z_0-9]+) \s*(?::\s*(?P<superclass>.*?) \s*)?(?:(?P<attributes>.*?)\s+)?{', line)
54         if match:
55             receiver_attributes = parse_attributes_string(match.group('attributes'))
56             if match.group('superclass'):
57                 superclass = match.group('superclass')
58             if conditions:
59                 master_condition = conditions
60                 conditions = []
61             destination = match.group('destination')
62             continue
63         if line.startswith('#'):
64             trimmed = line.rstrip()
65             if line.startswith('#if '):
66                 conditions.append(trimmed[4:])
67             elif line.startswith('#endif') and conditions:
68                 conditions.pop()
69             elif line.startswith('#else') or line.startswith('#elif'):
70                 raise Exception("ERROR: '%s' is not supported in the *.in files" % trimmed)
71             continue
72         match = re.search(r'([A-Za-z_0-9]+)\((.*?)\)(?:(?:\s+->\s+)\((.*?)\))?(?:\s+(.*))?', line)
73         if match:
74             name, parameters_string, reply_parameters_string, attributes_string = match.groups()
75             if parameters_string:
76                 parameters = parse_parameters_string(parameters_string)
77                 for parameter in parameters:
78                     parameter.condition = combine_condition(conditions)
79             else:
80                 parameters = []
81
82             attributes = parse_attributes_string(attributes_string)
83
84             if reply_parameters_string:
85                 reply_parameters = parse_parameters_string(reply_parameters_string)
86                 for reply_parameter in reply_parameters:
87                     reply_parameter.condition = combine_condition(conditions)
88             elif reply_parameters_string == '':
89                 reply_parameters = []
90             else:
91                 reply_parameters = None
92
93             messages.append(model.Message(name, parameters, reply_parameters, attributes, combine_condition(conditions)))
94     return model.MessageReceiver(destination, superclass, receiver_attributes, messages, combine_condition(master_condition))
95
96
97 def parse_attributes_string(attributes_string):
98     if not attributes_string:
99         return None
100     return attributes_string.split()
101
102
103 def split_parameters_string(parameters_string):
104     parameters = []
105     current_parameter_string = ''
106
107     nest_level = 0
108     for character in parameters_string:
109         if character == ',' and nest_level == 0:
110             parameters.append(current_parameter_string)
111             current_parameter_string = ''
112             continue
113
114         if character == '<':
115             nest_level += 1
116         elif character == '>':
117             nest_level -= 1
118
119         current_parameter_string += character
120
121     parameters.append(current_parameter_string)
122     return parameters
123
124 def parse_parameters_string(parameters_string):
125     parameters = []
126
127     for parameter_string in split_parameters_string(parameters_string):
128         match = re.search(r'\s*(?:\[(?P<attributes>.*?)\]\s+)?(?P<type_and_name>.*)', parameter_string)
129         attributes_string, type_and_name_string = match.group('attributes', 'type_and_name')
130         parameter_type, parameter_name = type_and_name_string.rsplit(' ', 1)
131         parameters.append(model.Parameter(type=parameter_type, name=parameter_name, attributes=parse_attributes_string(attributes_string)))
132     return parameters