Adding pure JavaScript implementation
diff --git a/bundles/org.eclipse.e4.languages.javascript.framework/.classpath b/bundles/org.eclipse.e4.languages.javascript.framework/.classpath
new file mode 100644
index 0000000..ad32c83
--- /dev/null
+++ b/bundles/org.eclipse.e4.languages.javascript.framework/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.languages.javascript.framework/.project b/bundles/org.eclipse.e4.languages.javascript.framework/.project
new file mode 100644
index 0000000..1fa88b8
--- /dev/null
+++ b/bundles/org.eclipse.e4.languages.javascript.framework/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.e4.languages.javascript.framework</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.wst.jsdt.core.jsNature</nature>
+ </natures>
+</projectDescription>
diff --git a/bundles/org.eclipse.e4.languages.javascript.framework/.settings/.jsdtscope b/bundles/org.eclipse.e4.languages.javascript.framework/.settings/.jsdtscope
new file mode 100644
index 0000000..8e0b886
--- /dev/null
+++ b/bundles/org.eclipse.e4.languages.javascript.framework/.settings/.jsdtscope
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="scripts"/>
+ <classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.JRE_CONTAINER"/>
+ <classpathentry exported="true" kind="con" path="org.eclipse.wst.jsdt.launching.baseBrowserLibrary"/>
+ <classpathentry kind="con" path="org.eclipse.wst.jsdt.launching.WebProject">
+ <attributes>
+ <attribute name="hide" value="true"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="output" path=""/>
+</classpath>
diff --git a/bundles/org.eclipse.e4.languages.javascript.framework/.settings/org.eclipse.jdt.core.prefs b/bundles/org.eclipse.e4.languages.javascript.framework/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..9d55ece
--- /dev/null
+++ b/bundles/org.eclipse.e4.languages.javascript.framework/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+#Fri May 14 15:54:58 EDT 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/bundles/org.eclipse.e4.languages.javascript.framework/.settings/org.eclipse.pde.core.prefs b/bundles/org.eclipse.e4.languages.javascript.framework/.settings/org.eclipse.pde.core.prefs
new file mode 100644
index 0000000..8b0b8e1
--- /dev/null
+++ b/bundles/org.eclipse.e4.languages.javascript.framework/.settings/org.eclipse.pde.core.prefs
@@ -0,0 +1,4 @@
+#Fri May 14 15:54:59 EDT 2010
+eclipse.preferences.version=1
+pluginProject.extensions=false
+resolve.requirebundle=false
diff --git a/bundles/org.eclipse.e4.languages.javascript.framework/.settings/org.eclipse.wst.jsdt.ui.superType.container b/bundles/org.eclipse.e4.languages.javascript.framework/.settings/org.eclipse.wst.jsdt.ui.superType.container
new file mode 100644
index 0000000..3bd5d0a
--- /dev/null
+++ b/bundles/org.eclipse.e4.languages.javascript.framework/.settings/org.eclipse.wst.jsdt.ui.superType.container
@@ -0,0 +1 @@
+org.eclipse.wst.jsdt.launching.baseBrowserLibrary
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.languages.javascript.framework/.settings/org.eclipse.wst.jsdt.ui.superType.name b/bundles/org.eclipse.e4.languages.javascript.framework/.settings/org.eclipse.wst.jsdt.ui.superType.name
new file mode 100644
index 0000000..05bd71b
--- /dev/null
+++ b/bundles/org.eclipse.e4.languages.javascript.framework/.settings/org.eclipse.wst.jsdt.ui.superType.name
@@ -0,0 +1 @@
+Window
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.languages.javascript.framework/META-INF/MANIFEST.MF b/bundles/org.eclipse.e4.languages.javascript.framework/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..931919e
--- /dev/null
+++ b/bundles/org.eclipse.e4.languages.javascript.framework/META-INF/MANIFEST.MF
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Framework
+Bundle-SymbolicName: org.eclipse.e4.languages.javascript.framework
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
diff --git a/bundles/org.eclipse.e4.languages.javascript.framework/build.properties b/bundles/org.eclipse.e4.languages.javascript.framework/build.properties
new file mode 100644
index 0000000..f38581b
--- /dev/null
+++ b/bundles/org.eclipse.e4.languages.javascript.framework/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ scripts/
diff --git a/bundles/org.eclipse.e4.languages.javascript.framework/scripts/Bundle.js b/bundles/org.eclipse.e4.languages.javascript.framework/scripts/Bundle.js
new file mode 100644
index 0000000..4d960d4
--- /dev/null
+++ b/bundles/org.eclipse.e4.languages.javascript.framework/scripts/Bundle.js
@@ -0,0 +1,364 @@
+function Bundle(framework, bundleData) {
+ this._framework = framework;
+ this._bundleData = bundleData;
+ this._name = null;
+ this._version = null;
+ this._imports = [];
+ this._requires = [];
+ this._exports = [];
+ this._resources = {};
+ this._singleton = false;
+ this._markedStarted = false;
+ this._state = Bundle.INSTALLED;
+ this._scope = {};
+ this._bundleContext = null;
+ this._activator = null;
+
+ var headers = bundleData.getHeaders();
+ this._parseName(headers[Constants.BUNDLE_NAME]);
+ this._parseVersion(headers[Constants.BUNDLE_VERSION]);
+ this._parseImports(headers[Constants.BUNDLE_IMPORTS]);
+ this._parseExports(headers[Constants.BUNDLE_EXPORTS]);
+ this._parseRequires(headers[Constants.BUNDLE_REQUIRES]);
+ this._parseResources(headers[Constants.BUNDLE_RESOURCES]);
+}
+
+Bundle.UNINSTALLED = 1;
+Bundle.INSTALLED = 2;
+Bundle.RESOLVED = 4;
+Bundle.STARTING = 8;
+Bundle.STOPPING = 16;
+Bundle.ACTIVE = 32;
+
+Bundle.prototype = {
+ getName : function() {
+ return this._name;
+ },
+ getVersion : function() {
+ return this._version;
+ },
+ getBundleId : function() {
+ return this._bundleData.getBundleId();
+ },
+ getLocation : function() {
+ return this._bundleData.getLocation();
+ },
+ getHeaders : function() {
+ return this._bundleData.getHeaders();
+ },
+ getState : function() {
+ return this._state;
+ },
+ getEntry : function(path) {
+ if (!path || !path instanceof String || !this._resources[path])
+ return null;
+
+ return this.getLocation() + path;
+ },
+ getResource : function(path) {
+ if (!path || !path instanceof String)
+ return null;
+
+ var i = 0;
+ var resource;
+ for (i = 0; i < this._imports.length; i++) {
+ var jsImport = this._imports[i];
+ var jsExport = jsImport.getWiredExport();
+ if (!jsExport)
+ continue; // optional
+ var name = jsExport.getName();
+ if (name.charAt(0) != "/")
+ continue; // not a resource
+ if (path.indexOf(name)==0) {
+ resource = jsExport.getExportingBundle().getEntry(path);
+ if (resource)
+ return resource;
+ }
+ }
+
+ // process requires
+ for (i = 0; i < this._requires.length; i++) {
+ var jsRequire = this._requires[i];
+ var wiredBundle = jsRequire.getWiredBundle();
+ if (!wiredBundle) {
+ continue; //optional
+ }
+ var wiredBundleExports = wiredBundle._getExports();
+ for (var j=0; j < wiredBundleExports.length; j++) {
+ jsExport = wiredBundleExports[j];
+ var name = jsExport.getName();
+ if (name.charAt(0) != "/")
+ continue; // not a resource
+ if (path.indexOf(name)==0) {
+ resource = jsExport.getExportingBundle().getEntry(path);
+ if (resource)
+ return resource;
+ }
+ }
+ }
+ return this.getEntry(path);
+ },
+ equals : function(other) {
+ if (this === other)
+ return true;
+
+ if (!other instanceof Bundle)
+ return false;
+
+ if (this._name !== other._name)
+ return false;
+ if (this._version === null) {
+ if (other._version !== null)
+ return false;
+ } else if (!this._version.equals(other._version))
+ return false;
+ return true;
+ },
+ uninstall : function() {
+ this._state = Bundle.UNINSTALLED;
+ },
+ start : function() {
+ this._markedStarted = true;
+ if (this._state !== Bundle.RESOLVED)
+ return;
+
+ this._state = Bundle.STARTING;
+ this._bundleContext = this._framework._getBundleContext(this);
+ this._activator = this._createActivatorInstance();
+ if (this._activator) {
+ this._activator.start(this._bundleContext);
+ }
+ this._state = Bundle.ACTIVE;
+ },
+ stop : function() {
+ markedStarted = false;
+ if (this._state !== Bundle.ACTIVE)
+ return;
+
+ this._state = Bundle.STOPPING;
+ if (this._activator) {
+ this._activator.stop(this._bundleContext);
+ }
+ this._state = Bundle.RESOLVED;
+ },
+ load : function(name) {
+ var value = this._scope;
+ if (value === null || value === undefined) {
+ return undefined;
+ }
+ var names = name.split(".");
+ for ( var i = 0; i < names.length; i++) {
+ if (value === null || value === undefined) {
+ return undefined;
+ }
+ value = value[names[i]];
+ }
+ return value;
+ },
+ _isSingleton : function() {
+ return this._singleton;
+ },
+ _isMarkedStarted : function() {
+ return this._markedStarted;
+ },
+ _getImports : function() {
+ return this._imports;
+ },
+ _getExports : function() {
+ return this._exports;
+ },
+ _getRequires : function() {
+ return this._requires;
+ },
+ _createActivatorInstance : function() {
+ var activatorName = this.getHeaders()[Constants.BUNDLE_ACTIVATOR];
+ if (activatorName === null || activatorName === undefined)
+ return null;
+
+ var activatorFunction = this.load(activatorName);
+ if (typeof activatorFunction !== "function")
+ throw "" + activatorName + " is not a function.";
+ return new activatorFunction();
+ },
+ _resolve : function() {
+ if (this._state != Bundle.INSTALLED)
+ return;
+
+ var namedExports = {};
+ var jsExport = null;
+ var i = 0;
+ // process imports (first)
+ for (i = 0; i < this._imports.length; i++) {
+ var jsImport = this._imports[i];
+ var jsExport = jsImport.getWiredExport();
+ if (!jsExport)
+ continue; // optional
+ var name = jsExport.getName();
+ if (name.charAt(0) == "/")
+ continue; // resource
+ if (!namedExports.hasOwnProperty(name))
+ namedExports[name] = jsImport.getWiredExport();
+ }
+
+ // process requires
+ for (i = 0; i < this._requires.length; i++) {
+ var jsRequire = this._requires[i];
+ var wiredBundle = jsRequire.getWiredBundle();
+ if (!wiredBundle) {
+ continue; //optional
+ }
+ var wiredBundleExports = wiredBundle._getExports();
+ for (var j=0; j < wiredBundleExports.length; j++) {
+ jsExport = wiredBundleExports[j];
+ var name = jsExport.getName();
+ if (name.charAt(0) == "/")
+ continue; // resource
+ if (!namedExports.hasOwnProperty(name))
+ namedExports[name] = jsImport.getWiredExport();
+ }
+ }
+
+ var names = [];
+ var exportName = null;
+ for (exportName in namedExports) {
+ if (namedExports.hasOwnProperty(exportName))
+ names.push(exportName);
+ }
+
+ // this sorts the set of names we'll be importing alphabetically and
+ // perhaps more importantly will allow us to create the shorter/parent dotted entries first
+ names.sort();
+
+ var importScope = {};
+ for (i = 0; i < names.length; i++) {
+ exportName = names[i];
+ jsExport = namedExports[exportName];
+ jsExport.addToScope(importScope);
+ }
+
+ this._evalScript(importScope);
+ this._state = Bundle.RESOLVED;
+ },
+ _evalScript : function(importScope) {
+ var parameterNames = [];
+ var parameterValues = [];
+ var parameterName = null;
+ for (parameterName in importScope) {
+ if (importScope.hasOwnProperty(parameterName)) {
+ parameterNames.push(parameterName);
+ parameterValues.push(importScope[parameterName]);
+ }
+
+ }
+
+ var exportNames = [];
+ for (i = 0; i < this._exports.length; i++) {
+ var exportName = this._exports[i].getName();
+ if (exportName.charAt(0) == "/")
+ continue; // resource
+ var dotIndex = exportName.indexOf(".");
+ if (dotIndex !== -1)
+ exportName = exportName.substring(0,dotIndex);
+
+ if (! exportNames.hasOwnProperty(exportName)) {
+ exportNames[exportName] = true;
+ exportNames.push(exportName + ":" + exportName);
+ }
+ }
+
+ var parameterStatement = parameterNames.join(",");
+ var script = this._bundleData.getHeaders()[Constants.BUNDLE_SCRIPT] || "";
+ var returnStatement = "\n\nreturn {" + exportNames.join(",") + "};";
+
+ var that = this;
+ var loader = {
+ getResources: function(path) {
+ return that.getResources(path);
+ }
+ };
+
+ var finalScript = script + returnStatement;
+ var load = new Function(parameterStatement, finalScript);
+ this._scope = load.apply(loader, parameterValues);
+ },
+ _unresolve : function() {
+ if (this._state == Bundle.ACTIVE) {
+ this.stop();
+ markedStarted = true;
+ }
+ this._scope = null;
+
+ if (this._state == Bundle.RESOLVED)
+ this._state = Bundle.INSTALLED;
+ },
+ _parseName : function(header) {
+ var tokens = header.split(Constants.PARAMETER_DELIMITER);
+ this._name = tokens[0].replace(/^\s+|\s+$/g, '');
+ for ( var i = 1; i < tokens.length; i++) {
+ var token = tokens[i];
+ if (token.indexOf(Constants.DIRECTIVE_EQUALS) != -1) {
+ var index = token.indexOf(Constants.DIRECTIVE_EQUALS);
+ var directiveName = token.substring(0, index).replace(/^\s+|\s+$/g, '');
+ if (directiveName.length === 0)
+ throw "bad syntax: " + token + " in " + header;
+
+ if (directiveName !== Constants.SINGLETON_DIRECTIVE)
+ continue;
+ var value = token.substring(index + Constants.DIRECTIVE_EQUALS.length).replace(/^\s+|\s+$/g, '');
+ if (value.toLowerCase() === "true")
+ this._singleton = true;
+ } else
+ throw "bad syntax: " + token + " in " + header;
+ }
+ },
+ _parseVersion : function(header) {
+ this._version = Version.parseVersion(header);
+ },
+ _parseResources : function(header) {
+ if (!header)
+ return;
+
+ var tokens = header.split(Constants.CLAUSE_DELIMITER);
+ for ( var i = 0; i < tokens.length; i++) {
+ if (tokens[i]) {
+ var path = tokens[i].replace(/^\s+|\s+$/g, '');
+ this._resources[path] = true;
+ }
+ }
+ },
+ _parseRequires : function(header) {
+ if (!header)
+ return;
+
+ var tokens = header.split(Constants.CLAUSE_DELIMITER);
+ for ( var i = 0; i < tokens.length; i++) {
+ var token = tokens[i];
+ var jsRequire = new _Require(token);
+ if (jsRequire !== null)
+ this._requires.push(jsRequire);
+ }
+ },
+ _parseExports : function(header) {
+ if (!header)
+ return;
+ var tokens = header.split(Constants.CLAUSE_DELIMITER);
+ for ( var i = 0; i < tokens.length; i++) {
+ var token = tokens[i];
+ var jsExport = new _Export(token, this);
+ if (jsExport !== null)
+ this._exports.push(jsExport);
+ }
+ },
+ _parseImports : function(header) {
+ if (!header)
+ return;
+
+ var tokens = header.split(Constants.CLAUSE_DELIMITER);
+ for ( var i = 0; i < tokens.length; i++) {
+ var token = tokens[i];
+ var jsImport = new _Import(token);
+ if (jsImport !== null)
+ this._imports.push(jsImport);
+ }
+ }
+};
diff --git a/bundles/org.eclipse.e4.languages.javascript.framework/scripts/BundleContext.js b/bundles/org.eclipse.e4.languages.javascript.framework/scripts/BundleContext.js
new file mode 100644
index 0000000..2685312
--- /dev/null
+++ b/bundles/org.eclipse.e4.languages.javascript.framework/scripts/BundleContext.js
@@ -0,0 +1,19 @@
+function BundleContext(bundle, framework) {
+ this._bundle = bundle;
+ this._framework = framework;
+}
+
+BundleContext.prototype = {
+ getBundle : function() {
+ return this._bundle;
+ },
+ getBundles : function() {
+ return this._framework.getBundles();
+ },
+ getProperty : function(name) {
+ return this._framework.getProperty(name);
+ },
+ installBundle : function(location, headers) {
+ return this._framework.installBundle(location, headers);
+ }
+};
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.languages.javascript.framework/scripts/BundleData.js b/bundles/org.eclipse.e4.languages.javascript.framework/scripts/BundleData.js
new file mode 100644
index 0000000..21f57ce
--- /dev/null
+++ b/bundles/org.eclipse.e4.languages.javascript.framework/scripts/BundleData.js
@@ -0,0 +1,17 @@
+function BundleData(bundleId, location, headers) {
+ this._bundleId = bundleId;
+ this._location = location;
+ this._headers = headers;
+}
+
+BundleData.prototype = {
+ getBundleId : function() {
+ return this._bundleId;
+ },
+ getLocation : function() {
+ return this._location;
+ },
+ getHeaders : function() {
+ return this._headers;
+ }
+};
diff --git a/bundles/org.eclipse.e4.languages.javascript.framework/scripts/Constants.js b/bundles/org.eclipse.e4.languages.javascript.framework/scripts/Constants.js
new file mode 100644
index 0000000..89f5f08
--- /dev/null
+++ b/bundles/org.eclipse.e4.languages.javascript.framework/scripts/Constants.js
@@ -0,0 +1,26 @@
+var Constants = {
+ ATTRIBUTE_EQUALS : "=",
+ DIRECTIVE_EQUALS : ":=",
+ PARAMETER_DELIMITER : ";",
+ MANDATORY_DELIMITER : ",",
+ SCRIPT_PATH_DELIMITER : ",",
+ CLAUSE_DELIMITER : ",",
+ BUNDLE_NAME : "name",
+ BUNDLE_VERSION : "version",
+ BUNDLE_IMPORTS : "imports",
+ BUNDLE_EXPORTS : "exports",
+ BUNDLE_REQUIRES : "requires",
+ BUNDLE_SCRIPT : "script",
+ BUNDLE_PATH : "path",
+ BUNDLE_ACTIVATOR : "activator",
+ BUNDLE_RESOURCES : "resources",
+ SCRIPT_PATH_DOT : ".",
+ BUNDLE_NAME_ATTRIBUTE : "bundle-name",
+ BUNDLE_VERSION_ATTRIBUTE : "bundle-version",
+ VERSION_ATTRIBUTE : "version",
+ RESOLUTION_DIRECTIVE : "resolution",
+ RESOLUTION_OPTIONAL : "optional",
+ RESOLUTION_MANDATORY : "mandatory",
+ MANDATORY_DIRECTIVE : "mandatory",
+ SINGLETON_DIRECTIVE : "singleton"
+};
\ No newline at end of file
diff --git a/bundles/org.eclipse.e4.languages.javascript.framework/scripts/Framework.js b/bundles/org.eclipse.e4.languages.javascript.framework/scripts/Framework.js
new file mode 100644
index 0000000..d56f4fc
--- /dev/null
+++ b/bundles/org.eclipse.e4.languages.javascript.framework/scripts/Framework.js
@@ -0,0 +1,280 @@
+function Framework() {
+ this._installOrderBundles = [];
+ this._resolveOrderBundles = [];
+ this._exports = {};
+ this._requiredBundles = {};
+ this._properties = {};
+ this._currentBundleId = 0;
+}
+
+Framework.prototype = {
+ getBundles : function() {
+ return this._installOrderBundles.slice();
+ },
+ getProperty : function(name) {
+ return this._properties[name];
+ },
+ setProperty : function(name, value) {
+ this._properties[name] = value;
+ },
+ installBundle : function(location, headers) {
+ if (location === undefined)
+ throw "location cannot be undefined";
+
+ if (location === null)
+ throw "location cannot be null";
+
+ var bundleData = new BundleData(this._currentBundleId, location, headers);
+ var bundle = new Bundle(this, bundleData);
+
+ for ( var i = 0; i < this._installOrderBundles.length; i++) {
+ if (bundle.equals(this._installOrderBundles[i]))
+ return this._installOrderBundles[i];
+ }
+ this._installOrderBundles[this._currentBundleId] = bundle;
+ this._currentBundleId++;
+
+ return bundle;
+ },
+ refresh : function() {
+ var uninstalledBundleFound = false;
+ var resolvedBundles = this._resolveOrderBundles.slice();
+ var i = 0;
+ var bundle = null;
+
+ var newInstallOrderBundles = [];
+ for (i = 0; i < this._installOrderBundles.length; i++) {
+ bundle = this._installOrderBundles[i];
+ if (bundle.getState() !== Bundle.UNINSTALLED) {
+ newInstallOrderBundles.push(bundle);
+ }
+ }
+ this._installOrderBundles = newInstallOrderBundles;
+
+ for (i = 0; i < resolvedBundles.length; i++) {
+ bundle = resolvedBundles[i];
+ if (bundle.getState() === Bundle.UNINSTALLED) {
+ uninstalledBundleFound = true;
+ }
+
+ if (uninstalledBundleFound) {
+ this._unresolveBundle(bundle);
+ }
+ }
+ if (uninstalledBundleFound) {
+ var newResolveOrderBundles = [];
+ for (i = 0; i < this._resolveOrderBundles.length; i++) {
+ bundle = this._resolveOrderBundles[i];
+ if (bundle.getState() === Bundle.RESOLVED || bundle.getState() === Bundle.ACTIVE) {
+ newResolveOrderBundles.push(bundle);
+ }
+ }
+ this._resolveOrderBundles = newResolveOrderBundles;
+
+ this.resolve();
+ }
+ },
+ resolve : function() {
+ var unresolvedBundles = [];
+ var i = 0;
+ for (i = 0; i < this._installOrderBundles.length; i++) {
+ var bundle = this._installOrderBundles[i];
+ if (bundle.getState() === Bundle.INSTALLED)
+ unresolvedBundles.push(bundle);
+ }
+
+ var resolvedBundles = [];
+ var resolvedBundle = null;
+ while (unresolvedBundles.length !== 0) {
+ resolvedBundle = this._stepResolver(unresolvedBundles);
+ if (resolvedBundle !== null)
+ resolvedBundles.push(resolvedBundle);
+ else
+ break;
+ }
+ for (i = 0; i < resolvedBundles; i++) {
+ resolvedBundle = resolvedBundles[i];
+ if (resolvedBundle.isMarkedStarted())
+ resolvedBundle.start();
+ }
+ },
+ shutdown : function() {
+ var reversed = this._installOrderBundles.slice().reverse();
+ for ( var i = 0; i < reversed.length; i++) {
+ var bundle = reversed[i];
+ bundle.stop();
+ bundle.uninstall();
+ }
+ this.refresh();
+ },
+ _getBundleContext : function(bundle) {
+ return new BundleContext(bundle, this);
+ },
+ _stepResolver : function(unresolvedBundles) {
+ for (var i = 0; i < unresolvedBundles.length; i++) {
+ var bundle = unresolvedBundles[i];
+ if (this._resolveBundle(bundle)) {
+ this._resolveOrderBundles.push(bundle);
+ unresolvedBundles.splice(i,1);
+ return bundle;
+ }
+ }
+ return null;
+ },
+ _resolveBundle: function(bundle) {
+ if (bundle._isSingleton() && this._requiredBundles[bundle.getName()])
+ return false;
+
+ if (this._wire(bundle)) {
+ bundle._resolve();
+ this._addExports(bundle);
+ this._addRequiredBundle(bundle);
+ return true;
+ }
+ this._unwire(bundle);
+ return false;
+ },
+ _wire : function(bundle) {
+ return this._wireRequires(bundle) && this._wireImports(bundle);
+ },
+ _wireRequires : function(bundle) {
+ var requires = bundle._getRequires();
+ for (var i = 0; i < requires.length; i++) {
+ var jsRequire = requires[i];
+ var name = jsRequire.getName();
+ var candidates = this._requiredBundles[name];
+ var satisfied = false;
+ if (candidates) {
+ for (var j = 0; j < candidates.length; j++) {
+ var candidate = candidates[j];
+ satisfied = jsRequire.wire(candidate);
+ if (satisfied)
+ break;
+ }
+ }
+ if (!satisfied && !jsRequire.isOptional())
+ return false;
+ }
+ return true;
+ },
+ _wireImports : function(bundle) {
+ var imports = bundle._getImports();
+ for (var i = 0; i < imports.length; i++) {
+ var jsImport = imports[i];
+ var name = jsImport.getName();
+ var candidates = this._exports[name];
+ var satisfied = false;
+ if (candidates) {
+ for (var j = 0; j < candidates.length; j++) {
+ var candidate = candidates[j];
+ satisfied = jsImport.wire(candidate);
+ if (satisfied)
+ break;
+ }
+ }
+ if (!satisfied && !jsImport.isOptional())
+ return false;
+ }
+ return true;
+ },
+ _addExports : function(bundle) {
+ var exports = bundle._getExports();
+ for (var i = 0; i < exports.length; i++) {
+ var jsExport = exports[i];
+ var name = jsExport.getName();
+ var namedExports = this._exports[name];
+ if (!namedExports) {
+ namedExports = [];
+ this._exports[name] = namedExports;
+ }
+ namedExports.push(jsExport);
+ namedExports.sort(Framework._exportsComparator);
+ }
+ },
+ _addRequiredBundle : function(bundle) {
+ var name = bundle.getName();
+ var namedBundles = this._requiredBundles[name];
+ if (! namedBundles) {
+ namedBundles = [];
+ this._requiredBundles[name]= namedBundles;
+ }
+ namedBundles.push(bundle);
+ namedBundles.sort(Framework._requireBundlesComparator);
+ },
+ _unresolveBundle : function(bundle) {
+ this._removeExports(bundle);
+ this._removeRequiredBunde(bundle);
+ bundle._unresolve();
+ this._unwire(bundle);
+ },
+ _removeExports : function(bundle) {
+ var exports = bundle._getExports();
+ for ( var i = 0; i < exports.length; i++) {
+ var jsExport = exports[i];
+ var name = jsExport.getName();
+ var namedExports = this._exports[name];
+ if (!namedExports)
+ continue;
+
+ for ( var j = 0; j < namedExports.length; j++) {
+ if (namedExports[j] === jsExport) {
+ namedExports.splice(j, 1);
+ break;
+ }
+ }
+ if (namedExports.length === 0)
+ delete this._exports[name];
+ }
+ },
+ _removeRequiredBunde : function(bundle) {
+ var name = bundle.getName();
+ var namedBundles = this._requiredBundles[name];
+ if (!namedBundles)
+ return;
+
+ for ( var i = 0; i < namedBundles.length; i++) {
+ if (namedBundles[i] === bundle) {
+ namedBundles.splice(i, 1);
+ break;
+ }
+ }
+ if (namedBundles.length === 0)
+ delete this._requiredBundles[name];
+ },
+ _unwire : function(bundle) {
+ this._unwireImports(bundle);
+ this._unwireRequires(bundle);
+ },
+ _unwireImports : function(bundle) {
+ var imports = bundle._getImports();
+ for ( var i = 0; i < imports.length; i++) {
+ var jsImport = imports[i];
+ jsImport.unwire();
+ }
+ },
+ _unwireRequires : function(bundle) {
+ var requires = bundle._getRequires();
+ for ( var i = 0; i < requires.length; i++) {
+ var jsRequires = requires[i];
+ jsRequires.unwire();
+ }
+ }
+};
+
+Framework._exportsComparator = function(export0, export1) {
+ // order switched for descending order
+ var result = export1.getVersion().compareTo(export0.getVersion());
+ if (result == 0)
+ result = export0.getBundleId() - export1.getBundleId();
+
+ return result;
+};
+
+Framework._requireBundlesComparator = function(bundle0, bundle1) {
+ // order switched for descending order
+ var result = bundle1.getVersion().compareTo(bundle0.getVersion());
+ if (result == 0)
+ result = bundle0.getBundleId() - bundle1.getBundleId();
+
+ return result;
+};
diff --git a/bundles/org.eclipse.e4.languages.javascript.framework/scripts/Version.js b/bundles/org.eclipse.e4.languages.javascript.framework/scripts/Version.js
new file mode 100644
index 0000000..9909e66
--- /dev/null
+++ b/bundles/org.eclipse.e4.languages.javascript.framework/scripts/Version.js
@@ -0,0 +1,114 @@
+function Version(major, minor, micro, qualifier) {
+ if (!Version._isInteger(major) || major < 0)
+ throw "invalid major:" + major;
+
+ if (!Version._isInteger(minor) || minor < 0)
+ throw "invalid minor:" + minor;
+
+ if (!Version._isInteger(micro) || micro < 0)
+ throw "invalid micro:" + micro;
+
+ if (qualifier === null || qualifier === undefined)
+ qualifier = "";
+ else if (typeof qualifier !== "string" || !qualifier.match(/[\w\-]*/))
+ throw "invalid qualifier: " + qualifier;
+
+ this._major = (major > Version.MAX_VALUE) ? Version.MAX_VALUE : major;
+ this._minor = (minor > Version.MAX_VALUE) ? Version.MAX_VALUE : minor;
+ this._micro = (micro > Version.MAX_VALUE) ? Version.MAX_VALUE : micro;
+
+ if (this._major == Version.MAX_VALUE && this._minor == Version.MAX_VALUE && this._micro == Version.MAX_VALUE)
+ this._qualifier = "";
+ else
+ this._qualifier = qualifier;
+};
+
+Version.prototype = {
+ getMajor : function() {
+ return this._major;
+ },
+ getMinor : function() {
+ return this._minor;
+ },
+ getMicro : function() {
+ return this._micro;
+ },
+ getQualifier : function() {
+ return this._qualifier;
+ },
+ toString : function() {
+ var result = "" + this._major + "." + this._minor + "." + this._micro;
+ if (this._qualifier.length > 0)
+ result += "." + this._qualifier;
+ return result;
+ },
+ equals : function(other) {
+ return other instanceof Version && this._major === other._major && this._minor === other._minor && this._micro === other._micro && this._qualifier === other._qualifier;
+ },
+ compareTo : function(other) {
+ if (this === other)
+ return 0;
+
+ var result = this._major - other._major;
+ if (result !== 0)
+ return result;
+
+ result = this._minor - other._minor;
+ if (result !== 0)
+ return result;
+
+ result = this._micro - other._micro;
+ if (result !== 0)
+ return result;
+
+ if (this._qualifier === other._qualifier)
+ return 0;
+
+ return this._qualifier > other._qualifier ? 1 : -1;
+ }
+};
+Version._isInteger = function(number) {
+ return (typeof number == "number" && !isNaN(number) && isFinite(number) && Math.floor(number) == number);
+};
+Version.MAX_VALUE = Math.pow(2, 32);
+Version.EMPTY_VERSION = new Version(0, 0, 0);
+Version.MAX_VERSION = new Version(Version.MAX_VALUE, Version.MAX_VALUE, Version.MAX_VALUE);
+Version.parseVersion = function(text) {
+ if (text === null || text === undefined)
+ return Version.EMPTY_VERSION;
+
+ if (typeof text !== "string")
+ throw "invalid text:" + text;
+
+ text = text.replace(/^\s+|\s+$/g, '');
+ if (text.length === 0 || text === "0.0.0")
+ return Version.EMPTY_VERSION;
+
+ var tokens = text.split(".");
+ if (tokens.length > 4)
+ throw "invalid format: " + text;
+
+ if (!tokens[0].match(/[\d]+/))
+ throw "invalid format: " + text;
+
+ var major = parseInt(tokens[0]);
+ var minor = 0;
+ var micro = 0;
+ var qualifier = "";
+
+ if (tokens.length > 1) {
+ if (!tokens[1].match(/[\d]+/))
+ throw "invalid format: " + text;
+ minor = parseInt(tokens[1]);
+
+ if (tokens.length > 2) {
+ if (!tokens[2].match(/[\d]+/))
+ throw "invalid format: " + text;
+ micro = parseInt(tokens[2]);
+
+ if (tokens.length > 3)
+ qualifier = tokens[3];
+ }
+ }
+ return new Version(major, minor, micro, qualifier);
+};
diff --git a/bundles/org.eclipse.e4.languages.javascript.framework/scripts/VersionRange.js b/bundles/org.eclipse.e4.languages.javascript.framework/scripts/VersionRange.js
new file mode 100644
index 0000000..b67c0d6
--- /dev/null
+++ b/bundles/org.eclipse.e4.languages.javascript.framework/scripts/VersionRange.js
@@ -0,0 +1,107 @@
+function VersionRange(minVersion, includeMin, maxVersion, includeMax) {
+ if (minVersion != null && !(minVersion instanceof Version))
+ throw "invalid minVersion:" + minVersion;
+
+ if (typeof includeMin !== "boolean")
+ throw "invalid includeMin:" + includeMin;
+
+ if (maxVersion != null && !(maxVersion instanceof Version))
+ throw "invalid maxVersion:" + minVersion;
+
+ if (typeof includeMax !== "boolean")
+ throw "invalid includeMax:" + includeMax;
+
+ this._minVersion = minVersion || Version.EMPTY_VERSION;
+ this._includeMin = includeMin;
+ this._maxVersion = maxVersion || Version.MAX_VERSION;
+ this._includeMax = includeMax;
+}
+
+VersionRange.prototype = {
+ getMinimum : function() {
+ return this._minVersion;
+ },
+ getIncludeMinimum : function() {
+ return this._includeMin;
+ },
+ getMaximum : function() {
+ return this._maxVersion;
+ },
+ getIncludeMaximum : function() {
+ return this._includeMax;
+ },
+ equals : function(other) {
+ if (this === other)
+ return true;
+
+ if (!other instanceof VersionRange)
+ return false;
+
+ if (this._includeMin !== other._includeMin || this._includeMax !== other._includeMax)
+ return false;
+
+ if (!this._minVersion.equals(other._minVersion))
+ return false;
+
+ if (!this._maxVersion.equals(other._maxVersion))
+ return false;
+
+ return true;
+ },
+ isIncluded : function(version) {
+ if (version == null)
+ version = Version.MIN_VERSION;
+
+ if (!version instanceof Version)
+ return false;
+
+ var minCheck = this._includeMin ? 0 : 1;
+ var maxCheck = this._includeMax ? 0 : -1;
+ return version.compareTo(this._minVersion) >= minCheck && version.compareTo(this._maxVersion) <= maxCheck;
+ },
+ toString : function() {
+ if (this._includeMin && this._includeMax && Version.MAX_VERSION.equals(this._maxVersion))
+ return this._minVersion.toString();
+
+ return (this._includeMin ? '[' : '(') + this._minVersion + ',' + this._maxVersion + (this._includeMax ? ']' : ')');
+ }
+};
+
+VersionRange.EMPTY_RANGE = new VersionRange(Version.EMPTY_VERSION, true, Version.MAX_VERSION, true);
+
+VersionRange.parseVersionRange = function(text) {
+ if (text === null)
+ return VersionRange.EMPTY_RANGE;
+
+ if (typeof text !== "string")
+ throw "invalid text:" + text;
+
+ text = text.replace(/^\s+|\s+$/g, '');
+ if (text.length === 0)
+ return VersionRange.EMPTY_RANGE;
+
+ var minVersion = null;
+ var includeMin = false;
+ var maxVersion = null;
+ var includeMax = false;
+
+ if (text.charAt(0) === '[' || text.charAt(0) == '(') {
+ var comma = text.indexOf(',');
+ if (comma === -1)
+ throw "invalid text:" + text;
+ var last = text.charAt(text.length - 1);
+ if (last !== ']' && last !== ')')
+ throw "invalid text:" + text;
+
+ minVersion = Version.parseVersion(text.substring(1, comma).replace(/^\s+|\s+$/g, ''));
+ includeMin = text.charAt(0) == '[';
+ maxVersion = Version.parseVersion(text.substring(comma + 1, text.length() - 1).replace(/^\s+|\s+$/g, ''));
+ includeMax = last == ']';
+ } else {
+ minVersion = Version.parseVersion(text);
+ includeMin = true;
+ maxVersion = Version.MAX_VERSION;
+ includeMax = true;
+ }
+ return new VersionRange(minVersion, includeMin, maxVersion, includeMax);
+};
diff --git a/bundles/org.eclipse.e4.languages.javascript.framework/scripts/_Export.js b/bundles/org.eclipse.e4.languages.javascript.framework/scripts/_Export.js
new file mode 100644
index 0000000..0cb404b
--- /dev/null
+++ b/bundles/org.eclipse.e4.languages.javascript.framework/scripts/_Export.js
@@ -0,0 +1,128 @@
+function _Export(header, exportingBundle) {
+ if (header === null)
+ throw "header cannot be null";
+
+ if (exportingBundle === null)
+ throw "exportingBundle cannot be null";
+
+ this._name = null;
+ this._version = Version.EMPTY_VERSION;
+ this._attributes = {};
+ this._directives = {};
+ this._mandatory = [];
+ this._exportingBundle = exportingBundle;
+
+ this._parseExport(header);
+}
+
+_Export.prototype = {
+ _parseExport : function(header) {
+ var tokens = header.split(Constants.PARAMETER_DELIMITER);
+ this._name = tokens[0].replace(/^\s+|\s+$/g, '');
+ for ( var i = 1; i < tokens.length; i++) {
+ var token = tokens[i];
+ if (token.indexOf(Constants.DIRECTIVE_EQUALS) !== -1)
+ this._parseDirective(token);
+ else if (token.indexOf(Constants.ATTRIBUTE_EQUALS) !== -1)
+ this._parseAttribute(token);
+ else
+ throw "bad export syntax: " + token + " in " + header;
+ }
+ },
+ _parseAttribute : function(token) {
+ var index = token.indexOf(Constants.ATTRIBUTE_EQUALS);
+ var attributeName = token.substring(0, index).replace(/^\s+|\s+$/g, '');
+ if (attributeName.length === 0)
+ return;
+
+ var value = token.substring(index + Constants.ATTRIBUTE_EQUALS.length).replace(/^\s+|\s+$/g, '');
+
+ if (attributeName === Constants.VERSION_ATTRIBUTE)
+ this._version = Version.parseVersion(value);
+
+ this._attributes[attributeName] = value;
+ },
+ _parseDirective : function(token) {
+ var index = token.indexOf(Constants.DIRECTIVE_EQUALS);
+ var directiveName = token.substring(0, index).replace(/^\s+|\s+$/g, '');
+ if (directiveName.length === 0)
+ return;
+
+ var value = token.substring(index + Constants.DIRECTIVE_EQUALS.length).replace(/^\s+|\s+$/g, '');
+ if (directiveName === Constants.MANDATORY_DIRECTIVE)
+ this._parseMandatory(value);
+
+ this._directives[directiveName] = value;
+ },
+ _parseMandatory : function(value) {
+ var tokens = value.split(Constants.MANDATORY_DELIMITER);
+ for ( var i = 0; i < tokens.length; i++) {
+ var token = tokens[i].replace(/^\s+|\s+$/g, '');
+ if (token.length > 0)
+ this._mandatory.push(token);
+ }
+ },
+ getName : function() {
+ return this._name;
+ },
+ getVersion : function() {
+ return this._version;
+ },
+ getBundleId : function() {
+ return this._exportingBundle.getBundleId();
+ },
+ getBundleSymbolicName : function() {
+ return this._exportingBundle.getSymbolicName();
+ },
+ getBundleVersion : function() {
+ return this._exportingBundle.getVersion();
+ },
+ getAttributes : function() {
+ this._attributes;
+ },
+ getDirectives : function() {
+ return this._directives;
+ },
+ getExportingBundle : function() {
+ return this._exportingBundle;
+ },
+ getMandatory : function() {
+ return this._mandatory;
+ },
+ addToScope : function (scope) {
+ var value = this._exportingBundle.load(this._name);
+ var tokens = this._name.split(".");
+ var Wrapper = function() {};
+ var i = 0;
+ while (true) {
+ var token = tokens[i++];
+ var current = null;
+ if (scope.hasOwnProperty(token)) {
+ current = scope[token];
+ }
+ if (i === tokens.length) {
+ if (current === null || current === undefined) {
+ if (typeof value === "object") {
+ Wrapper.prototype = value;
+ value = new Wrapper();
+ }
+ scope[token]= value;
+ return;
+ }
+ throw "Resolve error: " + this._name + " already exists for " + this.toString();
+ }
+ if (current === null || current === undefined) {
+ current = scope[token];
+ if (current === null || current === undefined) {
+ current = {};
+ } else if (typeof current === "object") {
+ Wrapper.prototype = current;
+ current = new Wrapper();
+ } else
+ throw "Resolve error: " + this._name + "-" + token + " already exists for " + this.toString(); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
+ scope[token] = current;
+ }
+ scope = current;
+ }
+ }
+};
diff --git a/bundles/org.eclipse.e4.languages.javascript.framework/scripts/_Import.js b/bundles/org.eclipse.e4.languages.javascript.framework/scripts/_Import.js
new file mode 100644
index 0000000..78dbc25
--- /dev/null
+++ b/bundles/org.eclipse.e4.languages.javascript.framework/scripts/_Import.js
@@ -0,0 +1,128 @@
+function _Import(header) {
+ if (header === null)
+ throw "header cannot be null";
+
+ this._name = null;
+ this._versionRange = VersionRange.EMPTY_RANGE;
+ this._bundleSymbolicName = null;
+ this._bundleVersionRange = VersionRange.EMPTY_RANGE;
+ this._optional = false;
+ this._attributes = {};
+ this._directives = {};
+ this._wiredExport = null;
+
+ this._parseImport(header);
+}
+
+_Import.prototype = {
+ _parseImport : function(header) {
+ var tokens = header.split(Constants.PARAMETER_DELIMITER);
+ this._name = tokens[0].replace(/^\s+|\s+$/g, '');
+ for ( var i = 1; i < tokens.length; i++) {
+ var token = tokens[i];
+ if (token.indexOf(Constants.DIRECTIVE_EQUALS) !== -1)
+ this._parseDirective(token);
+ else if (token.indexOf(Constants.ATTRIBUTE_EQUALS) !== -1)
+ this._parseAttribute(token);
+ else
+ throw "bad import syntax: " + token + " in " + header;
+ }
+ },
+ _parseAttribute : function(token) {
+ var index = token.indexOf(Constants.ATTRIBUTE_EQUALS);
+ var attributeName = token.substring(0, index).replace(/^\s+|\s+$/g, '');
+ if (attributeName.length === 0)
+ return;
+
+ var value = token.substring(index + Constants.ATTRIBUTE_EQUALS.length).replace(/^\s+|\s+$/g, '');
+
+ if (attributeName === Constants.VERSION_ATTRIBUTE)
+ this._versionRange = VersionRange.parseVersionRange(value);
+ else if (attributeName === Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE)
+ this._bundleSymbolicName = value;
+ else if (attributeName === Constants.BUNDLE_VERSION_ATTRIBUTE)
+ this._bundleVersionRange = VersionRange.parseVersionRange(value);
+ this._attributes[attributeName] = value;
+ },
+ _parseDirective : function(token) {
+ var index = token.indexOf(Constants.DIRECTIVE_EQUALS);
+ var directiveName = token.substring(0, index).replace(/^\s+|\s+$/g, '');
+ if (directiveName.length === 0)
+ return;
+
+ var value = token.substring(index + Constants.DIRECTIVE_EQUALS.length).replace(/^\s+|\s+$/g, '');
+ if (directiveName === Constants.RESOLUTION_DIRECTIVE && value === Constants.RESOLUTION_OPTIONAL)
+ this._optional = true;
+ this._directives[directiveName] = value;
+ },
+ getName : function() {
+ return this._name;
+ },
+ getVersionRange : function() {
+ return this._versionRange;
+ },
+ getBundleSymbolicName : function() {
+ return this._bundleSymbolicName;
+ },
+ getBundleVersionRange : function() {
+ return this._bundleVersionRange;
+ },
+ isOptional : function() {
+ return this._optional;
+ },
+ getAttributes : function() {
+ this._attributes;
+ },
+ getDirectives : function() {
+ return this._directives;
+ },
+ wire : function(candidate) {
+ if (this._name !== candidate.getName())
+ return false;
+
+ if (!this._checkAttributes(candidate))
+ return false;
+
+ if (!this._checkMandatory(candidate))
+ return false;
+
+ this._wiredExport = candidate;
+ return true;
+ },
+ _checkAttributes : function(candidate) {
+ for ( var key in this._attributes) {
+ if (key === Constants.VERSION_ATTRIBUTE) {
+ if (!this._versionRange.isIncluded(candidate.getVersion()))
+ return false;
+ } else if (key === Constants.BUNDLE_SYMBOLICNAME_ATTRIBUTE) {
+ if (!this._bundleSymbolicName === candidate.getBundleSymbolicName())
+ return false;
+ } else if (key === Constants.BUNDLE_VERSION_ATTRIBUTE) {
+ if (!this._bundleVersionRange.isIncluded(candidate.getBundleVersion()))
+ return false;
+ } else {
+ var value = this._attributes[key];
+ var attributeValue = candidate.getAttributes()[key];
+ if (attributeValue !== value)
+ return false;
+ }
+ }
+ return true;
+ },
+ _checkMandatory : function(candidate) {
+ for ( var i = 0; i < candidate.getMandatory().length; i++) {
+ var key = candidate.getMandatory()[i];
+ var mandatoryValue = candidate.getAttributes()[key];
+ var value = this._attributes[key];
+ if (value !== mandatoryValue)
+ return false;
+ }
+ return true;
+ },
+ getWiredExport : function() {
+ return this._wiredExport;
+ },
+ unwire : function() {
+ this._wiredExport = null;
+ }
+};
diff --git a/bundles/org.eclipse.e4.languages.javascript.framework/scripts/_Require.js b/bundles/org.eclipse.e4.languages.javascript.framework/scripts/_Require.js
new file mode 100644
index 0000000..3663ee3
--- /dev/null
+++ b/bundles/org.eclipse.e4.languages.javascript.framework/scripts/_Require.js
@@ -0,0 +1,93 @@
+function _Require(header) {
+ if (header === null)
+ throw "header cannot be null";
+
+ this._name = null;
+ this._attributes = {};
+ this._directives = {};
+ this._optional = false;
+ this._bundleVersionRange = VersionRange.emptyRange;
+ this._wiredBundle = null;
+
+ this._parseRequire(header);
+}
+
+_Require.prototype = {
+ _parseRequire : function(header) {
+ var tokens = header.split(Constants.PARAMETER_DELIMITER);
+ this._name = tokens[0].replace(/^\s+|\s+$/g, '');
+ for ( var i = 1; i < tokens.length; i++) {
+ var token = tokens[i];
+ if (token.indexOf(Constants.DIRECTIVE_EQUALS) !== -1)
+ this._parseDirective(token);
+ else if (token.indexOf(Constants.ATTRIBUTE_EQUALS) !== -1)
+ this._parseAttribute(token);
+ else
+ throw "bad import syntax: " + token + " in " + header;
+ }
+ },
+ _parseAttribute : function(token) {
+ var index = token.indexOf(Constants.ATTRIBUTE_EQUALS);
+ var attributeName = token.substring(0, index).replace(/^\s+|\s+$/g, '');
+ if (attributeName.length === 0)
+ return;
+
+ var value = token.substring(index + Constants.ATTRIBUTE_EQUALS.length).replace(/^\s+|\s+$/g, '');
+
+ if (attributeName === Constants.BUNDLE_VERSION_ATTRIBUTE)
+ this._bundleVersionRange = VersionRange.parseVersionRange(value);
+
+ this._attributes[attributeName] = value;
+ },
+ _parseDirective : function(token) {
+ var index = token.indexOf(Constants.DIRECTIVE_EQUALS);
+ var directiveName = token.substring(0, index).replace(/^\s+|\s+$/g, '');
+ if (directiveName.length === 0)
+ return;
+
+ var value = token.substring(index + Constants.DIRECTIVE_EQUALS.length).replace(/^\s+|\s+$/g, '');
+ if (directiveName === Constants.RESOLUTION_DIRECTIVE && value === Constants.RESOLUTION_OPTIONAL)
+ this._optional = true;
+ this._directives[directiveName] = value;
+ },
+ getName : function() {
+ return this._name;
+ },
+ getBundleVersionRange : function() {
+ return this._bundleVersionRange;
+ },
+ isOptional : function() {
+ return this._optional;
+ },
+ getAttributes : function() {
+ this._attributes;
+ },
+ getDirectives : function() {
+ return this._directives;
+ },
+ wire : function(candidate) {
+ if (this._name !== candidate.getName())
+ return false;
+
+ if (!this._checkAttributes(candidate))
+ return false;
+
+ this._wiredBundle = candidate;
+ return true;
+ },
+ _checkAttributes : function(candidate) {
+ for ( var key in this._attributes) {
+ if (key === Constants.BUNDLE_VERSION_ATTRIBUTE) {
+ if (!this._bundleVersionRange.isIncluded(candidate.getVersion()))
+ return false;
+ }
+ }
+ return true;
+ },
+ getWiredBundle : function() {
+ return this._wiredBundle;
+ },
+ unwire : function() {
+ this._wiredBundle = null;
+ }
+};