UNPKG

@remotex-labs/xmap

Version:

A library with a sourcemap parser and TypeScript code formatter for the CLI

424 lines (423 loc) 15.7 kB
import type * as ts from "typescript"; /** * Defines the color scheme for syntax highlighting different code elements. * * @interface HighlightSchemeInterface * * @property enumColor - Color code for enum declarations and references * @property typeColor - Color code for type annotations and primitive types * @property classColor - Color code for class declarations and references * @property stringColor - Color code for string literals and template strings * @property keywordColor - Color code for language keywords * @property commentColor - Color code for comments (single-line and multi-line) * @property functionColor - Color code for function declarations and calls * @property variableColor - Color code for variable declarations and references * @property interfaceColor - Color code for interface declarations and references * @property parameterColor - Color code for function and method parameters * @property getAccessorColor - Color code for getter accessor methods * @property numericLiteralColor - Color code for numeric literals * @property methodSignatureColor - Color code for method signatures in interfaces * @property regularExpressionColor - Color code for regular expression literals * @property propertyAssignmentColor - Color code for property assignments in object literals * @property propertyAccessExpressionColor - Color code for property access expressions * @property expressionWithTypeArgumentsColor - Color code for type arguments in expressions * * @example * ```ts * const darkTheme: HighlightSchemeInterface = { * enumColor: Colors.cyan, * typeColor: Colors.blue, * classColor: Colors.yellow, * // ...other color definitions * }; * ``` * * @since 1.0.0 */ export interface HighlightSchemeInterface { enumColor: string; typeColor: string; classColor: string; stringColor: string; keywordColor: string; commentColor: string; functionColor: string; variableColor: string; interfaceColor: string; parameterColor: string; getAccessorColor: string; numericLiteralColor: string; methodSignatureColor: string; regularExpressionColor: string; propertyAssignmentColor: string; propertyAccessExpressionColor: string; expressionWithTypeArgumentsColor: string; } /** * Represents a segment of source code to be highlighted with specific styling. * * @interface HighlightNodeSegmentInterface * * @property start - The starting character position of the segment in the source text * @property end - The ending character position of the segment in the source text * @property color - The color or style code to apply to this segment * @property reset - The reset code that returns formatting to normal after this segment * * @remarks * Segments are the fundamental units of the highlighting system. * Each segment represents a portion of text that should receive specific styling. * When the source code is processed for display, * these segments are used to insert the appropriate color/style codes at the correct positions. * * The highlighter maintains a collection of these segments and applies them * in position order to create the complete highlighted output. * * @example * ```ts * const keywordSegment: HighlightNodeSegmentInterface = { * start: 0, * end: 6, * color: '\x1b[34m', // Blue for the keyword "import" * reset: '\x1b[0m' // Reset to default * }; * ``` * * @see HighlightSchemeInterface * @see addSegment * * @since 1.0.0 */ export interface HighlightNodeSegmentInterface { end: number; start: number; color: string; reset: string; } /** * An enum containing ANSI escape sequences for various colors * * @remarks * This enum is primarily intended for terminal output and won't work directly in JavaScript for web development. * It defines color codes for various colors and a reset code to return to the default text color. * * @example * ```ts * console.log(`${Colors.red}This text will be red in the terminal.${Colors.reset}`); * ``` * * @since 1.0.0 */ export declare const enum Colors { reset = "\u001B[0m", gray = "\u001B[38;5;243m", darkGray = "\u001B[38;5;238m", lightCoral = "\u001B[38;5;203m", lightOrange = "\u001B[38;5;215m", oliveGreen = "\u001B[38;5;149m", burntOrange = "\u001B[38;5;208m", lightGoldenrodYellow = "\u001B[38;5;221m", lightYellow = "\u001B[38;5;230m", canaryYellow = "\u001B[38;5;227m", deepOrange = "\u001B[38;5;166m", lightGray = "\u001B[38;5;252m", brightPink = "\u001B[38;5;197m" } /** * Class responsible for applying semantic highlighting to a source code string based on a given color scheme * * @remarks * Processes TypeScript AST nodes and applies color formatting to different code elements * according to the provided color scheme. * * @example * ```ts * const sourceFile = ts.createSourceFile('example.ts', code, ts.ScriptTarget.Latest); * const highlighter = new CodeHighlighter(sourceFile, code, customScheme); * highlighter.parseNode(sourceFile); * const highlightedCode = highlighter.highlight(); * ``` * * @since 1.0.0 */ export declare class CodeHighlighter { private sourceFile; private code; private schema; /** * A Map of segments where the key is a combination of start and end positions. * * @remarks * This structure ensures unique segments and allows for fast lookups and updates. * * @see HighlightNodeSegmentInterface * @since 1.0.0 */ private segments; /** * Creates an instance of the CodeHighlighter class. * * @param sourceFile - The TypeScript AST node representing the source file * @param code - The source code string to be highlighted * @param schema - The color scheme used for highlighting different elements in the code * * @since 1.0.0 */ constructor(sourceFile: ts.Node, code: string, schema: HighlightSchemeInterface); /** * Parses a TypeScript AST node and processes its comments to identify segments that need highlighting. * * @param node - The TypeScript AST node to be parsed * * @since 1.0.0 */ parseNode(node: ts.Node): void; /** * Generates a string with highlighted code segments based on the provided color scheme. * * @returns The highlighted code as a string, with ANSI color codes applied to the segments * * @remarks * This method processes the stored segments, applies the appropriate colors to each segment, * and returns the resulting highlighted code as a single string. * * @since 1.0.0 */ highlight(): string; /** * Extracts a text segment from the source code using position indices. * * @param start - The starting index position in the source text * @param end - The ending index position in the source text (optional) * @returns The substring of source text between the start and end positions * * @remarks * This utility method provides access to specific portions of the source code * based on character positions. When the end parameter is omitted, the extraction * will continue to the end of the source text. * * This method is typically used during the highlighting process to access the * actual text content that corresponds to syntax nodes or other text ranges * before applying formatting. * * @example * ```ts * // Extract a variable name * const variableName = this.getSegmentSource(10, 15); * * // Extract from a position to the end of source * const remaining = this.getSegmentSource(100); * ``` * * @see addSegment * @see highlight * * @since 1.0.0 */ private getSegmentSource; /** * Registers a text segment for syntax highlighting with specified style information. * * @param start - The starting position of the segment in the source text * @param end - The ending position of the segment in the source text * @param color - The color code to apply to this segment * @param reset - The color reset code to apply after the segment (defaults to the standard reset code) * * @remarks * This method creates a unique key for each segment based on its position and stores the segment information in a map. * Each segment contains its position information, styling code, * and reset code which will later be used during the highlighting process. * * If multiple segments are added with the same positions, the later additions will * overwrite earlier ones due to the map's key-based storage. * * @example * ```ts * // Highlight a variable name in red * this.addSegment(10, 15, Colors.red); * * // Highlight a keyword with custom color and reset * this.addSegment(20, 26, Colors.blue, Colors.customReset); * ``` * * @see Colors * @see processNode * * @since 1.0.0 */ private addSegment; /** * Processes and highlights comments associated with a TypeScript AST node. * * @param node - The TypeScript AST node whose comments are to be processed * * @remarks * This method identifies both leading and trailing comments associated with the given node * and adds them to the highlighting segments. * The comments are extracted from the full source text using TypeScript's utility functions * and are highlighted using the color specified * in the schema's commentColor property. * * Leading comments appear before the node, while trailing comments appear after it. * Both types are processed with the same highlighting style. * * @example * ```ts * // For a node that might have comments like: * // This is a leading comment * const x = 5; // This is a trailing comment * * this.processComments(someNode); * // Both comments will be added to segments with the comment color * ``` * * @see addSegment * @see ts.getLeadingCommentRanges * @see ts.getTrailingCommentRanges * * @since 1.0.0 */ private processComments; /** * Processes TypeScript keywords and primitive type references in an AST node for syntax highlighting. * * @param node - The TypeScript AST node to be processed for keywords * * @remarks * This method handles two categories of tokens that require special highlighting: * * 1. Primitive type references: Highlights references to built-in types like `null`, * `void`, `string`, `number`, `boolean`, and `undefined` using the type color. * * 2. TypeScript keywords: Identifies any node whose kind falls within the TypeScript * keyword range (between FirstKeyword and LastKeyword) and highlights it using * the keyword color. * * Each identified token is added to the segments collection with appropriate position * and color information. * * @example * ```ts * // Inside syntax highlighting process * this.processKeywords(someNode); * // If the node represents a keyword like 'const' or a primitive type like 'string', * // it will be added to the segments with the appropriate color * ``` * * @see addSegment * @see ts.SyntaxKind * * @since 1.0.0 */ private processKeywords; /** * Processes identifier nodes and applies appropriate syntax highlighting based on their context. * * @param node - The TypeScript AST node representing the identifier to be processed * * @remarks * This method determines the appropriate color for an identifier by examining its parent node's kind. * Different colors are applied based on the identifier's role in the code: * - Enum members use enumColor * - Interface names use interfaceColor * - Class names use classColor * - Function and method names use functionColor * - Parameters use parameterColor * - Variables and properties use variableColor * - Types use typeColor * - And more specialized cases for other syntax kinds * * Special handling is applied to property access expressions to differentiate between * the object being accessed and the property being accessed. * * @example * ```ts * // Inside the CodeHighlighter class * const identifierNode = getIdentifierNode(); // Get some identifier node * this.processIdentifier(identifierNode); * // The identifier is now added to segments with appropriate color based on its context * ``` * * @see addSegment * @see HighlightSchemeInterface * * @since 1.0.0 */ private processIdentifier; /** * Processes a TypeScript template expression and adds highlighting segments for its literal parts. * * @param templateExpression - The TypeScript template expression to be processed * * @remarks * This method adds color segments for both the template head and each template span's literal part. * All template string components are highlighted using the color defined in the schema's stringColor. * * @example * ```ts * // Given a template expression like: `Hello ${name}` * this.processTemplateExpression(templateNode); * // Both "Hello " and the closing part after the expression will be highlighted * ``` * * @see addSegment * * @since 1.0.0 */ private processTemplateExpression; /** * Processes a TypeScript AST node and adds highlighting segments based on the node's kind. * * @param node - The TypeScript AST node to be processed * * @remarks * This method identifies the node's kind and applies the appropriate color for highlighting. * It handles various syntax kinds including literals (string, numeric, regular expressions), * template expressions, identifiers, and type references. * For complex node types like template expressions and identifiers, it delegates to specialized processing methods. * * @throws Error - When casting to TypeParameterDeclaration fails for non-compatible node kinds * * @example * ```ts * // Inside the CodeHighlighter class * const node = sourceFile.getChildAt(0); * this.processNode(node); * // Node is now added to the segments map with appropriate colors * ``` * * @see processTemplateExpression * @see processIdentifier * * @since 1.0.0 */ private processNode; } /** * Applies semantic highlighting to the provided code string using the specified color scheme. * * @param code - The source code to be highlighted * @param schema - An optional partial schema defining the color styles for various code elements * * @returns A string with the code elements wrapped in the appropriate color styles * * @remarks * If no schema is provided, the default schema will be used. The function creates a TypeScript * source file from the provided code and walks through its AST to apply syntax highlighting. * * @example * ```ts * const code = 'const x: number = 42;'; * const schema = { * keywordColor: '\x1b[34m', // Blue * numberColor: '\x1b[31m', // Red * }; * const highlightedCode = highlightCode(code, schema); * console.log(highlightedCode); * ``` * * @see CodeHighlighter * @see HighlightSchemeInterface * * @since 1.0.0 */ export declare function highlightCode(code: string, schema?: Partial<HighlightSchemeInterface>): string;