Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorangelozerr2016-08-19 17:48:57 +0000
committerVictor Rubezhny2017-05-09 13:54:46 +0000
commit5eef1eefcb72b1d0932d9c6cce93b2a25cbe39ea (patch)
tree7569ac127459b4a368f53ee408f6d1d4c3f07dac
parent2aea99e039882efc4512f16aa7001356cb9c0564 (diff)
downloadwebtools.jsdt-5eef1eefcb72b1d0932d9c6cce93b2a25cbe39ea.tar.gz
webtools.jsdt-5eef1eefcb72b1d0932d9c6cce93b2a25cbe39ea.tar.xz
webtools.jsdt-5eef1eefcb72b1d0932d9c6cce93b2a25cbe39ea.zip
Bug 487465 - TypeScript debugging
Change-Id: I45d2ea3276439125ac3118cb204f3c4cab14223b Signed-off-by: angelozerr <angelo.zerr@gmail.com> Signed-off-by: Victor Rubezhny <vrubezhny@redhat.com>
-rwxr-xr-xbundles/org.eclipse.wst.jsdt.chromium.debug.core/META-INF/MANIFEST.MF7
-rwxr-xr-xbundles/org.eclipse.wst.jsdt.chromium.debug.core/build.properties3
-rwxr-xr-xbundles/org.eclipse.wst.jsdt.chromium.debug.core/plugin.properties4
-rwxr-xr-xbundles/org.eclipse.wst.jsdt.chromium.debug.core/plugin.xml4
-rw-r--r--bundles/org.eclipse.wst.jsdt.chromium.debug.core/pom.xml2
-rw-r--r--bundles/org.eclipse.wst.jsdt.chromium.debug.core/schema/sourceMapLanguageSupports.exsd106
-rwxr-xr-xbundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/ChromiumDebugPlugin.java24
-rw-r--r--bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMap.java234
-rw-r--r--bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMapDecoder.java108
-rw-r--r--bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMapInfo.java64
-rw-r--r--bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMapInfoEntry.java79
-rw-r--r--bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMapLanguageSupportType.java53
-rw-r--r--bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMapManager.java155
-rw-r--r--bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/VlqDecoder.java156
-rw-r--r--bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/model/VProjectWorkspaceBridge.java176
-rw-r--r--bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/sourcemap/extension/ISourceMapLanguageSupport.java84
-rw-r--r--bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/sourcemap/extension/ISourceMapManager.java55
-rw-r--r--nodejs/org.eclipse.wst.jsdt.js.node/META-INF/MANIFEST.MF2
-rw-r--r--nodejs/org.eclipse.wst.jsdt.js.node/pom.xml2
-rw-r--r--nodejs/org.eclipse.wst.jsdt.js.node/src/org/eclipse/wst/jsdt/js/node/internal/launch/NodeLaunchConfigurationDelegate.java13
-rw-r--r--nodejs/org.eclipse.wst.jsdt.js.node/src/org/eclipse/wst/jsdt/js/node/internal/propertytesters/NodePropertyTester.java6
21 files changed, 1298 insertions, 39 deletions
diff --git a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/META-INF/MANIFEST.MF b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/META-INF/MANIFEST.MF
index b375bd268..e2f8e711e 100755
--- a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.wst.jsdt.chromium.debug.core;singleton:=true
-Bundle-Version: 0.5.200.qualifier
+Bundle-Version: 0.5.300.qualifier
Bundle-Activator: org.eclipse.wst.jsdt.chromium.debug.core.ChromiumDebugPlugin
Bundle-Vendor: %providerName
Bundle-Localization: plugin
@@ -14,13 +14,16 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.ui.workbench.texteditor;bundle-version="3.4.1",
org.eclipse.wst.jsdt.chromium;bundle-version="[0.4.0,0.6.0)",
org.eclipse.core.expressions;bundle-version="3.4.0",
- org.eclipse.wst.jsdt.debug.core;bundle-version="[3.1.200,4.0.0)"
+ org.eclipse.wst.jsdt.debug.core;bundle-version="[3.1.200,4.0.0)",
+ com.google.gson;bundle-version="2.2.4",
+ org.eclipse.core.filebuffers
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: bin/,
.
Export-Package: org.eclipse.wst.jsdt.chromium.debug.core,
org.eclipse.wst.jsdt.chromium.debug.core.model,
org.eclipse.wst.jsdt.chromium.debug.core.sourcemap,
+ org.eclipse.wst.jsdt.chromium.debug.core.sourcemap.extension,
org.eclipse.wst.jsdt.chromium.debug.core.util
Eclipse-LazyStart: true
Bundle-RequiredExecutionEnvironment: JavaSE-1.6
diff --git a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/build.properties b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/build.properties
index 2acc17d4a..774ec88c8 100755
--- a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/build.properties
+++ b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/build.properties
@@ -2,6 +2,7 @@ bin.includes = META-INF/,\
plugin.xml,\
.,\
plugin.properties,\
- about.html
+ about.html,\
+ schema/
source.. = src/
output.. = bin/
diff --git a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/plugin.properties b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/plugin.properties
index c4005e49a..0ff8c0320 100755
--- a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/plugin.properties
+++ b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/plugin.properties
@@ -9,4 +9,6 @@ providerName = Eclipse Web Tools Platform
pluginName = Chromium JavaScript Remote Debugger Core
SourceNameMapperContainer.name = JavaScript Source Name Mapper
-SourceNameMapperContainer.description = Transforms name of source and delegates lookup to another source container. \ No newline at end of file
+SourceNameMapperContainer.description = Transforms name of source and delegates lookup to another source container.
+
+sourceMapLanguageSupports.name=SourceMap Language Supports \ No newline at end of file
diff --git a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/plugin.xml b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/plugin.xml
index 87d83764e..4158e82b1 100755
--- a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/plugin.xml
+++ b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/plugin.xml
@@ -10,6 +10,10 @@
<plugin>
+ <extension-point id="sourceMapLanguageSupports"
+ name="%sourceMapLanguageSupports.name"
+ schema="schema/sourceMapLanguageSupports.exsd" />
+
<!-- Breakpoint-related extensions -->
<extension point="org.eclipse.debug.core.breakpoints">
<breakpoint
diff --git a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/pom.xml b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/pom.xml
index b273cea36..a6a8b32e3 100644
--- a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/pom.xml
+++ b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/pom.xml
@@ -10,6 +10,6 @@
</parent>
<groupId>org.eclipse.webtools.jsdt.bundles</groupId>
<artifactId>org.eclipse.wst.jsdt.chromium.debug.core</artifactId>
- <version>0.5.200-SNAPSHOT</version>
+ <version>0.5.300-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/schema/sourceMapLanguageSupports.exsd b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/schema/sourceMapLanguageSupports.exsd
new file mode 100644
index 000000000..b8c90b0bd
--- /dev/null
+++ b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/schema/sourceMapLanguageSupports.exsd
@@ -0,0 +1,106 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.wst.jsdt.chromium.debug.core" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.wst.jsdt.chromium.debug.core" id="sourceMapLanguageSupports" name="sourceMapLanguageSupports"/>
+ </appinfo>
+ <documentation>
+ TODO
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="support" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully-qualified name of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional id
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="support">
+ <complexType>
+ <sequence>
+ </sequence>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.wst.jsdt.chromium.debug.core.sourcemap.extension.ISourceMapLanguageSupport"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ <attribute name="fileExtensions" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 2.0
+ </documentation>
+ </annotation>
+
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="implementation"/>
+ </appinfo>
+ <documentation>
+ This plugin itself does not have any predefined builders.
+ </documentation>
+ </annotation>
+
+
+</schema>
diff --git a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/ChromiumDebugPlugin.java b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/ChromiumDebugPlugin.java
index 63a0e0937..69419b1b2 100755
--- a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/ChromiumDebugPlugin.java
+++ b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/ChromiumDebugPlugin.java
@@ -1,4 +1,4 @@
-// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009, 2017 The Chromium Authors. All rights reserved.
// This program and the accompanying materials are made available
// under the terms of the Eclipse Public License v1.0 which accompanies
// this distribution, and is available at
@@ -14,13 +14,6 @@ import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
-import org.eclipse.wst.jsdt.chromium.debug.core.model.ChromiumBreakpointWBAFactory;
-import org.eclipse.wst.jsdt.chromium.debug.core.model.ChromiumLineBreakpoint;
-import org.eclipse.wst.jsdt.chromium.debug.core.model.ConnectedTargetData;
-import org.eclipse.wst.jsdt.chromium.debug.core.model.DebugTargetImpl;
-import org.eclipse.wst.jsdt.chromium.debug.core.model.VmResource;
-import org.eclipse.wst.jsdt.chromium.debug.core.util.ScriptTargetMapping;
-import org.eclipse.wst.jsdt.chromium.JavascriptVmFactory;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdapterManager;
@@ -28,6 +21,15 @@ import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
+import org.eclipse.wst.jsdt.chromium.JavascriptVmFactory;
+import org.eclipse.wst.jsdt.chromium.debug.core.internal.sourcemap.SourceMapManager;
+import org.eclipse.wst.jsdt.chromium.debug.core.model.ChromiumBreakpointWBAFactory;
+import org.eclipse.wst.jsdt.chromium.debug.core.model.ChromiumLineBreakpoint;
+import org.eclipse.wst.jsdt.chromium.debug.core.model.ConnectedTargetData;
+import org.eclipse.wst.jsdt.chromium.debug.core.model.DebugTargetImpl;
+import org.eclipse.wst.jsdt.chromium.debug.core.model.VmResource;
+import org.eclipse.wst.jsdt.chromium.debug.core.sourcemap.extension.ISourceMapManager;
+import org.eclipse.wst.jsdt.chromium.debug.core.util.ScriptTargetMapping;
import org.osgi.framework.BundleContext;
/**
@@ -60,12 +62,14 @@ public class ChromiumDebugPlugin extends Plugin {
manager.registerAdapters(breakpointWorkbenchAdapterFactory, ChromiumLineBreakpoint.class);
plugin = this;
+ SourceMapManager.getInstance().initialize();
JavascriptVmFactory.getRootLogger().addHandler(SDK_LOG_HANDLER);
}
@Override
public void stop(BundleContext context) throws Exception {
JavascriptVmFactory.getRootLogger().removeHandler(SDK_LOG_HANDLER);
+ SourceMapManager.getInstance().destroy();
plugin = null;
IAdapterManager manager = Platform.getAdapterManager();
manager.unregisterAdapters(breakpointWorkbenchAdapterFactory);
@@ -174,4 +178,8 @@ public class ChromiumDebugPlugin extends Plugin {
public void close() throws SecurityException {
}
};
+
+ public static ISourceMapManager getSourceMapManager() {
+ return SourceMapManager.getInstance();
+ }
}
diff --git a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMap.java b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMap.java
new file mode 100644
index 000000000..0af726680
--- /dev/null
+++ b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMap.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2013, 2017 the Dart project authors.
+ *
+ * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * Contributors:
+ * Dart project authors
+ * Angelo Zerr <angelo.zerr@gmail.com> - adapt original class https://github.com/sdbg/sdbg/blob/master/com.github.sdbg.debug.core/src/com/github/sdbg/debug/core/internal/sourcemaps/SourceMap.java to use Gson/
+ */
+package org.eclipse.wst.jsdt.chromium.debug.core.internal.sourcemap;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.wst.jsdt.chromium.debug.core.sourcemap.TextSectionMapping;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonSyntaxException;
+
+////@ sourceMappingURL=/path/to/file.js.map
+
+/**
+* This maps from a generated file back to the original source files. It also supports the reverse
+* mapping; from locations in the source files to locations in the generated file.
+*
+* @see http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/
+*/
+public class SourceMap {
+
+ // Which version of the source map spec this map is following.
+ private String version;
+
+ // An array of URLs to the original source files.
+ private String[] sources;
+
+ // An array of identifiers which can be referenced by individual mappings.
+ private String[] names;
+
+ // Optional. The URL root from which all sources are relative.
+ private String sourceRoot;
+
+ // Optional. An array of contents of the original source files.
+ private String[] sourcesContent;
+ // A string of base64 VLQs which contain the actual mappings.
+
+ private String mappings;
+
+ // Optional. The generated filename this source map is associated with.
+ private String file;
+
+ private SourceMapInfoEntry[] entries;
+
+ private Map<String, TextSectionMapping> maps = new HashMap<String, TextSectionMapping>();
+
+ public static SourceMap load(Reader reader) {
+ Gson gson = new GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create();
+ SourceMap sourceMap = gson.fromJson(reader, SourceMap.class);
+ if (sourceMap == null) {
+ throw new JsonSyntaxException("JSON Syntax error");
+ }
+ sourceMap.update();
+ return sourceMap;
+ }
+
+ private void update() {
+ // Prepend sourceRoot to the sources entries.
+ if (sourceRoot != null && sourceRoot.length() > 0) {
+ for (int i = 0; i < sources.length; i++) {
+ sources[i] = sourceRoot + sources[i];
+ }
+ }
+
+ List<SourceMapInfoEntry> result = SourceMapDecoder.decode(sources, names, mappings);
+ entries = result.toArray(new SourceMapInfoEntry[result.size()]);
+ }
+
+ public static SourceMap load(InputStream in) {
+ Reader reader = null;
+ try {
+ reader = new InputStreamReader(in);
+ return load(reader);
+ } finally {
+ if (reader != null) {
+ try {
+ reader.close();
+ } catch (IOException e) {
+ }
+ }
+ }
+ }
+
+ public TextSectionMapping getMapping(String file) {
+ TextSectionMapping mapping = maps.get(file);
+ if (mapping == null) {
+ mapping = new SourceMapTextSectionMapping(file);
+ maps.put(file, mapping);
+ }
+ return mapping;
+ }
+
+ private class SourceMapTextSectionMapping implements TextSectionMapping {
+
+ private String file;
+
+ public SourceMapTextSectionMapping(String file) {
+ this.file = file;
+ }
+
+ @Override
+ public TextPoint transform(TextPoint point, Direction direction) {
+ if (direction == Direction.DIRECT) {
+ return getReverseMappingsFor(file, point.getLine(), point.getColumn());
+ }
+
+ SourceMapInfo info = getMappingFor(point.getLine(), point.getColumn());
+ if (info != null) {
+ return new TextPoint(info.getLine(), info.getColumn());
+ }
+
+ return getReverseMappingsFor(file, point.getLine(), point.getColumn());
+ }
+ }
+
+ /**
+ * Map from a location in the generated file back to the original source.
+ *
+ * @param line
+ * the line in the generated source
+ * @param column
+ * the column in the generated source; -1 means the column is not
+ * interesting
+ * @return the corresponding location in the original source
+ */
+ public SourceMapInfo getMappingFor(int line, int column) {
+ int index = findIndexForLine(line);
+
+ if (index == -1) {
+ return null;
+ }
+
+ SourceMapInfoEntry entry = entries[index];
+
+ // If column == -1, return the first mapping for that line.
+ if (column == -1) {
+ return entry.getInfo();
+ }
+
+ // Search for a matching mapping.
+ while (index < entries.length) {
+ entry = entries[index];
+
+ if (entry.column <= column) {
+ if (entry.endColumn == -1) {
+ return entry.getInfo();
+ }
+
+ if (column < entry.endColumn) {
+ return entry.getInfo();
+ }
+ }
+
+ index++;
+ }
+
+ // no mapping found
+ return null;
+ }
+
+ private int findIndexForLine(int line) {
+ // TODO(devoncarew): test this binary search
+
+ int location = Arrays.binarySearch(entries, SourceMapInfoEntry.forLine(line),
+ SourceMapInfoEntry.lineComparator());
+
+ if (location < 0) {
+ return -1;
+ }
+
+ while (location > 0 && entries[location - 1].line == line) {
+ location--;
+ }
+
+ return location;
+ }
+
+ /**
+ * Map from a location in a source file to a location in the generated
+ * source file.
+ *
+ * @param file
+ * @param line
+ * @param column
+ * @return
+ */
+ public TextSectionMapping.TextPoint getReverseMappingsFor(String file, int line, int column) {
+ // TODO(devoncarew): calculate this information once for O(1) lookup
+ for (SourceMapInfoEntry entry : entries) {
+ SourceMapInfo info = entry.getInfo();
+
+ if (info == null) {
+ continue;
+ }
+
+ if (line == info.getLine()) {
+ if (file.equals(info.getFile())) {
+ // TODO(devoncarew): there will be several entries on this
+ // line
+ // We need to choose one that has a non-zero range, or is a
+ // catch-all entry
+ return new TextSectionMapping.TextPoint(entry.line, entry.column);
+ // return Collections.singletonList(new SourceMapInfo(null,
+ // entry.line, entry.column));
+ }
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMapDecoder.java b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMapDecoder.java
new file mode 100644
index 000000000..b9658b443
--- /dev/null
+++ b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMapDecoder.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2013, 2017 the Dart project authors.
+ *
+ * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.eclipse.wst.jsdt.chromium.debug.core.internal.sourcemap;
+
+import java.util.ArrayList;
+import java.util.List;
+
+class SourceMapDecoder {
+
+ public static List<SourceMapInfoEntry> decode(String[] sources, String[] names, String mappings) {
+ return new SourceMapDecoder(sources, names).decodeLines(mappings);
+ }
+
+ private String[] sources;
+ private String[] names;
+
+ private List<SourceMapInfoEntry> entries;
+
+ int originalFileIndex = 0;
+ int originalLine = 0;
+ int originalColumn = 0;
+ int nameIndex = 0;
+
+ private SourceMapDecoder(String[] sources, String[] names) {
+ this.sources = sources;
+ this.names = names;
+ }
+
+ List<SourceMapInfoEntry> decodeLines(String mapStr) {
+ // In the given string, semi-colons demarcate lines and commas demarcate
+ // groups.
+ // A;A;;;;;;;A;A;;A;A;A,mB,W,C,C,I,C,C;A,cAyVEA;AAAiB,QAAK,MAAFC
+
+ entries = new ArrayList<SourceMapInfoEntry>();
+
+ int lineNumber = 0;
+
+ for (String line : mapStr.split(";")) {
+ if (line.length() > 0) {
+ decodeLine(line.split(","), lineNumber);
+ }
+
+ lineNumber++;
+ }
+
+ return entries;
+ }
+
+ private void decodeLine(String[] mappings, int line) {
+ int generatedColumn = 0;
+
+ SourceMapInfoEntry previousEntry = null;
+
+ for (String mapping : mappings) {
+ int[] indexes = VlqDecoder.decode(mapping);
+
+ if (indexes.length == 1 || indexes.length == 4 || indexes.length == 5) {
+ generatedColumn += indexes[0];
+
+ if (previousEntry != null) {
+ previousEntry.setEndColumn(generatedColumn);
+ }
+
+ if (indexes.length < 4) {
+ continue;
+ }
+
+ originalFileIndex += indexes[1];
+ originalLine += indexes[2];
+ originalColumn += indexes[3];
+
+ String originalFile = getString(sources, originalFileIndex);
+
+ SourceMapInfo info = new SourceMapInfo(originalFile, originalLine, originalColumn);
+
+ if (indexes.length > 4) {
+ nameIndex += indexes[4];
+ info.setName(getString(names, nameIndex));
+ }
+
+ previousEntry = new SourceMapInfoEntry(line, generatedColumn, info);
+
+ entries.add(previousEntry);
+ }
+ }
+ }
+
+ private String getString(String[] strs, int index) {
+ if (index >= 0 && index < strs.length) {
+ return strs[index];
+ } else {
+ return null;
+ }
+ }
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMapInfo.java b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMapInfo.java
new file mode 100644
index 000000000..444e70f81
--- /dev/null
+++ b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMapInfo.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2013, 2017 the Dart project authors.
+ *
+ * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.eclipse.wst.jsdt.chromium.debug.core.internal.sourcemap;
+
+/**
+ * A reference to a file, line, column, and (optionally) name.
+ */
+public class SourceMapInfo {
+ private String file;
+ private int line;
+ private int column;
+ private String name;
+
+ public SourceMapInfo() {
+
+ }
+
+ public SourceMapInfo(String file, int line, int column) {
+ this.file = file;
+ this.line = line;
+ this.column = column;
+ }
+
+ public int getColumn() {
+ return column;
+ }
+
+ public String getFile() {
+ return file;
+ }
+
+ public int getLine() {
+ return line;
+ }
+
+ /**
+ * @return the (optional) name reference
+ */
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return file + "," + line + "," + column;
+ }
+
+ void setName(String name) {
+ this.name = name;
+ }
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMapInfoEntry.java b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMapInfoEntry.java
new file mode 100644
index 000000000..2ae1d2233
--- /dev/null
+++ b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMapInfoEntry.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2013, 2017 the Dart project authors.
+ *
+ * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.eclipse.wst.jsdt.chromium.debug.core.internal.sourcemap;
+
+import java.util.Comparator;
+
+/**
+ * An entry that maps from a line and column range to a SourceMapInfo (an
+ * original source location).
+ */
+class SourceMapInfoEntry {
+
+ private static Comparator<SourceMapInfoEntry> COMPARATOR = new Comparator<SourceMapInfoEntry>() {
+ @Override
+ public int compare(SourceMapInfoEntry val1, SourceMapInfoEntry val2) {
+ return val1.line - val2.line;
+ }
+ };
+
+ public static SourceMapInfoEntry forLine(int line) {
+ return new SourceMapInfoEntry(line, 0, null);
+ }
+
+ public static Comparator<SourceMapInfoEntry> lineComparator() {
+ return COMPARATOR;
+ }
+
+ /**
+ * The source line.
+ */
+ public int line;
+
+ /**
+ * The starting source column (inclusive).
+ */
+ public int column;
+
+ /**
+ * The ending source column (non-inclusive).
+ */
+ public int endColumn = -1;
+
+ /**
+ * The associated SourceMapInfo for this range of generated source.
+ */
+ public SourceMapInfo info;
+
+ SourceMapInfoEntry(int line, int column, SourceMapInfo info) {
+ this.line = line;
+ this.column = column;
+ this.info = info;
+ }
+
+ public SourceMapInfo getInfo() {
+ return info;
+ }
+
+ @Override
+ public String toString() {
+ return "[" + line + ":" + column + "," + endColumn + "] ==> " + info.toString();
+ }
+
+ void setEndColumn(int endColumn) {
+ this.endColumn = endColumn;
+ }
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMapLanguageSupportType.java b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMapLanguageSupportType.java
new file mode 100644
index 000000000..62c07b9e8
--- /dev/null
+++ b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMapLanguageSupportType.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2016, 2017 Angelo Zerr.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.chromium.debug.core.internal.sourcemap;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.wst.jsdt.chromium.debug.core.sourcemap.extension.ISourceMapLanguageSupport;
+
+public class SourceMapLanguageSupportType {
+
+ private final String id;
+ private final ISourceMapLanguageSupport support;
+ private final Set<String> fileExtensions;
+
+ public SourceMapLanguageSupportType(IConfigurationElement ce) throws CoreException {
+ this.id = ce.getAttribute("id");
+ this.support = (ISourceMapLanguageSupport) ce.createExecutableExtension("class");
+ this.fileExtensions = createFileExtensions(ce);
+ }
+
+ private Set<String> createFileExtensions(IConfigurationElement ce) {
+ String[] fileExtensions = ce.getAttribute("fileExtensions").split(",");
+ Set<String> set = new HashSet<String>();
+ for (String fileExtension : fileExtensions) {
+ set.add(fileExtension.trim());
+ }
+ return set;
+ }
+
+ public ISourceMapLanguageSupport getSupport() {
+ return support;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public boolean canSupportSourceMap(String fileExtension) {
+ return fileExtensions.contains(fileExtension);
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMapManager.java b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMapManager.java
new file mode 100644
index 000000000..fa2076d06
--- /dev/null
+++ b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/SourceMapManager.java
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2016, 2017 Angelo Zerr.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.chromium.debug.core.internal.sourcemap;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IExtensionDelta;
+import org.eclipse.core.runtime.IExtensionRegistry;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IRegistryChangeEvent;
+import org.eclipse.core.runtime.IRegistryChangeListener;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.wst.jsdt.chromium.debug.core.ChromiumDebugPlugin;
+import org.eclipse.wst.jsdt.chromium.debug.core.sourcemap.extension.ISourceMapLanguageSupport;
+import org.eclipse.wst.jsdt.chromium.debug.core.sourcemap.extension.ISourceMapManager;
+
+/**
+ * Manager which loads the "org.eclipse.wst.jsdt.chromium.debug.core.sourceMapLanguageSupports" extensions point.
+ *
+ */
+public class SourceMapManager implements ISourceMapManager, IRegistryChangeListener {
+
+ private static final SourceMapManager INSTANCE = new SourceMapManager();
+ private static final String EXTENSION_SOURCEMAP_LANGUAGE_SUPPORTS = "sourceMapLanguageSupports";
+
+ public static SourceMapManager getInstance() {
+ return INSTANCE;
+ }
+
+ private List<SourceMapLanguageSupportType> sourceMapLanguageSupports;
+
+ private SourceMapManager() {
+ }
+
+ @Override
+ public boolean canSupportSourceMap(String fileExtension) {
+ return getSourceMapLanguageSupport(fileExtension) != null;
+ }
+
+ @Override
+ public String getJsFile(IPath file) throws CoreException {
+ ISourceMapLanguageSupport support = getSourceMapLanguageSupport(file.getFileExtension());
+ if (support == null) {
+ return null;
+ }
+ IPath jsFile = support.getJsFile(file);
+ return jsFile != null ? jsFile.toString() : null;
+ }
+
+ @Override
+ public ISourceMapLanguageSupport getSourceMapLanguageSupport(String fileExtension) {
+ loadSourceMapLanguageSupportsIfNeeded();
+ for (SourceMapLanguageSupportType type : sourceMapLanguageSupports) {
+ if (type.canSupportSourceMap(fileExtension)) {
+ return type.getSupport();
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public void registryChanged(final IRegistryChangeEvent event) {
+ IExtensionDelta[] deltas = event.getExtensionDeltas(ChromiumDebugPlugin.PLUGIN_ID,
+ EXTENSION_SOURCEMAP_LANGUAGE_SUPPORTS);
+ if (deltas != null) {
+ for (IExtensionDelta delta : deltas)
+ handleSourceMapLanguageSupportsDelta(delta);
+ }
+ }
+
+ private void loadSourceMapLanguageSupportsIfNeeded() {
+ if (sourceMapLanguageSupports != null) {
+ return;
+ }
+ loadSourceMapLanguageSupports();
+ }
+
+ /**
+ * Load the SourceMap language supports.
+ */
+ private synchronized void loadSourceMapLanguageSupports() {
+ if (sourceMapLanguageSupports != null) {
+ return;
+ }
+
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IConfigurationElement[] cf = registry.getConfigurationElementsFor(ChromiumDebugPlugin.PLUGIN_ID,
+ EXTENSION_SOURCEMAP_LANGUAGE_SUPPORTS);
+ List<SourceMapLanguageSupportType> list = new ArrayList<SourceMapLanguageSupportType>(cf.length);
+ addSourceMapLanguageSupports(cf, list);
+ sourceMapLanguageSupports = list;
+ }
+
+ /**
+ * Add the SourceMap language supports.
+ */
+ private synchronized void addSourceMapLanguageSupports(IConfigurationElement[] cf,
+ List<SourceMapLanguageSupportType> list) {
+ for (IConfigurationElement ce : cf) {
+ try {
+ list.add(new SourceMapLanguageSupportType(ce));
+ } catch (Throwable e) {
+ ChromiumDebugPlugin.log(e);
+ }
+ }
+ }
+
+ protected void handleSourceMapLanguageSupportsDelta(IExtensionDelta delta) {
+ if (sourceMapLanguageSupports == null) // not loaded yet
+ return;
+
+ IConfigurationElement[] cf = delta.getExtension().getConfigurationElements();
+
+ List<SourceMapLanguageSupportType> list = new ArrayList<SourceMapLanguageSupportType>(
+ sourceMapLanguageSupports);
+ if (delta.getKind() == IExtensionDelta.ADDED) {
+ addSourceMapLanguageSupports(cf, list);
+ } else {
+ int size = list.size();
+ SourceMapLanguageSupportType[] st = new SourceMapLanguageSupportType[size];
+ list.toArray(st);
+ int size2 = cf.length;
+
+ for (int i = 0; i < size; i++) {
+ for (int j = 0; j < size2; j++) {
+ if (st[i].getId().equals(cf[j].getAttribute("id"))) {
+ list.remove(st[i]);
+ }
+ }
+ }
+ }
+ sourceMapLanguageSupports = list;
+ }
+
+ public void initialize() {
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ registry.addRegistryChangeListener(this, ChromiumDebugPlugin.PLUGIN_ID);
+ }
+
+ public void destroy() {
+ Platform.getExtensionRegistry().removeRegistryChangeListener(this);
+ }
+
+}
diff --git a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/VlqDecoder.java b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/VlqDecoder.java
new file mode 100644
index 000000000..4946602e6
--- /dev/null
+++ b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/internal/sourcemap/VlqDecoder.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2013, 2017 the Dart project authors.
+ *
+ * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.eclipse.wst.jsdt.chromium.debug.core.internal.sourcemap;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A class to convert to and from base64 vlq encoded strings.
+ * <p>
+ * <code>"AAgBC" <==> {0, 0, 16, 1}</code>
+ */
+public class VlqDecoder {
+ // A Base64 VLQ digit can represent 5 bits, so it is base-32.
+ private static final int VLQ_BASE_SHIFT = 5;
+ private static final int VLQ_BASE = 1 << VLQ_BASE_SHIFT;
+
+ // A mask of bits for a VLQ digit (11111), 31 decimal.
+ private static final int VLQ_BASE_MASK = VLQ_BASE - 1;
+
+ // The continuation bit is the 6th bit.
+ private static final int VLQ_CONTINUATION_BIT = VLQ_BASE;
+
+ /**
+ * A map used to convert integer values in the range 0-63 to their base64
+ * values.
+ */
+ private static final String BASE64_MAP = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz"
+ + "0123456789+/";
+
+ /**
+ * A map used to convert base64 character into integer values.
+ */
+ private static final int[] BASE64_DECODE_MAP = new int[256];
+
+ static {
+ Arrays.fill(BASE64_DECODE_MAP, -1);
+
+ for (int i = 0; i < BASE64_MAP.length(); i++) {
+ BASE64_DECODE_MAP[BASE64_MAP.charAt(i)] = i;
+ }
+ }
+
+ /**
+ * Convert from a Base64 VLQ string sequence to the corresponding sequence
+ * of ints.
+ *
+ * @param str
+ * @return
+ */
+ public static int[] decode(String str) {
+ List<Integer> results = new ArrayList<Integer>();
+ int i = 0;
+ int strLen = str.length();
+
+ while (i < strLen) {
+ int result = 0;
+ boolean continuation;
+ int shift = 0;
+
+ do {
+ char c = str.charAt(i++);
+ int digit = fromBase64(c);
+ continuation = (digit & VLQ_CONTINUATION_BIT) != 0;
+ digit &= VLQ_BASE_MASK;
+ result = result + (digit << shift);
+ shift = shift + VLQ_BASE_SHIFT;
+ } while (continuation);
+
+ results.add(fromVLQSigned(result));
+ }
+
+ int[] array = new int[results.size()];
+ for (i = 0; i < results.size(); i++) {
+ array[i] = results.get(i);
+ }
+
+ return array;
+ }
+
+ /**
+ * Encode the given sequence of ints to a Base64 VLQ encoded string.
+ *
+ * @param values
+ * @return
+ */
+ public static String encode(int[] values) {
+ StringBuilder builder = new StringBuilder();
+
+ for (int value : values) {
+ value = toVLQSigned(value);
+ do {
+ int digit = value & VLQ_BASE_MASK;
+ value >>>= VLQ_BASE_SHIFT;
+ if (value > 0) {
+ digit |= VLQ_CONTINUATION_BIT;
+ }
+ builder.append(toBase64(digit));
+ } while (value > 0);
+ }
+
+ return builder.toString();
+ }
+
+ private static int fromBase64(char c) {
+ return BASE64_DECODE_MAP[c];
+ }
+
+ /**
+ * Converts to a two-complement value from a value where the sign bit is is
+ * placed in the least significant bit. For example, as decimals: 2 (10
+ * binary) becomes 1, 3 (11 binary) becomes -1 4 (100 binary) becomes 2, 5
+ * (101 binary) becomes -2
+ */
+ private static int fromVLQSigned(int value) {
+ boolean negate = (value & 1) == 1;
+ value = value >> 1;
+ return negate ? -value : value;
+ }
+
+ private static char toBase64(int value) {
+ return BASE64_MAP.charAt(value);
+ }
+
+ /**
+ * Converts from a two-complement value to a value where the sign bit is is
+ * placed in the least significant bit. For example, as decimals: 1 becomes
+ * 2 (10 binary), -1 becomes 3 (11 binary) 2 becomes 4 (100 binary), -2
+ * becomes 5 (101 binary)
+ */
+ private static int toVLQSigned(int value) {
+ if (value < 0) {
+ return ((-value) << 1) + 1;
+ } else {
+ return (value << 1) + 0;
+ }
+ }
+
+ private VlqDecoder() {
+
+ }
+
+} \ No newline at end of file
diff --git a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/model/VProjectWorkspaceBridge.java b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/model/VProjectWorkspaceBridge.java
index 73d788878..ebe356043 100644
--- a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/model/VProjectWorkspaceBridge.java
+++ b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/model/VProjectWorkspaceBridge.java
@@ -1,4 +1,4 @@
-// Copyright (c) 2009, 2016 The Chromium Authors. All rights reserved.
+// Copyright (c) 2009, 2017 The Chromium Authors. All rights reserved.
// This program and the accompanying materials are made available
// under the terms of the Eclipse Public License v1.0 which accompanies
// this distribution, and is available at
@@ -16,33 +16,47 @@ import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;
-import org.eclipse.wst.jsdt.chromium.debug.core.ChromiumDebugPlugin;
-import org.eclipse.wst.jsdt.chromium.debug.core.ChromiumSourceDirector;
-import org.eclipse.wst.jsdt.chromium.debug.core.ScriptNameManipulator.ScriptNamePattern;
-import org.eclipse.wst.jsdt.chromium.debug.core.model.BreakpointSynchronizer.Callback;
-import org.eclipse.wst.jsdt.chromium.debug.core.model.ChromiumLineBreakpoint.MutableProperty;
-import org.eclipse.wst.jsdt.chromium.debug.core.model.VmResource.Metadata;
-import org.eclipse.wst.jsdt.chromium.debug.core.util.ChromiumDebugPluginUtil;
-import org.eclipse.wst.jsdt.chromium.debug.core.util.JavaScriptRegExpSupport;
-import org.eclipse.wst.jsdt.chromium.Breakpoint;
-import org.eclipse.wst.jsdt.chromium.CallFrame;
-import org.eclipse.wst.jsdt.chromium.ExceptionData;
-import org.eclipse.wst.jsdt.chromium.JavascriptVm;
-import org.eclipse.wst.jsdt.chromium.JavascriptVm.ExceptionCatchMode;
-import org.eclipse.wst.jsdt.chromium.JavascriptVm.ScriptsCallback;
-import org.eclipse.wst.jsdt.chromium.RelayOk;
-import org.eclipse.wst.jsdt.chromium.Script;
-import org.eclipse.wst.jsdt.chromium.SyncCallback;
-import org.eclipse.wst.jsdt.chromium.util.GenericCallback;
+import org.eclipse.core.filebuffers.FileBuffers;
+import org.eclipse.core.filebuffers.ITextFileBuffer;
+import org.eclipse.core.filebuffers.ITextFileBufferManager;
+import org.eclipse.core.filebuffers.LocationKind;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.IBreakpointManager;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IBreakpoint;
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.jsdt.chromium.Breakpoint;
+import org.eclipse.wst.jsdt.chromium.CallFrame;
+import org.eclipse.wst.jsdt.chromium.ExceptionData;
+import org.eclipse.wst.jsdt.chromium.JavascriptVm;
+import org.eclipse.wst.jsdt.chromium.JavascriptVm.ScriptsCallback;
+import org.eclipse.wst.jsdt.chromium.RelayOk;
+import org.eclipse.wst.jsdt.chromium.Script;
+import org.eclipse.wst.jsdt.chromium.SyncCallback;
+import org.eclipse.wst.jsdt.chromium.debug.core.ChromiumDebugPlugin;
+import org.eclipse.wst.jsdt.chromium.debug.core.ChromiumSourceDirector;
+import org.eclipse.wst.jsdt.chromium.debug.core.ScriptNameManipulator.ScriptNamePattern;
+import org.eclipse.wst.jsdt.chromium.debug.core.internal.sourcemap.SourceMap;
+import org.eclipse.wst.jsdt.chromium.debug.core.model.BreakpointSynchronizer.Callback;
+import org.eclipse.wst.jsdt.chromium.debug.core.model.ChromiumLineBreakpoint.MutableProperty;
+import org.eclipse.wst.jsdt.chromium.debug.core.model.VmResource.Metadata;
+import org.eclipse.wst.jsdt.chromium.debug.core.model.VmResourceRef.Visitor;
+import org.eclipse.wst.jsdt.chromium.debug.core.sourcemap.SourcePositionMapBuilder;
+import org.eclipse.wst.jsdt.chromium.debug.core.sourcemap.TextSectionMapping;
+import org.eclipse.wst.jsdt.chromium.debug.core.sourcemap.extension.ISourceMapLanguageSupport;
+import org.eclipse.wst.jsdt.chromium.debug.core.sourcemap.extension.ISourceMapManager;
+import org.eclipse.wst.jsdt.chromium.debug.core.util.ChromiumDebugPluginUtil;
+import org.eclipse.wst.jsdt.chromium.debug.core.util.JavaScriptRegExpSupport;
/**
* Virtual project-supporting implementation of {@link WorkspaceBridge}.
@@ -78,14 +92,16 @@ public class VProjectWorkspaceBridge implements WorkspaceBridge {
private final ResourceManager resourceManager;
private final ConnectedTargetData connectedTargetData;
private final ChromiumSourceDirector sourceDirector;
-
+ private final UpdateMappingVisitor updateMappingVisitor;
+
public VProjectWorkspaceBridge(String projectName, ConnectedTargetData connectedTargetData,
JavascriptVm javascriptVm) {
this.connectedTargetData = connectedTargetData;
this.javascriptVm = javascriptVm;
this.debugProject = ChromiumDebugPluginUtil.createEmptyProject(projectName);
this.resourceManager = new ResourceManager(debugProject);
-
+ this.updateMappingVisitor = new UpdateMappingVisitor();
+
ILaunch launch = connectedTargetData.getDebugTarget().getLaunch();
sourceDirector = (ChromiumSourceDirector) launch.getSourceLocator();
@@ -250,6 +266,7 @@ public class VProjectWorkspaceBridge implements WorkspaceBridge {
public RelayOk createBreakpointOnRemote(final ChromiumLineBreakpoint lineBreakpoint,
final VmResourceRef vmResourceRef,
final CreateCallback createCallback, SyncCallback syncCallback) throws CoreException {
+ vmResourceRef.accept(updateMappingVisitor);
return lineBreakpointHandler.createBreakpointOnRemote(lineBreakpoint, vmResourceRef,
createCallback, syncCallback);
}
@@ -774,4 +791,121 @@ public class VProjectWorkspaceBridge implements WorkspaceBridge {
public ConnectedTargetData getConnectedTargetData() {
return connectedTargetData;
}
+
+
+ class UpdateMappingVisitor implements Visitor<Object> {
+
+ @Override
+ public Object visitRegExpBased(ScriptNamePattern scriptNamePattern) {
+ return null;
+ }
+
+ @Override
+ public Object visitResourceId(final VmResourceId tsResourceId) {
+ try {
+ String fileName = tsResourceId.getName();
+ int index = fileName.lastIndexOf('.');
+ if (index == -1) {
+ return null;
+ }
+ ISourceMapManager manager = ChromiumDebugPlugin.getSourceMapManager();
+ String fileExtension = fileName.substring(index + 1, fileName.length());
+ // check if the given resource support source map
+ ISourceMapLanguageSupport support = manager.getSourceMapLanguageSupport(fileExtension);
+ if (support == null) {
+ return null;
+ }
+
+ IPath tsFilePath = new Path(fileName);
+ final IFile tsFile = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(tsFilePath)[0];
+
+ IPath jsFilePath = support.getJsFile(tsFilePath);
+ final IFile jsFile = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(jsFilePath)[0];
+
+ IPath sourceMapFilePath = support.getSourceMapFile(tsFilePath);
+ final IFile sourceMapFile = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocation(sourceMapFilePath)[0];
+ final SourceMap sourceMap = SourceMap.load(sourceMapFile.getContents());
+
+
+ VmResourceRef jsRef = sourceDirector.findVmResourceRef(jsFile);
+
+ jsRef.accept(new Visitor<Object>() {
+ @Override
+ public Object visitRegExpBased(ScriptNamePattern scriptNamePattern) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Object visitResourceId(VmResourceId jsResourceId) {
+ SourcePositionMapBuilder.ResourceSection vmResourceSection = create(jsFile, jsResourceId);
+ SourcePositionMapBuilder.ResourceSection originalResourceSection = create(tsFile, tsResourceId);
+
+ try {
+ TextSectionMapping mapTable = sourceMap.getMapping(tsFile.getName());
+ connectedTargetData.getSourcePositionMapBuilder().addMapping(originalResourceSection,
+ vmResourceSection, mapTable);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+ });
+
+
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ return null;
+
+ }
+
+ }
+
+ private static SourcePositionMapBuilder.ResourceSection create(IFile file, VmResourceId resourceId) {
+ IDocument document = getDocument(file);
+ int endLine = document.getNumberOfLines();
+ if (endLine > 0) {
+ endLine--;
+ }
+ int endColumn = 0;
+ try {
+ endColumn = document.getLineLength(endLine);
+ } catch (BadLocationException e) {
+ e.printStackTrace();
+ }
+ return new SourcePositionMapBuilder.ResourceSection(resourceId, 0, 0, endLine, endColumn);
+ }
+
+ private static IDocument getDocument(IFile file) {
+ ITextFileBufferManager manager = FileBuffers.getTextFileBufferManager();
+ IPath location = file.getLocation();
+ boolean connected = false;
+ try {
+ ITextFileBuffer buffer = manager.getTextFileBuffer(location, LocationKind.NORMALIZE);
+ if (buffer == null) {
+ // no existing file buffer..create one
+ manager.connect(location, LocationKind.NORMALIZE, new NullProgressMonitor());
+ connected = true;
+ buffer = manager.getTextFileBuffer(location, LocationKind.NORMALIZE);
+ if (buffer == null) {
+ return null;
+ }
+ }
+
+ return buffer.getDocument();
+ } catch (CoreException ce) {
+ ChromiumDebugPlugin.log(ce);
+ return null;
+ } finally {
+ if (connected) {
+ try {
+ manager.disconnect(location, LocationKind.NORMALIZE, new NullProgressMonitor());
+ } catch (CoreException e) {
+ ChromiumDebugPlugin.log(e);
+ }
+ }
+ }
+ }
}
diff --git a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/sourcemap/extension/ISourceMapLanguageSupport.java b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/sourcemap/extension/ISourceMapLanguageSupport.java
new file mode 100644
index 000000000..2648b87dd
--- /dev/null
+++ b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/sourcemap/extension/ISourceMapLanguageSupport.java
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2016, 2017 Angelo Zerr.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.chromium.debug.core.sourcemap.extension;
+
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * API to implement to add SourceMap Language Support.
+ * <pre>
+ *
+1) Here a basic implementation for TypeScript:
+----------------------------------------------------------
+package ts.eclipse.ide.jsdt.debug.internal.support;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.wst.jsdt.chromium.debug.core.sourcemap.extension.ISourceMapLanguageSupport;
+
+public class TypeScriptSourceMapLanguageSupport implements ISourceMapLanguageSupport {
+
+ &#64;Override
+ public IPath getJsFile(IPath file) {
+ // TODO: search js file in the well folder by using tsconfig.json
+ return file.removeFileExtension().addFileExtension("js");
+ }
+
+ &#64;Override
+ public IPath getSourceMapFile(IPath file) {
+ // TODO: search js file in the well folder by using tsconfig.json
+ return file.removeFileExtension().addFileExtension("js.map");
+ }
+}
+----------------------------------------------------------
+
+2) Declare the extension point:
+----------------------------------------------------------
+<extension
+ point=
+"org.eclipse.wst.jsdt.chromium.debug.core.sourceMapLanguageSupports">
+ <support
+ class=
+"ts.eclipse.ide.jsdt.debug.internal.support.TypeScriptSourceMapLanguageSupport"
+ fileExtensions="ts,tsx"
+ id="ts.eclipse.ide.jsdt.debug.support1"
+ name="ts.eclipse.ide.jsdt.debug.support1">
+ </support>
+ </extension>
+----------------------------------------------------------
+ *
+ * </pre>
+ *
+ */
+public interface ISourceMapLanguageSupport {
+
+ /**
+ * Returns the ".js" file which is linked to the given file (".ts", ".tsx",
+ * ".coffee", etc).
+ *
+ * @param file
+ * a ".ts", ".tsx", ".coffee", etc to debug.
+ * @return the "js" file which is linked to the given file (".ts", ".tsx",
+ * ".coffee", etc).
+ */
+ IPath getJsFile(IPath file);
+
+ /**
+ * Returns the ".js.map" SourceMap file which is linked to the given file (".ts", ".tsx",
+ * ".coffee", etc).
+ *
+ * @param file
+ * a ".ts", ".tsx", ".coffee", etc to debug.
+ * @return the ".js.map" SourceMap file which is linked to the given file (".ts", ".tsx",
+ * ".coffee", etc).
+ */
+ IPath getSourceMapFile(IPath file);
+
+}
diff --git a/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/sourcemap/extension/ISourceMapManager.java b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/sourcemap/extension/ISourceMapManager.java
new file mode 100644
index 000000000..126275cd9
--- /dev/null
+++ b/bundles/org.eclipse.wst.jsdt.chromium.debug.core/src/org/eclipse/wst/jsdt/chromium/debug/core/sourcemap/extension/ISourceMapManager.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2016, 2017 Angelo Zerr.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.wst.jsdt.chromium.debug.core.sourcemap.extension;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+
+/**
+ * SourceMap manager API.
+ *
+ */
+public interface ISourceMapManager {
+
+ /**
+ * Returns the {@link ISourceMapLanguageSupport} for the given file
+ * extension and null otherwise.
+ *
+ * @param fileExtension
+ * "ts", "tsx", "coffee", etc
+ * @return the {@link ISourceMapLanguageSupport} for the given file
+ * extension and null otherwise.
+ */
+ ISourceMapLanguageSupport getSourceMapLanguageSupport(String fileExtension);
+
+ /**
+ * Returns true if the given file extension can support SourceMap and false
+ * otherwise.
+ *
+ * @param fileExtension
+ * "ts", "tsx", "coffee", etc
+ * @return true if the given file extension can support SourceMap and false
+ * otherwise.
+ */
+ boolean canSupportSourceMap(String fileExtension);
+
+ /**
+ * Returns the ".js" file which is linked to the given file (".ts", ".tsx",
+ * ".coffee", etc).
+ *
+ * @param file
+ * a ".ts", ".tsx", ".coffee", etc to debug.
+ * @return the "js" file which is linked to the given file (".ts", ".tsx",
+ * ".coffee", etc).
+ */
+ String getJsFile(IPath file) throws CoreException;
+
+}
diff --git a/nodejs/org.eclipse.wst.jsdt.js.node/META-INF/MANIFEST.MF b/nodejs/org.eclipse.wst.jsdt.js.node/META-INF/MANIFEST.MF
index 8744a6cf0..ffffce718 100644
--- a/nodejs/org.eclipse.wst.jsdt.js.node/META-INF/MANIFEST.MF
+++ b/nodejs/org.eclipse.wst.jsdt.js.node/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Node
Bundle-SymbolicName: org.eclipse.wst.jsdt.js.node;singleton:=true
-Bundle-Version: 1.1.0.qualifier
+Bundle-Version: 1.1.100.qualifier
Bundle-Activator: org.eclipse.wst.jsdt.js.node.NodePlugin
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
diff --git a/nodejs/org.eclipse.wst.jsdt.js.node/pom.xml b/nodejs/org.eclipse.wst.jsdt.js.node/pom.xml
index c044650b8..55983956d 100644
--- a/nodejs/org.eclipse.wst.jsdt.js.node/pom.xml
+++ b/nodejs/org.eclipse.wst.jsdt.js.node/pom.xml
@@ -21,6 +21,6 @@
<groupId>org.eclipse.webtools.jsdt.nodejs</groupId>
<artifactId>org.eclipse.wst.jsdt.js.node</artifactId>
- <version>1.1.0-SNAPSHOT</version>
+ <version>1.1.100-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>
diff --git a/nodejs/org.eclipse.wst.jsdt.js.node/src/org/eclipse/wst/jsdt/js/node/internal/launch/NodeLaunchConfigurationDelegate.java b/nodejs/org.eclipse.wst.jsdt.js.node/src/org/eclipse/wst/jsdt/js/node/internal/launch/NodeLaunchConfigurationDelegate.java
index e417dd014..ccb96623f 100644
--- a/nodejs/org.eclipse.wst.jsdt.js.node/src/org/eclipse/wst/jsdt/js/node/internal/launch/NodeLaunchConfigurationDelegate.java
+++ b/nodejs/org.eclipse.wst.jsdt.js.node/src/org/eclipse/wst/jsdt/js/node/internal/launch/NodeLaunchConfigurationDelegate.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2016 IBM Corporation.
+ * Copyright (c) 2016, 2017 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -18,6 +18,7 @@ import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.variables.VariablesPlugin;
import org.eclipse.debug.core.DebugPlugin;
@@ -27,6 +28,7 @@ import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
import org.eclipse.osgi.util.NLS;
+import org.eclipse.wst.jsdt.chromium.debug.core.ChromiumDebugPlugin;
import org.eclipse.wst.jsdt.core.runtime.IJSRunner;
import org.eclipse.wst.jsdt.core.runtime.IJSRuntimeInstall;
import org.eclipse.wst.jsdt.core.runtime.JSRunnerConfiguration;
@@ -101,6 +103,9 @@ public class NodeLaunchConfigurationDelegate extends LaunchConfigurationDelegate
}
ExecutionArguments execArgs = new ExecutionArguments(nodeArgs, pgmArgs);
+ // Replace with js file if mainTypeName is a TypeScript file
+ mainTypeName = getJsFile(mainTypeName);
+
// Create VM config
JSRunnerConfiguration runConfig = new JSRunnerConfiguration(mainTypeName);
runConfig.setProgramArguments(execArgs.getProgramArgumentsArray());
@@ -164,6 +169,12 @@ public class NodeLaunchConfigurationDelegate extends LaunchConfigurationDelegate
}
+ private String getJsFile(String mainTypeName) throws CoreException {
+ IPath file = new Path(mainTypeName);
+ String jsFile = ChromiumDebugPlugin.getSourceMapManager().getJsFile(file);
+ return jsFile != null ? jsFile : mainTypeName;
+ }
+
class DebuggerConnectRunnable implements Runnable {
private static final int TIMEOUT = 15000;
Exception exception = null;
diff --git a/nodejs/org.eclipse.wst.jsdt.js.node/src/org/eclipse/wst/jsdt/js/node/internal/propertytesters/NodePropertyTester.java b/nodejs/org.eclipse.wst.jsdt.js.node/src/org/eclipse/wst/jsdt/js/node/internal/propertytesters/NodePropertyTester.java
index 2ba1ca9ac..c492fb156 100644
--- a/nodejs/org.eclipse.wst.jsdt.js.node/src/org/eclipse/wst/jsdt/js/node/internal/propertytesters/NodePropertyTester.java
+++ b/nodejs/org.eclipse.wst.jsdt.js.node/src/org/eclipse/wst/jsdt/js/node/internal/propertytesters/NodePropertyTester.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2016 IBM Corporation.
+ * Copyright (c) 2016, 2017 IBM Corporation.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -14,6 +14,7 @@ import org.eclipse.core.expressions.PropertyTester;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
+import org.eclipse.wst.jsdt.chromium.debug.core.ChromiumDebugPlugin;
import org.eclipse.wst.jsdt.js.node.internal.NodeConstants;
/**
@@ -56,7 +57,8 @@ public class NodePropertyTester extends PropertyTester {
private boolean isValidFile(IFile file) {
// File must be a js file
String fileExtension = file.getFileExtension();
- if (fileExtension == null || !fileExtension.equals(JS_EXT)) {
+ if (fileExtension == null || !(fileExtension.equals(JS_EXT)
+ || ChromiumDebugPlugin.getSourceMapManager().canSupportSourceMap(fileExtension))) {
return false;
}

Back to the top