From 409fab31e60d1b5e0e31bd8cf99881c416978271 Mon Sep 17 00:00:00 2001 From: Francisco Tolmasky Date: Mon, 16 Mar 2009 00:39:28 -0700 Subject: [PATCH] Added beginnings of bundle app. Reviewed by me. --- Objective-J/{Runtime => }/Object.j | 0 Objective-J/Runtime/build.xml | 64 ------ Objective-J/Runtime/rakefile | 65 ------ Objective-J/Tools/bundle/main.js | 253 ++++++++++++++++++++++++ Objective-J/Tools/bundle/rakefile | 31 +++ Objective-J/Tools/rakefile | 2 +- Objective-J/{Runtime => }/bootstrap.js | 0 Objective-J/build.xml | 73 +++++-- Objective-J/{Runtime => }/constants.js | 0 Objective-J/{Runtime => }/debug.js | 0 Objective-J/{Runtime => }/dictionary.js | 0 Objective-J/{Runtime => }/evaluate.js | 0 Objective-J/{Runtime => }/exception.js | 0 Objective-J/{Runtime => }/file.js | 0 Objective-J/{Runtime => }/license.txt | 0 Objective-J/{Runtime => }/plist.js | 0 Objective-J/{Runtime => }/preprocess.js | 0 Objective-J/rakefile | 61 +++++- Objective-J/{Runtime => }/runtime.js | 0 Objective-J/{Runtime => }/utilities.js | 0 Rake/objective-j.rb | 15 +- 21 files changed, 408 insertions(+), 156 deletions(-) rename Objective-J/{Runtime => }/Object.j (100%) delete mode 100644 Objective-J/Runtime/build.xml delete mode 100644 Objective-J/Runtime/rakefile create mode 100644 Objective-J/Tools/bundle/main.js create mode 100644 Objective-J/Tools/bundle/rakefile rename Objective-J/{Runtime => }/bootstrap.js (100%) rename Objective-J/{Runtime => }/constants.js (100%) rename Objective-J/{Runtime => }/debug.js (100%) rename Objective-J/{Runtime => }/dictionary.js (100%) rename Objective-J/{Runtime => }/evaluate.js (100%) rename Objective-J/{Runtime => }/exception.js (100%) rename Objective-J/{Runtime => }/file.js (100%) rename Objective-J/{Runtime => }/license.txt (100%) rename Objective-J/{Runtime => }/plist.js (100%) rename Objective-J/{Runtime => }/preprocess.js (100%) rename Objective-J/{Runtime => }/runtime.js (100%) rename Objective-J/{Runtime => }/utilities.js (100%) diff --git a/Objective-J/Runtime/Object.j b/Objective-J/Object.j similarity index 100% rename from Objective-J/Runtime/Object.j rename to Objective-J/Object.j diff --git a/Objective-J/Runtime/build.xml b/Objective-J/Runtime/build.xml deleted file mode 100644 index 4084587f5e..0000000000 --- a/Objective-J/Runtime/build.xml +++ /dev/null @@ -1,64 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Objective-J/Runtime/rakefile b/Objective-J/Runtime/rakefile deleted file mode 100644 index 84b542598e..0000000000 --- a/Objective-J/Runtime/rakefile +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env ruby - -require 'rake' -require '../../common' -require 'objective-j' - - -$PRODUCT = File.join($PRODUCT_DIR, 'Objective-J') -$ENVIRONMENT_PRODUCT = File.join($ENVIRONMENT_FRAMEWORKS_DIR, 'Objective-J') - -$LICENSE_FILE = File.join($PRODUCT, 'LICENSE') -$BROWSER_FILE = File.join($PRODUCT, 'Objective-J.js') -$RHINO_FILE = File.join($PRODUCT, 'Rhino.platform', 'Objective-J.js') - -task :Products => [$BROWSER_FILE, $RHINO_FILE] - -task :build => [:Products, $ENVIRONMENT_PRODUCT] - -=begin -task :environment => [$PRODUCT_FILE, $LICENSE_FILE, ENVIRONMENT_FRAMEWORKS_DIR] do - cp_r($BUILD_PRODUCT_DIR, ENVIRONMENT_FRAMEWORKS_DIR) -end -=end -Files = [ 'LICENSE.txt', - 'constants.js', - 'utilities.js', - 'runtime.js', - 'dictionary.js', - 'plist.js', - 'file.js', - 'exception.js', - 'preprocess.js', - 'evaluate.js', - 'debug.js', - 'bootstrap.js']; - -file_d $BROWSER_FILE => Files do |t| - build_product(t.name) -end - -file_d $RHINO_FILE => Files do |t| - build_product(t.name) -end - -#Framework in environment directory -file_d $ENVIRONMENT_PRODUCT => [:Products] do - cp_r($PRODUCT, $ENVIRONMENT_PRODUCT) -end - -def build_product(path, *flags) - - IO.popen("gcc -E -x c -P -", "w+") do |preprocessor| - - Files.select { |name| name.match(/\.js$/) }.each do |fileName| - preprocessor.puts IO.read(fileName) - end - - preprocessor.close_write - - File.open(path, "w") do |file| - file.write(IO.read("LICENSE.txt") + preprocessor.read) - end - - end -end diff --git a/Objective-J/Tools/bundle/main.js b/Objective-J/Tools/bundle/main.js new file mode 100644 index 0000000000..1686615231 --- /dev/null +++ b/Objective-J/Tools/bundle/main.js @@ -0,0 +1,253 @@ + +importPackage(java.lang); + +importClass(java.io.File); +importClass(java.io.BufferedReader); +importClass(java.io.FileReader); +importClass(java.io.BufferedWriter); +importClass(java.io.FileWriter); + + +function main() +{ + var index = 0, + count = arguments.length, + bundlePath = NULL; + + for (; index < count; ++index) + bundlePath = arguments[index]; +alert(bundlePath) + var bundleFile = new File(bundlePath).getCanonicalFile(), + bundlePath = String(bundleFile.getCanonicalPath()), + inlinedBundle = readBundle(bundleFile, true), + inlinedFiles = [], + replacedFiles = [], + staticContent = ""; + + // Find all internal bundles. + var bundleCandidates = getFiles(bundleFile, "plist"), + bundleCandidatesCount = bundleCandidates.length; + + while (bundleCandidatesCount--) + { + var bundleCandidate = bundleCandidates[bundleCandidatesCount]; + + // We only care about Info.plists, specifically the ones that aren't us. + if (String(bundleCandidate.getName()) !== "Info.plist" || String(bundleCandidate.getCanonicalPath()) === inlinedBundle.path) + continue; + + var infoDictionary = readPlist(bundleCandidate); + + // At least one of these two has to be present for this to be a real deal bundle. + if (!dictionary_getValue(infoDictionary, "CPBundleIdentifier") && !dictionary_getValue(infoDictionary, "CPBundleName")) + continue; + + java.lang.System.out.println(" Examining " + pathRelativeTo(bundleCandidate.getCanonicalPath(), bundlePath)); + + dictionary_removeValue(infoDictionary, "CPBundleExecutable"); + + var bundle = readBundle(bundleCandidate.getParentFile(), true); + + bundle.path = pathRelativeTo(bundle.path, bundlePath); + + // We want to inline the info plist too. + var inlinedFiles = [makeOBJJPlistFile(infoDictionary, bundleCandidate, bundle)].concat(bundle.files), + index = 0, + count = inlinedFiles.length; + + for (; index < count; ++index) + { + var file = inlinedFiles[index]; + + file.path = pathRelativeTo(String(file.path), bundlePath); + + java.lang.System.out.println(" Inlining " + file.path); + + replacedFiles.push(file.path); + staticContent += fileToMarkedString(inlinedFiles[index], true); + } + } + + var index = 0, + existingStaticFiles = inlinedBundle.files, + count = existingStaticFiles.length, + topLevelContent = "@STATIC;1.0;"; + + for (; index < count; ++index) + { + var file = existingStaticFiles[index]; + + // If this isn't actually part of our bundle, drop it! + if (file.bundle !== inlinedBundle) + continue; + + file.path = pathRelativeTo(String(file.path), bundlePath); + + replacedFiles.push(file.path); + topLevelContent += fileToMarkedString(file, false); + } + + dictionary_setValue(inlinedBundle.info, "CPBundleReplacedFiles", replacedFiles); + + writeContentsToFile(CPPropertyListCreateXMLData(inlinedBundle.info).string, inlinedBundle.path); + writeContentsToFile(topLevelContent + staticContent, inlinedBundle._staticContentPath); +} + +function fileToMarkedString(anOBJJFile, encodeBundle) +{ + var markedString = ""; + + markedString += MARKER_PATH + ';' + anOBJJFile.path.length + ';' + anOBJJFile.path; + + if (encodeBundle) + markedString += MARKER_BUNDLE + ';' + anOBJJFile.bundle.path.length + ';' + anOBJJFile.bundle.path; + + var fragments = anOBJJFile.fragments; + + if (fragments && fragments.length > 0) + { + var fragmentIndex = 0, + fragmentCount = fragments.length; + + for (; fragmentIndex < fragmentCount; ++fragmentIndex) + markedString += fragments[fragmentIndex].toMarkedString(); + } + + else + markedString += MARKER_TEXT + ';' + anOBJJFile.contents.length + ';' + anOBJJFile.contents; + + return markedString; +} + +function makeOBJJPlistFile(aDictionary, aFile, aBundle) +{ + var file = new objj_file(); + + file.path = typeof aFile === "string" ? aFile : aFile.getCanonicalPath(); + file.bundle = aBundle; + file.contents = CPPropertyListCreate280NorthData(aDictionary).string; + + return file; +} + +function pathRelativeTo(target, relativeTo) +{ + var components = [], + targetParts = target.split("/"), + relativeParts = relativeTo ? relativeTo.split("/") : []; + + var i = 0; + while (i < targetParts.length) + { + if (targetParts[i] != relativeParts[i]) + break; + i++; + } + + for (var j = i; j < relativeParts.length; j++) + components.push(".."); + + for (var j = i; j < targetParts.length; j++) + components.push(targetParts[j]); + + var result = components.join("/"); + + return result; +} + +function readPlist(/*File*/ aFile) +{ + var fileContents = readFile(aFile); + + var data = new objj_data(); + data.string = fileContents; + + return new CPPropertyListCreateFromData(data); +} + +function readBundle(/*File*/ aFile, /*Boolean*/ shouldDecompile) +{ + var bundlePath = typeof aFile === "string" ? new File(aFile).getCanonicalPath() : aFile.getCanonicalPath(), + infoPath = bundlePath + "/Info.plist"; + + //err + var bundle = new objj_bundle(); + + bundle.path = infoPath; + bundle.info = readPlist(infoPath); + bundle._staticFilePaths = dictionary_getValue(bundle.info, "CPBundleReplacedFiles"); + + if (bundle._staticFilePaths.length) + { + bundle._staticContentPath = staticContentPath = bundlePath + '/' + dictionary_getValue(bundle.info, "CPBundleExecutable"); + + //err + + bundle._staticContent = readFile(staticContentPath); + + if (shouldDecompile) + bundle.files = objj_decompile(bundle._staticContent, bundle); + } + else + bundle._staticContent = ""; + + return bundle; +} + +function getFiles(/*File*/ sourceDirectory, /*nil|String|Array*/ extensions, /*Array*/ exclusions) +{ + var matches = [], + files = sourceDirectory.listFiles(), + hasMultipleExtensions = typeof extensions !== "string"; + + if (files) + { + var index = 0, + count = files.length; + + for (; index < count; ++index) + { + var file = files[index].getCanonicalFile(), + name = String(file.getName()), + isValidExtension = !extensions; + + if (exclusions && fileArrayContainsFile(exclusions, file)) + continue; + + if (!isValidExtension) + if (hasMultipleExtensions) + { + var extensionCount = extensions.length; + + while (extensionCount-- && !isValidExtension) + { + var extension = extensions[extensionCount]; + + if (name.substring(name.length - extension.length - 1) === ("." + extension)) + isValidExtension = true; + } + } + else if (name.substring(name.length - extensions.length - 1) === ("." + extensions)) + isValidExtension = true; + + if (isValidExtension) + matches.push(file); + + if (file.isDirectory()) + matches = matches.concat(getFiles(file, extensions, exclusions)); + } + } + + return matches; +} + +function writeContentsToFile(/*String*/ contents, /*File*/ aFile) +{ + var writer = new BufferedWriter(new FileWriter(aFile)); + + writer.write(contents); + + writer.close(); +} + +main.apply(main, arguments); diff --git a/Objective-J/Tools/bundle/rakefile b/Objective-J/Tools/bundle/rakefile new file mode 100644 index 0000000000..efecda5077 --- /dev/null +++ b/Objective-J/Tools/bundle/rakefile @@ -0,0 +1,31 @@ +#!/usr/bin/env ruby + +require 'rake' +require '../../../common' +require 'objective-j' + + +$BUNDLE_SCRIPT = File.join($BUILD_DIR, 'bundle.build', $CONFIGURATION, 'main-concat.js') +$BUNDLE_CLASS = File.join($ENVIRONMENT_LIB_DIR, 'bundle', 'main.class') +$BUNDLE_EXECUTABLE = File.join($ENVIRONMENT_BIN_DIR, 'bundle') +$STANDARD_EXECUTABLE = File.expand_path(File.join('..', 'executable')) + +task :build => [$BUNDLE_CLASS, $BUNDLE_EXECUTABLE] + +Files = [ File.join($HOME_DIR, 'Tools', 'Utilities', 'bridge.js'), #yuck! + File.join($ENVIRONMENT_FRAMEWORKS_DIR, 'Objective-J', 'Rhino.platform', 'Objective-J.js'), + 'main.js']; + +file_d $BUNDLE_EXECUTABLE => [$STANDARD_EXECUTABLE] do + cp($STANDARD_EXECUTABLE, $BUNDLE_EXECUTABLE) + File.chmod 0755, $BUNDLE_EXECUTABLE +end + +file_d $BUNDLE_SCRIPT => Files do |t| + cat(Files, $BUNDLE_SCRIPT) +end + +file_d $BUNDLE_CLASS => $BUNDLE_SCRIPT do |t| + js2java($BUNDLE_SCRIPT, 'main.class', false) + cp(File.join(File.dirname($BUNDLE_SCRIPT), 'main.class'), $BUNDLE_CLASS) +end diff --git a/Objective-J/Tools/rakefile b/Objective-J/Tools/rakefile index caa3700a67..40a27a38b8 100644 --- a/Objective-J/Tools/rakefile +++ b/Objective-J/Tools/rakefile @@ -4,7 +4,7 @@ require 'rake' require '../../common' -subprojects = %w{cplutil objj objjc} +subprojects = %w{bundle cplutil objj objjc} %w(build clean).each do |task_name| task task_name do diff --git a/Objective-J/Runtime/bootstrap.js b/Objective-J/bootstrap.js similarity index 100% rename from Objective-J/Runtime/bootstrap.js rename to Objective-J/bootstrap.js diff --git a/Objective-J/build.xml b/Objective-J/build.xml index 9e1a1bd0fb..4084587f5e 100644 --- a/Objective-J/build.xml +++ b/Objective-J/build.xml @@ -1,27 +1,64 @@ - + - + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + diff --git a/Objective-J/Runtime/constants.js b/Objective-J/constants.js similarity index 100% rename from Objective-J/Runtime/constants.js rename to Objective-J/constants.js diff --git a/Objective-J/Runtime/debug.js b/Objective-J/debug.js similarity index 100% rename from Objective-J/Runtime/debug.js rename to Objective-J/debug.js diff --git a/Objective-J/Runtime/dictionary.js b/Objective-J/dictionary.js similarity index 100% rename from Objective-J/Runtime/dictionary.js rename to Objective-J/dictionary.js diff --git a/Objective-J/Runtime/evaluate.js b/Objective-J/evaluate.js similarity index 100% rename from Objective-J/Runtime/evaluate.js rename to Objective-J/evaluate.js diff --git a/Objective-J/Runtime/exception.js b/Objective-J/exception.js similarity index 100% rename from Objective-J/Runtime/exception.js rename to Objective-J/exception.js diff --git a/Objective-J/Runtime/file.js b/Objective-J/file.js similarity index 100% rename from Objective-J/Runtime/file.js rename to Objective-J/file.js diff --git a/Objective-J/Runtime/license.txt b/Objective-J/license.txt similarity index 100% rename from Objective-J/Runtime/license.txt rename to Objective-J/license.txt diff --git a/Objective-J/Runtime/plist.js b/Objective-J/plist.js similarity index 100% rename from Objective-J/Runtime/plist.js rename to Objective-J/plist.js diff --git a/Objective-J/Runtime/preprocess.js b/Objective-J/preprocess.js similarity index 100% rename from Objective-J/Runtime/preprocess.js rename to Objective-J/preprocess.js diff --git a/Objective-J/rakefile b/Objective-J/rakefile index 4631e50dd9..ceb53bde62 100644 --- a/Objective-J/rakefile +++ b/Objective-J/rakefile @@ -2,12 +2,63 @@ require 'rake' require '../common' +require 'objective-j' -subprojects = %w{Runtime Tools} +$PRODUCT = File.join($PRODUCT_DIR, 'Objective-J') +$ENVIRONMENT_PRODUCT = File.join($ENVIRONMENT_FRAMEWORKS_DIR, 'Objective-J') -%w(build clean).each do |task_name| - task task_name do - subrake(subprojects) - end +$LICENSE_FILE = File.join($PRODUCT, 'LICENSE') +$BROWSER_FILE = File.join($PRODUCT, 'Objective-J.js') +$RHINO_FILE = File.join($PRODUCT, 'Rhino.platform', 'Objective-J.js') + +task :Products => [$BROWSER_FILE, $RHINO_FILE] + +task :build => [:Products, $ENVIRONMENT_PRODUCT, :Tools] + +task :Tools => [:Products] do + subrake(%w{Tools}) +end + +Files = [ 'LICENSE.txt', + 'constants.js', + 'utilities.js', + 'runtime.js', + 'dictionary.js', + 'plist.js', + 'file.js', + 'exception.js', + 'preprocess.js', + 'evaluate.js', + 'debug.js', + 'bootstrap.js']; + +file_d $BROWSER_FILE => Files do |t| + build_product(t.name) +end + +file_d $RHINO_FILE => Files do |t| + build_product(t.name, 'RHINO') +end + +#Framework in environment directory +file_d $ENVIRONMENT_PRODUCT => [:Products] do + cp_r($PRODUCT, $ENVIRONMENT_PRODUCT) +end + +def build_product(path, *flags) + + IO.popen("gcc #{resolve_flags(flags)} -E -x c -P -", "w+") do |preprocessor| + + Files.select { |name| name.match(/\.js$/) }.each do |fileName| + preprocessor.puts IO.read(fileName) + end + + preprocessor.close_write + + File.open(path, "w") do |file| + file.write(IO.read("LICENSE.txt") + preprocessor.read) + end + + end end diff --git a/Objective-J/Runtime/runtime.js b/Objective-J/runtime.js similarity index 100% rename from Objective-J/Runtime/runtime.js rename to Objective-J/runtime.js diff --git a/Objective-J/Runtime/utilities.js b/Objective-J/utilities.js similarity index 100% rename from Objective-J/Runtime/utilities.js rename to Objective-J/utilities.js diff --git a/Rake/objective-j.rb b/Rake/objective-j.rb index 7d41aa4b62..b09f5c5a1b 100644 --- a/Rake/objective-j.rb +++ b/Rake/objective-j.rb @@ -508,17 +508,26 @@ module License end def file_d(*args, &block) - - fileTask = file_create(*args, &block) + fileTask = Rake::FileTask.define_task(*args, &block) + fileDirectory = File.dirname(fileTask.name) directory fileDirectory file fileTask.name => fileDirectory - end def bundle(spec, *args, &block) task = ObjectiveJ::BundleTask.define_task(*args, &block) task.bundle_spec = spec end + +def resolve_flags(flags) + + case flags + when nil then '' + when String then '-D' + flags + when Array then flags.map { |flag| '-D' + flag }.join(' ') + when Hash then flags.map { |flag, value| '-D' + flag + '=' + value }.join(' ') + end +end