Skip to content

Latest commit

 

History

History
309 lines (273 loc) · 13.6 KB

README.md

File metadata and controls

309 lines (273 loc) · 13.6 KB

SemanticDB examples

Scalameta project Directory semanticdb-examples\ contains SemanticDB code examples coming from various websites - mostly from the SemanticDB project.

We need to install additional command-line tools in order to work on our code examples.

  • Metac 1 – to generate .semanticdb files from .scala files.
  • Metap – to prettyprint .semanticdb files.
  • Protoc 2 – to compile .proto files.

🔎 The above tools must be installed in two different ways:

In our case we execute the batch command semanticdb-examples\setenv.bat to provide additional settings to our environment :

> setenv.bat -verbose
Tool versions:
   java 17.0.9, javac 17.0.9, scalac 3.3.2-RC1,
   protoc 25.1, cs 2.0.13, kotlinc 1.9.22,
   git 2.43.0.windows.1, diff 3.10, bash 5.2.21(1)-release
Tool paths:
   C:\opt\jdk-temurin-17.0.9_9\bin\java.exe
   C:\opt\jdk-temurin-17.0.9_9\bin\javac.exe
   C:\opt\scala3-3.3.2-RC1\bin\scalac.bat
   C:\opt\protoc\bin\protoc.exe
   %LOCALAPPDATA%\Coursier\data\bin\cs.bat
   C:\opt\kotlinc-1.9.22\bin\kotlinc.bat
   C:\opt\Git\bin\git.exe
   C:\opt\Git\usr\bin\diff.exe
   C:\opt\Git\bin\bash.exe
Environment variables:
   "COURSIER_HOME=C:\opt\coursier-2.1.7"
   "GIT_HOME=C:\opt\Git"
   "JAVA_HOME=C:\opt\jdk-temurin-17.0.9_9"
   "KOTLIN_HOME=C:\opt\kotlinc-1.9.22"
   "PROTOC_HOME=C:\opt\protoc"
Path associations:
   I:\: => %USERPROFILE%\workspace-perso\dotty-examples

hello Example

Command build.bat run generates and prettyprints the SemanticDB data for the Scala program Main.scala :

> build -verbose run
Create semanticdb file
Prettyprint contents of semanticdb files
src/main/scala/Main.scala
−-----------------------
 
Summary:
Schema => SemanticDB v4
Uri => src/main/scala/Main.scala
Text => empty
Language => Scala
Symbols => 3 entries
Occurrences => 7 entries

Symbols:
_empty_/Main. => final object Main extends AnyRef { +1 decls }
_empty_/Main.main(). => method main(args: Array[String]): Unit
_empty_/Main.main().(args) => param args: Array[String]

Occurrences:
[0:7..0:11) <= _empty_/Main.
[2:6..2:10) <= _empty_/Main.main().
[2:11..2:15) <= _empty_/Main.main().(args)
[2:17..2:22) => scala/Array#
[2:23..2:29) => scala/Predef.String#
[2:33..2:37) => scala/Unit#
[3:4..3:11) => scala/Predef.println(+1).

Similarly command build.bat -lang:java run generates and prettyprints the SemanticDB data for the Java program Main.java :

> build -lang:java run
Main.java
−--------

Summary:
Schema => SemanticDB v4
Uri => Main.java
Text => empty
Language => Java
Symbols => 4 entries
Occurrences => 8 entries
 
Symbols:
``/Main# => class Main extends Object { +2 decls }
``/Main#``(). => ctor (): Unit
``/Main#main(). => static method main(private[main] unknown args: Array[String]): Unit
local0 => private[main] unknown args: Array[String]
 
Occurrences:
[0:13..0:17) <= ``/Main#
[0:13..0:17) <= ``/Main#``().
[2:23..2:27) <= ``/Main#main().
[2:28..2:34) => java/lang/String#
[2:37..2:41) <= local0
[3:8..3:14) => java/lang/System#
[3:15..3:18) => java/lang/System#out.
[3:19..3:26) => java/io/PrintStream#println(+8).

With tiny code examples such as Main.scala we could also update the PATH variable and work with the two commands metac and metap directly :

> set "PATH=%PATH%;%COURSIER_DATA_DIR%\bin;c:\opt\protoc-23.4"
 
> where metac
%LOCALAPPDATA%\Coursier\data\bin\metac.bat
 
> metac -d target\classes src\main\scala\Main.scala
 
> tree /f target\classes |findstr /b /v [a-z]
│   .latest-build
│
└───META-INF
    └───semanticdb
        └───src
            └───main
                └───scala
                        Main.scala.semanticdb
 
