Synopsis: The predefined program condition classes. Author: haahr, jonathan, keith, swm Module: dfmc-conditions-implementation Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND define generic convert-condition-slots-to-ppml(condition :: ) => (); define method convert-condition-slots-to-ppml(condition :: ) => (); end; define method convert-condition-slots-to-ppml (condition :: ) => (); for (i from 0 below condition.condition-format-arguments.size) condition.condition-format-arguments[i] := as(, condition.condition-format-arguments[i]) end; end; define method convert-condition-slots-to-ppml (condition :: ) => (); for (i from 0 below condition.condition-format-arguments.size) condition.condition-format-arguments[i] := as(, condition.condition-format-arguments[i]) end; end; /// // The root of the hierarchy is . All errors, // warnings, etc, about code in a program being compiled should be // reported as instances of this class. // // This class should only be used for type declarations and as the // superclass for mixin properties. For instantiable classes, it's // best to subclass one of , , or // instead. define open abstract class () // TODO: Inherit from when that exists. // TODO: Make this class primary. // The source-location is used for indicating to the user where the // error occured. It might be sensible for this information to be // obtained from a combination of the source-record and this slot, // if that could condense the size of source locations. slot condition-source-location = #f, init-keyword: source-location:; slot condition-program-note-creator = *current-dependent*, init-keyword: program-note-creator:; slot condition-compilation-stage = *current-stage*, init-keyword: compilation-stage:; end class ; /// The independently subclassable roots. // A is any message that the compiler wants to report, // including but not limited to errors and warnings. define constant = false-or(); define open primary abstract program-condition (, ) // TODO: inherit from , when exists // This slot can be initialized with some indication of the logical // context of the source the note is about, typically to give a concise // textual hint. Allowing for example: // // foo.dylan:180:Warning in process-foo: Bogus call to bar. // // where "process-foo" is the context. slot condition-context-id = #f, init-keyword: context-id:; // Notes may have subnotes, allowing hierarchical explanations to be // constructed. slot subnotes :: limited(, of: ) = #[], init-keyword: subnotes:; filter #f; end program-condition ; define program-condition-definer program-note; // Some common program note predicates define function program-note-in(form :: ) => (pred :: ) method (condition :: ) => (b :: ) instance?(condition, ) & form = condition.condition-context-id end end; define function program-note-location-between (from :: , to :: ) => (pred :: ) method (condition :: ) => (b :: ) if (instance?(condition, )) let loc = condition.condition-source-location; if (loc) let sr = loc.source-location-source-record; let (file-name, header-offset) = source-line-location(sr, 0); ignore(file-name); let start-minus-header = source-offset-line( source-location-start-offset(loc)); let start-line = start-minus-header + header-offset; start-line >= from & start-line <= to else #f end else #f end end end; define function program-note-class-= (class :: subclass()) => (pred :: ) method (condition :: ) => (b :: ) instance?(condition, class) end end; define function program-note-file-name-= (file-name :: ) => (pred :: ) method (condition :: ) => (b :: ) let loc = condition.condition-source-location; if (loc) let sr = loc.source-location-source-record; file-name = source-line-location(sr, 0) end end end; // Some common program note filters define generic add-program-condition (condition :: ) => (); define generic terminate-and-restart (condition :: ) => (); define open generic report-condition (condition :: ) => (); define method make-program-note-filter (#key file-name :: = "", from :: = 0, to :: = $maximum-integer, in :: = "", class :: subclass() = , action :: = add-program-condition) => (filter :: ); let predicates = make(); if (file-name ~= "") add!(predicates, program-note-file-name-=(file-name)) end if; if (in ~= "") add!(predicates, program-note-in(in)) end if; if (from ~= 0 | to ~= $maximum-integer) add!(predicates, program-note-location-between(from, to)) end if; if (class ~== ) add!(predicates, program-note-class-=(class)) end if; if (empty?(predicates)) action else method (c :: ) => () if (apply(conjoin, predicates)(c)) action(c) end; values () end end end; define constant $record-program-note = add-program-condition; define function $signal-program-error(c :: ) => () add-program-condition(c); terminate-and-restart(c) end; define function $signal-program-note(c :: ) => () add-program-condition(c); report-condition(c) end; // Each program note class has a filter associated with it. define open generic program-note-filter (class :: subclass()) => (filter :: ); define open generic program-note-filter-setter (filter :: , class :: subclass()) => (filter :: ); define method program-note-filter (class :: subclass()) => (filter :: ); ignore(class); #f end; define method program-note-filter-setter (filter :: , c :: subclass()) => (filter :: ); for (sc in c.direct-subclasses) program-note-filter(sc) := filter end; filter end; // A is a meant to be used as part of the // recovery protocol for some . define open primary abstract program-condition (, ) // TODO: inherit from , when exists slot condition-format-string, init-keyword: format-string:; slot condition-format-arguments, init-keyword: format-arguments:; keyword default?: = #f; end program-condition ; define program-condition-definer program-restart; /// a bit more of a hierarchy // A is a note about something that might be a // mistake in program, but the compiler is able to compile it without // intervention. define open abstract program-note filter $signal-program-note; end program-condition ; define program-condition-definer program-warning; define open abstract program-warning filter $signal-program-note; end program-warning ; define program-condition-definer serious-program-warning; // A is a language error. Examples would be (most) // syntax errors, inconsistent direct superclasses, or a reference to // an undefined name. // gts,98apr06 -- short term hack -- instead of having be // interesting in its own right, just stick it under serious-program-warning // for now. // define open abstract program-note define open abstract serious-program-warning // filter $signal-program-error; end program-note ; define program-condition-definer program-error; // Run-time-error warnings are given when the compiler can prove that // executing the code will lead definitely lead to a run-time error, // whether or not that error is handled. These warnings should be // hard for the user to suppress. It should be possible for a user to // treat these warnings as errors; that is, stop the compilation // process because of one. define open abstract program-warning filter $signal-program-note; end program-warning ; define program-condition-definer run-time-error-warning; // Style warnings are given when the compiler detects code in a style // that is legal (strictly speaking), but not desirable. The display // of style warnings can be inhibited globally, or on a class-by-class // basis. define open abstract program-warning filter #f; end program-warning ; define program-condition-definer style-warning; // Performance notes are given when the compiler is prevented from // doing an optimization that should be reasonable or expected in the // current context. Typical reasons would be that it has insufficient // type, sealing, or program flow information. define open abstract program-note filter #f; end program-note ; define program-condition-definer performance-note; // Portability notes are given when the compiler detects something // that is valid in the DylanWorks compiler, but is not part of // portable Dylan or could have undefined effects in Dylan. // // It should be possible to turn these warnings into errors, to // support a standards-conforming version of the compiler. define open abstract program-note filter #f; end program-note ; define program-condition-definer portability-note; //// EMULATOR HACK: Override the default warning handler for program warnings //// since we can't stop it being called in the emulator, and we handle //// and report them ourselves. define method default-handler (c :: ) end; // eof