(message: string, category?: string, colorText = (s: string) => s)
| 1872 | // Logs a message back to the editor. Does not add its own newlines, you must |
| 1873 | // provide them! |
| 1874 | protected logToUser(message: string, category?: string, colorText = (s: string) => s) { |
| 1875 | |
| 1876 | // If we get a multi-line message that contains an error/stack trace, process each |
| 1877 | // line individually, so we can attach location metadata to individual lines. |
| 1878 | const isMultiLine = message.trimRight().includes("\n"); |
| 1879 | if (isMultiLine && mayContainStackFrame(message)) { |
| 1880 | message.split("\n").forEach((line) => this.logToUser(`${line}\n`, category)); |
| 1881 | return; |
| 1882 | } |
| 1883 | |
| 1884 | // Extract stack frames from the message so we can do nicer formatting of them. |
| 1885 | const frame = parseStackFrame(message); |
| 1886 | |
| 1887 | const output = new OutputEvent(`${applyColor(message, colorText)}`, category) as OutputEvent & DebugProtocol.OutputEvent; |
| 1888 | const mayBeAsyncMarker = (output.body.output.trim().startsWith("<async") && output.body.output.trim().endsWith(">")) |
| 1889 | || (output.body.output.trim().startsWith("===== asynchronous gap ===")); |
| 1890 | |
| 1891 | // If the output line looks like a stack frame with users code, attempt to link it up to make |
| 1892 | // it clickable. |
| 1893 | if (frame) { |
| 1894 | let sourcePath: string | undefined = this.convertVMUriToSourcePath(frame.sourceUri); |
| 1895 | if (sourcePath && !path.isAbsolute(sourcePath) && this.cwd) |
| 1896 | sourcePath = path.join(this.cwd, sourcePath); |
| 1897 | const canShowSource = sourcePath && sourcePath !== frame.sourceUri && fs.existsSync(sourcePath); |
| 1898 | const shortName = this.formatUriForShortDisplay(frame.sourceUri); |
| 1899 | const source = canShowSource ? new Source(shortName, sourcePath, undefined, undefined, undefined) : undefined; |
| 1900 | |
| 1901 | let text = message.trim(); |
| 1902 | if (source) { |
| 1903 | output.body.source = source; |
| 1904 | output.body.line = frame.line || 1; |
| 1905 | output.body.column = frame.col || 1; |
| 1906 | // Replace the output to only the text part to avoid the duplicated uri. |
| 1907 | text = frame.text; |
| 1908 | } |
| 1909 | |
| 1910 | // Colour based on whether it's framework code or not. |
| 1911 | const isExternalCode = this.isSdkLibrary(frame.sourceUri) || this.isExternalLibrary(frame.sourceUri); |
| 1912 | |
| 1913 | // Fade out any stack frames for external code. |
| 1914 | const colouredText = frame.isStackFrame && isExternalCode ? applyColor(text, faint) : text; |
| 1915 | output.body.output = `${colouredText}\n`; |
| 1916 | } else if (mayBeAsyncMarker) { |
| 1917 | output.body.output = `${applyColor(output.body.output.trimRight(), faint)}\n`; |
| 1918 | } |
| 1919 | |
| 1920 | this.sendEvent(output); |
| 1921 | } |
| 1922 | } |
| 1923 | |
| 1924 | export interface InstanceWithEvaluateName extends VMInstanceRef { |
nothing calls this directly
no test coverage detected