From: W. Trevor King Date: Tue, 22 Feb 2011 21:15:44 +0000 (-0500) Subject: Condense p_cdef_statement() into p_statement() to reduce parsing duplication. X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=9e439052cf9ec7ff496f4632637e64b88d241582;p=cython.git Condense p_cdef_statement() into p_statement() to reduce parsing duplication. --- diff --git a/Cython/Compiler/Parsing.pxd b/Cython/Compiler/Parsing.pxd index 9fef7b87..98b83b38 100644 --- a/Cython/Compiler/Parsing.pxd +++ b/Cython/Compiler/Parsing.pxd @@ -151,7 +151,6 @@ cpdef p_c_arg_list(PyrexScanner s, ctx = *, bint in_pyfunc = *, bint cmethod_fla cdef p_optional_ellipsis(PyrexScanner s) cpdef p_c_arg_decl(PyrexScanner s, ctx, in_pyfunc, bint cmethod_flag = *, bint nonempty = *, bint kw_only = *, bint annotated = *) cdef p_api(PyrexScanner s) -cdef p_cdef_statement(PyrexScanner s, ctx) cdef p_cdef_block(PyrexScanner s, ctx) cdef p_cdef_extern_block(PyrexScanner s, pos, ctx) cdef p_c_enum_definition(PyrexScanner s, pos, ctx) @@ -161,14 +160,14 @@ cdef p_c_struct_or_union_definition(PyrexScanner s, pos, ctx) cdef p_visibility(PyrexScanner s, ctx) cdef p_c_modifiers(PyrexScanner s) cdef p_binding(PyrexScanner s, ctx) -cdef p_c_func_or_var_declaration(PyrexScanner s, pos, ctx) +cdef p_c_func_or_var_declaration(PyrexScanner s, pos, ctx, decorators = *) cdef p_ctypedef_statement(PyrexScanner s, pos, ctx) cdef p_decorators(PyrexScanner s) cdef p_def_statement(PyrexScanner s, list decorators = *) cpdef p_varargslist(PyrexScanner s, terminator=*, bint annotated = *) cpdef p_py_arg_decl(PyrexScanner s, bint annotated = *) cdef p_class_statement(PyrexScanner s, decorators) -cdef p_c_class_definition(PyrexScanner s, pos, ctx) +cdef p_c_class_definition(PyrexScanner s, pos, ctx, decorators = *) cdef p_c_class_options(PyrexScanner s) cdef p_property_decl(PyrexScanner s) cdef p_doc_string(PyrexScanner s) diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index d25b0eda..29407a91 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -1906,14 +1906,21 @@ def p_statement(s, ctx, first_statement = 0): if ctx.level not in ('module', 'module_pxd', 'function', 'c_class', 'c_class_pxd'): s.error('cdef statement not allowed here') s.level = ctx.level - node = p_cdef_statement(s, ctx) - if decorators is not None: - if not isinstance(node, (Nodes.CFuncDefNode, Nodes.CVarDefNode, Nodes.CClassDefNode)): - s.error("Decorators can only be followed by functions or classes") - node.decorators = decorators - return node - elif ctx.c_binding.api: - s.error("'api' not allowed with this statement") + if ctx.c_binding.api: + if ctx.c_source.cdef_flag: + if ctx.c_source.extern: + error(pos, "Cannot combine 'api' with 'extern'") + else: + s.error("'api' not allowed with this statement") + if ctx.c_source.cdef_flag and p_nogil(s): + ctx.nogil = 1 + if ctx.python_binding.overridable: + error(pos, "cdef blocks cannot be declared cpdef") + return p_cdef_block(s, ctx) + elif s.sy == ':' and ctx.c_source.cdef_flag: + if ctx.python_binding.overridable: + error(pos, "cdef blocks cannot be declared cpdef") + return p_cdef_block(s, ctx) elif s.sy == 'def': # def statements aren't allowed in pxd files, except # as part of a cdef class @@ -1922,15 +1929,42 @@ def p_statement(s, ctx, first_statement = 0): s.level = ctx.level return p_def_statement(s, decorators) elif s.sy == 'class': - if ctx.level not in ('module', 'function', 'class', 'other'): - s.error("class definition not allowed here") + if ctx.c_source.cdef_flag: + if ctx.level not in ('module', 'module_pxd'): + error(pos, "Extension type definition not allowed here") + if ctx.python_binding.overridable: + error(pos, "Extension types cannot be declared cpdef") + return p_c_class_definition(s, pos, ctx, decorators) + else: + if ctx.level not in ('module', 'function', 'class', 'other'): + s.error("class definition not allowed here") return p_class_statement(s, decorators) + elif s.sy == 'from' and ctx.c_source.extern: + return p_cdef_extern_block(s, pos, ctx) + elif s.sy == 'import' and ctx.c_source.cdef_flag: + s.next() + return p_cdef_extern_block(s, pos, ctx) elif s.sy == 'include': if ctx.level not in ('module', 'module_pxd'): s.error("include statement not allowed here") return p_include_statement(s, ctx) elif ctx.level == 'c_class' and s.sy == 'IDENT' and s.systring == 'property': return p_property_decl(s) + elif ctx.c_source.cdef_flag: + if s.sy == 'IDENT' and s.systring == 'cppclass': + if not ctx.c_source.extern: + error(pos, "C++ classes need to be declared extern") + return p_cpp_class_definition(s, pos, ctx) + elif s.sy == 'IDENT' and s.systring in ("struct", "union", "enum", "packed"): + if ctx.level not in ('module', 'module_pxd'): + error(pos, "C struct/union/enum definition not allowed here") + if ctx.python_binding.overridable: + error(pos, "C struct/union/enum cannot be declared cpdef") + if s.systring == "enum": + return p_c_enum_definition(s, pos, ctx) + else: + return p_c_struct_or_union_definition(s, pos, ctx) + return p_c_func_or_var_declaration(s, pos, ctx, decorators) elif s.sy == 'pass' and ctx.level != 'property': return p_pass_statement(s, with_newline = 1) elif ctx.level in ('c_class_pxd', 'property'): @@ -2553,47 +2587,6 @@ def p_api(s): else: return 0 -def p_cdef_statement(s, ctx): - pos = s.position() - if ctx.c_binding.api: - if ctx.c_source.extern: - error(pos, "Cannot combine 'api' with 'extern'") - if ctx.c_source.extern and s.sy == 'from': - return p_cdef_extern_block(s, pos, ctx) - elif s.sy == 'import': - s.next() - return p_cdef_extern_block(s, pos, ctx) - elif p_nogil(s): - ctx.nogil = 1 - if ctx.python_binding.overridable: - error(pos, "cdef blocks cannot be declared cpdef") - return p_cdef_block(s, ctx) - elif s.sy == ':': - if ctx.python_binding.overridable: - error(pos, "cdef blocks cannot be declared cpdef") - return p_cdef_block(s, ctx) - elif s.sy == 'class': - if ctx.level not in ('module', 'module_pxd'): - error(pos, "Extension type definition not allowed here") - if ctx.python_binding.overridable: - error(pos, "Extension types cannot be declared cpdef") - return p_c_class_definition(s, pos, ctx) - elif s.sy == 'IDENT' and s.systring == 'cppclass': - if not ctx.c_source.extern: - error(pos, "C++ classes need to be declared extern") - return p_cpp_class_definition(s, pos, ctx) - elif s.sy == 'IDENT' and s.systring in ("struct", "union", "enum", "packed"): - if ctx.level not in ('module', 'module_pxd'): - error(pos, "C struct/union/enum definition not allowed here") - if ctx.python_binding.overridable: - error(pos, "C struct/union/enum cannot be declared cpdef") - if s.systring == "enum": - return p_c_enum_definition(s, pos, ctx) - else: - return p_c_struct_or_union_definition(s, pos, ctx) - else: - return p_c_func_or_var_declaration(s, pos, ctx) - def p_cdef_block(s, ctx): return p_suite(s, ctx(cdef_flag = 1)) @@ -2801,7 +2794,7 @@ def p_binding(s, ctx): _LOG.info(' python binding overridable: %s' % new_ctx.python_binding.overridable) return new_ctx -def p_c_func_or_var_declaration(s, pos, ctx): +def p_c_func_or_var_declaration(s, pos, ctx, decorators=None): _LOG.debug('p_c_func_or_var_declaration(s=)' % (s.sy, s.systring)) cmethod_flag = ctx.level in ('c_class', 'c_class_pxd') @@ -2825,6 +2818,7 @@ def p_c_func_or_var_declaration(s, pos, ctx): visibility = visibility, base_type = base_type, declarator = declarator, + decorators = decorators, body = suite, doc = doc, modifiers = modifiers, @@ -2852,6 +2846,7 @@ def p_c_func_or_var_declaration(s, pos, ctx): overridable = ctx.python_binding.overridable, base_type = base_type, declarators = declarators, + decorators = decorators, in_pxd = ctx.level == 'module_pxd') return result @@ -2983,7 +2978,7 @@ def p_class_statement(s, decorators): starstar_arg = starstar_arg, doc = doc, body = body, decorators = decorators) -def p_c_class_definition(s, pos, ctx): +def p_c_class_definition(s, pos, ctx, decorators=None): # s.sy == 'class' s.next() module_path = [] @@ -3059,6 +3054,7 @@ def p_c_class_definition(s, pos, ctx): base_class_name = base_class_name, objstruct_name = objstruct_name, typeobj_name = typeobj_name, + decorators = decorators, in_pxd = ctx.level == 'module_pxd', doc = doc, body = body) diff --git a/tests/errors/builtin_type_inheritance.pyx b/tests/errors/builtin_type_inheritance.pyx index 79ff24a5..0d11207d 100644 --- a/tests/errors/builtin_type_inheritance.pyx +++ b/tests/errors/builtin_type_inheritance.pyx @@ -11,7 +11,7 @@ cdef class MyStr(str): # only in Py2, but can't know that during compilation pass _ERRORS = """ -4:5: inheritance from PyVarObject types like 'tuple' is not currently supported -7:5: inheritance from PyVarObject types like 'bytes' is not currently supported -10:5: inheritance from PyVarObject types like 'str' is not currently supported +4:0: inheritance from PyVarObject types like 'tuple' is not currently supported +7:0: inheritance from PyVarObject types like 'bytes' is not currently supported +10:0: inheritance from PyVarObject types like 'str' is not currently supported """ diff --git a/tests/errors/cdefspecial.pyx b/tests/errors/cdefspecial.pyx index 53a484ea..f942006c 100644 --- a/tests/errors/cdefspecial.pyx +++ b/tests/errors/cdefspecial.pyx @@ -7,6 +7,6 @@ cdef class Test: pass _ERRORS = u""" -3:9: Special methods must be declared with 'def', not 'cdef' -6:9: Special methods must be declared with 'def', not 'cdef' +3:4: Special methods must be declared with 'def', not 'cdef' +6:4: Special methods must be declared with 'def', not 'cdef' """ diff --git a/tests/errors/cmethbasematch.pyx b/tests/errors/cmethbasematch.pyx index b0b1222e..fbbafe2d 100644 --- a/tests/errors/cmethbasematch.pyx +++ b/tests/errors/cmethbasematch.pyx @@ -7,6 +7,6 @@ cdef class D(C): pass _ERRORS = u""" -6: 9: Signature not compatible with previous declaration -2: 9: Previous declaration is here +6: 4: Signature not compatible with previous declaration +2: 4: Previous declaration is here """ diff --git a/tests/errors/cpdef_syntax.pyx b/tests/errors/cpdef_syntax.pyx index 654a1fe0..569750d3 100644 --- a/tests/errors/cpdef_syntax.pyx +++ b/tests/errors/cpdef_syntax.pyx @@ -3,7 +3,7 @@ cpdef nogil: pass cpdef nogil class test: pass _ERRORS = u""" - 2: 6: cdef blocks cannot be declared cpdef - 3: 6: cdef blocks cannot be declared cpdef + 2: 0: cdef blocks cannot be declared cpdef + 3: 0: cdef blocks cannot be declared cpdef 3:12: Expected ':', found 'class' """ diff --git a/tests/errors/e_cdefemptysue.pyx b/tests/errors/e_cdefemptysue.pyx index d71a8ab3..5ed13497 100644 --- a/tests/errors/e_cdefemptysue.pyx +++ b/tests/errors/e_cdefemptysue.pyx @@ -7,7 +7,7 @@ ctypedef union eggs: cdef enum ham: pass _ERRORS = u""" -1:5: Empty struct or union definition not allowed outside a 'cdef extern from' block +1:0: Empty struct or union definition not allowed outside a 'cdef extern from' block 4:0: Empty struct or union definition not allowed outside a 'cdef extern from' block -7:5: Empty enum definition not allowed outside a 'cdef extern from' block +7:0: Empty enum definition not allowed outside a 'cdef extern from' block """ diff --git a/tests/errors/e_cmethbasematch.pyx b/tests/errors/e_cmethbasematch.pyx index b434c82a..271421dc 100644 --- a/tests/errors/e_cmethbasematch.pyx +++ b/tests/errors/e_cmethbasematch.pyx @@ -6,6 +6,6 @@ cdef class D(C): cdef void f(self, int x): pass _ERRORS = u""" -6:6: Signature not compatible with previous declaration -2:6: Previous declaration is here +6:1: Signature not compatible with previous declaration +2:1: Previous declaration is here """ diff --git a/tests/errors/e_ctypedefornot.pyx b/tests/errors/e_ctypedefornot.pyx index 632ba780..1d8396b4 100644 --- a/tests/errors/e_ctypedefornot.pyx +++ b/tests/errors/e_ctypedefornot.pyx @@ -13,5 +13,5 @@ cdef Blarg b _ERRORS = u""" 3:0: 'Foo' previously declared using 'cdef' -9:5: 'Blarg' previously declared using 'ctypedef' +9:0: 'Blarg' previously declared using 'ctypedef' """ diff --git a/tests/errors/e_func_in_pxd.pyx b/tests/errors/e_func_in_pxd.pyx index 83dc574e..10a882e1 100644 --- a/tests/errors/e_func_in_pxd.pyx +++ b/tests/errors/e_func_in_pxd.pyx @@ -1,7 +1,7 @@ cimport e_func_in_pxd_support _ERRORS = u""" -1:5: function definition in pxd file must be declared 'cdef inline' -4:12: inline function definition in pxd file cannot be 'public' -7:9: inline function definition in pxd file cannot be 'api' +1:0: function definition in pxd file must be declared 'cdef inline' +4:0: inline function definition in pxd file cannot be 'public' +7:0: inline function definition in pxd file cannot be 'api' """ diff --git a/tests/errors/e_nogilcmeth.pyx b/tests/errors/e_nogilcmeth.pyx index ec596524..6f4cb6ee 100644 --- a/tests/errors/e_nogilcmeth.pyx +++ b/tests/errors/e_nogilcmeth.pyx @@ -3,6 +3,6 @@ cdef class C: pass _ERRORS = u""" -2:6: Signature not compatible with previous declaration +2:1: Signature not compatible with previous declaration 2:12: Previous declaration is here """ diff --git a/tests/errors/e_packedstruct_T290.pyx b/tests/errors/e_packedstruct_T290.pyx index 408246c8..8a3ef5e6 100644 --- a/tests/errors/e_packedstruct_T290.pyx +++ b/tests/errors/e_packedstruct_T290.pyx @@ -3,5 +3,5 @@ cdef extern: char a _ERRORS = u""" -2:9: Cannot declare extern struct as 'packed' +2:4: Cannot declare extern struct as 'packed' """ diff --git a/tests/errors/e_undefexttype.pyx b/tests/errors/e_undefexttype.pyx index 232f4d73..0a9f6a9b 100644 --- a/tests/errors/e_undefexttype.pyx +++ b/tests/errors/e_undefexttype.pyx @@ -1,6 +1,6 @@ cdef class Spam cdef extern class external.Eggs _ERRORS = u""" -1:5: C class 'Spam' is declared but not defined -2:12: C class 'Eggs' is declared but not defined +1:0: C class 'Spam' is declared but not defined +2:0: C class 'Eggs' is declared but not defined """ diff --git a/tests/errors/missing_self_in_cpdef_method_T156.pyx b/tests/errors/missing_self_in_cpdef_method_T156.pyx index 7f060e49..3fbb7f6d 100644 --- a/tests/errors/missing_self_in_cpdef_method_T156.pyx +++ b/tests/errors/missing_self_in_cpdef_method_T156.pyx @@ -4,5 +4,5 @@ cdef class B: pass _ERRORS = u""" -3:10: C method has no self argument +3:4: C method has no self argument """ diff --git a/tests/errors/missing_self_in_cpdef_method_T165.pyx b/tests/errors/missing_self_in_cpdef_method_T165.pyx index 3b66bc72..89fc1947 100644 --- a/tests/errors/missing_self_in_cpdef_method_T165.pyx +++ b/tests/errors/missing_self_in_cpdef_method_T165.pyx @@ -4,5 +4,5 @@ cdef class A: pass _ERRORS = u""" -3:10: Self argument (int) of C method 'a' does not match parent type (A) +3:4: Self argument (int) of C method 'a' does not match parent type (A) """ diff --git a/tests/errors/nogil.pyx b/tests/errors/nogil.pyx index 623d1ff4..1e85d08d 100644 --- a/tests/errors/nogil.pyx +++ b/tests/errors/nogil.pyx @@ -90,11 +90,11 @@ def bare_pyvar_name(object x): # except these: 29, 34, 44, 56, 58, 60, 62-64 _ERRORS = u""" -1:5: Function with Python return type cannot be declared nogil -4:5: Function declared nogil has Python locals or temporaries +1:0: Function with Python return type cannot be declared nogil +4:0: Function declared nogil has Python locals or temporaries 6:6: Assignment of Python object not allowed without gil 9:5: Discarding owned Python object not allowed without gil -11:5: Function with Python return type cannot be declared nogil +11:0: Function with Python return type cannot be declared nogil 15:5: Calling gil-requiring function not allowed without gil 24:9: Calling gil-requiring function not allowed without gil 26:12: Assignment of Python object not allowed without gil diff --git a/tests/errors/nogilcmeth.pyx b/tests/errors/nogilcmeth.pyx index c7b3ce38..77327b23 100644 --- a/tests/errors/nogilcmeth.pyx +++ b/tests/errors/nogilcmeth.pyx @@ -3,6 +3,6 @@ cdef class C: pass _ERRORS = u""" -2:9: Signature not compatible with previous declaration +2:4: Signature not compatible with previous declaration 2:15: Previous declaration is here """ diff --git a/tests/errors/pxd_cdef_class_declaration_T286.pyx b/tests/errors/pxd_cdef_class_declaration_T286.pyx index 7114bf8f..e377f6a4 100644 --- a/tests/errors/pxd_cdef_class_declaration_T286.pyx +++ b/tests/errors/pxd_cdef_class_declaration_T286.pyx @@ -2,5 +2,5 @@ cdef class A: pass _ERRORS = u""" -1:5: C class 'A' is declared but not defined +1:0: C class 'A' is declared but not defined """ diff --git a/tests/errors/subtyping_final_class.pyx b/tests/errors/subtyping_final_class.pyx index 477669b1..ac16fbe8 100644 --- a/tests/errors/subtyping_final_class.pyx +++ b/tests/errors/subtyping_final_class.pyx @@ -9,5 +9,5 @@ cdef class SubType(FinalClass): pass _ERRORS = """ -8:5: Base class 'FinalClass' of type 'SubType' is final +8:0: Base class 'FinalClass' of type 'SubType' is final """