mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-08-25 21:17:03 +00:00
Merge branch 'master' of git@github.com:280north/cappuccino
This commit is contained in:
@@ -53,6 +53,7 @@ file_d $THEME_PRODUCT => ThemeFiles << $ENVIRONMENT_PRODUCT do
|
||||
puts str
|
||||
end
|
||||
end
|
||||
rake abort if ($? != 0)
|
||||
end
|
||||
|
||||
task :build => [:build_subprojects, :AppKit, $ENVIRONMENT_PRODUCT, $THEME_PRODUCT, $ENVIRONMENT_THEME_PRODUCT]
|
||||
|
||||
@@ -48,9 +48,7 @@ def platform_flags(*platforms)
|
||||
end
|
||||
|
||||
def build_product(path, flags)
|
||||
|
||||
IO.popen("gcc #{flags} -E -x c -P -", "w+") 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, "w") do |file|
|
||||
file.write(IO.read("header.txt") + preprocessor.read)
|
||||
end
|
||||
|
||||
end
|
||||
rake abort if ($? != 0)
|
||||
end
|
||||
|
||||
task :build => [:Products, $ENVIRONMENT_PRODUCT, :build_subprojects]
|
||||
|
||||
+166
-155
@@ -1,173 +1,184 @@
|
||||
function objj_backtrace_format(aReceiver, aSelector)
|
||||
// formatting helpers
|
||||
|
||||
function objj_debug_object_format(aReceiver)
|
||||
{
|
||||
return "[<" + GETMETA(aReceiver).name + " " + (typeof sprintf == "function" ? sprintf("%#08x", aReceiver.__address) : aReceiver.__address.toString(16)) + "> " + aSelector + "]";
|
||||
return (aReceiver && aReceiver.isa) ? sprintf("<%s %#08x>", 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;
|
||||
|
||||
objj_debug_backtrace.push(objj_backtrace_format(aReceiver, aSelector));
|
||||
|
||||
try
|
||||
{
|
||||
var result = class_getMethodImplementation(aReceiver.isa, aSelector).apply(aReceiver, arguments);
|
||||
}
|
||||
catch (anException)
|
||||
{
|
||||
CPLog.error("Exception " + anException + " in " + objj_backtrace_format(aReceiver, aSelector));
|
||||
objj_debug_print_backtrace();
|
||||
}
|
||||
|
||||
objj_debug_backtrace.pop();
|
||||
|
||||
return result;
|
||||
return sprintf("[%s %s]", objj_debug_object_format(aReceiver), aSelector);
|
||||
}
|
||||
|
||||
function objj_msgSendSuper_Backtrace(/*id*/ aSuper, /*SEL*/ aSelector)
|
||||
|
||||
// save the original msgSend implementations so we can restore them later
|
||||
var objj_msgSend_original = objj_msgSend,
|
||||
objj_msgSendSuper_original = objj_msgSendSuper;
|
||||
|
||||
|
||||
// decorator management functions
|
||||
|
||||
// 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;
|
||||
|
||||
arguments[0] = aSuper.receiver;
|
||||
|
||||
try
|
||||
{
|
||||
var result = class_getMethodImplementation(super_class, aSelector).apply(aSuper.receiver, arguments);
|
||||
}
|
||||
catch (anException)
|
||||
{
|
||||
CPLog.error("Exception " + anException + " in " + objj_backtrace_format(aSuper.receiver, aSelector));
|
||||
objj_debug_print_backtrace();
|
||||
}
|
||||
|
||||
objj_debug_backtrace.pop();
|
||||
|
||||
return result;
|
||||
objj_msgSend = objj_msgSend_original;
|
||||
objj_msgSendSuper = objj_msgSendSuper_original;
|
||||
}
|
||||
|
||||
function objj_msgSend_Profile(/*id*/ aReceiver, /*SEL*/ aSelector)
|
||||
// decorate both objj_msgSend and objj_msgSendSuper
|
||||
function objj_msgSend_decorate()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
arguments[0] = aSuper.receiver;
|
||||
|
||||
var result = class_getMethodImplementation(super_class, aSelector).apply(aSuper.receiver, arguments);
|
||||
|
||||
profileRecord.end = new Date();
|
||||
objj_debug_profile = profileRecord.parent;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (enabled)
|
||||
for (var i = 0; i < arguments.length; i++)
|
||||
{
|
||||
objj_debug_backtrace = [];
|
||||
objj_msgSend = objj_msgSend_Backtrace;
|
||||
objj_msgSendSuper = objj_msgSendSuper_Backtrace;
|
||||
objj_msgSend = arguments[i](objj_msgSend);
|
||||
objj_msgSendSuper = arguments[i](objj_msgSendSuper);
|
||||
}
|
||||
}
|
||||
|
||||
// reset then decorate both objj_msgSend and objj_msgSendSuper
|
||||
function objj_msgSend_set_decorators()
|
||||
{
|
||||
objj_msgSend_reset();
|
||||
objj_msgSend_decorate.apply(null, arguments);
|
||||
}
|
||||
|
||||
|
||||
// backtrace decorator
|
||||
|
||||
var objj_backtrace = [];
|
||||
|
||||
function objj_backtrace_print(stream) {
|
||||
for (var i = 0; i < objj_backtrace.length; i++)
|
||||
objj_fprintf(stream, objj_debug_message_format(objj_backtrace[i].receiver, objj_backtrace[i].selector));
|
||||
}
|
||||
|
||||
function objj_backtrace_decorator(msgSend)
|
||||
{
|
||||
return function(aReceiverOrSuper, aSelector)
|
||||
{
|
||||
var aReceiver = aReceiverOrSuper && (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, "Exception " + anException + " in " + objj_debug_message_format(aReceiver, aSelector));
|
||||
objj_backtrace_print(warning_stream);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// make sure to always pop
|
||||
objj_backtrace.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// type checking decorator
|
||||
|
||||
var objj_typechecks_reported = {},
|
||||
objj_typecheck_prints_backtrace = false;
|
||||
|
||||
function objj_typecheck_decorator(msgSend)
|
||||
{
|
||||
return function(aReceiverOrSuper, aSelector)
|
||||
{
|
||||
var aReceiver = aReceiverOrSuper && (aReceiverOrSuper.receiver || aReceiverOrSuper);
|
||||
|
||||
if (!aReceiver)
|
||||
return msgSend.apply(null, arguments);
|
||||
|
||||
var types = aReceiver.isa.method_dtable[aSelector].types;
|
||||
for (var i = 2; i < arguments.length; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
objj_debug_typecheck(types[i-1], arguments[i]);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
var key = [GETMETA(aReceiver).name, aSelector, i, e].join(";");
|
||||
if (!objj_typechecks_reported[key]) {
|
||||
objj_typechecks_reported[key] = true;
|
||||
objj_fprintf(warning_stream, "Type check failed on argument " + (i-2) + " of " + objj_debug_message_format(aReceiver, aSelector) + ": " + 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, "ret", e].join(";");
|
||||
if (!objj_typechecks_reported[key]) {
|
||||
objj_typechecks_reported[key] = true;
|
||||
objj_fprintf(warning_stream, "Type check failed on return val of " + objj_debug_message_format(aReceiver, aSelector) + ": " + e);
|
||||
if (objj_typecheck_prints_backtrace)
|
||||
objj_backtrace_print(warning_stream);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// type checking logic:
|
||||
function objj_debug_typecheck(expectedType, object)
|
||||
{
|
||||
var objjClass;
|
||||
|
||||
if (!expectedType)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (expectedType === "id")
|
||||
{
|
||||
if (object !== undefined)
|
||||
return;
|
||||
}
|
||||
else if (expectedType === "void")
|
||||
{
|
||||
if (object === undefined)
|
||||
return;
|
||||
}
|
||||
else if (objjClass = objj_getClass(expectedType))
|
||||
{
|
||||
if (object === nil)
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (object && object.isa)
|
||||
{
|
||||
var theClass = object.isa;
|
||||
for (; theClass; theClass = theClass.super_class)
|
||||
if (theClass === objjClass)
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
objj_msgSend = objj_msgSend_Standard;
|
||||
objj_msgSendSuper = objj_msgSendSuper_Standard;
|
||||
}
|
||||
}
|
||||
|
||||
function objj_debug_print_backtrace()
|
||||
{
|
||||
alert(objj_debug_backtrace_string());
|
||||
}
|
||||
|
||||
function objj_debug_backtrace_string()
|
||||
{
|
||||
return objj_debug_backtrace ? objj_debug_backtrace.join("\n") : "";
|
||||
}
|
||||
|
||||
var objj_debug_profile = null,
|
||||
objj_currently_profiling = false,
|
||||
objj_profile_cleanup;
|
||||
|
||||
function objj_profile(title)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
objj_currently_profiling = true;
|
||||
}
|
||||
|
||||
function objj_profileEnd()
|
||||
{
|
||||
if (!objj_currently_profiling)
|
||||
return;
|
||||
|
||||
objj_debug_profile = null;
|
||||
objj_currently_profiling = false;
|
||||
|
||||
return objj_profile_cleanup();
|
||||
var actualType;
|
||||
if (object === null)
|
||||
actualType = "null";
|
||||
else if (object === undefined)
|
||||
actualType = "void";
|
||||
else if (object.isa)
|
||||
actualType = GETMETA(object).name;
|
||||
else
|
||||
actualType = typeof object;
|
||||
|
||||
throw ("expected=" + expectedType + ", actual=" + actualType);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
var OBJJ_PREPROCESSOR_DEBUG_SYMBOLS = 1 << 0;
|
||||
var OBJJ_PREPROCESSOR_DEBUG_SYMBOLS = 1 << 0,
|
||||
OBJJ_PREPROCESSOR_TYPE_SIGNATURES = 1 << 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 = "",
|
||||
parameters = [];
|
||||
parameters = [],
|
||||
types = [null];
|
||||
|
||||
while((token = tokens.skip_whitespace()) && token != TOKEN_OPEN_BRACE)
|
||||
{
|
||||
if (token == TOKEN_COLON)
|
||||
{
|
||||
var type = "";
|
||||
|
||||
// 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()) && token != TOKEN_CLOSE_PARENTHESIS) ;
|
||||
while((token = tokens.skip_whitespace()) && 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 = "";
|
||||
|
||||
// Since :( is handled above, this must be the return type, just swallow it.
|
||||
while((token = tokens.skip_whitespace()) && token != TOKEN_CLOSE_PARENTHESIS) ;
|
||||
while((token = tokens.skip_whitespace()) && token != TOKEN_CLOSE_PARENTHESIS)
|
||||
type += token;
|
||||
|
||||
// types[0] is the return argument
|
||||
types[0] = type || null;
|
||||
}
|
||||
|
||||
// Argument list ", ..."
|
||||
else if (token == TOKEN_COMMA)
|
||||
@@ -654,7 +670,11 @@ objj_preprocessor.prototype.method = function(tokens)
|
||||
|
||||
CONCAT(buffer, ")\n{ with(self)\n{");
|
||||
CONCAT(buffer, this.preprocess(tokens, NULL, TOKEN_CLOSE_BRACE, TOKEN_OPEN_BRACE));
|
||||
CONCAT(buffer, "}\n})");
|
||||
CONCAT(buffer, "}\n}");
|
||||
// TODO: actually use OBJJ_PREPROCESSOR_TYPE_SIGNATURES flag instead of tying to OBJJ_PREPROCESSOR_DEBUG_SYMBOLS
|
||||
if (this._flags & OBJJ_PREPROCESSOR_DEBUG_SYMBOLS) //OBJJ_PREPROCESSOR_TYPE_SIGNATURES)
|
||||
CONCAT(buffer, ","+JSON.stringify(types));
|
||||
CONCAT(buffer, ")");
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@@ -86,7 +86,9 @@ file_d $STARTER_DOWNLOAD_APPLICATION => [$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 => [:tools_download] do
|
||||
else
|
||||
prefix = ''
|
||||
end
|
||||
|
||||
system %{cd #{$TOOLS_DOWNLOAD} && sudo sh ./install-tools #{prefix} }
|
||||
rake abort if ($? != 0)
|
||||
end
|
||||
|
||||
task :test => [:build] do
|
||||
@@ -122,6 +126,8 @@ end
|
||||
task :docs do
|
||||
if executable_exists? "doxygen"
|
||||
system %{doxygen #{$DOXYGEN_CONFIG} }
|
||||
rake abort if ($? != 0)
|
||||
|
||||
rm_rf $DOCUMENTATION_BUILD
|
||||
mv "debug.txt", "Documentation"
|
||||
mv "Documentation", $DOCUMENTATION_BUILD
|
||||
@@ -133,6 +139,7 @@ end
|
||||
task :submodules do
|
||||
if executable_exists? "git"
|
||||
system %{git submodule init && git submodule update}
|
||||
rake abort if ($? != 0)
|
||||
else
|
||||
puts "Git not installed"
|
||||
rake abort
|
||||
|
||||
@@ -390,6 +390,7 @@ module ObjectiveJ
|
||||
puts str
|
||||
end
|
||||
end
|
||||
#rake abort if ($? != 0)
|
||||
end
|
||||
|
||||
{ 'copy' => include_nibs, 'copied_resources' => [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
|
||||
|
||||
@@ -21,7 +21,22 @@
|
||||
</script>
|
||||
|
||||
<script src = "Frameworks/Debug/Objective-J/Objective-J.js" type = "text/javascript"></script>
|
||||
|
||||
|
||||
<script type = "text/javascript">
|
||||
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;
|
||||
</script>
|
||||
|
||||
<style type = "text/css">
|
||||
body{margin:0; padding:0;}
|
||||
#container {position: absolute; top:50%; left:50%;}
|
||||
|
||||
@@ -16,6 +16,7 @@ file_d $BLEND_PRODUCT => ['ThemeDescriptors.j'] do
|
||||
puts str
|
||||
end
|
||||
end
|
||||
rake abort if ($? != 0)
|
||||
end
|
||||
|
||||
task :default => [$BLEND_PRODUCT]
|
||||
|
||||
@@ -77,8 +77,8 @@ end
|
||||
def subrake(directories, task_name)
|
||||
directories.each do |directory|
|
||||
if (File.directory?(directory) && File.file?(File.join(directory, "Rakefile")))
|
||||
ok = system(%{cd #{directory} && #{$serialized_env} #{$0} #{task_name}})
|
||||
rake abort unless ok
|
||||
system(%{cd #{directory} && #{$serialized_env} #{$0} #{task_name}})
|
||||
rake abort if ($? != 0)
|
||||
else
|
||||
puts "warning: subrake missing: " + directory +" (this is not necessarily an error, "+directory+" may be optional)"
|
||||
end
|
||||
@@ -147,4 +147,5 @@ task :clobberall => ['clobber-all']
|
||||
|
||||
def spawn_rake(task_name)
|
||||
system %{#{$serialized_env} #{$0} #{task_name}}
|
||||
rake abort if ($? != 0)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user