/// <summary> /// Finds the mapping for a generated position to the source position, /// and, if provided by the source map, source file name and source function names. /// </summary> /// <param name="line">Line in the generated JavaScript file</param> /// <param name="column">Column in the generated JavaScript file</param> /// <returns></returns> public SourceMapping SourceMappingFor(uint line, uint column) { var mockItem = new SourceMapping() { GeneratedLine = line, GeneratedColumn = column }; var position = generatedMappings.BinarySearch(mockItem, new CompareGeneratedItems()); if (position < 0) { return(generatedMappings[Math.Min(~position, generatedMappings.Count - 1)]); } else { return(generatedMappings[position]); } }
void processSourceMap() { if (sourceMap.version != SOURCE_MAP_VERSION) { throw new SourceMapParsingException("Invalid source map: version != 3"); } var numSources = sourceMap.sources.Length; var numNames = sourceMap.names.Length; var generatedMappings = new List <SourceMapping>(); uint generatedLine = 0; uint previousOriginalLine = 0; uint previousOriginalColumn = 0; uint previousSource = 0; uint previousName = 0; foreach (string line in sourceMap.mappings.Split(';')) { generatedLine += 1; uint previousGeneratedColumn = 0; foreach (string segment in line.Split(',')) { var segmentLength = segment.Length; var fields = new List <int>(); var characterIndex = 0; while (characterIndex < segmentLength) { var field = Base64VLQConverter.Decode(segment.Substring(characterIndex, segmentLength - characterIndex)); fields.Add(field.Result); characterIndex += field.CharactersRead; } var numFields = fields.Count; if (numFields < 1) { continue; } if (numFields == 2) { throw new SourceMapParsingException("Found a source, but no line and column"); } if (numFields == 3) { throw new SourceMapParsingException("Found a source and line, but no column"); } previousGeneratedColumn = (uint)(previousGeneratedColumn + fields[0]); var mapping = new SourceMapping() { GeneratedLine = generatedLine, GeneratedColumn = previousGeneratedColumn }; if (numFields < 2) { mapping.SourceFile = ""; mapping.SourceName = ""; } else { previousSource = (uint)(previousSource + fields[1]); if (previousSource >= 0 && previousSource < numSources) { mapping.SourceFile = sourceMap.sources[previousSource]; } else { throw new SourceMapParsingException($"Invalid source map: reference to source index {previousSource} when source list length is {numSources}"); } previousOriginalLine = (uint)(previousOriginalLine + fields[2]); mapping.SourceLine = previousOriginalLine + 1; previousOriginalColumn = (uint)(previousOriginalColumn + fields[3]); mapping.SourceColumn = previousOriginalColumn; if (numFields > 4) { previousName = (uint)(previousName + fields[4]); if (previousName >= 0 && previousName < numNames) { mapping.SourceName = sourceMap.names[previousName]; } else { throw new SourceMapParsingException($"Invalid source map: reference to name index {previousName} when name list length is {numNames}"); } } else { mapping.SourceName = ""; } } generatedMappings.Add(mapping); } } if (generatedMappings.Count < 1) { throw new SourceMapParsingException("Source map contains no mappings"); } generatedMappings.Sort(new CompareGeneratedItems()); this.generatedMappings = generatedMappings; }