main
ts 98 lines 2.5 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 import {Monaco} from '@monaco-editor/react';
9 import {
10 CompilerDiagnostic,
11 CompilerErrorDetail,
12 ErrorSeverity,
13 } from 'babel-plugin-react-compiler';
14 import {MarkerSeverity, type editor} from 'monaco-editor';
15
16 function mapReactCompilerSeverityToMonaco(
17 level: ErrorSeverity,
18 monaco: Monaco,
19 ): MarkerSeverity {
20 switch (level) {
21 case ErrorSeverity.Todo:
22 return monaco.MarkerSeverity.Warning;
23 default:
24 return monaco.MarkerSeverity.Error;
25 }
26 }
27
28 function mapReactCompilerDiagnosticToMonacoMarker(
29 detail: CompilerErrorDetail | CompilerDiagnostic,
30 monaco: Monaco,
31 source: string,
32 ): editor.IMarkerData | null {
33 const loc = detail.primaryLocation();
34 if (loc == null || typeof loc === 'symbol') {
35 return null;
36 }
37 const severity = mapReactCompilerSeverityToMonaco(detail.severity, monaco);
38 let message = detail.printErrorMessage(source, {eslint: true});
39 return {
40 severity,
41 message,
42 startLineNumber: loc.start.line,
43 startColumn: loc.start.column + 1,
44 endLineNumber: loc.end.line,
45 endColumn: loc.end.column + 1,
46 };
47 }
48
49 type ReactCompilerMarkerConfig = {
50 monaco: Monaco;
51 model: editor.ITextModel;
52 details: Array<CompilerErrorDetail | CompilerDiagnostic>;
53 source: string;
54 };
55 let decorations: Array<string> = [];
56 export function renderReactCompilerMarkers({
57 monaco,
58 model,
59 details,
60 source,
61 }: ReactCompilerMarkerConfig): void {
62 const markers: Array<editor.IMarkerData> = [];
63 for (const detail of details) {
64 const marker = mapReactCompilerDiagnosticToMonacoMarker(
65 detail,
66 monaco,
67 source,
68 );
69 if (marker == null) {
70 continue;
71 }
72 markers.push(marker);
73 }
74 if (markers.length > 0) {
75 monaco.editor.setModelMarkers(model, 'owner', markers);
76 const newDecorations = markers.map(marker => {
77 return {
78 range: new monaco.Range(
79 marker.startLineNumber,
80 marker.startColumn,
81 marker.endLineNumber,
82 marker.endColumn,
83 ),
84 options: {
85 isWholeLine: true,
86 glyphMarginClassName: 'bg-red-300',
87 },
88 };
89 });
90 decorations = model.deltaDecorations(decorations, newDecorations);
91 } else {
92 monaco.editor.setModelMarkers(model, 'owner', []);
93 decorations = model.deltaDecorations(
94 model.getAllDecorations().map(d => d.id),
95 [],
96 );
97 }
98 }