SemanticDB examples ⬆
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:
- We need Coursier to install the
metac
andmetap
comand line tools 3 (no Tgz/Zip archive available).- We extract the Zip archive
protoc-yy.z-win64.zip
(available from GitHub projectprotocolbuffers/protobuf
) into directoryC:\opt\protoc-yy.z\
.
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
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