> metap target\classes
src/main/scala/Main.scala
−−−−−−−−−−−−−−−−
 
Summary:
Schema => SemanticDB v4
Uri => src/main/scala/Main.scala
Text => empty
Language => Scala
Symbols => 3 entries
Occurrences => 7 entries
 
Symbols:
_empty_/Main. => final object Main extends AnyRef { +1 decls }
_empty_/Main.main(). => method main(args: Array[String]): Unit
_empty_/Main.main().(args) => param args: Array[String]

Occurrences:
[0:7..0:11) <= _empty_/Main.
[1:6..1:10) <= _empty_/Main.main().
[1:11..1:15) <= _empty_/Main.main().(args)
[1:17..1:22) => scala/Array#
[1:23..1:29) => scala/Predef.String#
[1:33..1:37) => scala/Unit#
[2:4..2:11) => scala/Predef.println(+1).

🔎 By default command metap <classpath> prints only the most important parts of the SemanticDB payload (default option is -compact).

Finally command build.bat -lang:kotlin run fails to generate the SemanticDB data for the Kotlin program Main.kt :

> build -verbose -lang:kotlin clean run
Delete directory "target"
Create semanticdb file
warning: flag is not supported by this version of the compiler: \
-Xplugin:semanticdb \
-sourceroot:%USERPROFILE%\workspace-perso\dotty-examples\semanticdb-examples\hello\src\main\kotlin \
-targetroot:%USERPROFILE%\workspace-perso\dotty-examples\semanticdb-examples\hello\target\kotlin-classes
Prettyprint contents of semanticdb files
 
> C:\opt\kotlinc-1.9.22\bin\kotlinc -version
info: kotlinc-jvm 1.9.22 (JRE 17.0.9+9)

semanticdb-example

This code example is an updated version of Geirsson's example (May 2018) available from his GitHub project olafurpg/semantic-example.

This example is interesting because we programmatically access the generated .semanticdb files from the main program Main.scala.

> build -verbose compile
Generate SemanticDB data for 2 Scala source files into directory "example\target\classes"
Compile 1 Scala source file to directory "cli\target\classes"
 
> tree /f example\target\classes |findstr /b /v [a-z]
└───META-INF
    └───semanticdb
        └───example
            └───src
                └───main
                    └───scala
                        └───example
                                Domain.scala.semanticdb
                                Example.scala.semanticdb

Then we execute the main program and redirect the output to some file, e.g. output.txt:

> build -verbose run > output.txt
No action required ('example\src\main\scala\*.scala')
No action required ('cli\src\main\scala\*.scala')
 
> more output.txt
W:\semanticdb-examples\semanticdb-example\cli\src\main\scala\tool\Main.scala:28 document.uri: "example/src/main/scala/example/Domain.scala"
range {
  start_line: 8
  start_character: 27
  end_line: 8
  end_character: 33
}
symbol: "scala/Predef.String#"
role: REFERENCE
[...]
range {
  start_line: 8
  start_character: 57

Footnotes

[1] Scalameta CLI tools

CLI tool Java archive Entry point
metac.bat scalameta_2.13-X.Y.Z.jar scala.meta.cli.Metac
metacp.bat scalameta_2.13-X.Y.Z.jar scala.meta.cli.Metacp
metap.bat scalameta_2.13-X.Y.Z.jar scala.meta.cli.Metap
> where /r %COURSIER_DATA_DIR% metac
%LOCALAPPDATA%\Coursier\data\bin\metac.bat

[2] protoc

> c:\opt\protoc\bin\protoc.exe --version
libprotoc 25.1

[3] Installation with Coursier

> where cs
C:\opt\coursier-2.1.7\cs.exe
 
> cs install metac metap
https://repo1.maven.org/maven2/io/get-coursier/apps/maven-metadata.xml
  100.0% [##########] 2.0 KiB (18.6 KiB / s)
[...]
https://repo1.maven.org/maven2/org/scalameta/semanticdb-scalac_2.13.11/4.7.8/semanticdb-scalac_2.13.11-4.7.8.jar
  100.0% [##########] 14.6 MiB (1.2 MiB / s)
Wrote metac
[...]
https://repo1.maven.org/maven2/com/thesamet/scalapb/scalapb-runtime_2.13/0.11.11/scalapb-runtime_2.13-0.11.11.jar
  100.0% [##########] 2.3 MiB (1.1 MiB / s)
Wrote metap
Warning: %LOCALAPPDATA%\Coursier\data\bin is not in your PATH

mics/November 2024