diff options
author | asargent@chromium.org <asargent@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-05 17:38:43 +0000 |
---|---|---|
committer | asargent@chromium.org <asargent@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-05 17:38:43 +0000 |
commit | d01e6ff96b89ad55855f4e29684d059a8798e8f8 (patch) | |
tree | 8b43192473c8d5b154357f8bed80d67e94554639 | |
parent | 00565d06c051fe61fbc707ca89508e8cd441a608 (diff) | |
download | chromium_src-d01e6ff96b89ad55855f4e29684d059a8798e8f8.zip chromium_src-d01e6ff96b89ad55855f4e29684d059a8798e8f8.tar.gz chromium_src-d01e6ff96b89ad55855f4e29684d059a8798e8f8.tar.bz2 |
This adds support for a number of features in the current WebIDL spec (http://dev.w3.org/2006/webapi/WebIDL/):
-Callbacks
-Dictionaries
-static functions in interfaces
-optional parameters and dictionary members
It also introduces a "namespace" production to the grammar, which is just a named scope surrounding a list of other IDL fragments.
Finally, there are a couple of random cleanups.
BUG=116636
TEST=existing tests should still work
Review URL: https://chromiumcodereview.appspot.com/9388002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@124959 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ppapi/api/dev/pp_cursor_type_dev.idl | 3 | ||||
-rwxr-xr-x | ppapi/generators/idl_lexer.py | 20 | ||||
-rwxr-xr-x | ppapi/generators/idl_node.py | 6 | ||||
-rw-r--r-- | ppapi/generators/idl_option.py | 3 | ||||
-rwxr-xr-x | ppapi/generators/idl_parser.py | 117 |
5 files changed, 119 insertions, 30 deletions
diff --git a/ppapi/api/dev/pp_cursor_type_dev.idl b/ppapi/api/dev/pp_cursor_type_dev.idl index 7166c2af..08abec3 100644 --- a/ppapi/api/dev/pp_cursor_type_dev.idl +++ b/ppapi/api/dev/pp_cursor_type_dev.idl @@ -7,8 +7,7 @@ * This file defines enumerations for cursor types. */ -[assert_size(4)] -[notypedef] enum PP_CursorType_Dev { +[assert_size(4),notypedef] enum PP_CursorType_Dev { PP_CURSORTYPE_CUSTOM = -1, PP_CURSORTYPE_POINTER = 0, PP_CURSORTYPE_CROSS = 1, diff --git a/ppapi/generators/idl_lexer.py b/ppapi/generators/idl_lexer.py index d33414c..d45a4b8 100755 --- a/ppapi/generators/idl_lexer.py +++ b/ppapi/generators/idl_lexer.py @@ -55,6 +55,16 @@ class IDLLexer(object): 'STRUCT', 'TYPEDEF', + # Extra WebIDL keywords + 'CALLBACK', + 'DICTIONARY', + 'OPTIONAL', + 'STATIC', + + # Invented for apps use + 'NAMESPACE', + + # Data types 'FLOAT', 'OCT', @@ -77,11 +87,17 @@ class IDLLexer(object): 'readonly' : 'READONLY', 'struct' : 'STRUCT', 'typedef' : 'TYPEDEF', + + 'callback' : 'CALLBACK', + 'dictionary' : 'DICTIONARY', + 'optional' : 'OPTIONAL', + 'static' : 'STATIC', + 'namespace' : 'NAMESPACE', } # 'literals' is a value expected by lex which specifies a list of valid # literal tokens, meaning the token type and token value are identical. - literals = '"*.(){}[],;:=+-/~|&^' + literals = '"*.(){}[],;:=+-/~|&^?' # Token definitions # @@ -116,7 +132,7 @@ class IDLLexer(object): # A C or C++ style comment: /* xxx */ or // def t_COMMENT(self, t): - r'(/\*(.|\n)*?\*/)|(//.*)' + r'(/\*(.|\n)*?\*/)|(//.*(\n[ \t]*//.*)*)' self.AddLines(t.value.count('\n')) return t diff --git a/ppapi/generators/idl_node.py b/ppapi/generators/idl_node.py index 0fee3ec..275562c 100755 --- a/ppapi/generators/idl_node.py +++ b/ppapi/generators/idl_node.py @@ -132,14 +132,18 @@ class IDLNode(IDLRelease): tab = ''.rjust(depth * 2) if is_comment: + out.write('%sComment\n' % tab) for line in self.GetName().split('\n'): - out.write('%s%s\n' % (tab, line)) + out.write('%s "%s"\n' % (tab, line)) else: out.write('%s%s\n' % (tab, self)) properties = self.property_node.GetPropertyList() if properties: out.write('%s Properties\n' % tab) for p in properties: + if is_comment and p == 'NAME': + # Skip printing the name for comments, since we printed above already + continue out.write('%s %s : %s\n' % (tab, p, self.GetProperty(p))) for child in self.children: child.Dump(depth+1, comments=comments, out=out) diff --git a/ppapi/generators/idl_option.py b/ppapi/generators/idl_option.py index 714b686..54ac4cf 100644 --- a/ppapi/generators/idl_option.py +++ b/ppapi/generators/idl_option.py @@ -60,7 +60,7 @@ def DumpHelp(option=None): InfoOut.Log('Usage:') for opt in sorted(OptionMap.keys()): DumpOption(OptionMap[opt]) - + sys.exit(0) # # Default IDL options @@ -70,6 +70,7 @@ def DumpHelp(option=None): # --test : test this module # Option('h', 'Help', callfunc=DumpHelp) +Option('help', 'Help', callfunc=DumpHelp) Option('verbose', 'Verbose') Option('test', 'Test the IDL scripts') diff --git a/ppapi/generators/idl_parser.py b/ppapi/generators/idl_parser.py index 45f1021..f1045c3 100755 --- a/ppapi/generators/idl_parser.py +++ b/ppapi/generators/idl_parser.py @@ -223,11 +223,14 @@ class IDLParser(IDLLexer): # Build a list of top level items. def p_top_list(self, p): - """top_list : describe_block top_list + """top_list : callback_decl top_list + | describe_block top_list + | dictionary_block top_list | enum_block top_list | inline top_list | interface_block top_list | label_block top_list + | namespace top_list | struct_block top_list | typedef_decl top_list | """ @@ -267,6 +270,44 @@ class IDLParser(IDLLexer): # +# Namespace +# +# A namespace provides a named scope to an enclosed top_list. +# + def p_namespace(self, p): + """namespace : modifiers NAMESPACE namespace_name '{' top_list '}' ';'""" + children = ListFromConcat(p[1], p[5]) + p[0] = self.BuildNamed('Namespace', p, 3, children) + + # We allow namespace names of the form foo.bar.baz. + def p_namespace_name(self, p): + """namespace_name : SYMBOL + | SYMBOL '.' namespace_name""" + p[0] = "".join(p[1:]) + + +# +# Dictionary +# +# A dictionary contains is a named list of optional and required members. +# + def p_dictionary_block(self, p): + """dictionary_block : modifiers DICTIONARY SYMBOL '{' struct_list '}' ';'""" + p[0] = self.BuildNamed('Dictionary', p, 3, ListFromConcat(p[5])) + +# +# Callback +# +# A callback is essentially a single function declaration (outside of an +# Interface). +# + def p_callback_decl(self, p): + """callback_decl : modifiers CALLBACK SYMBOL '=' SYMBOL param_list ';'""" + children = ListFromConcat(p[1], p[6]) + p[0] = self.BuildNamed('Callback', p, 3, children) + + +# # Inline # # Inline blocks define option code to be emitted based on language tag, @@ -482,6 +523,19 @@ class IDLParser(IDLLexer): elif len(p) == 1: return if self.parse_debug: DumpReduction('arrays', p) + +# An identifier is a legal value for a parameter or attribute name. Lots of +# existing IDL files use "callback" as a parameter/attribute name, so we allow +# a SYMBOL or the CALLBACK keyword. + def p_identifier(self, p): + """identifier : SYMBOL + | CALLBACK""" + p[0] = p[1] + # Save the line number of the underlying token (otherwise it gets + # discarded), since we use it in the productions with an identifier in + # them. + p.set_lineno(0, p.lineno(1)) + # # Parameter List # @@ -499,12 +553,19 @@ class IDLParser(IDLLexer): if self.parse_debug: DumpReduction('param_list', p) def p_param_item(self, p): - """param_item : modifiers SYMBOL arrays SYMBOL""" - typeref = self.BuildAttribute('TYPEREF', p[2]) - children = ListFromConcat(p[1],typeref, p[3]) - p[0] = self.BuildNamed('Param', p, 4, children) + """param_item : modifiers optional SYMBOL arrays identifier""" + typeref = self.BuildAttribute('TYPEREF', p[3]) + children = ListFromConcat(p[1],p[2], typeref, p[4]) + p[0] = self.BuildNamed('Param', p, 5, children) if self.parse_debug: DumpReduction('param_item', p) + def p_optional(self, p): + """optional : OPTIONAL + | """ + if len(p) == 2: + p[0] = self.BuildAttribute('OPTIONAL', True) + + def p_param_cont(self, p): """param_cont : ',' param_item param_cont | """ @@ -520,7 +581,7 @@ class IDLParser(IDLLexer): # # Typedef # -# A typedef creates a new referencable type. The tyepdef can specify an array +# A typedef creates a new referencable type. The typedef can specify an array # definition as well as a function declaration. # def p_typedef_data(self, p): @@ -615,26 +676,31 @@ class IDLParser(IDLLexer): # A member attribute or function of a struct or interface. # def p_member_attribute(self, p): - """member_attribute : modifiers SYMBOL SYMBOL """ - typeref = self.BuildAttribute('TYPEREF', p[2]) - children = ListFromConcat(p[1], typeref) - p[0] = self.BuildNamed('Member', p, 3, children) - if self.parse_debug: DumpReduction('attribute', p) - - def p_member_attribute_array(self, p): - """member_attribute : modifiers SYMBOL arrays SYMBOL """ + """member_attribute : modifiers SYMBOL arrays questionmark identifier""" typeref = self.BuildAttribute('TYPEREF', p[2]) - children = ListFromConcat(p[1], typeref, p[3]) - p[0] = self.BuildNamed('Member', p, 4, children) + children = ListFromConcat(p[1], typeref, p[3], p[4]) + p[0] = self.BuildNamed('Member', p, 5, children) if self.parse_debug: DumpReduction('attribute', p) def p_member_function(self, p): - """member_function : modifiers SYMBOL SYMBOL param_list""" - typeref = self.BuildAttribute('TYPEREF', p[2]) - children = ListFromConcat(p[1], typeref, p[4]) - p[0] = self.BuildNamed('Member', p, 3, children) + """member_function : modifiers static SYMBOL SYMBOL param_list""" + typeref = self.BuildAttribute('TYPEREF', p[3]) + children = ListFromConcat(p[1], p[2], typeref, p[5]) + p[0] = self.BuildNamed('Member', p, 4, children) if self.parse_debug: DumpReduction('function', p) + def p_static(self, p): + """static : STATIC + | """ + if len(p) == 2: + p[0] = self.BuildAttribute('STATIC', True) + + def p_questionmark(self, p): + """questionmark : '?' + | """ + if len(p) == 2: + p[0] = self.BuildAttribute('OPTIONAL', True) + # # Interface # @@ -770,14 +836,17 @@ class IDLParser(IDLLexer): name = p[index] # Remove comment markers + lines = [] if name[:2] == '//': - # For C++ style, remove the preceding '//' + # For C++ style, remove any leading whitespace and the '//' marker from + # each line. form = 'cc' - name = name[2:].rstrip() + for line in name.split('\n'): + start = line.find('//') + lines.append(line[start+2:]) else: # For C style, remove ending '*/'' form = 'c' - lines = [] for line in name[:-2].split('\n'): # Remove characters until start marker for this line '*' if found # otherwise it should be blank. @@ -787,7 +856,7 @@ class IDLParser(IDLLexer): else: line = '' lines.append(line) - name = '\n'.join(lines) + name = '\n'.join(lines) childlist = [self.BuildAttribute('NAME', name), self.BuildAttribute('FORM', form)] |