Ejemplo n.º 1
0
        public static void Encode(StringBuilder sb, int value)
        {
            int vlq = VLQ.ToVLQSigned(value);

            do
            {
                int digit = (vlq & VLQ.BaseMask);
                vlq >>= VLQ.BaseShift;
                if (vlq > 0)
                {
                    digit |= VLQ.ContinuationBit;
                }
                sb.Append(VLQ.Base64Chars[digit]);
            }while (vlq > 0);
        }
Ejemplo n.º 2
0
        public void Write(Stream stream, string generatedFilePath, string sourceFilePathRoot)
        {
            if (string.IsNullOrEmpty(sourceFilePathRoot) == false &&
                (sourceFilePathRoot.EndsWith("\\") || sourceFilePathRoot.EndsWith("/")) == false)
            {
                sourceFilePathRoot = sourceFilePathRoot + Path.DirectorySeparatorChar;
            }

            // Gather sources
            var sources      = new List <string>();
            var sourcesIndex = new Dictionary <string, int>();

            foreach (var mappingEntry in Mappings)
            {
                string filepath = AbsolutePath(mappingEntry.Source.Name);
                if (sourcesIndex.ContainsKey(filepath))
                {
                    continue;
                }

                sourcesIndex.Add(filepath, sources.Count);
                string relativeFilePath = mappingEntry.Source.Name;
                if (string.IsNullOrEmpty(sourceFilePathRoot) == false)
                {
                    var rootUri = new UriBuilder(sourceFilePathRoot).Uri;
                    //Note(Maik): Path.MakeRelativeUri() requires the presence of a trailing slash in the
                    // 'this' URI.
                    relativeFilePath = rootUri.MakeRelativeUri(new UriBuilder(mappingEntry.Source.Name).Uri).ToString();
                }
                sources.Add(relativeFilePath);
            }

            // Build mappings
            var mappings            = new StringBuilder();
            var indices             = new StringBuilder();
            var columnInterpolation = new StringBuilder();

            bool newLine          = true;
            int  prevSourceLine   = 1;
            int  prevSourceColumn = 1;

            int prevGeneratedLine   = 1;
            int prevGeneratedColumn = 1;

            int prevSourcesIndex = 0;

            int prevCallerIndex = 0;

            foreach (var mappingEntry in Mappings)
            {
                int lineDiff = (mappingEntry.Generated.Line - prevGeneratedLine);
                for (int i = 0; i < lineDiff; ++i)
                {
                    mappings.Append(";");
                    indices.Append(";");
                    columnInterpolation.Append(";");
                }
                if (lineDiff > 0)
                {
                    prevGeneratedLine   = mappingEntry.Generated.Line;
                    prevGeneratedColumn = 1;
                    newLine             = true;
                }

                if (lineDiff == 0 && newLine == false)
                {
                    mappings.Append(",");
                    indices.Append(",");
                    columnInterpolation.Append(",");
                }

                // Field 1: "zero-based starting column of the line in the generated code"
                int generatedColumn = mappingEntry.Generated.Column;
                VLQ.Encode(mappings, generatedColumn - prevGeneratedColumn);
                prevGeneratedColumn = generatedColumn;

                // Field 2: "zero-based index into the sources list"
                int sourceIndex = sourcesIndex[AbsolutePath(mappingEntry.Source.Name)];
                VLQ.Encode(mappings, sourceIndex - prevSourcesIndex);
                prevSourcesIndex = sourceIndex;

                // Field 3: "zero-based starting line in the source"
                int sourceLine = mappingEntry.Source.Line;
                VLQ.Encode(mappings, sourceLine - prevSourceLine);
                prevSourceLine = sourceLine;

                // Field 4: "zero-based starting column of the line in the source"
                int sourceColumn = mappingEntry.Source.Column;
                VLQ.Encode(mappings, sourceColumn - prevSourceColumn);
                prevSourceColumn = sourceColumn;

                //
                //
                int callerIndex = mappingEntry.CallerIndex;
                if (callerIndex != -1)
                {
                    VLQ.Encode(indices, callerIndex - prevCallerIndex);
                    prevCallerIndex = callerIndex;
                }

                //
                //
                if ((mappingEntry.Features & EntryFeatures.ColumnInterpolation) != 0)
                {
                    VLQ.Encode(columnInterpolation, 1);
                }

                newLine = false;
            }

            // Build Callstack
            var callers = new StringBuilder();

            prevSourcesIndex = 0;
            prevSourceLine   = 1;
            prevSourceColumn = 1;
            int prevParentIndex = 0;

            foreach (var caller in Callers)
            {
                if (callers.Length > 0)
                {
                    callers.Append(";");
                }

                // Field 1: "zero-based index into the sources list"
                int sourceIndex = sourcesIndex[AbsolutePath(caller.Source.Name)];
                VLQ.Encode(callers, sourceIndex - prevSourcesIndex);
                prevSourcesIndex = sourceIndex;

                // Field 2: "zero-based starting line in the source"
                int sourceLine = caller.Source.Line;
                VLQ.Encode(callers, sourceLine - prevSourceLine);
                prevSourceLine = sourceLine;

                // Field 3: "zero-based starting column of the line in the source"
                int sourceColumn = caller.Source.Column;
                VLQ.Encode(callers, sourceColumn - prevSourceColumn);
                prevSourceColumn = sourceColumn;

                // Field 4: "zero-based index of parent caller"
                int parentIndex = caller.ParentIndex;
                if (parentIndex != -1)
                {
                    VLQ.Encode(callers, parentIndex - prevParentIndex);
                    prevParentIndex = parentIndex;
                }
            }

            var callstack = new CallstackExtension {
                Callers = callers.ToString(), Indices = indices.ToString()
            };
            var graph = new SourceMapGraph
            {
                File                = new UriBuilder(generatedFilePath).Path,
                SourceRoot          = string.IsNullOrEmpty(sourceFilePathRoot) ? string.Empty : new UriBuilder(sourceFilePathRoot).Path,
                Sources             = sources,
                Mappings            = mappings.ToString(),
                Callstack           = callstack,
                ColumnInterpolation = columnInterpolation.ToString()
            };
            var serializer = new DataContractJsonSerializer(typeof(SourceMapGraph));

            serializer.WriteObject(stream, graph);
        }