Adding script source properties to allow better source lookup
diff --git a/bundles/org.eclipse.e4.languages.javascript.debug.jsdi.rhino/src/org/eclipse/e4/languages/javascript/jsdi/rhino/ScriptReferenceImpl.java b/bundles/org.eclipse.e4.languages.javascript.debug.jsdi.rhino/src/org/eclipse/e4/languages/javascript/jsdi/rhino/ScriptReferenceImpl.java
index eca9cd6..216f4a5 100644
--- a/bundles/org.eclipse.e4.languages.javascript.debug.jsdi.rhino/src/org/eclipse/e4/languages/javascript/jsdi/rhino/ScriptReferenceImpl.java
+++ b/bundles/org.eclipse.e4.languages.javascript.debug.jsdi.rhino/src/org/eclipse/e4/languages/javascript/jsdi/rhino/ScriptReferenceImpl.java
@@ -23,6 +23,7 @@
 	private final Boolean generated;
 	private final List lineLocations = new ArrayList();
 	private final List functionLocations = new ArrayList();
+	private final Map sourceProperties;
 
 	/**
 	 * Constructor
@@ -32,16 +33,15 @@
 	 */
 	public ScriptReferenceImpl(VirtualMachineImpl vm, Map jsonScript) {
 		super(vm);
-		this.scriptId = new Long(((Number) jsonScript
-				.get(JSONConstants.SCRIPT_ID)).longValue());
+		this.scriptId = new Long(((Number) jsonScript.get(JSONConstants.SCRIPT_ID)).longValue());
 		this.sourcePath = (String) jsonScript.get(JSONConstants.LOCATION);
+		this.sourceProperties = (Map) jsonScript.get(JSONConstants.PROPERTIES);
 		this.source = (String) jsonScript.get(JSONConstants.SOURCE);
 		this.generated = (Boolean) jsonScript.get(JSONConstants.GENERATED);
 		List lines = (List) jsonScript.get(JSONConstants.LINES);
 		for (Iterator iterator = lines.iterator(); iterator.hasNext();) {
 			Number lineNumber = (Number) iterator.next();
-			Location location = new LocationImpl(vm, null, lineNumber
-					.intValue(), this);
+			Location location = new LocationImpl(vm, null, lineNumber.intValue(), this);
 			lineLocations.add(location);
 		}
 		List functions = (List) jsonScript.get(JSONConstants.FUNCTIONS);
@@ -55,9 +55,7 @@
 	/*
 	 * (non-Javadoc)
 	 * 
-	 * @see
-	 * org.eclipse.e4.languages.javascript.jsdi.ScriptReference#allFunctionLocations
-	 * ()
+	 * @see org.eclipse.e4.languages.javascript.jsdi.ScriptReference#allFunctionLocations ()
 	 */
 	public List allFunctionLocations() {
 		return Collections.unmodifiableList(functionLocations);
@@ -66,9 +64,7 @@
 	/*
 	 * (non-Javadoc)
 	 * 
-	 * @see
-	 * org.eclipse.e4.languages.javascript.jsdi.ScriptReference#allLineLocations
-	 * ()
+	 * @see org.eclipse.e4.languages.javascript.jsdi.ScriptReference#allLineLocations ()
 	 */
 	public List allLineLocations() {
 		return Collections.unmodifiableList(lineLocations);
@@ -77,13 +73,10 @@
 	/*
 	 * (non-Javadoc)
 	 * 
-	 * @see
-	 * org.eclipse.e4.languages.javascript.jsdi.ScriptReference#functionLocation
-	 * (java.lang.String)
+	 * @see org.eclipse.e4.languages.javascript.jsdi.ScriptReference#functionLocation (java.lang.String)
 	 */
 	public Location functionLocation(String functionName) {
-		for (Iterator iterator = functionLocations.iterator(); iterator
-				.hasNext();) {
+		for (Iterator iterator = functionLocations.iterator(); iterator.hasNext();) {
 			Location location = (Location) iterator.next();
 			if (location.functionName().equals(functionName))
 				return location;
@@ -94,9 +87,7 @@
 	/*
 	 * (non-Javadoc)
 	 * 
-	 * @see
-	 * org.eclipse.e4.languages.javascript.jsdi.ScriptReference#lineLocation
-	 * (int)
+	 * @see org.eclipse.e4.languages.javascript.jsdi.ScriptReference#lineLocation (int)
 	 */
 	public Location lineLocation(int lineNumber) {
 		for (Iterator iterator = lineLocations.iterator(); iterator.hasNext();) {
@@ -119,8 +110,7 @@
 	/*
 	 * (non-Javadoc)
 	 * 
-	 * @see
-	 * org.eclipse.e4.languages.javascript.jsdi.ScriptReference#sourcePath()
+	 * @see org.eclipse.e4.languages.javascript.jsdi.ScriptReference#sourcePath()
 	 */
 	public String sourcePath() {
 		return sourcePath;
@@ -140,4 +130,11 @@
 		return generated;
 	}
 
+	public Map sourceProperties() {
+		if (sourceProperties == null)
+			return Collections.EMPTY_MAP;
+
+		return sourceProperties;
+	}
+
 }
diff --git a/bundles/org.eclipse.e4.languages.javascript.debug.jsdi/src/org/eclipse/e4/languages/javascript/jsdi/ScriptReference.java b/bundles/org.eclipse.e4.languages.javascript.debug.jsdi/src/org/eclipse/e4/languages/javascript/jsdi/ScriptReference.java
index 2b07b4a..2cd77c1 100644
--- a/bundles/org.eclipse.e4.languages.javascript.debug.jsdi/src/org/eclipse/e4/languages/javascript/jsdi/ScriptReference.java
+++ b/bundles/org.eclipse.e4.languages.javascript.debug.jsdi/src/org/eclipse/e4/languages/javascript/jsdi/ScriptReference.java
@@ -1,6 +1,7 @@
 package org.eclipse.e4.languages.javascript.jsdi;
 
 import java.util.List;
+import java.util.Map;
 
 public interface ScriptReference extends Mirror {
 
@@ -15,4 +16,6 @@
 	public String source();
 
 	public String sourcePath();
+
+	public Map sourceProperties();
 }
diff --git a/bundles/org.eclipse.e4.languages.javascript.debug.rhino/src/org/eclipse/e4/languages/javascript/debug/rhino/ScriptImpl.java b/bundles/org.eclipse.e4.languages.javascript.debug.rhino/src/org/eclipse/e4/languages/javascript/debug/rhino/ScriptImpl.java
index 50a146f..1bfb9fe 100644
--- a/bundles/org.eclipse.e4.languages.javascript.debug.rhino/src/org/eclipse/e4/languages/javascript/debug/rhino/ScriptImpl.java
+++ b/bundles/org.eclipse.e4.languages.javascript.debug.rhino/src/org/eclipse/e4/languages/javascript/debug/rhino/ScriptImpl.java
@@ -17,6 +17,7 @@
 import java.util.TreeSet;
 
 import org.eclipse.e4.languages.javascript.debug.connect.JSONConstants;
+import org.eclipse.e4.languages.javascript.debug.connect.JSONUtil;
 import org.mozilla.javascript.debug.DebuggableScript;
 
 /**
@@ -26,6 +27,8 @@
  */
 public class ScriptImpl {
 
+	private static final String TOP_NAME = ""; //$NON-NLS-1$
+
 	/**
 	 * struct for a script handle
 	 */
@@ -36,6 +39,7 @@
 
 	private final Long scriptId;
 	private final String location;
+	private final Map sourceProperties;
 	private final String source;
 	private final Boolean generated;
 	private final Collection functionNames = new HashSet();
@@ -53,7 +57,11 @@
 	 */
 	public ScriptImpl(Long scriptId, DebuggableScript debuggableScript, String source) {
 		this.scriptId = scriptId;
-		this.location = debuggableScript.getSourceName();
+
+		String sourceName = debuggableScript.getSourceName();
+		this.sourceProperties = parseSourceProperties(sourceName);
+		this.location = (sourceProperties == null) ? sourceName : (String) sourceProperties.get(JSONConstants.NAME);
+
 		this.generated = Boolean.valueOf(debuggableScript.isGeneratedScript());
 		this.source = source;
 
@@ -63,7 +71,21 @@
 		}
 		scriptRecords.put(debuggableScript, new ScriptRecord());
 
-		expandFunctions("", debuggableScript);
+		expandFunctions(TOP_NAME, debuggableScript);
+	}
+
+	private static Map parseSourceProperties(String sourceName) {
+		if (sourceName != null) {
+			try {
+				Object json = JSONUtil.read(sourceName);
+				if (json instanceof Map) {
+					return (Map) json;
+				}
+			} catch (RuntimeException e) {
+				// ignore
+			}
+		}
+		return null;
 	}
 
 	/**
@@ -81,7 +103,7 @@
 			scriptRecords.put(functionScript, record);
 
 			String functionName = functionScript.getFunctionName();
-			if ((functionName == null) || functionName.equals("")) {
+			if ((functionName == null) || functionName.equals(TOP_NAME)) {
 				functionName = "%" + i; //$NON-NLS-1$
 			}
 			record.name = prefix + functionName;
diff --git a/bundles/org.eclipse.e4.languages.javascript/src/org/eclipse/e4/internal/languages/javascript/JSBundleImpl.java b/bundles/org.eclipse.e4.languages.javascript/src/org/eclipse/e4/internal/languages/javascript/JSBundleImpl.java
index e71c1fe..a9d40a9 100644
--- a/bundles/org.eclipse.e4.languages.javascript/src/org/eclipse/e4/internal/languages/javascript/JSBundleImpl.java
+++ b/bundles/org.eclipse.e4.languages.javascript/src/org/eclipse/e4/internal/languages/javascript/JSBundleImpl.java
@@ -24,11 +24,13 @@
 
 import org.eclipse.e4.languages.javascript.JSBundle;
 import org.eclipse.e4.languages.javascript.JSConstants;
+import org.eclipse.e4.languages.javascript.JSONUtil;
 import org.mozilla.javascript.Callable;
 import org.mozilla.javascript.Context;
 import org.mozilla.javascript.ContextAction;
 import org.mozilla.javascript.Function;
 import org.mozilla.javascript.Scriptable;
+import org.osgi.framework.Bundle;
 import org.osgi.framework.Constants;
 import org.osgi.framework.Version;
 
@@ -286,7 +288,7 @@
 			if (token.equals(JSConstants.SCRIPT_PATH_DOT)) {
 				String script = (String) bundleData.getHeaders().get(JSConstants.BUNDLE_SCRIPT);
 				if (script != null)
-					context.evaluateString(scriptScope, script, "script.js", 0, null); //$NON-NLS-1$
+					context.evaluateString(scriptScope, script, "dot.js", 0, null); //$NON-NLS-1$
 				continue;
 			}
 
@@ -294,7 +296,22 @@
 			try {
 				URL scriptURL = bundleData.getEntry(token);
 				reader = new InputStreamReader(scriptURL.openStream());
-				context.evaluateReader(scriptScope, reader, token, 0, null);
+				
+				Map scriptProperties = new HashMap();
+				scriptProperties.put("name", token);
+				scriptProperties.put("base", bundleData.getLocation());
+				scriptProperties.put(Constants.BUNDLE_SYMBOLICNAME, symbolicName);
+				scriptProperties.put(Constants.BUNDLE_VERSION, version.toString());
+				if (bundleData.getContextClassLoader() instanceof RhinoClassLoader) {
+					RhinoClassLoader rhinoClassLoader = (RhinoClassLoader) bundleData.getContextClassLoader();
+					Bundle bundle = rhinoClassLoader.getBundle();
+					if (bundle != null) {
+						scriptProperties.put("OSGi." + Constants.BUNDLE_SYMBOLICNAME, bundle.getSymbolicName());
+						scriptProperties.put("OSGi." + Constants.BUNDLE_VERSION, bundle.getVersion().toString());
+					}
+				}
+			
+				context.evaluateReader(scriptScope, reader, JSONUtil.write(scriptProperties), 0, null);
 			} catch (IOException e) {
 				throw new IllegalStateException("Error reading script for " + this.toString() + ": " + e.getMessage()); //$NON-NLS-1$ //$NON-NLS-2$
 			} finally {
diff --git a/bundles/org.eclipse.e4.languages.javascript/src/org/eclipse/e4/internal/languages/javascript/RhinoClassLoader.java b/bundles/org.eclipse.e4.languages.javascript/src/org/eclipse/e4/internal/languages/javascript/RhinoClassLoader.java
index 0453e33..bcb47dc 100644
--- a/bundles/org.eclipse.e4.languages.javascript/src/org/eclipse/e4/internal/languages/javascript/RhinoClassLoader.java
+++ b/bundles/org.eclipse.e4.languages.javascript/src/org/eclipse/e4/internal/languages/javascript/RhinoClassLoader.java
@@ -50,12 +50,19 @@
 			throw new ClassNotFoundException(name);
 		}
 	};
+	private final Bundle bundle;
 
 	public RhinoClassLoader() {
 		super(RHINOBUNDLE, new RhinoContextFinder(EMPTY_CLASSLOADER));
+		this.bundle = null;
 	}
 
 	public RhinoClassLoader(Bundle bundle) {
 		super(bundle, new BundleProxyClassLoader(RHINOBUNDLE, new RhinoContextFinder(EMPTY_CLASSLOADER)));
+		this.bundle = bundle;
+	}
+
+	public Bundle getBundle() {
+		return bundle;
 	}
 }