Commit dd3705db authored by Dag Sverre Seljebotn's avatar Dag Sverre Seljebotn

Abort compilation prior to code generation transforms if errors were recorded

parent c5c7012c
...@@ -63,11 +63,16 @@ class InternalError(Exception): ...@@ -63,11 +63,16 @@ class InternalError(Exception):
def __init__(self, message): def __init__(self, message):
Exception.__init__(self, "Internal compiler error: %s" Exception.__init__(self, "Internal compiler error: %s"
% message) % message)
class AbortCompilationError(Exception):
"""
Raised in order to abort compilation.
"""
listing_file = None listing_file = None
num_errors = 0 num_errors = 0
echo_file = None echo_file = None
last_error = None
def open_listing_file(path, echo_to_stderr = 1): def open_listing_file(path, echo_to_stderr = 1):
# Begin a new error listing. If path is None, no file # Begin a new error listing. If path is None, no file
...@@ -90,7 +95,7 @@ def close_listing_file(): ...@@ -90,7 +95,7 @@ def close_listing_file():
listing_file = None listing_file = None
def report_error(err): def report_error(err):
global num_errors global num_errors, last_error
# See Main.py for why dual reporting occurs. Quick fix for now. # See Main.py for why dual reporting occurs. Quick fix for now.
if err.reported: return if err.reported: return
err.reported = True err.reported = True
...@@ -100,6 +105,7 @@ def report_error(err): ...@@ -100,6 +105,7 @@ def report_error(err):
if echo_file: if echo_file:
echo_file.write(line) echo_file.write(line)
num_errors = num_errors + 1 num_errors = num_errors + 1
last_error = err
def error(position, message): def error(position, message):
#print "Errors.error:", repr(position), repr(message) ### #print "Errors.error:", repr(position), repr(message) ###
......
...@@ -84,6 +84,11 @@ class Context: ...@@ -84,6 +84,11 @@ class Context:
from Buffer import IntroduceBufferAuxiliaryVars from Buffer import IntroduceBufferAuxiliaryVars
from ModuleNode import check_c_classes from ModuleNode import check_c_classes
def abort_if_errors(t):
if Errors.num_errors > 0:
raise Errors.AbortCompilationError()
return t
if pxd: if pxd:
_check_c_classes = None _check_c_classes = None
_specific_post_parse = PxdPostParse(self) _specific_post_parse = PxdPostParse(self)
...@@ -123,10 +128,10 @@ class Context: ...@@ -123,10 +128,10 @@ class Context:
# (this seems strange -- I believe the right concept is to split # (this seems strange -- I believe the right concept is to split
# ModuleNode into a ModuleNode and a CodeGenerator, and tell that # ModuleNode into a ModuleNode and a CodeGenerator, and tell that
# CodeGenerator to generate code both from the pyx and pxd ModuleNodes. # CodeGenerator to generate code both from the pyx and pxd ModuleNodes.
stats.append(statlistnode) stats.append(statlistnode)
# Until utility code is moved to code generation phase everywhere, # Until utility code is moved to code generation phase everywhere,
# we need to copy it over to the main scope # we need to copy it over to the main scope
module_node.scope.utility_code_list.extend(scope.utility_code_list) module_node.scope.utility_code_list.extend(scope.utility_code_list)
return module_node return module_node
return ([ return ([
...@@ -167,10 +172,16 @@ class Context: ...@@ -167,10 +172,16 @@ class Context:
for phase in pipeline: for phase in pipeline:
if phase is not None: if phase is not None:
data = phase(data) data = phase(data)
print Errors.num_errors
except CompileError, err: except CompileError, err:
# err is set print "hello", err
Errors.report_error(err) Errors.report_error(err)
return (err, data) raise err
except Errors.AbortCompilationError:
print "abort", Errors.num_errors
pass
print "normal"
return data
def find_module(self, module_name, def find_module(self, module_name,
relative_to = None, pos = None, need_pxd = 1): relative_to = None, pos = None, need_pxd = 1):
...@@ -227,10 +238,7 @@ class Context: ...@@ -227,10 +238,7 @@ class Context:
if debug_find_module: if debug_find_module:
print("Context.find_module: Parsing %s" % pxd_pathname) print("Context.find_module: Parsing %s" % pxd_pathname)
source_desc = FileSourceDescriptor(pxd_pathname) source_desc = FileSourceDescriptor(pxd_pathname)
err, result = self.process_pxd(source_desc, scope, module_name) pxd_codenodes, pxd_scope = self.process_pxd(source_desc, scope, module_name)
if err:
raise err
(pxd_codenodes, pxd_scope) = result
self.pxds[module_name] = (pxd_codenodes, pxd_scope) self.pxds[module_name] = (pxd_codenodes, pxd_scope)
except CompileError: except CompileError:
pass pass
...@@ -399,7 +407,7 @@ class Context: ...@@ -399,7 +407,7 @@ class Context:
except UnicodeDecodeError, msg: except UnicodeDecodeError, msg:
error((source_desc, 0, 0), "Decoding error, missing or incorrect coding=<encoding-name> at top of source (%s)" % msg) error((source_desc, 0, 0), "Decoding error, missing or incorrect coding=<encoding-name> at top of source (%s)" % msg)
if Errors.num_errors > 0: if Errors.num_errors > 0:
raise CompileError raise Errors.AbortCompilationError()
return tree return tree
def extract_module_name(self, path, options): def extract_module_name(self, path, options):
...@@ -429,15 +437,13 @@ class Context: ...@@ -429,15 +437,13 @@ class Context:
else: else:
Errors.open_listing_file(None) Errors.open_listing_file(None)
def teardown_errors(self, err, options, result): def teardown_errors(self, options, result):
source_desc = result.compilation_source.source_desc source_desc = result.compilation_source.source_desc
if not isinstance(source_desc, FileSourceDescriptor): if not isinstance(source_desc, FileSourceDescriptor):
raise RuntimeError("Only file sources for code supported") raise RuntimeError("Only file sources for code supported")
Errors.close_listing_file() Errors.close_listing_file()
result.num_errors = Errors.num_errors result.num_errors = Errors.num_errors
if result.num_errors > 0: if result.num_errors > 0 and result.c_file:
err = True
if err and result.c_file:
try: try:
Utils.castrate_file(result.c_file, os.stat(source_desc.filename)) Utils.castrate_file(result.c_file, os.stat(source_desc.filename))
except EnvironmentError: except EnvironmentError:
...@@ -498,8 +504,13 @@ def run_pipeline(source, options, full_module_name = None): ...@@ -498,8 +504,13 @@ def run_pipeline(source, options, full_module_name = None):
pipeline = context.create_pyx_pipeline(options, result) pipeline = context.create_pyx_pipeline(options, result)
context.setup_errors(options) context.setup_errors(options)
err, enddata = context.run_pipeline(pipeline, source) try:
context.teardown_errors(err, options, result) enddata = context.run_pipeline(pipeline, source)
except Errors.CompileError:
pass
except Errors.AbortCompilationError:
pass
context.teardown_errors(options, result)
return result return result
#------------------------------------------------------------------------ #------------------------------------------------------------------------
......
...@@ -8,5 +8,5 @@ elif x == 4: ...@@ -8,5 +8,5 @@ elif x == 4:
print 34 print 34
_ERRORS = """ _ERRORS = """
4:23: undeclared name not builtin: NONEXISTING 3:19: undeclared name not builtin: NONEXISTING
""" """
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment