1use lsp_types::{SemanticToken, SemanticTokenType, SemanticTokensLegend};
11use sqruff_lib::core::linter::core::Linter;
12use sqruff_lib_core::dialects::syntax::SyntaxKind;
13use sqruff_lib_core::parser::segments::{ErasedSegment, Tables};
14
15#[derive(Clone, Copy, PartialEq, Eq, Debug)]
21pub(crate) enum Highlight {
22 Keyword,
23 String,
24 Number,
25 Comment,
26 Operator,
27 Function,
28 Type,
29 Variable,
30 Parameter,
31 Property,
32 Macro,
33}
34
35const HIGHLIGHTS: [Highlight; 11] = [
37 Highlight::Keyword,
38 Highlight::String,
39 Highlight::Number,
40 Highlight::Comment,
41 Highlight::Operator,
42 Highlight::Function,
43 Highlight::Type,
44 Highlight::Variable,
45 Highlight::Parameter,
46 Highlight::Property,
47 Highlight::Macro,
48];
49
50impl Highlight {
51 fn token_type(self) -> u32 {
53 HIGHLIGHTS.iter().position(|&h| h == self).unwrap() as u32
54 }
55
56 fn semantic_token_type(self) -> SemanticTokenType {
57 match self {
58 Highlight::Keyword => SemanticTokenType::KEYWORD,
59 Highlight::String => SemanticTokenType::STRING,
60 Highlight::Number => SemanticTokenType::NUMBER,
61 Highlight::Comment => SemanticTokenType::COMMENT,
62 Highlight::Operator => SemanticTokenType::OPERATOR,
63 Highlight::Function => SemanticTokenType::FUNCTION,
64 Highlight::Type => SemanticTokenType::TYPE,
65 Highlight::Variable => SemanticTokenType::VARIABLE,
66 Highlight::Parameter => SemanticTokenType::PARAMETER,
67 Highlight::Property => SemanticTokenType::PROPERTY,
68 Highlight::Macro => SemanticTokenType::MACRO,
69 }
70 }
71}
72
73pub fn legend() -> SemanticTokensLegend {
76 SemanticTokensLegend {
77 token_types: HIGHLIGHTS.iter().map(|h| h.semantic_token_type()).collect(),
78 token_modifiers: Vec::new(),
79 }
80}
81
82pub(crate) fn classify(kind: SyntaxKind) -> Option<Highlight> {
85 use SyntaxKind::*;
86
87 let highlight = match kind {
88 Keyword | BareFunction | NullLiteral | BooleanLiteral | DatePart | DatePartWeek => {
90 Highlight::Keyword
91 }
92
93 NumericLiteral | IntegerLiteral | DollarNumericLiteral | BitStringLiteral => {
95 Highlight::Number
96 }
97
98 QuotedLiteral
100 | RawQuotedLiteral
101 | BytesQuotedLiteral
102 | SignedQuotedLiteral
103 | DateConstructorLiteral
104 | FileLiteral
105 | DollarLiteral
106 | AtSignLiteral => Highlight::String,
107
108 Comment | InlineComment | BlockComment => Highlight::Comment,
110
111 BinaryOperator
113 | ComparisonOperator
114 | RawComparisonOperator
115 | AssignmentOperator
116 | CastingOperator
117 | LikeOperator
118 | WalrusOperator
119 | JsonOperator
120 | ParameterAssigner
121 | FunctionAssigner
122 | SignIndicator
123 | Plus
124 | Minus
125 | Divide
126 | DoubleDivide
127 | Star
128 | Percent
129 | Caret
130 | Tilde
131 | Ampersand
132 | Pipe
133 | VerticalBar
134 | Not
135 | RightArrow
136 | Lambda
137 | Dash => Highlight::Operator,
138
139 FunctionNameIdentifier | ProcedureNameIdentifier | SystemFunctionName => {
141 Highlight::Function
142 }
143
144 DataTypeIdentifier | PrimitiveType => Highlight::Type,
146
147 Parameter => Highlight::Parameter,
149
150 Variable | TsqlVariable | Placeholder => Highlight::Macro,
152
153 PropertyNameIdentifier | PropertiesNakedIdentifier | WidgetNameIdentifier => {
155 Highlight::Property
156 }
157
158 NakedIdentifier | QuotedIdentifier | Identifier | NakedIdentifierAll => Highlight::Variable,
161
162 Unparsable
166 | File
167 | ColumnReference
168 | ObjectReference
169 | Expression
170 | WildcardIdentifier
171 | Function
172 | FunctionContents
173 | HavingClause
174 | PathSegment
175 | LimitClause
176 | CubeRollupClause
177 | GroupingSetsClause
178 | GroupingExpressionList
179 | SetClause
180 | FetchClause
181 | FunctionDefinition
182 | AlterSequenceOptionsSegment
183 | RoleReference
184 | TablespaceReference
185 | ExtensionReference
186 | TagReference
187 | ColumnDefinition
188 | ColumnConstraintSegment
189 | CommentClause
190 | TableEndClause
191 | MergeMatch
192 | MergeWhenNotMatchedClause
193 | MergeInsertClause
194 | MergeUpdateClause
195 | MergeDeleteClause
196 | MergeTreeOrderByClause
197 | SetClauseList
198 | TableReference
199 | GroupbyClause
200 | FrameClause
201 | WithCompoundStatement
202 | CommonTableExpression
203 | CTEColumnList
204 | ReferencedColumnList
205 | TriggerReference
206 | TableConstraint
207 | JoinOnCondition
208 | DatabaseReference
209 | CollationReference
210 | OverClause
211 | NamedWindow
212 | WindowSpecification
213 | PartitionbyClause
214 | JoinClause
215 | DropTriggerStatement
216 | SampleExpression
217 | TableExpression
218 | CreateTriggerStatement
219 | DropModelStatement
220 | DescribeStatement
221 | UseStatement
222 | ExplainStatement
223 | CreateSequenceStatement
224 | CreateSequenceOptionsSegment
225 | AlterSequenceStatement
226 | DropSequenceStatement
227 | DropCastStatement
228 | CreateFunctionStatement
229 | DropFunctionStatement
230 | CreateModelStatement
231 | CreateViewStatement
232 | DeleteStatement
233 | UpdateStatement
234 | CreateCastStatement
235 | CreateRoleStatement
236 | DropRoleStatement
237 | AlterTableStatement
238 | CreateSchemaStatement
239 | SetSchemaStatement
240 | DropSchemaStatement
241 | DropTypeStatement
242 | CreateDatabaseStatement
243 | DropDatabaseStatement
244 | FunctionParameterList
245 | CreateIndexStatement
246 | DropIndexStatement
247 | CreateTableStatement
248 | AccessStatement
249 | InsertStatement
250 | TransactionStatement
251 | DropTableStatement
252 | DropViewStatement
253 | CreateUserStatement
254 | DropUserStatement
255 | ArrayExpression
256 | LocalAlias
257 | MergeStatement
258 | IndexColumnDefinition
259 | AggregateOrderByClause
260 | FunctionName
261 | CaseExpression
262 | WhenClause
263 | ElseClause
264 | PreWhereClause
265 | WhereClause
266 | SetOperator
267 | ValuesClause
268 | EmptyStructLiteral
269 | ObjectLiteral
270 | ObjectLiteralElement
271 | TimeZoneGrammar
272 | BracketedArguments
273 | DataType
274 | AliasExpression
275 | ArrayAccessor
276 | ArrayLiteral
277 | TypedArrayLiteral
278 | StructType
279 | StructLiteral
280 | TypedStructLiteral
281 | IntervalExpression
282 | ArrayType
283 | SizedArrayType
284 | SelectStatement
285 | OverlapsClause
286 | SelectClause
287 | Statement
288 | WithNoSchemaBindingClause
289 | WithDataClause
290 | SetExpression
291 | FromClause
292 | EmptyStructLiteralBrackets
293 | WildcardExpression
294 | OrderbyClause
295 | TruncateStatement
296 | FromExpression
297 | FromExpressionElement
298 | SelectClauseModifier
299 | NamedWindowExpression
300 | SelectClauseElement
301 | QualifyClause
302 | MultiStatementSegment
303 | AssertStatement
304 | ForInStatements
305 | ForInStatement
306 | RepeatStatements
307 | RepeatStatement
308 | IfStatements
309 | IfStatement
310 | LoopStatements
311 | LoopStatement
312 | WhileStatements
313 | WhileStatement
314 | SelectExceptClause
315 | SelectApplyClause
316 | SelectReplaceClause
317 | StructTypeSchema
318 | Tuple
319 | NamedArgument
320 | DeclareSegment
321 | SetSegment
322 | PartitionBySegment
323 | ClusterBySegment
324 | OptionsSegment
325 | CreateExternalTableStatement
326 | AlterViewStatement
327 | CreateMaterializedViewStatement
328 | CreateDictionaryStatement
329 | AlterMaterializedViewSetOptionsStatement
330 | DropMaterializedViewStatement
331 | ParameterizedExpression
332 | PivotForClause
333 | FromPivotExpression
334 | UnpivotClause
335 | FromUnpivotExpression
336 | NotMatchedByTargetClause
337 | MergeWhenMatchedClause
338 | ProcedureName
339 | ExportStatement
340 | ProcedureParameterList
341 | ProcedureStatements
342 | CallStatement
343 | ReturnStatement
344 | BreakStatement
345 | LeaveStatement
346 | ContinueStatement
347 | RaiseStatement
348 | PsqlVariable
349 | DatetimeTypeIdentifier
350 | DatetimeLiteral
351 | IndexAccessMethod
352 | OperatorClassReference
353 | DefinitionParameter
354 | DefinitionParameters
355 | RelationOption
356 | RelationOptions
357 | AlterFunctionActionSegment
358 | AlterProcedureActionSegment
359 | AlterProcedureStatement
360 | DropProcedureStatement
361 | WktGeometryType
362 | IntoClause
363 | ForClause
364 | AlterRoleStatement
365 | ExplainOption
366 | CreateTableAsStatement
367 | AlterPublicationStatement
368 | CreatePublicationStatement
369 | PublicationObjects
370 | PublicationTable
371 | PublicationReference
372 | DropExtensionStatement
373 | CreateExtensionStatement
374 | VersionIdentifier
375 | AlterTableActionSegment
376 | DropPublicationStatement
377 | AlterMaterializedViewStatement
378 | AlterMaterializedViewActionSegment
379 | RefreshMaterializedViewStatement
380 | WithCheckOption
381 | AlterPolicyStatement
382 | AlterDatabaseStatement
383 | VacuumStatement
384 | LikeOptionSegment
385 | PartitionBoundSpec
386 | IndexParameters
387 | ReferentialActionSegment
388 | IndexElement
389 | ExclusionConstraintElement
390 | AlterDefaultPrivilegesStatement
391 | AlterDefaultPrivilegesObjectPrivilege
392 | AlterDefaultPrivilegesSchemaObject
393 | AlterDefaultPrivilegesToFromRoles
394 | AlterDefaultPrivilegesGrant
395 | DropOwnedStatement
396 | ReassignOwnedStatement
397 | IndexElementOptions
398 | AlterDefaultPrivilegesRevoke
399 | AlterIndexStatement
400 | ReindexStatementSegment
401 | AnalyzeStatement
402 | AlterTrigger
403 | OperationClassReference
404 | ConflictAction
405 | ConflictTarget
406 | SetStatement
407 | CreatePolicyStatement
408 | CreateDomainStatement
409 | AlterDomainStatement
410 | DropDomainStatement
411 | DropPolicyStatement
412 | LoadStatement
413 | ResetStatement
414 | ListenStatement
415 | NotifyStatement
416 | UnlistenStatement
417 | ClusterStatement
418 | LanguageClause
419 | DoStatement
420 | CreateUserMappingStatement
421 | ImportForeignSchemaStatement
422 | CreateServerStatement
423 | CreateCollationStatement
424 | AlterTypeStatement
425 | CreateTypeStatement
426 | LockTableStatement
427 | CopyStatement
428 | DiscardStatement
429 | AlterSchemaStatement
430 | ServerReference
431 | ArrayJoinClause
432 | TableEngineFunction
433 | OnClusterClause
434 | Engine
435 | EngineFunction
436 | DatabaseEngine
437 | ColumnTtlSegment
438 | TableTtlSegment
439 | DropDictionaryStatement
440 | DropQuotaStatement
441 | DropSettingProfileStatement
442 | SystemMergesSegment
443 | SystemTtlMergesSegment
444 | SystemMovesSegment
445 | SystemReplicaSegment
446 | SystemFilesystemSegment
447 | SystemReplicatedSegment
448 | SystemReplicationSegment
449 | SystemFetchesSegment
450 | SystemDistributedSegment
451 | SystemModelSegment
452 | SystemFileSegment
453 | SystemUnfreezeSegment
454 | SystemStatement
455 | ConnectbyClause
456 | CallSegment
457 | WithingroupClause
458 | PatternExpression
459 | MatchRecognizeClause
460 | ChangesClause
461 | MatchConditionClause
462 | FromAtExpression
463 | FromBeforeExpression
464 | SnowflakeKeywordExpression
465 | SemiStructuredExpression
466 | SelectExcludeClause
467 | SelectRenameClause
468 | AlterTableTableColumnAction
469 | AlterTableClusteringAction
470 | AlterTableConstraintAction
471 | AlterWarehouseStatement
472 | AlterShareStatement
473 | AlterStorageIntegrationStatement
474 | AlterExternalTableStatement
475 | CommentEqualsClause
476 | TagBracketedEquals
477 | TagEquals
478 | CreateCloneStatement
479 | CreateDatabaseFromShareStatement
480 | CreateProcedureStatement
481 | ScriptingBlockStatement
482 | ScriptingLetStatement
483 | AlterFunctionStatement
484 | CreateExternalFunctionStatement
485 | WarehouseObjectProperties
486 | ConstraintPropertiesSegment
487 | CopyOptions
488 | SchemaObjectProperties
489 | CreateTaskStatement
490 | SnowflakeTaskExpressionSegment
491 | CreateStatement
492 | CreateFileFormatSegment
493 | AlterFileFormatSegment
494 | CsvFileFormatTypeParameters
495 | JsonFileFormatTypeParameters
496 | AvroFileFormatTypeParameters
497 | OrcFileFormatTypeParameters
498 | ParquetFileFormatTypeParameters
499 | XmlFileFormatTypeParameters
500 | AlterPipeSegment
501 | FileFormatSegment
502 | FormatTypeOptions
503 | CopyIntoLocationStatement
504 | CopyIntoTableStatement
505 | StorageLocation
506 | StageParameters
507 | S3ExternalStageParameters
508 | GcsExternalStageParameters
509 | AzureBlobStorageExternalStageParameters
510 | CreateStageStatement
511 | AlterStageStatement
512 | CreateStreamStatement
513 | AlterStreamStatement
514 | ShowStatement
515 | AlterUserStatement
516 | AlterSessionStatement
517 | AlterSessionSetStatement
518 | AlterSessionUnsetClause
519 | AlterTaskStatement
520 | AlterTaskSpecialSetClause
521 | AlterTaskSetClause
522 | AlterTaskUnsetClause
523 | ExecuteTaskClause
524 | UndropStatement
525 | CommentStatement
526 | DropExternalTableStatement
527 | ListStatement
528 | GetStatement
529 | PutStatement
530 | RemoveStatement
531 | CastExpression
532 | DropObjectStatement
533 | UnsetStatement
534 | SqlConfOption
535 | CreateWidgetStatement
536 | ReplaceTableStatement
537 | RemoveWidgetStatement
538 | UseDatabaseStatement
539 | InsertOverwriteDirectoryStatement
540 | InsertOverwriteDirectoryHiveFmtStatement
541 | LoadDataStatement
542 | ClusterByClause
543 | DistributeByClause
544 | HintFunction
545 | SelectHint
546 | WithCubeRollupClause
547 | SortByClause
548 | LateralViewClause
549 | PivotClause
550 | TransformClause
551 | AddFileStatement
552 | AddJarStatement
553 | AnalyzeTableStatement
554 | CacheTable
555 | ClearCache
556 | ListFileStatement
557 | ListJarStatement
558 | RefreshStatement
559 | UncacheTable
560 | FileReference
561 | GeneratedColumnDefinition
562 | IntervalLiteral
563 | DescribeHistoryStatement
564 | DescribeDetailStatement
565 | GenerateManifestFileStatement
566 | ConvertToDeltaStatement
567 | RestoreTableStatement
568 | ConstraintStatement
569 | ApplyChangesIntoStatement
570 | UsingClause
571 | DataSourceFormat
572 | IcebergTransformation
573 | MsckRepairTableStatement
574 | RowFormatClause
575 | SkewedByClause
576 | Bracketed
577 | EndOfFile
578 | Whitespace
579 | Newline
580 | Unlexable
581 | StartBracket
582 | EndBracket
583 | Raw
584 | Dot
585 | Comma
586 | EmitsSegment
587 | Literal
588 | Meta
589 | Colon
590 | TernaryColon
591 | StatementTerminator
592 | StartSquareBracket
593 | EndSquareBracket
594 | StartCurlyBracket
595 | Word
596 | DoubleQuote
597 | SingleQuote
598 | Semicolon
599 | BackQuote
600 | DollarQuote
601 | Question
602 | EndCurlyBracket
603 | Dedent
604 | Indent
605 | Implicit
606 | QuestionMark
607 | UdfBody
608 | StartAngleBracket
609 | EndAngleBracket
610 | ProcedureOption
611 | ExportOption
612 | Symbol
613 | ExecuteScriptStatement
614 | Batch
615 | PivotColumnReference
616 | IntoTableClause
617 | PasswordAuth
618 | ExecuteAsClause
619 | ExecuteImmediateClause
620 | UnicodeSingleQuote
621 | EscapedSingleQuote
622 | UnicodeDoubleQuote
623 | At
624 | FileKeyword
625 | SemiStructuredElement
626 | BytesDoubleQuote
627 | BytesSingleQuote
628 | FileFormat
629 | FileType
630 | StartHint
631 | EndHint
632 | UnquotedFilePath
633 | Dollar
634 | StageEncryptionOption
635 | BucketPath
636 | QuotedStar
637 | StagePath
638 | ColumnSelector
639 | ExcludeBracketClose
640 | WarehouseSize
641 | ExcludeBracketOpen
642 | SymlinkFormatManifest
643 | StartExcludeBracket
644 | CompressionType
645 | CopyOnErrorOption
646 | ColumnIndexIdentifierSegment
647 | ScalingPolicy
648 | ValidationModeOption
649 | EndExcludeBracket
650 | IdentifierList
651 | TemplateLoop
652 | ColonDelimiter
653 | SqlcmdOperator
654 | Slice
655 | TableEndClauseSegment
656 | PragmaStatement
657 | PragmaReference
658 | Slash
659 | DataFormatSegment
660 | AuthorizationSegment
661 | ColumnAttributeSegment
662 | ShowModelStatement
663 | CreateExternalSchemaStatement
664 | CreateLibraryStatement
665 | UnloadStatement
666 | DeclareStatement
667 | FetchStatement
668 | CloseStatement
669 | CreateDatashareStatement
670 | DescDatashareStatement
671 | DropDatashareStatement
672 | ShowDatasharesStatement
673 | GrantDatashareStatement
674 | CreateRlsPolicyStatement
675 | ManageRlsPolicyStatement
676 | DropRlsPolicyStatement
677 | AnalyzeCompressionStatement
678 | PartitionedBySegment
679 | RowFormatDelimitedSegment
680 | ObjectUnpivoting
681 | ArrayUnnesting
682 | AlterGroup
683 | CreateGroup
684 | ListaggOverflowClauseSegment
685 | UnorderedSelectStatementSegment
686 | MapType
687 | MapTypeSchema
688 | PrepareStatement
689 | ExecuteStatement
690 | RenameTableStatement
691 | ActionParameter
692 | AggregateClause
693 | AggregateOrderBy
694 | AliasOperator
695 | AllowConnections
696 | AlterAccountStatement
697 | AlterAggregateStatement
698 | AlterBiCapacityStatement
699 | AlterCapacityStatement
700 | AlterCatalogStatement
701 | AlterDynamicTableStatement
702 | AlterEventStatement
703 | AlterExtensionStatement
704 | AlterExternalVolumeStatement
705 | AlterForeignTableActionSegment
706 | AlterForeignTableStatement
707 | AlterMaskingPolicy
708 | AlterMasterKeyStatement
709 | AlterNetworkPolicyStatement
710 | AlterOptionSegment
711 | AlterOrganizationStatement
712 | AlterPartitionFunctionStatement
713 | AlterPartitionSchemeStatement
714 | AlterPasswordPolicyStatement
715 | AlterProjectStatement
716 | AlterReservationStatement
717 | AlterResourceMonitorStatement
718 | AlterRowAccessPolicyStatement
719 | AlterSecurityPolicyStatement
720 | AlterStatisticsStatement
721 | AlterStreamlitStatement
722 | AlterSubscription
723 | AlterTableSwitchStatement
724 | AlterTagStatement
725 | AlterTextSearchConfigurationStatement
726 | AlterVolumeStatement
727 | ArnCatalogSchemaSegment
728 | ArrayTypeSchema
729 | AtSign
730 | AtomicBeginEndBlock
731 | Atsign
732 | AutoOption
733 | BackupStorageRedundancy
734 | BeginEndBlock
735 | BeginStatement
736 | BinaryLiteral
737 | BindVariable
738 | BitValueLiteral
739 | BracketedIndexColumnListGrammar
740 | BulkInsertStatement
741 | BulkInsertWithSegment
742 | ByteLengthLiteral
743 | CallOperator
744 | CatalogReference
745 | CharacteristicStatement
746 | CheckConstraintGrammar
747 | CheckTableStatement
748 | ChecksumTableStatement
749 | CloseCursorStatement
750 | ClusterbyClause
751 | Code
752 | CollationClause
753 | ColonLiteral
754 | ColonPrefix
755 | ColumnPathOperator
756 | ColumnPropertiesSegment
757 | ColumnTypeReference
758 | ColumnsExpression
759 | Command
760 | CompatibilityLevel
761 | CompositeValueExpansion
762 | ComputedColumnDefinition
763 | ConflictClause
764 | ConnectionConstraintGrammar
765 | ConnectionLimitSegment
766 | CopyFilesIntoLocationStatement
767 | CreateAggregateStatement
768 | CreateAssignmentStatement
769 | CreateAuthenticationPolicySegment
770 | CreateCapacityStatement
771 | CreateCatalogStatement
772 | CreateColumnstoreIndexStatement
773 | CreateCortexSearchServiceStatement
774 | CreateDatabaseRoleStatement
775 | CreateDatabaseScopedCredentialStatement
776 | CreateDatabaseWithOptions
777 | CreateEventStatement
778 | CreateEventTableStatement
779 | CreateExternalDataSourceStatement
780 | CreateExternalFileFormat
781 | CreateExternalVolumeStatement
782 | CreateForeignDataWrapper
783 | CreateForeignTableStatement
784 | CreateFulltextCatalogStatement
785 | CreateFulltextIndexStatement
786 | CreateLoginStatement
787 | CreateMasterKeyStatement
788 | CreateMaterializedViewAsReplicaOfStatement
789 | CreateOperatorStatement
790 | CreateOptionSegment
791 | CreatePartitionFunctionStatement
792 | CreatePartitionSchemeStatement
793 | CreatePasswordPolicyStatement
794 | CreateReservationStatement
795 | CreateResourceMonitorStatement
796 | CreateRowAccessPolicyStatement
797 | CreateSearchIndexStatement
798 | CreateSecurityPolicyStatement
799 | CreateServerRoleStatement
800 | CreateSnapshotTableStatement
801 | CreateSqlFunctionStatement
802 | CreateStatisticsStatement
803 | CreateStreamlitStatement
804 | CreateSubscription
805 | CreateSynonymStatement
806 | CreateTableAsSelectStatement
807 | CreateTableFunctionStatement
808 | CreateTableGraphStatement
809 | CreateTableUsingStatement
810 | CreateTextSearchConfigurationStatement
811 | CreateTrigger
812 | CreateVectorIndexStatement
813 | CreateVirtualTableStatement
814 | CreateVolumeStatement
815 | CursorDefinition
816 | CursorFetchSegment
817 | CursorOpenCloseSegment
818 | DataGovernancePolicyTagActionSegment
819 | DatabaseRoleReference
820 | DateFormat
821 | DeallocateCursorStatement
822 | DeallocateSegment
823 | DeallocateStatement
824 | DeclareOrReplaceVariableStatement
825 | DefaultCollate
826 | DefinerSegment
827 | DeleteTargetTable
828 | DelimiterStatement
829 | DisableTrigger
830 | DistributebyClause
831 | DoubleAmpersand
832 | DoubleAtSignLiteral
833 | DoubleVerticalBar
834 | DropAggregateStatement
835 | DropAssignmentStatement
836 | DropCapacityStatement
837 | DropCatalogStatement
838 | DropCollationStatement
839 | DropColumnClause
840 | DropDynamicTableSegment
841 | DropEventStatement
842 | DropExternalVolumeStatement
843 | DropForeignTableStatement
844 | DropIcebergTableStatement
845 | DropMasterKeyStatement
846 | DropModelstatement
847 | DropPasswordPolicyStatement
848 | DropReservationStatement
849 | DropResourceMonitorStatement
850 | DropRowAccessPolicyStatement
851 | DropSearchIndexStatement
852 | DropSecurityPolicy
853 | DropStatement
854 | DropStatisticsStatement
855 | DropSubscription
856 | DropSynonymStatement
857 | DropTableFunctionStatement
858 | DropTextSearchConfigurationStatement
859 | DropTrigger
860 | DropVectorIndexStatement
861 | DropVolumeStatement
862 | DynamicTableLagIntervalSegment
863 | DynamicTableOptions
864 | Edition
865 | EncryptedWithGrammar
866 | ExceptionBlockStatement
867 | ExceptionCode
868 | ExecuteArrow
869 | ExecuteImmediate
870 | ExecuteOption
871 | ExecuteSegment
872 | ExtendClause
873 | ExternalAccessIntegrationEquals
874 | ExternalFileDelimitedTextClause
875 | ExternalFileDelimitedTextFormatOptionsClause
876 | ExternalFileDeltaClause
877 | ExternalFileJsonClause
878 | ExternalFileOrcClause
879 | ExternalFileParquetClause
880 | ExternalFileRcClause
881 | ExternalLocation
882 | ExternalVolumeReference
883 | FatRightArrow
884 | FetchCursorStatement
885 | FileCompression
886 | FileEncoding
887 | FileSpec
888 | FileSpecFileGrowth
889 | FileSpecFileName
890 | FileSpecMaxSize
891 | FileSpecNewName
892 | FileSpecSize
893 | FileSpecWithoutBracket
894 | FilegroupClause
895 | FilegroupName
896 | FilestreamOnOptionStatement
897 | FlushStatement
898 | ForSystemTimeAsOfSegment
899 | FormatClause
900 | FromDatashareClause
901 | FromIntegrationClause
902 | FullTextSearchOperator
903 | FunctionOptionSegment
904 | FunctionParameterListWithComments
905 | GetDiagnosticsSegment
906 | GlobOperator
907 | GoStatement
908 | GotoStatement
909 | GrantToSegment
910 | GraphTableConstraint
911 | GroupAndOrderbyClause
912 | HashIdentifier
913 | HashPrefix
914 | HelpStatement
915 | HexadecimalLiteral
916 | IamRoleClause
917 | IcebergTableOptions
918 | IdentifierClauseSegment
919 | IdentityGrammar
920 | IfClause
921 | IfThenStatement
922 | IndexHintClause
923 | IndexOption
924 | IndexReference
925 | IndexType
926 | InitializeType
927 | InlineDollarSign
928 | InlinePathOperator
929 | InsertRowAlias
930 | IntoOutfileClause
931 | IsolationLevelClause
932 | IterateStatement
933 | JsonPath
934 | LabelSegment
935 | LambdaArrow
936 | LambdaFunction
937 | LeadingDot
938 | LimitClauseComponent
939 | ListComprehension
940 | ListaggOverflowClause
941 | LocalAliasSegment
942 | LogLevelEquals
943 | LogicalFileName
944 | LoginUserSegment
945 | MagicCellSegment
946 | MagicLine
947 | MagicSingleLine
948 | MagicStart
949 | MaskStatement
950 | MasterKeyEncryptionOption
951 | MatchCondition
952 | MaxDuration
953 | MaxLiteral
954 | MetaCommand
955 | MetaCommandQueryBuffer
956 | MetaCommandStatement
957 | MlTableExpression
958 | MsckTableStatement
959 | NotOperator
960 | NotebookStart
961 | ObevoAnnotation
962 | OffsetClause
963 | OnPartitionOrFilegroupStatement
964 | OnPartitionsClause
965 | OpenCursorStatement
966 | OpenSymmetricKeyStatement
967 | OpenjsonSegment
968 | OpenjsonWithClause
969 | OpenquerySegment
970 | OpenrowsetSegment
971 | OpenrowsetWithClause
972 | OpenxmlSegment
973 | Operator
974 | OptimizeTableStatement
975 | Option
976 | OptionClause
977 | OptionIndicator
978 | OutputClause
979 | ParameterDirection
980 | PartitionClause
981 | PartitionSchemeClause
982 | PartitionSchemeName
983 | PasswordPolicyOptions
984 | PasswordPolicyReference
985 | PeriodSegment
986 | PgTrgmOperator
987 | PgvectorOperator
988 | PipeOperator
989 | PipeOperatorClause
990 | PipeStatement
991 | PivotOperator
992 | PostTableExpression
993 | PostgisOperator
994 | PrepareSegment
995 | PrewhereClause
996 | PrintStatement
997 | ProcedureStatement
998 | PurgeBinaryLogsStatement
999 | QualifiedOperator
1000 | QueryHintSegment
1001 | QuestionLiteral
1002 | RaiserrorStatement
1003 | RawDoubleQuote
1004 | RawSingleQuote
1005 | ReconfigureStatement
1006 | ReferencesConstraintGrammar
1007 | RelationalIndexOptions
1008 | RenameColumnClause
1009 | RenameStatement
1010 | RepairTableStatement
1011 | ReplaceStatement
1012 | ResetMasterStatement
1013 | ResetSessionAuthorizationStatement
1014 | ResignalSegment
1015 | ResourceConstraint
1016 | ResourceMonitorOptions
1017 | ReturnSegment
1018 | ReturningClause
1019 | SchemaReference
1020 | ScriptingDeclareStatement
1021 | ScriptingIfStatement
1022 | ScriptingRaiseStatement
1023 | SearchOptimizationAction
1024 | SecurityLabelStatement
1025 | SelectVariableAssignment
1026 | SequenceNextValue
1027 | SequenceReference
1028 | SerdeMethod
1029 | ServiceObjective
1030 | SetConstraintStatement
1031 | SetContextInfoStatement
1032 | SetLanguageStatement
1033 | SetLocalVariableSegment
1034 | SetNamesStatement
1035 | SetOperatorClause
1036 | SetSessionAuthorizationStatement
1037 | SetSessionStatement
1038 | SetTimezoneStatement
1039 | SetTransactionStatement
1040 | SetVariableStatement
1041 | SettingsClause
1042 | SimplifiedPivot
1043 | SimplifiedUnpivot
1044 | SingleQuoteWithN
1045 | SizeLiteral
1046 | SortbyClause
1047 | SqlcmdCommandSegment
1048 | SquareQuote
1049 | StatisticsReference
1050 | StoringSegment
1051 | SubscriptionReference
1052 | SynonymReference
1053 | SystemVariable
1054 | TableClausesSegment
1055 | TableClusterByClause
1056 | TableColumnCommentAction
1057 | TableDistributionClause
1058 | TableDistributionIndexClause
1059 | TableIndexClause
1060 | TableIndexSegment
1061 | TableLocationClause
1062 | TableOptionStatement
1063 | TableSpecificationSegment
1064 | TagStatement
1065 | TemporalQuery
1066 | TextimageOnOptionStatement
1067 | ThrowStatement
1068 | TraceLevelEquals
1069 | TruncateTable
1070 | TryCatch
1071 | TupleTypeSchema
1072 | UndropSchemaStatement
1073 | UnpivotMultiColumn
1074 | UnpivotOperator
1075 | UnpivotSingleColumn
1076 | UnquotedRelativeSqlFilePath
1077 | UpdateStatisticsStatement
1078 | UpsertClause
1079 | UpsertClauseList
1080 | UseCatalogStatement
1081 | VolumeReference
1082 | WaitforStatement
1083 | WildcardExclude
1084 | WildcardPatternMatching
1085 | WildcardRename
1086 | WildcardReplace
1087 | WithCheckOptions
1088 | WithFill
1089 | WithRollupClause
1090 | WithinGroupClause
1091 | WithordinalityClause
1092 | OracleAtSign
1093 | OraclePowerOperator
1094 | OracleAssignmentOperator
1095 | HierarchicalQueryClause
1096 | PivotSegment
1097 | UnpivotSegment
1098 | TriggerCorrelationName
1099 | OracleBindVariable
1100 | AlterTableProperties
1101 | AlterTableColumnClauses
1102 | AlterTableConstraintClauses
1103 | IndexTypeReference
1104 | ExecuteFileStatement
1105 | SlashBufferExecutor
1106 | OracleBatch
1107 | OracleCommentStatement
1108 | OracleCreateProcedureStatement
1109 | OracleDropProcedureStatement
1110 | OracleDeclareSegment
1111 | OracleColumnTypeReference
1112 | OracleRowTypeReference
1113 | CollectionType
1114 | RecordType
1115 | RefCursorType
1116 | DeclareCursorVariable
1117 | OracleExecuteImmediateStatement
1118 | OracleBeginEndBlock
1119 | OracleCreateFunctionStatement
1120 | OracleAlterFunctionStatement
1121 | OracleCreateTypeStatement
1122 | OracleTypeReference
1123 | OracleCreateTypeBodyStatement
1124 | OracleCreatePackageStatement
1125 | OraclePackageReference
1126 | OracleAlterPackageStatement
1127 | OracleDropPackageStatement
1128 | OracleCreateTriggerStatement
1129 | DmlEventClause
1130 | OracleReferencingClause
1131 | CompoundTriggerStatement
1132 | TimingPointSection
1133 | OracleAlterTriggerStatement
1134 | AssignmentSegmentStatement
1135 | OracleIfThenStatement
1136 | OracleIfClause
1137 | OracleCaseExpression
1138 | OracleWhenClause
1139 | OracleElseClause
1140 | OracleNullStatement
1141 | ForLoopStatement
1142 | WhileLoopStatement
1143 | OracleLoopStatement
1144 | ForallStatement
1145 | OracleOpenStatement
1146 | OracleOpenForStatement
1147 | OracleFetchStatement
1148 | OracleIntoClause
1149 | BulkCollectIntoClause
1150 | OracleExitStatement
1151 | OracleReturnStatement
1152 | OracleCreateUserStatement
1153 | OracleReturningClause
1154 | DatabaseLinkReference
1155 | OracleCreateDatabaseLinkStatement
1156 | OracleDropDatabaseLinkStatement
1157 | OracleAlterDatabaseLinkStatement
1158 | OracleCreateSynonymStatement
1159 | OracleDropSynonymStatement
1160 | OracleAlterSynonymStatement
1161 | OracleWithinGroupClause
1162 | OracleListaggOverflowClause
1163 | OracleNamedArgument
1164 | OracleCreateTableStatement
1165 | OracleColumnDefinition
1166 | OracleSqlplusVariable
1167 | StartwithClause
1168 | OracleTableReference
1169 | OracleCreateViewStatement
1170 | OracleAlterIndexStatement
1171 | OracleAlterTableStatement
1172 | OracleAlterSessionStatement
1173 | JsonTableColumnDefinition
1174 | JsonTableColumnsClause
1175 | JsonTableFunctionContents
1176 | OracleMergeUpdateClause
1177 | OracleInsertStatement
1178 | OracleUpdateStatement
1179 | OracleDeleteStatement
1180 | OracleTransactionStatement
1181 | OracleValuesClause
1182 | OracleTableConstraint
1183 | OracleFunctionName
1184 | OracleOrderByClause
1185 | EngineType
1186 | PartitionSegment
1187 | DistributionSegment
1188 | IndexDefinition
1189 | CreateRoutineLoadStatement
1190 | RoutineLoadProperties
1191 | RoutineLoadDataSourceProperties
1192 | StopRoutineLoadStatement
1193 | PauseRoutineLoadStatement
1194 | ResumeRoutineLoadStatement
1195 | InsertOverwriteStatement
1196 | AlterConnection
1197 | AlterConsumerGroupStatement
1198 | AlterSystemStatement
1199 | AlterTableAddColumn
1200 | AlterTableAlterColumn
1201 | AlterTableColumnStatement
1202 | AlterTableConstraintStatement
1203 | AlterTableDistributePartitionStatement
1204 | AlterTableDropColumn
1205 | AlterTableModifyColumn
1206 | AlterTableRenameColumn
1207 | AlterVirtualSchemaStatement
1208 | CloseSchemaStatement
1209 | ColumnDatatypeDefinition
1210 | ColumnReferenceList
1211 | ConnectByClause
1212 | ConnectionDefinition
1213 | ConsumerGroupParameter
1214 | CreateAdapterScript
1215 | CreateConnection
1216 | CreateConsumerGroupStatement
1217 | CreateScriptingLuaScript
1218 | CreateUdfScript
1219 | CreateVirtualSchemaStatement
1220 | CsvCols
1221 | DropConnectionStatement
1222 | DropConsumerGroupStatement
1223 | DropScriptStatement
1224 | EscapedIdentifier
1225 | ExplainVirtualStatement
1226 | ExportIntoClause
1227 | FbvCols
1228 | FileOpts
1229 | FlushStatisticsStatement
1230 | FunctionAssignment
1231 | FunctionBody
1232 | FunctionForLoop
1233 | FunctionIfBranch
1234 | FunctionReference
1235 | FunctionScriptTerminator
1236 | FunctionWhileLoop
1237 | GrantRevokeConnection
1238 | GrantRevokeConnectionRestricted
1239 | GrantRevokeImpersonation
1240 | GrantRevokeObjectPrivileges
1241 | GrantRevokeRoles
1242 | GrantRevokeSystemPrivileges
1243 | ImpersonateStatement
1244 | ImportColumns
1245 | ImportErrorDestination
1246 | ImportErrorsClause
1247 | ImportExportDbsrc
1248 | ImportFile
1249 | ImportFromClause
1250 | ImportScript
1251 | ImportStatement
1252 | KerberosAuth
1253 | KillStatement
1254 | LdapAuth
1255 | ObjectPrivilege
1256 | OpenSchemaStatement
1257 | OpenidAuth
1258 | PlusPriorInverse
1259 | PreferenceTerm
1260 | PreferringClause
1261 | PreloadStatement
1262 | RangeOperator
1263 | RecompressReorganizeStatement
1264 | RejectClause
1265 | ScriptContent
1266 | ScriptReference
1267 | SessionParameter
1268 | SystemParameter
1269 | SystemPrivilege
1270 | TableConstraintDefinition
1271 | TableContentDefinition
1272 | TableDistributionPartitionClause
1273 | TableLikeClause
1274 | TruncateAuditLogsStatement
1275 | UdfParamDotSyntax
1276 | ValuesClauseElements
1277 | ValuesInsertClause
1278 | ValuesRangeClause
1279 | ViewReference
1280 | WithInvalidForeignKeyClause
1281 | WithInvalidUniquePkClause
1282 | TupleElementAccess
1283 | MaterializeSize
1284 | AlterConnectionRotateKeys
1285 | AlterRenameStatement
1286 | AlterSecretStatement
1287 | AlterSourceSinkSizeStatement
1288 | CopyToStatement
1289 | CopyFromStatement
1290 | CreateClusterStatement
1291 | CreateClusterReplicaStatement
1292 | CreateConnectionStatement
1293 | CreateSecretStatement
1294 | CreateSinkKafkaStatement
1295 | CreateSourceKafkaStatement
1296 | CreateSourceLoadGeneratorStatement
1297 | CreateSourcePostgresStatement
1298 | ShowCreateStatement
1299 | ShowIndexesStatement
1300 | ShowMaterializedViewsStatement
1301 | BteqKeyWordSegment
1302 | BteqStatement
1303 | CollectStatUsingOptionClause
1304 | CollectStatisticsStatement
1305 | CreateTableOptionsStatement
1306 | DatabaseStatement
1307 | FromInUpdateClause
1308 | SetQueryBandStatement
1309 | TdColumnAttributeConstraint
1310 | TdPartitioningLevel
1311 | TdTableConstraint => return None,
1312 };
1313
1314 Some(highlight)
1315}
1316
1317pub fn semantic_tokens(
1321 linter: &Linter,
1322 source: &str,
1323 filename: Option<String>,
1324) -> Vec<SemanticToken> {
1325 let tables = Tables::default();
1326 match linter.parse_string(&tables, source, filename) {
1327 Ok(parsed) => parsed
1328 .tree
1329 .map(|tree| build_semantic_tokens(&tree, source))
1330 .unwrap_or_default(),
1331 Err(e) => {
1332 eprintln!("Failed to parse for semantic tokens: {}", e.value);
1333 Vec::new()
1334 }
1335 }
1336}
1337
1338pub(crate) fn build_semantic_tokens(tree: &ErasedSegment, source: &str) -> Vec<SemanticToken> {
1340 let line_index = LineIndex::new(source);
1341 let mut tokens: Vec<RawToken> = Vec::new();
1342
1343 for segment in tree.get_raw_segments() {
1344 let Some(highlight) = classify(segment.get_type()) else {
1345 continue;
1346 };
1347 let Some(marker) = segment.get_position_marker() else {
1348 continue;
1349 };
1350
1351 let range = marker.source_slice.clone();
1352 if range.is_empty() || range.end > source.len() {
1353 continue;
1354 }
1355 let text = &source[range.clone()];
1356 let token_type = highlight.token_type();
1357
1358 line_index.split_lines(range.start, text, |line, start, length| {
1361 tokens.push(RawToken {
1362 line,
1363 start,
1364 length,
1365 token_type,
1366 });
1367 });
1368 }
1369
1370 tokens.sort_by_key(|t| (t.line, t.start));
1373
1374 let mut data = Vec::with_capacity(tokens.len());
1375 let mut prev_line = 0;
1376 let mut prev_start = 0;
1377 for token in tokens {
1378 let delta_line = token.line - prev_line;
1379 let delta_start = if delta_line == 0 {
1380 token.start - prev_start
1381 } else {
1382 token.start
1383 };
1384 data.push(SemanticToken {
1385 delta_line,
1386 delta_start,
1387 length: token.length,
1388 token_type: token.token_type,
1389 token_modifiers_bitset: 0,
1390 });
1391 prev_line = token.line;
1392 prev_start = token.start;
1393 }
1394
1395 data
1396}
1397
1398struct RawToken {
1400 line: u32,
1401 start: u32,
1402 length: u32,
1403 token_type: u32,
1404}
1405
1406struct LineIndex<'a> {
1409 source: &'a str,
1410 line_starts: Vec<usize>,
1412}
1413
1414impl<'a> LineIndex<'a> {
1415 fn new(source: &'a str) -> Self {
1416 let mut line_starts = vec![0];
1417 for (offset, byte) in source.bytes().enumerate() {
1418 if byte == b'\n' {
1419 line_starts.push(offset + 1);
1420 }
1421 }
1422 Self {
1423 source,
1424 line_starts,
1425 }
1426 }
1427
1428 fn position(&self, offset: usize) -> (u32, u32) {
1430 let line = match self.line_starts.binary_search(&offset) {
1431 Ok(line) => line,
1432 Err(next) => next - 1,
1433 };
1434 let line_start = self.line_starts[line];
1435 let column = utf16_len(&self.source[line_start..offset]);
1436 (line as u32, column)
1437 }
1438
1439 fn split_lines(&self, start: usize, text: &str, mut emit: impl FnMut(u32, u32, u32)) {
1443 let mut offset = start;
1444 for piece in text.split_inclusive('\n') {
1445 let content = piece.strip_suffix('\n').unwrap_or(piece);
1447 let content = content.strip_suffix('\r').unwrap_or(content);
1448 if !content.is_empty() {
1449 let (line, column) = self.position(offset);
1450 emit(line, column, utf16_len(content));
1451 }
1452 offset += piece.len();
1453 }
1454 }
1455}
1456
1457fn utf16_len(text: &str) -> u32 {
1459 text.chars().map(|c| c.len_utf16() as u32).sum()
1460}
1461
1462#[cfg(test)]
1463mod tests {
1464 use super::*;
1465 use sqruff_lib::core::config::FluffConfig;
1466
1467 fn linter() -> Linter {
1468 let config = FluffConfig::from_source("[sqruff]\ndialect = ansi\n", None);
1469 Linter::new(config, None, None, false).unwrap()
1470 }
1471
1472 fn decode(tokens: &[SemanticToken]) -> Vec<(u32, u32, u32, u32)> {
1475 let mut line = 0;
1476 let mut start = 0;
1477 let mut out = Vec::new();
1478 for token in tokens {
1479 if token.delta_line == 0 {
1480 start += token.delta_start;
1481 } else {
1482 line += token.delta_line;
1483 start = token.delta_start;
1484 }
1485 out.push((line, start, token.length, token.token_type));
1486 }
1487 out
1488 }
1489
1490 fn tokens(sql: &str) -> Vec<(u32, u32, u32, u32)> {
1491 decode(&semantic_tokens(&linter(), sql, None))
1492 }
1493
1494 #[test]
1495 fn highlights_keywords_identifiers_and_literals() {
1496 let decoded = tokens("SELECT a, 1, 'x' FROM t");
1498 let kw = Highlight::Keyword.token_type();
1499 let var = Highlight::Variable.token_type();
1500 let num = Highlight::Number.token_type();
1501 let string = Highlight::String.token_type();
1502
1503 assert_eq!(
1504 decoded,
1505 vec![
1506 (0, 0, 6, kw), (0, 7, 1, var), (0, 10, 1, num), (0, 13, 3, string), (0, 17, 4, kw), (0, 22, 1, var), ]
1513 );
1514 }
1515
1516 #[test]
1517 fn skips_whitespace_and_punctuation() {
1518 let decoded = tokens("SELECT a, b");
1520 assert!(decoded.iter().all(|&(_, _, len, _)| len > 0));
1521 assert_eq!(decoded.len(), 3);
1523 }
1524
1525 #[test]
1526 fn splits_block_comment_across_lines() {
1527 let decoded = tokens("SELECT 1 /* line one\nline two */ FROM t");
1528 let comment = Highlight::Comment.token_type();
1529 let comment_tokens: Vec<_> = decoded
1530 .iter()
1531 .filter(|&&(_, _, _, ty)| ty == comment)
1532 .collect();
1533 assert_eq!(comment_tokens.len(), 2);
1535 assert_eq!(comment_tokens[0].0, 0);
1536 assert_eq!(comment_tokens[1].0, 1);
1537 }
1538
1539 #[test]
1540 fn utf16_columns_after_non_ascii() {
1541 let sql = "SELECT 'é' AS a";
1544 let decoded = tokens(sql);
1545 let var = Highlight::Variable.token_type();
1546 let alias = decoded
1550 .iter()
1551 .rev()
1552 .find(|&&(_, _, _, ty)| ty == var)
1553 .unwrap();
1554 assert_eq!(alias.1, 14);
1555 }
1556}