diff options
author | angelozerr | 2016-08-19 17:48:57 +0000 |
---|---|---|
committer | Victor Rubezhny | 2017-05-09 13:54:46 +0000 |
commit | 5eef1eefcb72b1d0932d9c6cce93b2a25cbe39ea (patch) | |
tree | 7569ac127459b4a368f53ee408f6d1d4c3f07dac | |
parent | 2aea99e039882efc4512f16aa7001356cb9c0564 (diff) | |
download | webtools.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>
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 {
+
+ @Override
+ public IPath getJsFile(IPath file) {
+ // TODO: search js file in the well folder by using tsconfig.json
+ return file.removeFileExtension().addFileExtension("js");
+ }
+
+ @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;
}
|