diff --git a/README.md b/README.md index f7d77f6..0092ed3 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,17 @@ To test the highlighting configure run: npx tree-sitter highlight examples/Main.mo ``` +## Tags + +tree-sitter-metamodelica supports +[tagging for code navigation systems](https://tree-sitter.github.io/tree-sitter/code-navigation-systems) +to provide a list of all definitions. + +```bash +npx tree-sitter tags examples/Main.mo +``` + + ## Usage Use [Web Tree-sitter](https://github.com/tree-sitter/tree-sitter/blob/master/lib/binding_web/README.md) @@ -75,11 +86,15 @@ parser.setLanguage(MetaModelica) ## Current Status -tree-sitter-metamodelica has been tested on a "Save Total" version of the -[Modelica.Fluid.Examples.DrumBoiler.DrumBoiler](./examples/DrumBoiler.mo) which -was successfully parsed and highlighted. +tree-sitter-metamodelica has been tested on all of the MetaModelica files of the +OpenModelica Compiler and can parse all but the following features: + + - Susan / Template interface packages + - `code_equations` + ```bash -npx tree-sitter parse examples/DrumBoiler.mo -npx tree-sitter highlight examples/DrumBoiler.mo +npx tree-sitter parse examples/Main.mo +npx tree-sitter highlight examples/Main.mo +npx tree-sitter tags examples/Main.mo ``` diff --git a/examples/test.mo b/examples/test.mo deleted file mode 100644 index ac52cde..0000000 --- a/examples/test.mo +++ /dev/null @@ -1,4 +0,0 @@ -pure function foo -algorithm - pure := foldExp(fn, function checkPureCall(fn = fn), true); -end foo; diff --git a/package.json b/package.json index 94d64bf..f365f8e 100644 --- a/package.json +++ b/package.json @@ -58,7 +58,8 @@ "file-types": [ "mo" ], - "highlights": "queries/highlights.scm" + "highlights": "queries/highlights.scm", + "tags": "queries/tags.scm" } ] } diff --git a/queries/highlights.scm b/queries/highlights.scm index 1e70538..e578c7f 100644 --- a/queries/highlights.scm +++ b/queries/highlights.scm @@ -14,7 +14,7 @@ [ (BLOCK_COMMENT) ;; >/* comment */< (COMMENT) ;; >// comment< -] +] @comment (string_comment (STRING) @comment) ;; model foo >"description"< ;;; Numbers @@ -36,7 +36,11 @@ (polymorphic_type_specifier (name_path)@type) ;;; Variables -(declaration (IDENT) @variable.parameter) ;; Real >x< +(declaration [ + (IDENT) + (OPERATOR) + ] @variable.parameter +) ;; Real >x< (component_reference__function_call componentReference: (component_reference) @variable.parameter) ;; >x< ;;; Function calls @@ -107,7 +111,6 @@ (MATCH) (MATCHCONTINUE) (MODEL) - (OPERATOR) (OPTIMIZATION) (OVERLOAD) (PACKAGE) diff --git a/queries/tags.scm b/queries/tags.scm new file mode 100644 index 0000000..f6858c8 --- /dev/null +++ b/queries/tags.scm @@ -0,0 +1,168 @@ +;;;;; Tagging for code navigation + +;;; Class definitions + +(class_definition + (class_type + class: (CLASS) + ) + (class_specifier + identifier: (identifier) @name + comment: (string_comment + (STRING) @doc + ( + (PLUS) + (STRING) @doc + )* + )* + ) + (#strip! @doc "^\\\"|\\\"$") +) @definition.class + +(class_definition + (class_type + optimization: (OPTIMIZATION) + ) + (class_specifier + identifier: (identifier) @name + comment: (string_comment + (STRING) @doc + ( + (PLUS) + (STRING) @doc + )* + )* + ) + (#strip! @doc "^\\\"|\\\"$") +) @definition.optimization + +(class_definition + (class_type + model: (MODEL) + ) + (class_specifier + identifier: (identifier) @name + comment: (string_comment + (STRING) @doc + ( + (PLUS) + (STRING) @doc + )* + )* + ) + (#strip! @doc "^\\\"|\\\"$") +) @definition.model + +(class_definition + (class_type + record: (RECORD) + ) + (class_specifier + identifier: (identifier) @name + comment: (string_comment + (STRING) @doc + ( + (PLUS) + (STRING) @doc + )* + )* + ) + (#strip! @doc "^\\\"|\\\"$") +) @definition.record + +(class_definition + (class_type + connector: (CONNECTOR) + ) + (class_specifier + identifier: (identifier) @name + comment: (string_comment + (STRING) @doc + ( + (PLUS) + (STRING) @doc + )* + )* + ) + (#strip! @doc "^\\\"|\\\"$") +) @definition.connector + +(class_definition + (class_type + type: (TYPE) + ) + (class_specifier + identifier: (identifier) @name + comment: (string_comment + (STRING) @doc + ( + (PLUS) + (STRING) @doc + )* + )* + ) + (#strip! @doc "^\\\"|\\\"$") +) @definition.type + +(class_definition + (class_type + package: (PACKAGE) + ) + (class_specifier + identifier: (identifier) @name + comment: (string_comment + (STRING) @doc + ( + (PLUS) + (STRING) @doc + )* + )* + ) + (#strip! @doc "^\\\"|\\\"$") +) @definition.package + +(class_definition + (class_type + function: (FUNCTION) + ) + (class_specifier + identifier: (identifier) @name + comment: (string_comment + (STRING) @doc + ( + (PLUS) + (STRING) @doc + )* + )* + ) + (#strip! @doc "^\\\"|\\\"$") +) @definition.function + +(class_definition + (class_type + uniontype: (UNIONTYPE) + ) + (class_specifier + identifier: (identifier) @name + comment: (string_comment + (STRING) @doc + ( + (PLUS) + (STRING) @doc + )* + )* + ) + (#strip! @doc "^\\\"|\\\"$") +) @definition.uniontype + +;;; Variable definitions + +(component_declaration + declaration: (declaration + [ + identifier: (IDENT) @name + (OPERATOR) @name + ] + ) + comment: (comment)* @doc +) @definition.variable diff --git a/test/highlight/Scopes.mo b/test/highlight/Scopes.mo new file mode 100644 index 0000000..5f1e852 --- /dev/null +++ b/test/highlight/Scopes.mo @@ -0,0 +1,25 @@ +package A "Package" + function foo + end foo; + + function bar + algorithm + foo(); // In scope + end bar; +end A; + +package B + function bar1 + Real x; + algorithm + x := foo(); // Not in scope + x := A.foo(); // In scope + end bar1; + + function bar2 + Real y; + algorithm + show(x); // Not in scope + show(y); // In scope + end bar2; +end B; diff --git a/test/tags/ClassDefinitions.mo b/test/tags/ClassDefinitions.mo new file mode 100644 index 0000000..a1f927b --- /dev/null +++ b/test/tags/ClassDefinitions.mo @@ -0,0 +1,40 @@ +class C1 "Documentation" +// ^ definition.class +end C1; + +class C2 +// ^ definition.class + "Documentation" +end C2; + +optimization Opt "This has" + "a lot of documentation" +// ^ definition.optimization +end Opt; + +model MyModel +// ^ definition.model +end MyModel; + +record R +// ^ definition.record +end R; + +connector C +// ^ definition.connector +end C; + +type T +// ^ definition.type +end T; + +package PackageA +// ^ definition.package +end PackageA; + +function foo +// ^ definition.function +end foo; + +uniontype T2 +// ^ definition.uniontype +end T2; diff --git a/test/tags/MatchLocalDefinitions.mo b/test/tags/MatchLocalDefinitions.mo new file mode 100644 index 0000000..aa96709 --- /dev/null +++ b/test/tags/MatchLocalDefinitions.mo @@ -0,0 +1,24 @@ +function foo "Some + longish documentation." + input T1 x; +// ^ definition.variable +algorithm + () := match x + local + Real y1; +// ^ definition.variable + list y2; +// ^ definition.variable + list y3; +// ^ definition.variable + list>> y4; +// ^ definition.variable + case T1.R(_) + algorithm + doStuff(y1, y2); + then (); + + else + then fail(); + end match; +end foo; diff --git a/test/tags/VariableDefinitions.mo b/test/tags/VariableDefinitions.mo new file mode 100644 index 0000000..e14a256 --- /dev/null +++ b/test/tags/VariableDefinitions.mo @@ -0,0 +1,30 @@ +function foo + input Absyn.Operator operator; +// ^ definition.variable + input Real i1 "This is some input"; +// ^ definition.variable + output Real o1 "This is some output"; +// ^ definition.variable +protected + Real x1 "Some protected variable"; +// ^ definition.variable + Integer x2; +// ^ definition.variable + Boolean x3; +// ^ definition.variable + String x4; +// ^ definition.variable + MyType x5; +// ^ definition.variable +public + List x6 "Some public variable"; +// ^ definition.variable + List x7; +// ^ definition.variable + Option x8; +// ^ definition.variable + Option x9; +// ^ definition.variable + Tuple x10; +// ^ definition.variable +end foo;