function _renderLine(input) {
        var fontIsMonospace = input.fontIsMonospace;
        var containsForeignElements = input.containsForeignElements;
        var lineContent = input.lineContent;
        var len = input.len;
        var isOverflowing = input.isOverflowing;
        var parts = input.parts;
        var tabSize = input.tabSize;
        var containsRTL = input.containsRTL;
        var spaceWidth = input.spaceWidth;
        var renderWhitespace = input.renderWhitespace;
        var renderControlCharacters = input.renderControlCharacters;
        var characterMapping = new CharacterMapping(len + 1, parts.length);
        var charIndex = 0;
        var tabsCharDelta = 0;
        var charOffsetInPart = 0;
        var out = '<span>';
        for (var partIndex = 0, tokensLen = parts.length; partIndex < tokensLen; partIndex++) {
            var part = parts[partIndex];
            var partEndIndex = part.endIndex;
            var partType = part.type;
            var partRendersWhitespace = (renderWhitespace !== 0 /* None */ && (partType.indexOf('vs-whitespace') >= 0));
            charOffsetInPart = 0;
            if (partRendersWhitespace) {
                var partContentCnt = 0;
                var partContent = '';
                for (; charIndex < partEndIndex; charIndex++) {
                    characterMapping.setPartData(charIndex, partIndex, charOffsetInPart);
                    var charCode = lineContent.charCodeAt(charIndex);
                    if (charCode === 9 /* Tab */) {
                        var insertSpacesCount = tabSize - (charIndex + tabsCharDelta) % tabSize;
                        tabsCharDelta += insertSpacesCount - 1;
                        charOffsetInPart += insertSpacesCount - 1;
                        if (insertSpacesCount > 0) {
                            partContent += '&rarr;';
                            partContentCnt++;
                            insertSpacesCount--;
                        }
                        while (insertSpacesCount > 0) {
                            partContent += '&nbsp;';
                            partContentCnt++;
                            insertSpacesCount--;
                        }
                    }
                    else {
                        // must be CharCode.Space
                        partContent += '&middot;';
                        partContentCnt++;
                    }
                    charOffsetInPart++;
                }
                characterMapping.setPartLength(partIndex, partContentCnt);
                if (fontIsMonospace || containsForeignElements) {
                    out += "<span class=\"" + partType + "\">" + partContent + "</span>";
                }
                else {
                    out += "<span class=\"" + partType + "\" style=\"width:" + spaceWidth * partContentCnt + "px\">" + partContent + "</span>";
                }
            }
            else {
                var partContentCnt = 0;
                var partContent = '';
                for (; charIndex < partEndIndex; charIndex++) {
                    characterMapping.setPartData(charIndex, partIndex, charOffsetInPart);
                    var charCode = lineContent.charCodeAt(charIndex);
                    switch (charCode) {
                        case 9 /* Tab */:
                            var insertSpacesCount = tabSize - (charIndex + tabsCharDelta) % tabSize;
                            tabsCharDelta += insertSpacesCount - 1;
                            charOffsetInPart += insertSpacesCount - 1;
                            while (insertSpacesCount > 0) {
                                partContent += '&nbsp;';
                                partContentCnt++;
                                insertSpacesCount--;
                            }
                            break;
                        case 32 /* Space */:
                            partContent += '&nbsp;';
                            partContentCnt++;
                            break;
                        case 60 /* LessThan */:
                            partContent += '&lt;';
                            partContentCnt++;
                            break;
                        case 62 /* GreaterThan */:
                            partContent += '&gt;';
                            partContentCnt++;
                            break;
                        case 38 /* Ampersand */:
                            partContent += '&amp;';
                            partContentCnt++;
                            break;
                        case 0 /* Null */:
                            partContent += '&#00;';
                            partContentCnt++;
                            break;
                        case 65279 /* UTF8_BOM */:
                        case 8232 /* LINE_SEPARATOR_2028 */:
                            partContent += '\ufffd';
                            partContentCnt++;
                            break;
                        case 13 /* CarriageReturn */:
                            // zero width space, because carriage return would introduce a line break
                            partContent += '&#8203';
                            partContentCnt++;
                            break;
                        default:
                            if (renderControlCharacters && charCode < 32) {
                                partContent += String.fromCharCode(9216 + charCode);
                                partContentCnt++;
                            }
                            else {
                                partContent += String.fromCharCode(charCode);
                                partContentCnt++;
                            }
                    }
                    charOffsetInPart++;
                }
                characterMapping.setPartLength(partIndex, partContentCnt);
                if (containsRTL) {
                    out += "<span dir=\"ltr\" class=\"" + partType + "\">" + partContent + "</span>";
                }
                else {
                    out += "<span class=\"" + partType + "\">" + partContent + "</span>";
                }
            }
        }
        // When getting client rects for the last character, we will position the
        // text range at the end of the span, insteaf of at the beginning of next span
        characterMapping.setPartData(len, parts.length - 1, charOffsetInPart);
        if (isOverflowing) {
            out += "<span>&hellip;</span>";
        }
        out += '</span>';
        return new RenderLineOutput(characterMapping, out, containsRTL, containsForeignElements);
    }
This function is on purpose not split up into multiple functions to allow runtime type inference (i.e. performance reasons).
Notice how all the needed data is fully resolved and passed in (i.e. no other calls).