• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (C) 2025 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15import {
16  LRLanguage,
17  LanguageSupport,
18  delimitedIndent,
19  foldInside,
20  foldNodeProp,
21  indentNodeProp,
22} from '@codemirror/language';
23import {styleTags, tags as t} from '@lezer/highlight';
24import {parser} from './perfetto_sql.grammar'; // Generated by Lezer
25import {TreeCursor} from '@lezer/common';
26
27export const language = LRLanguage.define({
28  parser: parser.configure({
29    props: [
30      indentNodeProp.add({
31        Application: delimitedIndent({closing: ')', align: false}),
32      }),
33      foldNodeProp.add({
34        Application: foldInside,
35      }),
36      styleTags({
37        'Keyword': t.keyword,
38        'Boolean': t.bool,
39        'String': t.string,
40        'Number': t.number,
41        'LineComment': t.lineComment,
42        'Macro': t.macroName,
43        'MacroVariable': t.variableName,
44        'Function': t.function(t.variableName),
45        '( )': t.paren,
46      }),
47    ],
48  }),
49  languageData: {
50    commentTokens: {line: '--'},
51  },
52});
53
54export function perfettoSql() {
55  return new LanguageSupport(language);
56}
57
58export function parseAndPrintTree(code: string) {
59  const tree = language.parser.parse(code);
60  const cursor = tree.cursor();
61  printCST(cursor, code);
62}
63
64// Helper function to pretty-print the CST
65function printCST(cursor: TreeCursor, source: string, indent = 0) {
66  const nodeName = cursor.name;
67  const nodeText = source.substring(cursor.from, cursor.to);
68
69  console.log(`${'  '.repeat(indent)}${nodeName}: "${nodeText}"`);
70
71  if (cursor.firstChild()) {
72    do {
73      printCST(cursor, source, indent + 1);
74    } while (cursor.nextSibling());
75    cursor.parent(); // Important: Move back up to the parent
76  }
77}
78