<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -48,9 +48,7 @@ def platform_flags(*platforms)
 end
 
 def build_product(path, flags)
-
     IO.popen(&quot;gcc #{flags} -E -x c -P -&quot;, &quot;w+&quot;) do |preprocessor|
-
         Files.select { |name| name.match(/\.js$/) }.each do |fileName|
           preprocessor.puts IO.read(fileName)
         end
@@ -60,8 +58,8 @@ def build_product(path, flags)
         File.open(path, &quot;w&quot;) do |file|
             file.write(IO.read(&quot;header.txt&quot;) + preprocessor.read)
         end
-
     end
+    rake abort if ($? != 0)
 end
 
 task :build =&gt; [:Products, $ENVIRONMENT_PRODUCT, :build_subprojects]</diff>
      <filename>Objective-J/Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -1,173 +1,184 @@
-function objj_backtrace_format(aReceiver, aSelector)
+// formatting helpers
+
+function objj_debug_object_format(aReceiver)
 {
-    return &quot;[&lt;&quot; + GETMETA(aReceiver).name + &quot; &quot; + (typeof sprintf == &quot;function&quot; ? sprintf(&quot;%#08x&quot;, aReceiver.__address) : aReceiver.__address.toString(16)) + &quot;&gt; &quot; + aSelector + &quot;]&quot;;
+    return (aReceiver &amp;&amp; aReceiver.isa) ? sprintf(&quot;&lt;%s %#08x&gt;&quot;, GETMETA(aReceiver).name, aReceiver.__address) : String(aReceiver);
 }
 
-function objj_msgSend_Backtrace(/*id*/ aReceiver, /*SEL*/ aSelector)
+function objj_debug_message_format(aReceiver, aSelector)
 {
-    if (aReceiver == nil)
-        return nil;
+    return sprintf(&quot;[%s %s]&quot;, objj_debug_object_format(aReceiver), aSelector);
+}
 
-    objj_debug_backtrace.push(objj_backtrace_format(aReceiver, aSelector));
 
-    try
-    {
-        var result = class_getMethodImplementation(aReceiver.isa, aSelector).apply(aReceiver, arguments);
-    }
-    catch (anException)
-    {
-        CPLog.error(&quot;Exception &quot; + anException + &quot; in &quot; + objj_backtrace_format(aReceiver, aSelector));
-        objj_debug_print_backtrace();
-    }
+// save the original msgSend implementations so we can restore them later
+var objj_msgSend_original = objj_msgSend,
+    objj_msgSendSuper_original = objj_msgSendSuper;
 
-    objj_debug_backtrace.pop();
 
-    return result;
-}
+// decorator management functions
 
-function objj_msgSendSuper_Backtrace(/*id*/ aSuper, /*SEL*/ aSelector)
+// reset to default objj_msgSend* implementations
+function objj_msgSend_reset()
 {
-    objj_debug_backtrace.push(objj_backtrace_format(aSuper.receiver, aSelector));
-    var super_class = aSuper.super_class;
+    objj_msgSend = objj_msgSend_original;
+    objj_msgSendSuper = objj_msgSendSuper_original;
+}
 
-    arguments[0] = aSuper.receiver;
-    
-    try
-    {
-        var result = class_getMethodImplementation(super_class, aSelector).apply(aSuper.receiver, arguments);
-    }
-    catch (anException)
+// decorate both objj_msgSend and objj_msgSendSuper
+function objj_msgSend_decorate()
+{
+    for (var i = 0; i &lt; arguments.length; i++)
     {
-        CPLog.error(&quot;Exception &quot; + anException + &quot; in &quot; + objj_backtrace_format(aSuper.receiver, aSelector));
-        objj_debug_print_backtrace();
+        objj_msgSend = arguments[i](objj_msgSend);
+        objj_msgSendSuper = arguments[i](objj_msgSendSuper);
     }
-
-    objj_debug_backtrace.pop();
-
-    return result;
 }
 
-function objj_msgSend_Profile(/*id*/ aReceiver, /*SEL*/ aSelector)
+// reset then decorate both objj_msgSend and objj_msgSendSuper
+function objj_msgSend_set_decorators()
 {
-    if (aReceiver == nil)
-        return nil;
-
-    // profiling book keeping 
-    var profileRecord = {
-        parent      : objj_debug_profile,
-        receiver    : GETMETA(aReceiver).name,
-        selector    : aSelector,
-        calls       : []
-    }
-    objj_debug_profile.calls.push(profileRecord);
-    objj_debug_profile = profileRecord;
-    profileRecord.start = new Date();
-    
-    var result = class_getMethodImplementation(aReceiver.isa, aSelector).apply(aReceiver, arguments);
-    
-    profileRecord.end = new Date();
-    objj_debug_profile = profileRecord.parent;
-
-    return result;
+    objj_msgSend_reset();
+    objj_msgSend_decorate.apply(null, arguments);
 }
 
-function objj_msgSendSuper_Profile(/*id*/ aSuper, /*SEL*/ aSelector)
-{
-    // profiling book keeping 
-    var profileRecord = {
-        parent      : objj_debug_profile,
-        receiver    : GETMETA(aReceiver).name,
-        selector    : aSelector,
-        calls       : []
-    }
-    objj_debug_profile.calls.push(profileRecord);
-    objj_debug_profile = profileRecord;
-    profileRecord.start = new Date();
 
-    var super_class = aSuper.super_class;
+// backtrace decorator
 
-    arguments[0] = aSuper.receiver;
-    
-    var result = class_getMethodImplementation(super_class, aSelector).apply(aSuper.receiver, arguments);
-    
-    profileRecord.end = new Date();
-    objj_debug_profile = profileRecord.parent;
+var objj_backtrace = [];
 
-    return result;
+function objj_backtrace_print(stream) {
+    for (var i = 0; i &lt; objj_backtrace.length; i++)
+        objj_fprintf(stream, objj_debug_message_format(objj_backtrace[i].receiver, objj_backtrace[i].selector));
 }
 
-var objj_msgSend_Standard = objj_msgSend,
-    objj_msgSendSuper_Standard = objj_msgSendSuper;
-
-// FIXME: This could be much better.
-var objj_debug_backtrace;
-    
-function objj_backtrace_set_enabled(enabled)
+function objj_backtrace_decorator(msgSend)
 {
-    if (enabled)
-    {
-        objj_debug_backtrace = [];
-        objj_msgSend = objj_msgSend_Backtrace;
-        objj_msgSendSuper = objj_msgSendSuper_Backtrace;
-    }
-    else
+    return function(aReceiverOrSuper, aSelector)
     {
-        objj_msgSend = objj_msgSend_Standard;
-        objj_msgSendSuper = objj_msgSendSuper_Standard;
+        var aReceiver = aReceiverOrSuper &amp;&amp; (aReceiverOrSuper.receiver || aReceiverOrSuper);
+        
+        // push the receiver and selector onto the backtrace stack
+        objj_backtrace.push({ receiver: aReceiver, selector : aSelector });
+        try
+        {
+            return msgSend.apply(null, arguments);
+        }
+        catch (anException)
+        {
+            // print the exception and backtrace
+            objj_fprintf(warning_stream, &quot;Exception &quot; + anException + &quot; in &quot; + objj_debug_message_format(aReceiver, aSelector));
+            objj_backtrace_print(warning_stream);
+        }
+        finally
+        {
+            // make sure to always pop
+            objj_backtrace.pop();
+        }
     }
 }
 
-function objj_debug_print_backtrace()
-{
-    alert(objj_debug_backtrace_string());
-}
+// type checking decorator
 
-function objj_debug_backtrace_string()
-{
-    return objj_debug_backtrace ? objj_debug_backtrace.join(&quot;\n&quot;) : &quot;&quot;;
-}
+var objj_typechecks_reported = {},
+    objj_typecheck_prints_backtrace = false;
 
-var objj_debug_profile = null,
-    objj_currently_profiling = false,
-    objj_profile_cleanup;
-
-function objj_profile(title)
+function objj_typecheck_decorator(msgSend)
 {
-    if (objj_currently_profiling)
-        return;
-    
-    var objj_msgSend_profile_saved = objj_msgSend,
-        objj_msgSendSuper_profile_saved = objj_msgSendSuper;
-    
-    objj_msgSend = objj_msgSend_Profile;
-    objj_msgSendSuper = objj_msgSendSuper_Profile;
-    
-    var root = { calls: [] };
-    objj_debug_profile = root;
-    
-    var context = {
-        start : new Date(),
-        title : title,
-        profile : root
-    };
-
-    objj_profile_cleanup = function() {
-        objj_msgSend = objj_msgSend_profile_saved;
-        objj_msgSendSuper = objj_msgSendSuper_profile_saved;
-        context.end = new Date();
-        return context;
+    return function(aReceiverOrSuper, aSelector)
+    {
+        var aReceiver = aReceiverOrSuper &amp;&amp; (aReceiverOrSuper.receiver || aReceiverOrSuper);
+        
+        if (!aReceiver)
+            return msgSend.apply(null, arguments);
+
+        var types = aReceiver.isa.method_dtable[aSelector].types;
+        for (var i = 2; i &lt; arguments.length; i++)
+        {
+            try
+            {
+                objj_debug_typecheck(types[i-1], arguments[i]);
+            }
+            catch (e)
+            {
+                var key = [GETMETA(aReceiver).name, aSelector, i, e].join(&quot;;&quot;);
+                if (!objj_typechecks_reported[key]) {
+                    objj_typechecks_reported[key] = true;
+                    objj_fprintf(warning_stream, &quot;Type check failed on argument &quot; + (i-2) + &quot; of &quot; + objj_debug_message_format(aReceiver, aSelector) + &quot;: &quot; + e);
+                    if (objj_typecheck_prints_backtrace)
+                        objj_backtrace_print(warning_stream);
+                }
+            }
+        }
+        
+        var result = msgSend.apply(null, arguments);
+
+        try
+        {
+            objj_debug_typecheck(types[0], result);
+        }
+        catch (e)
+        {
+            var key = [GETMETA(aReceiver).name, aSelector, &quot;ret&quot;, e].join(&quot;;&quot;);
+            if (!objj_typechecks_reported[key]) {
+                objj_typechecks_reported[key] = true;
+                objj_fprintf(warning_stream, &quot;Type check failed on return val of &quot; + objj_debug_message_format(aReceiver, aSelector) + &quot;: &quot; + e);
+                if (objj_typecheck_prints_backtrace)
+                    objj_backtrace_print(warning_stream);
+            }
+        }
+
+        return result;
     }
-    
-    objj_currently_profiling = true;
 }
 
-function objj_profileEnd()
+// type checking logic:
+function objj_debug_typecheck(expectedType, object)
 {
-    if (!objj_currently_profiling)
-        return;
+    var objjClass;
     
-    objj_debug_profile = null;
-    objj_currently_profiling = false;
+    if (!expectedType)
+    {
+        return;
+    }
+    else if (expectedType === &quot;id&quot;)
+    {
+        if (object !== undefined)
+            return;
+    }
+    else if (expectedType === &quot;void&quot;)
+    {
+        if (object === undefined)
+            return;
+    }
+    else if (objjClass = objj_getClass(expectedType))
+    {
+        if (object === nil)
+        {
+            return;
+        }
+        else if (object &amp;&amp; object.isa)
+        {
+            var theClass = object.isa;
+            for (; theClass; theClass = theClass.super_class)
+            if (theClass === objjClass)
+                return;
+        }
+    }
+    else
+    {
+        return;
+    }
     
-    return objj_profile_cleanup();
+    var actualType;
+    if (object === null)
+        actualType = &quot;null&quot;;
+    else if (object === undefined)
+        actualType = &quot;void&quot;;
+    else if (object.isa)
+        actualType = GETMETA(object).name;
+    else
+        actualType = typeof object;
+        
+    throw (&quot;expected=&quot; + expectedType + &quot;, actual=&quot; + actualType);
 }</diff>
      <filename>Objective-J/debug.js</filename>
    </modified>
    <modified>
      <diff>@@ -20,7 +20,8 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-var OBJJ_PREPROCESSOR_DEBUG_SYMBOLS = 1 &lt;&lt; 0;
+var OBJJ_PREPROCESSOR_DEBUG_SYMBOLS = 1 &lt;&lt; 0,
+    OBJJ_PREPROCESSOR_TYPE_SIGNATURES = 1 &lt;&lt; 1;
 
 function objj_preprocess(/*String*/ aString, /*objj_bundle*/ aBundle, /*objj_file*/ aSourceFile, /*unsigned*/ flags) 
 {    
@@ -592,12 +593,15 @@ objj_preprocessor.prototype.method = function(tokens)
     var buffer = new objj_stringBuffer(),
         token,
         selector = &quot;&quot;,
-        parameters = [];
+        parameters = [],
+        types = [null];
     
     while((token = tokens.skip_whitespace()) &amp;&amp; token != TOKEN_OPEN_BRACE)
     {
         if (token == TOKEN_COLON)
         {
+            var type = &quot;&quot;;
+
             // Colons are part of the selector name
             selector += token;
             
@@ -606,18 +610,30 @@ objj_preprocessor.prototype.method = function(tokens)
             if (token == TOKEN_OPEN_PARENTHESIS)
             {
                 // Swallow parameter/return type.  Perhaps later we can use this for debugging?
-                while((token = tokens.skip_whitespace()) &amp;&amp; token != TOKEN_CLOSE_PARENTHESIS) ;
+                while((token = tokens.skip_whitespace()) &amp;&amp; token != TOKEN_CLOSE_PARENTHESIS)
+                    type += token;
     
                 token = tokens.skip_whitespace();
             }
             
+            // Add the type. If it's empty, add null instead.
+            types[parameters.length+1] = type || null;
+
             // Since this follows a colon, this must be the parameter name.
             parameters[parameters.length] = token;
         }
         
         else if (token == TOKEN_OPEN_PARENTHESIS)
+        {
+            var type = &quot;&quot;;
+
             // Since :( is handled above, this must be the return type, just swallow it.
-            while((token = tokens.skip_whitespace()) &amp;&amp; token != TOKEN_CLOSE_PARENTHESIS) ;
+            while((token = tokens.skip_whitespace()) &amp;&amp; token != TOKEN_CLOSE_PARENTHESIS)
+                type += token;
+
+            // types[0] is the return argument
+            types[0] = type || null;
+        }
         
         // Argument list &quot;, ...&quot;
         else if (token == TOKEN_COMMA)
@@ -654,7 +670,11 @@ objj_preprocessor.prototype.method = function(tokens)
 
     CONCAT(buffer, &quot;)\n{ with(self)\n{&quot;);
     CONCAT(buffer, this.preprocess(tokens, NULL, TOKEN_CLOSE_BRACE, TOKEN_OPEN_BRACE));
-    CONCAT(buffer, &quot;}\n})&quot;);
+    CONCAT(buffer, &quot;}\n}&quot;);
+    // TODO: actually use OBJJ_PREPROCESSOR_TYPE_SIGNATURES flag instead of tying to OBJJ_PREPROCESSOR_DEBUG_SYMBOLS
+    if (this._flags &amp; OBJJ_PREPROCESSOR_DEBUG_SYMBOLS) //OBJJ_PREPROCESSOR_TYPE_SIGNATURES)
+        CONCAT(buffer, &quot;,&quot;+JSON.stringify(types));
+    CONCAT(buffer, &quot;)&quot;);
 
     return buffer;
 }</diff>
      <filename>Objective-J/preprocess.js</filename>
    </modified>
    <modified>
      <diff>@@ -86,7 +86,9 @@ file_d $STARTER_DOWNLOAD_APPLICATION =&gt; [$TOOLS_DOWNLOAD_ENV] do
 
     rm_rf($STARTER_DOWNLOAD_APPLICATION)
     mkdir_p($STARTER_DOWNLOAD)
+    
     system %{capp gen #{$STARTER_DOWNLOAD_APPLICATION} -t Application --noconfig }
+    rake abort if ($? != 0)
 
     # No tools means no objective-j gem
     rm(File.join($STARTER_DOWNLOAD_APPLICATION, 'Rakefile'))
@@ -103,7 +105,9 @@ task :install =&gt; [:tools_download] do
     else
         prefix = ''
     end
+    
     system %{cd #{$TOOLS_DOWNLOAD} &amp;&amp; sudo sh ./install-tools #{prefix} }
+    rake abort if ($? != 0)
 end
 
 task :test =&gt; [:build] do
@@ -122,6 +126,8 @@ end
 task :docs do
     if executable_exists? &quot;doxygen&quot;
       system %{doxygen #{$DOXYGEN_CONFIG} }
+      rake abort if ($? != 0)
+      
       rm_rf $DOCUMENTATION_BUILD
       mv &quot;debug.txt&quot;, &quot;Documentation&quot;
       mv &quot;Documentation&quot;, $DOCUMENTATION_BUILD
@@ -133,6 +139,7 @@ end
 task :submodules do
     if executable_exists? &quot;git&quot;
         system %{git submodule init &amp;&amp; git submodule update}
+        rake abort if ($? != 0)
     else
         puts &quot;Git not installed&quot;
         rake abort</diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -390,6 +390,7 @@ module ObjectiveJ
                                 puts str
                             end
                         end
+                        #rake abort if ($? != 0)
                     end
 
                     { 'copy' =&gt; include_nibs, 'copied_resources' =&gt; [copied_resource] }
@@ -424,6 +425,7 @@ module ObjectiveJ
                             puts str
                         end
                     end
+                    rake abort if ($? != 0)
                 end
 
                 enhance([frameworks_path])
@@ -510,6 +512,7 @@ module ObjectiveJ
                             puts str
                         end
                     end
+                    rake abort if ($? != 0)
                 end
 
                 BundleTask.compact(build_path) if needs_compact</diff>
      <filename>Tools/Rake/lib/objective-j/bundletask.rb</filename>
    </modified>
    <modified>
      <diff>@@ -21,7 +21,22 @@
         &lt;/script&gt;
         
         &lt;script src = &quot;Frameworks/Debug/Objective-J/Objective-J.js&quot; type = &quot;text/javascript&quot;&gt;&lt;/script&gt;
-
+        
+        &lt;script type = &quot;text/javascript&quot;&gt;
+            objj_msgSend_reset();
+            
+            // DEBUG OPTIONS:
+            
+            // Uncomment to enable printing of backtraces on exceptions:
+            //objj_msgSend_decorate(objj_backtrace_decorator);
+            
+            // Uncomment to enable runtime type checking:
+            //objj_msgSend_decorate(objj_typecheck_decorator);
+            
+            // Uncomment (along with both above) to print backtraces on type check errors:
+            //objj_typecheck_prints_backtrace = true;
+        &lt;/script&gt;
+        
         &lt;style type = &quot;text/css&quot;&gt;
             body{margin:0; padding:0;}
             #container {position: absolute; top:50%; left:50%;}</diff>
      <filename>Tools/capp/Templates/Application/index-debug.html</filename>
    </modified>
    <modified>
      <diff>@@ -16,6 +16,7 @@ file_d $BLEND_PRODUCT =&gt; ['ThemeDescriptors.j'] do
             puts str
         end
     end
+    rake abort if ($? != 0)
 end
 
 task :default =&gt; [$BLEND_PRODUCT]</diff>
      <filename>Tools/capp/Templates/ThemeDescriptor/Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -77,8 +77,8 @@ end
 def subrake(directories, task_name)
     directories.each do |directory|
       if (File.directory?(directory) &amp;&amp; File.file?(File.join(directory, &quot;Rakefile&quot;)))
-        ok = system(%{cd #{directory} &amp;&amp; #{$serialized_env} #{$0} #{task_name}})
-        rake abort unless ok
+        system(%{cd #{directory} &amp;&amp; #{$serialized_env} #{$0} #{task_name}})
+        rake abort if ($? != 0)
       else
         puts &quot;warning: subrake missing: &quot; + directory +&quot; (this is not necessarily an error, &quot;+directory+&quot; may be optional)&quot;
       end
@@ -147,4 +147,5 @@ task :clobberall =&gt; ['clobber-all']
 
 def spawn_rake(task_name)
     system %{#{$serialized_env} #{$0} #{task_name}}
+    rake abort if ($? != 0)
 end</diff>
      <filename>common.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>0876653ae3fe9016ef950fd640bb0a1762bf82c1</id>
    </parent>
    <parent>
      <id>0c349a8d7f67b185747290595dbd666fb841408d</id>
    </parent>
  </parents>
  <author>
    <name>Francisco Ryan Tolmasky I</name>
    <email>francisco@280north.com</email>
  </author>
  <url>http://github.com/280north/cappuccino/commit/69fa064509eaca0b7b9637edafe075fa321c18cc</url>
  <id>69fa064509eaca0b7b9637edafe075fa321c18cc</id>
  <committed-date>2009-07-29T20:28:42-07:00</committed-date>
  <authored-date>2009-07-29T20:28:42-07:00</authored-date>
  <message>Merge branch 'master' of git@github.com:280north/cappuccino</message>
  <tree>3965f2288ed9a797143e5893c3d7f4e2a13331d8</tree>
  <committer>
    <name>Francisco Ryan Tolmasky I</name>
    <email>francisco@280north.com</email>
  </committer>
</commit>
