mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-01 09:03:31 +07:00
nested sourcemaps support for V8 inspector
This commit is contained in:
+30
-19
@@ -18,17 +18,34 @@ package org.jetbrains.debugger.sourcemap
|
||||
import com.intellij.openapi.editor.Document
|
||||
import java.util.*
|
||||
|
||||
abstract class MappingList(private val mappings: List<MappingEntry>) {
|
||||
interface Mappings {
|
||||
fun get(line: Int, column: Int): MappingEntry?
|
||||
|
||||
fun getNextOnTheSameLine(index: Int, skipIfColumnEquals: Boolean = true): MappingEntry?
|
||||
|
||||
fun getNext(mapping: MappingEntry): MappingEntry?
|
||||
|
||||
fun getNextOnTheSameLine(mapping: MappingEntry): MappingEntry? {
|
||||
val nextMapping = getNext(mapping)
|
||||
return if (nextMapping != null && getLine(nextMapping) == getLine(mapping)) nextMapping else null
|
||||
}
|
||||
|
||||
fun indexOf(line: Int, column: Int): Int
|
||||
|
||||
fun getByIndex(index: Int): MappingEntry
|
||||
|
||||
fun getLine(mapping: MappingEntry): Int
|
||||
|
||||
fun getColumn(mapping: MappingEntry): Int
|
||||
}
|
||||
|
||||
abstract class MappingList(private val mappings: List<MappingEntry>) : Mappings {
|
||||
val size: Int
|
||||
get() = mappings.size
|
||||
|
||||
protected abstract val comparator: Comparator<MappingEntry>
|
||||
|
||||
abstract fun getLine(mapping: MappingEntry): Int
|
||||
|
||||
abstract fun getColumn(mapping: MappingEntry): Int
|
||||
|
||||
fun indexOf(line: Int, column: Int): Int {
|
||||
override fun indexOf(line: Int, column: Int): Int {
|
||||
var low = 0
|
||||
var high = mappings.size - 1
|
||||
if (getLine(mappings[low]) > line || getLine(mappings[high]) < line) {
|
||||
@@ -103,43 +120,37 @@ abstract class MappingList(private val mappings: List<MappingEntry>) {
|
||||
}
|
||||
|
||||
// todo honor Google Chrome bug related to paused location
|
||||
fun get(line: Int, column: Int) = mappings.getOrNull(indexOf(line, column))
|
||||
override fun get(line: Int, column: Int) = mappings.getOrNull(indexOf(line, column))
|
||||
|
||||
fun getNext(index: Int) = mappings.getOrNull(index + 1)
|
||||
|
||||
fun getNext(mapping: MappingEntry) = getNext(mappings.binarySearch(mapping, comparator))
|
||||
override fun getNext(mapping: MappingEntry) = getNext(mappings.binarySearch(mapping, comparator))
|
||||
|
||||
@JvmOverloads
|
||||
fun getNextOnTheSameLine(_index: Int, skipIfColumnEquals: Boolean = true): MappingEntry? {
|
||||
var index = _index
|
||||
override fun getNextOnTheSameLine(index: Int, skipIfColumnEquals: Boolean): MappingEntry? {
|
||||
var nextMapping = getNext(index) ?: return null
|
||||
|
||||
val mapping = get(index)
|
||||
val mapping = getByIndex(index)
|
||||
if (getLine(nextMapping) != getLine(mapping)) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (skipIfColumnEquals) {
|
||||
var i = index
|
||||
// several generated segments can point to one source segment, so, in mapping list ordered by source, could be several mappings equal in terms of source position
|
||||
while (getColumn(nextMapping) == getColumn(mapping)) {
|
||||
nextMapping = getNextOnTheSameLine(++index, false) ?: return null
|
||||
nextMapping = getNextOnTheSameLine(++i, false) ?: return null
|
||||
}
|
||||
}
|
||||
|
||||
return nextMapping
|
||||
}
|
||||
|
||||
fun getNextOnTheSameLine(mapping: MappingEntry): MappingEntry? {
|
||||
val nextMapping = getNext(mapping)
|
||||
return if (nextMapping != null && getLine(nextMapping) == getLine(mapping)) nextMapping else null
|
||||
}
|
||||
|
||||
fun getEndOffset(mapping: MappingEntry, lineStartOffset: Int, document: Document): Int {
|
||||
val nextMapping = getNextOnTheSameLine(Collections.binarySearch(mappings, mapping, comparator))
|
||||
return if (nextMapping == null) document.getLineEndOffset(getLine(mapping)) else lineStartOffset + getColumn(nextMapping)
|
||||
}
|
||||
|
||||
fun get(index: Int) = mappings.get(index)
|
||||
override fun getByIndex(index: Int) = mappings.get(index)
|
||||
|
||||
// entries will be processed in this list order
|
||||
fun processMappingsInLine(line: Int, entryProcessor: MappingsProcessorInLine): Boolean {
|
||||
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* 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.jetbrains.debugger.sourcemap
|
||||
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.util.Url
|
||||
import gnu.trove.THashMap
|
||||
|
||||
class NestedSourceMap(private val childMap: SourceMap, private val parentMap: SourceMap) : SourceMap {
|
||||
override val sourceResolver: SourceResolver
|
||||
get() = parentMap.sourceResolver
|
||||
|
||||
override val sources: Array<Url>
|
||||
get() = parentMap.sources
|
||||
|
||||
private val sourceIndexToSourceMappings = arrayOfNulls<Mappings>(parentMap.sources.size)
|
||||
|
||||
private val childMappingToTransformed = THashMap<MappingEntry, MappingEntry>()
|
||||
|
||||
override val outFile: String?
|
||||
get() = childMap.outFile
|
||||
|
||||
override val hasNameMappings: Boolean
|
||||
get() = childMap.hasNameMappings || parentMap.hasNameMappings
|
||||
|
||||
override val generatedMappings: Mappings by lazy {
|
||||
NestedMappings(childMap.generatedMappings, parentMap.generatedMappings, false)
|
||||
}
|
||||
|
||||
override fun findSourceMappings(sourceIndex: Int): Mappings {
|
||||
var result = sourceIndexToSourceMappings.get(sourceIndex)
|
||||
if (result == null) {
|
||||
result = NestedMappings(childMap.findSourceMappings(sourceIndex), parentMap.findSourceMappings(sourceIndex), true)
|
||||
sourceIndexToSourceMappings.set(sourceIndex, result)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
override fun findSourceIndex(sourceFile: VirtualFile, localFileUrlOnly: Boolean) = parentMap.findSourceIndex(sourceFile, localFileUrlOnly)
|
||||
|
||||
override fun findSourceIndex(sourceUrls: List<Url>,
|
||||
sourceFile: VirtualFile?,
|
||||
resolver: Lazy<SourceFileResolver?>?,
|
||||
localFileUrlOnly: Boolean) = parentMap.findSourceIndex(sourceUrls, sourceFile, resolver, localFileUrlOnly)
|
||||
|
||||
override fun processSourceMappingsInLine(sourceIndex: Int, sourceLine: Int, mappingProcessor: MappingsProcessorInLine): Boolean {
|
||||
val childSourceMappings = childMap.findSourceMappings(sourceIndex)
|
||||
return (parentMap.findSourceMappings(sourceIndex) as MappingList).processMappingsInLine(sourceLine, object: MappingsProcessorInLine {
|
||||
override fun process(entry: MappingEntry, nextEntry: MappingEntry?): Boolean {
|
||||
val childIndex = childSourceMappings.indexOf(entry.generatedLine, entry.generatedColumn)
|
||||
if (childIndex == -1) {
|
||||
return true
|
||||
}
|
||||
|
||||
val childEntry = childSourceMappings.getByIndex(childIndex)
|
||||
// todo not clear - should we resolve next child entry by current child index or by provided parent nextEntry?
|
||||
val nextChildEntry = if (nextEntry == null) null else childSourceMappings.getNextOnTheSameLine(childIndex)
|
||||
return mappingProcessor.process(childMappingToTransformed.getOrPut(childEntry) { NestedMappingEntry(childEntry, entry) },
|
||||
nextChildEntry?.let { childMappingToTransformed.getOrPut(it) { NestedMappingEntry(it, entry) } })
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private class NestedMappings(private val child: Mappings, private val parent: Mappings, private val isSourceMappings: Boolean) : Mappings {
|
||||
override fun getNextOnTheSameLine(index: Int, skipIfColumnEquals: Boolean) = parent.getNextOnTheSameLine(index, skipIfColumnEquals)
|
||||
|
||||
override fun getNext(mapping: MappingEntry) = parent.getNext(mapping)
|
||||
|
||||
override fun indexOf(line: Int, column: Int) = parent.indexOf(line, column)
|
||||
|
||||
override fun getByIndex(index: Int) = parent.getByIndex(index)
|
||||
|
||||
override fun getLine(mapping: MappingEntry) = parent.getLine(mapping)
|
||||
|
||||
override fun getColumn(mapping: MappingEntry) = parent.getColumn(mapping)
|
||||
|
||||
override fun get(line: Int, column: Int): MappingEntry? {
|
||||
return if (isSourceMappings) {
|
||||
parent.get(line, column)?.let { child.get(it.generatedLine, it.generatedColumn) }
|
||||
}
|
||||
else {
|
||||
child.get(line, column)?.let { parent.get(it.sourceLine, it.sourceColumn) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private data class NestedMappingEntry(private val child: MappingEntry, private val parent: MappingEntry) : MappingEntry {
|
||||
override val generatedLine: Int
|
||||
get() = child.generatedLine
|
||||
|
||||
override val generatedColumn: Int
|
||||
get() = child.generatedColumn
|
||||
|
||||
override val sourceLine: Int
|
||||
get() = parent.sourceLine
|
||||
|
||||
override val sourceColumn: Int
|
||||
get() = parent.sourceColumn
|
||||
|
||||
override val name: String?
|
||||
get() = parent.name
|
||||
}
|
||||
+51
-18
@@ -15,33 +15,66 @@
|
||||
*/
|
||||
package org.jetbrains.debugger.sourcemap
|
||||
|
||||
import com.intellij.openapi.util.NullableLazyValue
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.util.Url
|
||||
|
||||
// sources - is not originally specified, but canonicalized/normalized
|
||||
class SourceMap(val outFile: String?, val mappings: MappingList, internal val sourceIndexToMappings: Array<MappingList?>, val sourceResolver: SourceResolver, val hasNameMappings: Boolean) {
|
||||
interface SourceMap {
|
||||
val outFile: String?
|
||||
|
||||
/**
|
||||
* note: Nested map returns only parent sources
|
||||
*/
|
||||
val sources: Array<Url>
|
||||
|
||||
val generatedMappings: Mappings
|
||||
val hasNameMappings: Boolean
|
||||
val sourceResolver: SourceResolver
|
||||
|
||||
fun findSourceMappings(sourceIndex: Int): Mappings
|
||||
|
||||
fun findSourceIndex(sourceUrls: List<Url>, sourceFile: VirtualFile?, resolver: Lazy<SourceFileResolver?>?, localFileUrlOnly: Boolean): Int
|
||||
|
||||
fun findSourceMappings(sourceUrls: List<Url>, sourceFile: VirtualFile?, resolver: Lazy<SourceFileResolver?>?, localFileUrlOnly: Boolean): Mappings? {
|
||||
val sourceIndex = findSourceIndex(sourceUrls, sourceFile, resolver, localFileUrlOnly)
|
||||
return if (sourceIndex >= 0) findSourceMappings(sourceIndex) else null
|
||||
}
|
||||
|
||||
fun getSourceLineByRawLocation(rawLine: Int, rawColumn: Int) = generatedMappings.get(rawLine, rawColumn)?.sourceLine ?: -1
|
||||
|
||||
fun findSourceIndex(sourceFile: VirtualFile, localFileUrlOnly: Boolean): Int
|
||||
|
||||
fun processSourceMappingsInLine(sourceIndex: Int, sourceLine: Int, mappingProcessor: MappingsProcessorInLine): Boolean
|
||||
|
||||
fun processSourceMappingsInLine(sourceUrls: List<Url>, sourceLine: Int, mappingProcessor: MappingsProcessorInLine, sourceFile: VirtualFile?, resolver: Lazy<SourceFileResolver?>?, localFileUrlOnly: Boolean): Boolean {
|
||||
val sourceIndex = findSourceIndex(sourceUrls, sourceFile, resolver, localFileUrlOnly)
|
||||
return sourceIndex >= 0 && processSourceMappingsInLine(sourceIndex, sourceLine, mappingProcessor)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class OneLevelSourceMap(override val outFile: String?,
|
||||
override val generatedMappings: Mappings,
|
||||
internal val sourceIndexToMappings: Array<MappingList?>,
|
||||
override val sourceResolver: SourceResolver,
|
||||
override val hasNameMappings: Boolean) : SourceMap {
|
||||
override val sources: Array<Url>
|
||||
get() = sourceResolver.canonicalizedUrls
|
||||
|
||||
fun getSourceLineByRawLocation(rawLine: Int, rawColumn: Int) = mappings.get(rawLine, rawColumn)?.sourceLine ?: -1
|
||||
|
||||
fun findMappingList(sourceUrls: List<Url>, sourceFile: VirtualFile?, resolver: NullableLazyValue<SourceResolver.Resolver>?): MappingList? {
|
||||
var mappings = sourceResolver.findMappings(sourceUrls, this, sourceFile)
|
||||
if (mappings == null && resolver != null) {
|
||||
mappings = resolver.value?.let { sourceResolver.findMappings(sourceFile, this, it) }
|
||||
override fun findSourceIndex(sourceUrls: List<Url>, sourceFile: VirtualFile?, resolver: Lazy<SourceFileResolver?>?, localFileUrlOnly: Boolean): Int {
|
||||
val index = sourceResolver.findSourceIndex(sourceUrls, sourceFile, localFileUrlOnly)
|
||||
if (index == -1 && resolver != null) {
|
||||
return resolver.value?.let { sourceResolver.findSourceIndex(sourceFile, it) } ?: -1
|
||||
}
|
||||
return mappings
|
||||
return index
|
||||
}
|
||||
|
||||
fun processMappingsInLine(sourceUrls: List<Url>,
|
||||
sourceLine: Int,
|
||||
mappingProcessor: MappingsProcessorInLine,
|
||||
sourceFile: VirtualFile?,
|
||||
resolver: NullableLazyValue<SourceResolver.Resolver>?): Boolean {
|
||||
val mappings = findMappingList(sourceUrls, sourceFile, resolver)
|
||||
return mappings != null && mappings.processMappingsInLine(sourceLine, mappingProcessor)
|
||||
}
|
||||
// returns SourceMappingList
|
||||
override fun findSourceMappings(sourceIndex: Int) = sourceIndexToMappings.get(sourceIndex)!!
|
||||
|
||||
fun getMappingsOrderedBySource(source: Int) = sourceIndexToMappings.get(source)!!
|
||||
override fun findSourceIndex(sourceFile: VirtualFile, localFileUrlOnly: Boolean) = sourceResolver.findSourceIndexByFile(sourceFile, localFileUrlOnly)
|
||||
|
||||
override fun processSourceMappingsInLine(sourceIndex: Int, sourceLine: Int, mappingProcessor: MappingsProcessorInLine): Boolean {
|
||||
return findSourceMappings(sourceIndex).processMappingsInLine(sourceLine, mappingProcessor)
|
||||
}
|
||||
}
|
||||
+17
-14
@@ -176,7 +176,7 @@ private fun parseMap(reader: JsonReaderEx,
|
||||
SourceMappingList(entries)
|
||||
}
|
||||
}
|
||||
return SourceMap(file, GeneratedMappingList(mappings), sourceToEntries, sourceResolverFactory(sources, sourcesContent), !names.isNullOrEmpty())
|
||||
return OneLevelSourceMap(file, GeneratedMappingList(mappings), sourceToEntries, sourceResolverFactory(sources, sourcesContent), !names.isNullOrEmpty())
|
||||
}
|
||||
|
||||
private fun readSourcePath(reader: JsonReaderEx) = PathUtil.toSystemIndependentName(StringUtil.nullize(reader.nextString().trim { it <= ' ' }))
|
||||
@@ -269,10 +269,10 @@ private fun readSources(reader: JsonReaderEx, sourceRoot: String?): List<String>
|
||||
}
|
||||
|
||||
private fun getMapping(reverseMappingsBySourceUrl: Array<MutableList<MappingEntry>?>, sourceIndex: Int): MutableList<MappingEntry> {
|
||||
var reverseMappings = reverseMappingsBySourceUrl[sourceIndex]
|
||||
var reverseMappings = reverseMappingsBySourceUrl.get(sourceIndex)
|
||||
if (reverseMappings == null) {
|
||||
reverseMappings = ArrayList<MappingEntry>()
|
||||
reverseMappingsBySourceUrl[sourceIndex] = reverseMappings
|
||||
reverseMappingsBySourceUrl.set(sourceIndex, reverseMappings)
|
||||
}
|
||||
return reverseMappings
|
||||
}
|
||||
@@ -289,11 +289,7 @@ private fun isSeparator(charIterator: CharSequenceIterator): Boolean {
|
||||
/**
|
||||
* Not mapped to a section in the original source.
|
||||
*/
|
||||
private open class UnmappedEntry(line: Int, column: Int) : MappingEntry {
|
||||
override val generatedColumn = column
|
||||
|
||||
override val generatedLine = line
|
||||
|
||||
private data class UnmappedEntry(override val generatedLine: Int, override val generatedColumn: Int) : MappingEntry {
|
||||
override val sourceLine = UNMAPPED
|
||||
|
||||
override val sourceColumn = UNMAPPED
|
||||
@@ -302,23 +298,30 @@ private open class UnmappedEntry(line: Int, column: Int) : MappingEntry {
|
||||
/**
|
||||
* Mapped to a section in the original source.
|
||||
*/
|
||||
private open class UnnamedEntry(line: Int, column: Int, override val source: Int, override val sourceLine: Int, override val sourceColumn: Int) : UnmappedEntry(line, column) {
|
||||
}
|
||||
private data class UnnamedEntry(override val generatedLine: Int,
|
||||
override val generatedColumn: Int,
|
||||
override val source: Int,
|
||||
override val sourceLine: Int,
|
||||
override val sourceColumn: Int) : MappingEntry
|
||||
|
||||
/**
|
||||
* Mapped to a section in the original source, and is associated with a name.
|
||||
*/
|
||||
private class NamedEntry(override val name: String, line: Int, column: Int, source: Int, sourceLine: Int, sourceColumn: Int) : UnnamedEntry(line, column, source, sourceLine, sourceColumn) {
|
||||
}
|
||||
private data class NamedEntry(override val name: String,
|
||||
override val generatedLine: Int,
|
||||
override val generatedColumn: Int,
|
||||
override val source: Int,
|
||||
override val sourceLine: Int,
|
||||
override val sourceColumn: Int) : MappingEntry
|
||||
|
||||
// java CharacterIterator is ugly, next() impl, so, we reinvent
|
||||
private class CharSequenceIterator(private val content: CharSequence) : CharIterator {
|
||||
private val length = content.length
|
||||
private var current = 0
|
||||
|
||||
override fun next() = content[current++]
|
||||
override fun next() = content.get(current++)
|
||||
|
||||
internal fun peek() = content[current]
|
||||
internal fun peek() = content.get(current)
|
||||
|
||||
override fun hasNext() = current < length
|
||||
}
|
||||
|
||||
+30
-31
@@ -40,7 +40,15 @@ fun SourceResolver(rawSources: List<String>,
|
||||
return SourceResolver(rawSources, sourceContents) { canonicalizeUrl(it, baseUrl, trimFileScheme, baseUrlIsFile) }
|
||||
}
|
||||
|
||||
interface SourceFileResolver {
|
||||
fun resolve(sourceFile: VirtualFile?, map: ObjectIntHashMap<Url>): Int
|
||||
}
|
||||
|
||||
class SourceResolver(private val rawSources: List<String>, internal val canonicalizedUrls: Array<Url>, private val sourceContents: List<String>?) {
|
||||
companion object {
|
||||
fun isAbsolute(path: String) = path.startsWith('/') || (SystemInfo.isWindows && (path.length > 2 && path[1] == ':'))
|
||||
}
|
||||
|
||||
private val canonicalizedUrlToSourceIndex: ObjectIntHashMap<Url> = if (SystemInfo.isFileSystemCaseSensitive) ObjectIntHashMap(rawSources.size) else ObjectIntHashMap(rawSources.size, Urls.getCaseInsensitiveUrlHashingStrategy())
|
||||
|
||||
init {
|
||||
@@ -49,10 +57,6 @@ class SourceResolver(private val rawSources: List<String>, internal val canonica
|
||||
}
|
||||
}
|
||||
|
||||
interface Resolver {
|
||||
fun resolve(sourceFile: VirtualFile?, map: ObjectIntHashMap<Url>): Int
|
||||
}
|
||||
|
||||
fun getSource(entry: MappingEntry): Url? {
|
||||
val index = entry.source
|
||||
return if (index < 0) null else canonicalizedUrls[index]
|
||||
@@ -81,59 +85,54 @@ class SourceResolver(private val rawSources: List<String>, internal val canonica
|
||||
return if (index < 0) null else rawSources[index]
|
||||
}
|
||||
|
||||
fun findMappings(sourceFile: VirtualFile?, sourceMap: SourceMap, resolver: Resolver): MappingList? {
|
||||
val index = resolver.resolve(sourceFile, canonicalizedUrlToSourceIndex)
|
||||
return if (index < 0) null else sourceMap.sourceIndexToMappings[index]
|
||||
}
|
||||
internal fun findSourceIndex(sourceFile: VirtualFile?, resolver: SourceFileResolver) = resolver.resolve(sourceFile, canonicalizedUrlToSourceIndex)
|
||||
|
||||
fun findMappings(sourceUrls: List<Url>, sourceMap: SourceMap, sourceFile: VirtualFile?): MappingList? {
|
||||
fun findSourceIndex(sourceUrls: List<Url>, sourceFile: VirtualFile?, localFileUrlOnly: Boolean): Int {
|
||||
for (sourceUrl in sourceUrls) {
|
||||
val index = canonicalizedUrlToSourceIndex.get(sourceUrl)
|
||||
if (index != -1) {
|
||||
return sourceMap.sourceIndexToMappings[index]
|
||||
return index
|
||||
}
|
||||
}
|
||||
|
||||
if (sourceFile != null) {
|
||||
findByFile(sourceMap, sourceFile)?.let {
|
||||
return it
|
||||
}
|
||||
return findSourceIndexByFile(sourceFile, localFileUrlOnly)
|
||||
}
|
||||
return null
|
||||
return -1
|
||||
}
|
||||
|
||||
fun findByFile(sourceMap: SourceMap, sourceFile: VirtualFile): MappingList? {
|
||||
var index = canonicalizedUrlToSourceIndex.get(Urls.newFromVirtualFile(sourceFile).trimParameters())
|
||||
if (index != -1) {
|
||||
return sourceMap.sourceIndexToMappings[index]
|
||||
internal fun findSourceIndexByFile(sourceFile: VirtualFile, localFileUrlOnly: Boolean): Int {
|
||||
if (!localFileUrlOnly) {
|
||||
val index = canonicalizedUrlToSourceIndex.get(Urls.newFromVirtualFile(sourceFile).trimParameters())
|
||||
if (index != -1) {
|
||||
return index
|
||||
}
|
||||
}
|
||||
|
||||
if (sourceFile.isInLocalFileSystem) {
|
||||
// local file url - without "file" scheme, just path
|
||||
index = canonicalizedUrlToSourceIndex.get(Urls.newLocalFileUrl(sourceFile))
|
||||
if (index != -1) {
|
||||
return sourceMap.sourceIndexToMappings[index]
|
||||
}
|
||||
if (!sourceFile.isInLocalFileSystem) {
|
||||
return -1
|
||||
}
|
||||
|
||||
// local file url - without "file" scheme, just path
|
||||
val index = canonicalizedUrlToSourceIndex.get(Urls.newLocalFileUrl(sourceFile))
|
||||
if (index != -1) {
|
||||
return index
|
||||
}
|
||||
|
||||
// ok, search by canonical path
|
||||
val canonicalFile = sourceFile.canonicalFile
|
||||
if (canonicalFile != null && canonicalFile != sourceFile) {
|
||||
for (i in canonicalizedUrls.indices) {
|
||||
val url = canonicalizedUrls[i]
|
||||
val url = canonicalizedUrls.get(i)
|
||||
if (Urls.equalsIgnoreParameters(url, canonicalFile)) {
|
||||
return sourceMap.sourceIndexToMappings[i]
|
||||
return i
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
return -1
|
||||
}
|
||||
|
||||
fun getUrlIfLocalFile(entry: MappingEntry) = canonicalizedUrls.getOrNull(entry.source)?.let { if (it.isInLocalFileSystem) it else null }
|
||||
|
||||
companion object {
|
||||
fun isAbsolute(path: String) = path.firstOrNull() == '/' || (SystemInfo.isWindows && (path.length > 2 && path[1] == ':'))
|
||||
}
|
||||
}
|
||||
|
||||
fun canonicalizePath(url: String, baseUrl: Url, baseUrlIsFile: Boolean): String {
|
||||
|
||||
@@ -86,13 +86,11 @@ abstract class LineBreakpointManager(internal val debugProcess: DebugProcessImpl
|
||||
}
|
||||
else {
|
||||
vmBreakpoints = IDE_TO_VM_BREAKPOINTS_KEY.get(vm)?.remove(breakpoint) ?: return nullPromise()
|
||||
if (!vmBreakpoints.isEmpty()) {
|
||||
for (vmBreakpoint in vmBreakpoints) {
|
||||
vmToIdeBreakpoints.remove(vmBreakpoint, breakpoint)
|
||||
if (vmToIdeBreakpoints.containsKey(vmBreakpoint)) {
|
||||
// we must not remove vm breakpoint - it is used for another ide breakpoints
|
||||
return nullPromise()
|
||||
}
|
||||
for (vmBreakpoint in vmBreakpoints) {
|
||||
vmToIdeBreakpoints.remove(vmBreakpoint, breakpoint)
|
||||
if (vmToIdeBreakpoints.containsKey(vmBreakpoint)) {
|
||||
// we must not remove vm breakpoint - it is used for another ide breakpoints
|
||||
return nullPromise()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -23,7 +23,7 @@ import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiNamedElement
|
||||
import gnu.trove.THashMap
|
||||
import org.jetbrains.debugger.sourcemap.MappingEntry
|
||||
import org.jetbrains.debugger.sourcemap.MappingList
|
||||
import org.jetbrains.debugger.sourcemap.Mappings
|
||||
import org.jetbrains.debugger.sourcemap.SourceMap
|
||||
import org.jetbrains.rpc.LOG
|
||||
|
||||
@@ -34,7 +34,7 @@ private val OPERATOR_TRIMMER = CharMatcher.INVISIBLE.or(CharMatcher.anyOf(S1))
|
||||
val NAME_TRIMMER = CharMatcher.INVISIBLE.or(CharMatcher.anyOf(S1 + ".&:"))
|
||||
|
||||
// generateVirtualFile only for debug purposes
|
||||
open class NameMapper(private val document: Document, private val transpiledDocument: Document, private val sourceMappings: MappingList, protected val sourceMap: SourceMap, private val transpiledFile: VirtualFile? = null) {
|
||||
open class NameMapper(private val document: Document, private val transpiledDocument: Document, private val sourceMappings: Mappings, protected val sourceMap: SourceMap, private val transpiledFile: VirtualFile? = null) {
|
||||
var rawNameToSource: MutableMap<String, String>? = null
|
||||
private set
|
||||
|
||||
@@ -50,7 +50,7 @@ open class NameMapper(private val document: Document, private val transpiledDocu
|
||||
return null
|
||||
}
|
||||
|
||||
val sourceEntry = sourceMappings.get(sourceEntryIndex)
|
||||
val sourceEntry = sourceMappings.getByIndex(sourceEntryIndex)
|
||||
val next = sourceMappings.getNextOnTheSameLine(sourceEntryIndex, false)
|
||||
if (next != null && sourceMappings.getColumn(next) == sourceMappings.getColumn(sourceEntry)) {
|
||||
warnSeveralMapping(identifierOrNamedElement)
|
||||
@@ -98,7 +98,7 @@ fun warnSeveralMapping(element: PsiElement) {
|
||||
|
||||
private fun getGeneratedName(document: Document, sourceMap: SourceMap, sourceEntry: MappingEntry): CharSequence {
|
||||
val lineStartOffset = document.getLineStartOffset(sourceEntry.generatedLine)
|
||||
val nextGeneratedMapping = sourceMap.mappings.getNextOnTheSameLine(sourceEntry)
|
||||
val nextGeneratedMapping = sourceMap.generatedMappings.getNextOnTheSameLine(sourceEntry)
|
||||
val endOffset: Int
|
||||
if (nextGeneratedMapping == null) {
|
||||
endOffset = document.getLineEndOffset(sourceEntry.generatedLine)
|
||||
|
||||
+1
@@ -11,6 +11,7 @@ import com.intellij.util.containers.ObjectIntHashMap
|
||||
|
||||
abstract class FileUrlMapper {
|
||||
companion object {
|
||||
@JvmField
|
||||
val EP_NAME = ExtensionPointName.create<FileUrlMapper>("com.jetbrains.fileUrlMapper")
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user