SlideShare a Scribd company logo
1 of 54
Download to read offline
Community sponsors
Discover TASTy Query
The library for Scala program analysis
Jamie Thompson
2
● Not For Profit Organisation
● Located at EPFL, Switzerland
● Sponsored by donations
Scalafix
Metals
Scala Debug Adapter
BSP
scala3-migrate
Scala Native
Scala.js
● Website: https://scala.epfl.ch/
● Twitter: @scala_lang
● Discord: https://discord.gg/scala
● Scala Contributors Forum: https://contributors.scala-lang.org/
● Scala Users Forum: https://users.scala-lang.org/
● LinkedIn: https://www.linkedin.com/company/scala-center
3
Find us online
What is it?
TASTy Query
4
TASTy Query Elevator Pitch
● Cross platform (JS, JVM)
● Reason about and analyse APIs defined in Scala 3, Java, and Scala 2.13
● Extract full information from TASTy files.
● Simple to use
● Independent of compiler
5
A general purpose IR for Scala
So… TASTy?
6
7
Compiler Pipeline
Foo.scala
parser typer pickler
scalac
backend
➢ Typed AST
➢ Binary format
➢ Signatures for downstream libraries
➢ inline bodies
➢ Lossy
➢ Erased types
Foo.tasty
��
Foo.class
☕
TASTy Structure
8
0: PACKAGE(63)
2: TERMREFpkg 1 [<empty>]
4: TYPEDEF(59) 2 [Foo]
7: TEMPLATE(38)
9: PARAM(9) 3 [x]
12: TYPEREF 4 [String]
14: TERMREF 5 [Predef]
16: TERMREFpkg 6 [scala]
18: PRIVATE
19: LOCAL
20: APPLY(10)
22: SELECTin(8) 13 [<init>[Signed Signature(List(),java.lang.Object) @<init>]]
25: NEW
26: TYPEREF 11 [Object]
28: TERMREFpkg 10 [java[Qualified . lang]]
30: SHAREDtype 26
32: DEFDEF(13) 7 [<init>]
35: PARAM(5) 3 [x]
38: IDENTtpt 4 [String]
40: SHAREDtype 12
42: TYPEREF 14 [Unit]
44: SHAREDtype 16
46: STABLE
47: ANNOTATION(16)
49: TYPEREF 15 [SourceFile]
51: TERMREFpkg 19 [scala[Qualified . annotation][Qualified . internal]]
53: APPLY(10)
55: SELECTin(6) 22 [<init>[Signed Signature(List(java.lang.String),scala.annotation.internal.SourceFile) @<init>]]
58: NEW
59: SHAREDtype 49
61: SHAREDtype 49
63: STRINGconst 23 [Foo.scala]
class Foo(x: String)
package `<empty>`
@scala.annotation.internal.SourceFile(“Foo.scala”)
class Foo(private[this] val x: scala.Predef.String)
extends java.lang.Object()
9
Why is TASTy useful as a format?
● Stores the whole program
● Stable with respect to dependencies
○ Method overloads are already resolved
○ Implicits are already resolved
Foo.tasty
��
Why do we need it?
TASTy Query
10
11
Example Application
org::utils:1.0.0
my::app:2.7.2
foo::macros:3.3.
5
@main def app: Unit =
println(Macros.foo())
✅ my::app:2.7.2
12
object Utils:
def asList(xs: Seq[Int]): List[Int] = xs.toList org::utils:1.0.0
object Macros:
inline def foo(): String =
Utils.asList(Seq(1, 2, 3)).sum.toString
foo::macros:3.3.
5
Example Application: Code
13
Example Application: Upgrade
org::utils:1.0.0
my::app:2.7.2
foo::macros:3.3.
5
14
Example Application: Upgrade
org::utils:1.0.0
my::app:2.7.2
foo::macros:3.3.
5
org::utils:1.0.1 New patch release 🚀
15
Example Application: Upgrade
org::utils:1.0.0
my::app:2.7.2
foo::macros:3.3.
5
org::utils:1.0.1
Patch release? Let’s upgrade!
16
Example Application: Upgrade
org::utils:1.0.0
my::app:2.7.3
foo::macros:3.3.
5
org::utils:1.0.1
🤔
17
Example Application: Upgrade
org::utils:1.0.0
my::app:2.7.3
foo::macros:3.3.
5
org::utils:1.0.1
❌
😭
18
Example Application: Upgrade
org::utils:1.0.0
my::app:2.7.3
foo::macros:3.3.
5
org::utils:1.0.1
❌
😭
MiMa ✅ (binary compatible)
19
Example Application: Upgrade
org::utils:1.0.0
my::app:2.7.3
foo::macros:3.3.
5
org::utils:1.0.1
❌
😭
TASTy Compatibility ❌
20
Before
object Macros:
inline def foo(): String =
Utils.asList(Seq(1, 2, 3)).sum.toString
@main def app: Unit =
println(Macros.foo())
object Utils:
def asList(xs: Seq[Int]): List[Int] = xs.toList org::utils:1.0.0
my::app:2.7.2
foo::macros:3.3.
5
🤔
Seq[Int]
org::utils:1.0.0
21
After
object Macros:
inline def foo(): String =
Utils.asList(Seq(1, 2, 3)).sum.toString
@main def app: Unit =
println(Macros.foo())
object Utils:
def asList(xs: Int*): List[Int] = xs.toList
🤯 org::utils:1.0.1
my::app:2.7.3
foo::macros:3.3.
5
❌😭
❌😭
22
-- [E007] Type Mismatch Error: app.scala:2:20 ----------------------------------
2 | println(Macros.foo())
| ^^^^^^^^^^^^
| Found: Seq[Int]
| Required: Int
|-----------------------------------------------------------------------------
|Inline stack trace
|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|This location contains code that was inlined from Macros.scala:3
3 | Utils.asList(Seq(1, 2, 3)).sum.toString
| ^^^^^^^^^^^^
|-----------------------------------------------------------------------------
|
| longer explanation available when compiling with `-explain`
1 error found
23
So, What’s Happening?
1. Recompile my::app:2.7.3 against new dependency org::utils:1.0.1 .
2. def app calls inline def Macros.foo from foo::macros:3.3.5 .
○ ⚠ foo::macros:3.3.5 still depends on older org::utils:1.0.0 .
3. Compiler substitutes Macros.foo call by its inline body from TASTy.
4. Macros.foo body calls Utils.asList , which resolves to newer org::utils:1.0.1 .
5. Seq(1, 2, 3) argument not passed as varargs and so no longer type-checks!
○ org::utils:1.0.0 and org::utils:1.0.1 are not TASTy compatible!
24
TASTy Query Use Cases
● Validate API compatibility between releases ✅
● Metals Debugger ✅
● TASTy interpreter (for research) ✅
● Custom Analyses
Making a Query
TASTy Query
25
26
Goal: Analyse Inheritance in scala-library .
class A extends B with C
class B
trait C
A
B C
AnyRef
27
First Step: Building the Classpath
● Ordered sequence of entries ✅
● Each entry is a .jar file or directory ✅
● Inside each entry is .class/.tasty files, organised by package
✅
[0] my-library/target/scala-3.2.1/classes
[1]
maven2/org/scala-lang/scala3-library_3/3.2.1/scala3-library_3-3.2.1.jar
[2] maven2/org/scala-lang/scala-library/2.13.10/scala-library-2.13.10.jar
[3] jrt:/modules/java.base
import java.nio.file.*
val cpPaths = List(
Paths.get("my-library/target/scala-3.2.1/classes"),
Paths.get(".../scala3-library_3-3.2.1.jar"),
Paths.get(".../scala-library-2.13.10.jar"),
jrtFileSystem.getPath("modules/java.base")
)
28
First Step: Read the Classpath
import tastyquery.jdk.ClasspathLoaders
import tastyquery.Classpaths.Classpath
val classpath: Classpath = ClasspathLoaders.read(cpPaths)
val lookup: Map[Path, Classpath.Entry] =
cpPaths.zip(classpath.entries).toMap
import java.nio.file.*
val cpPaths = List(...) // from previous slide
29
First Step: Read the Classpath
● Pure, in-memory representation of classpath ✅
● Each Entry stores .class/.tasty files found in its source path ✅
● Platform agnostic (JS/JVM) ✅
Classpath.Entry
Classpath
30
● A Context wraps a Classpath ✅
● Entry point to inspect definitions ✅
● Summon a Context with ctx ✅
Second Step: Context
import tastyquery.Contexts
import tastyquery.Contexts.*
Context
given Context = Contexts.init(classpath)
31
Third Step: Query
🤔 how to find only the classes from scala-library ?
val scalaLib: Classpath.Entry =
lookup.filterKeys(_.toString.contains("scala-library")).values.head
val scalaLibRoots: Iterable[Symbol] =
ctx.findSymbolsByClasspathEntry(scalaLib) // top-level classes
val lookup: Map[Path, Classpath.Entry] = … // from earlier slide
import tastyquery.Symbols.*
32
Core Concepts: Data
Symbols
● Unique identity for a definition ✅
● Store all information about the definition ✅
● Specialised for each kind of definition ✅
import tastyquery.Symbols.*
DeclaringSymbol
33
Core Concepts: Data
Symbols
Symbol
ClassSymbol TypeParamSymbol
TypeMemberSymbol
PackageSymbol TermSymbol
TypeSymbol
import tastyquery.Symbols.*
34
ClassSymbol Methods
cls.parentClasses List[ClassSymbol] of the parents of the class.
cls.fullName FullyQualifiedName of the class.
cls.owner What symbol was cls declared in?
cls.getDecls(name) Find all overloads in cls matching a Name .
cls.declarations Find all symbols declared in cls .
ClassSymbol
35
Comparison to the Compiler API
● Inspired by compiler ✅
● Single “temporal” view ✅
● Favor specialisation over abstraction ✅
TermSymbol
declaredType
Type
TypeMemberSymbol
bounds
TypeBounds
ClassSymbol
parents
List[Type]
typeParams
List[CTPSymbol]
36
Comparison to the Compiler API
dotty.tools.dotc API
Symbol
info
Type | TypeBounds | ClassInfo
❌
● Inspired by compiler ✅
● Single “temporal” view ✅
● Favor specialisation over abstraction ✅
37
Third Step: Query
🤔 how to find only the classes in scala.collection.mutable ?
val mutablePackage = ctx.findPackage("scala.collection.mutable")
val mutableClasses: Iterable[ClassSymbol] =
scalaLibRoots.collect {
case cls: ClassSymbol if cls.owner == mutablePackage => cls
}
val scalaLibRoots: Iterable[Symbol] = … // from earlier slide
Algorithm
Inheritance Graph
38
39
Computing inheritance graph of class A
1. Links := []; explore := {class A}
2. While explore is non-empty:
a. remove class A from explore
b. For each parent class P of A:
i. add a link class A -> class P
ii. add class P to explore
3. Return Links
Demo
Inheritance Graph
40
API Overview
TASTy Query
41
Symbols Names
42
Core Concepts: Data
import tastyquery.Names.*
import tastyquery.Symbols.*
import tastyquery.Types.*
import tastyquery.Trees.*
Trees
Types
Names
43
Core Concepts: Data
Name
TermName ...
TypeName SignedName
Trees
Types
sym.name
Names
44
Core Concepts: Data
SignedName
foo [
Signed @bar (1,java.lang.Object):java.lang.Object
]
@targetName("bar") def foo[T](t: T): T
def foo(x: Int, y: String): Int
Trees
Types
sym.signedName
Types
45
Core Concepts: Data Trees
Type
TermRef ...
TypeRef
TypeBounds
sym.declaredType
46
Core Concepts: Data
TypeTree Tree
Trees
Ident ...
Select
sym.tree
Cheatsheet
TASTy Query
47
48
Types
tp1.isSubType(tp2) Boolean is tp1 <:< tp2 by Scala’s type rules
tp1.isSameType(tp2) Boolean is tp1 =:= tp2 by Scala’s type rules
tp1.member(name) Find a (possibly inherited) member of tp1 called name .
tp1.isRef(sym) Does tp1 reduce to a reference of sym ?
val tp1: Type
val tp2: Type
val name: Name
val sym: Symbol
49
Overrides
f.overridenSymbol(cls) Which term/type in cls is overridden by f ?
f.overridingSymbol(cls) Which term/type in cls overrides f ?
f.allOverriddenSymbols
Find all the terms/types overridden by f in parent
classes.
f.nextOverriddenSymbol
Find the first term/type overridden by f in parent
classes.
val f: TermOrTypeSymbol
val cls: ClassSymbol
Do They Exist?
Alternatives
50
51
Why Not Use…
● Scala 3 compiler’s tasty-inspector library?
● Scalameta?
Summary
52
Summary
● TASTy Query will be critical for Scala ecosystem’s infrastructure
● Simple API to inspect definitions from all the classpath
● Cross platform
● Accessible for many kinds of user.
53
Community sponsors
Thank you!
Any questions?

More Related Content

Similar to Discover Tasty Query: The library for Scala program analysis

New features in jdk8 iti
New features in jdk8 itiNew features in jdk8 iti
New features in jdk8 itiAhmed mar3y
 
Develop realtime web with Scala and Xitrum
Develop realtime web with Scala and XitrumDevelop realtime web with Scala and Xitrum
Develop realtime web with Scala and XitrumNgoc Dao
 
Inria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMP
Inria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMPInria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMP
Inria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMPStéphanie Roger
 
New Features in JDK 8
New Features in JDK 8New Features in JDK 8
New Features in JDK 8Martin Toshev
 
Reducing Redundancies in Multi-Revision Code Analysis
Reducing Redundancies in Multi-Revision Code AnalysisReducing Redundancies in Multi-Revision Code Analysis
Reducing Redundancies in Multi-Revision Code AnalysisSebastiano Panichella
 
Plugin-based software design with Ruby and RubyGems
Plugin-based software design with Ruby and RubyGemsPlugin-based software design with Ruby and RubyGems
Plugin-based software design with Ruby and RubyGemsSadayuki Furuhashi
 
Implementing one feature set in two JavaScript engines (Web Engines Hackfest ...
Implementing one feature set in two JavaScript engines (Web Engines Hackfest ...Implementing one feature set in two JavaScript engines (Web Engines Hackfest ...
Implementing one feature set in two JavaScript engines (Web Engines Hackfest ...Igalia
 
SQLGitHub - Access GitHub API with SQL-like syntaxes
SQLGitHub - Access GitHub API with SQL-like syntaxesSQLGitHub - Access GitHub API with SQL-like syntaxes
SQLGitHub - Access GitHub API with SQL-like syntaxesJasmine Chen
 
Managing Binary Compatibility in Scala (Scala Days 2011)
Managing Binary Compatibility in Scala (Scala Days 2011)Managing Binary Compatibility in Scala (Scala Days 2011)
Managing Binary Compatibility in Scala (Scala Days 2011)mircodotta
 
130614 sebastiano panichella - mining source code descriptions from develo...
130614   sebastiano panichella -  mining source code descriptions from develo...130614   sebastiano panichella -  mining source code descriptions from develo...
130614 sebastiano panichella - mining source code descriptions from develo...Ptidej Team
 
Microservices Application Tracing Standards and Simulators - Adrians at OSCON
Microservices Application Tracing Standards and Simulators - Adrians at OSCONMicroservices Application Tracing Standards and Simulators - Adrians at OSCON
Microservices Application Tracing Standards and Simulators - Adrians at OSCONAdrian Cockcroft
 
JDD2015: ClassIndex - szybka alternatywa dla skanowania klas - Sławek Piotrowski
JDD2015: ClassIndex - szybka alternatywa dla skanowania klas - Sławek PiotrowskiJDD2015: ClassIndex - szybka alternatywa dla skanowania klas - Sławek Piotrowski
JDD2015: ClassIndex - szybka alternatywa dla skanowania klas - Sławek PiotrowskiPROIDEA
 
DEF CON 27 - workshop - ISAAC EVANS - discover exploit and eradicate entire v...
DEF CON 27 - workshop - ISAAC EVANS - discover exploit and eradicate entire v...DEF CON 27 - workshop - ISAAC EVANS - discover exploit and eradicate entire v...
DEF CON 27 - workshop - ISAAC EVANS - discover exploit and eradicate entire v...Felipe Prado
 
Python and Zope: An introduction (May 2004)
Python and Zope: An introduction (May 2004)Python and Zope: An introduction (May 2004)
Python and Zope: An introduction (May 2004)Kiran Jonnalagadda
 
JavaScript Miller Columns
JavaScript Miller ColumnsJavaScript Miller Columns
JavaScript Miller ColumnsJonathan Fine
 
Using advanced C# features in Sharepoint development
Using advanced C# features in Sharepoint developmentUsing advanced C# features in Sharepoint development
Using advanced C# features in Sharepoint developmentsadomovalex
 
Hadoop cluster performance profiler
Hadoop cluster performance profilerHadoop cluster performance profiler
Hadoop cluster performance profilerIhor Bobak
 

Similar to Discover Tasty Query: The library for Scala program analysis (20)

New features in jdk8 iti
New features in jdk8 itiNew features in jdk8 iti
New features in jdk8 iti
 
Nzitf Velociraptor Workshop
Nzitf Velociraptor WorkshopNzitf Velociraptor Workshop
Nzitf Velociraptor Workshop
 
Develop realtime web with Scala and Xitrum
Develop realtime web with Scala and XitrumDevelop realtime web with Scala and Xitrum
Develop realtime web with Scala and Xitrum
 
Inria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMP
Inria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMPInria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMP
Inria Tech Talk : Comment améliorer la qualité de vos logiciels avec STAMP
 
New Features in JDK 8
New Features in JDK 8New Features in JDK 8
New Features in JDK 8
 
Reducing Redundancies in Multi-Revision Code Analysis
Reducing Redundancies in Multi-Revision Code AnalysisReducing Redundancies in Multi-Revision Code Analysis
Reducing Redundancies in Multi-Revision Code Analysis
 
Plugin-based software design with Ruby and RubyGems
Plugin-based software design with Ruby and RubyGemsPlugin-based software design with Ruby and RubyGems
Plugin-based software design with Ruby and RubyGems
 
Implementing one feature set in two JavaScript engines (Web Engines Hackfest ...
Implementing one feature set in two JavaScript engines (Web Engines Hackfest ...Implementing one feature set in two JavaScript engines (Web Engines Hackfest ...
Implementing one feature set in two JavaScript engines (Web Engines Hackfest ...
 
SQLGitHub - Access GitHub API with SQL-like syntaxes
SQLGitHub - Access GitHub API with SQL-like syntaxesSQLGitHub - Access GitHub API with SQL-like syntaxes
SQLGitHub - Access GitHub API with SQL-like syntaxes
 
Managing Binary Compatibility in Scala (Scala Days 2011)
Managing Binary Compatibility in Scala (Scala Days 2011)Managing Binary Compatibility in Scala (Scala Days 2011)
Managing Binary Compatibility in Scala (Scala Days 2011)
 
130614 sebastiano panichella - mining source code descriptions from develo...
130614   sebastiano panichella -  mining source code descriptions from develo...130614   sebastiano panichella -  mining source code descriptions from develo...
130614 sebastiano panichella - mining source code descriptions from develo...
 
Microservices Application Tracing Standards and Simulators - Adrians at OSCON
Microservices Application Tracing Standards and Simulators - Adrians at OSCONMicroservices Application Tracing Standards and Simulators - Adrians at OSCON
Microservices Application Tracing Standards and Simulators - Adrians at OSCON
 
Java 8 Lambda
Java 8 LambdaJava 8 Lambda
Java 8 Lambda
 
JDD2015: ClassIndex - szybka alternatywa dla skanowania klas - Sławek Piotrowski
JDD2015: ClassIndex - szybka alternatywa dla skanowania klas - Sławek PiotrowskiJDD2015: ClassIndex - szybka alternatywa dla skanowania klas - Sławek Piotrowski
JDD2015: ClassIndex - szybka alternatywa dla skanowania klas - Sławek Piotrowski
 
DEF CON 27 - workshop - ISAAC EVANS - discover exploit and eradicate entire v...
DEF CON 27 - workshop - ISAAC EVANS - discover exploit and eradicate entire v...DEF CON 27 - workshop - ISAAC EVANS - discover exploit and eradicate entire v...
DEF CON 27 - workshop - ISAAC EVANS - discover exploit and eradicate entire v...
 
Python and Zope: An introduction (May 2004)
Python and Zope: An introduction (May 2004)Python and Zope: An introduction (May 2004)
Python and Zope: An introduction (May 2004)
 
JavaScript Miller Columns
JavaScript Miller ColumnsJavaScript Miller Columns
JavaScript Miller Columns
 
9-roslyn-guidelines
9-roslyn-guidelines9-roslyn-guidelines
9-roslyn-guidelines
 
Using advanced C# features in Sharepoint development
Using advanced C# features in Sharepoint developmentUsing advanced C# features in Sharepoint development
Using advanced C# features in Sharepoint development
 
Hadoop cluster performance profiler
Hadoop cluster performance profilerHadoop cluster performance profiler
Hadoop cluster performance profiler
 

Recently uploaded

Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsAndrey Dotsenko
 
Bluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfBluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfngoud9212
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Alan Dix
 
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024BookNet Canada
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Snow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter RoadsSnow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter RoadsHyundai Motor Group
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 

Recently uploaded (20)

Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Bluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfBluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdf
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...Swan(sea) Song – personal research during my six years at Swansea ... and bey...
Swan(sea) Song – personal research during my six years at Swansea ... and bey...
 
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
 
The transition to renewables in India.pdf
The transition to renewables in India.pdfThe transition to renewables in India.pdf
The transition to renewables in India.pdf
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Snow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter RoadsSnow Chain-Integrated Tire for a Safe Drive on Winter Roads
Snow Chain-Integrated Tire for a Safe Drive on Winter Roads
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 

Discover Tasty Query: The library for Scala program analysis

  • 1. Community sponsors Discover TASTy Query The library for Scala program analysis Jamie Thompson
  • 2. 2 ● Not For Profit Organisation ● Located at EPFL, Switzerland ● Sponsored by donations Scalafix Metals Scala Debug Adapter BSP scala3-migrate Scala Native Scala.js
  • 3. ● Website: https://scala.epfl.ch/ ● Twitter: @scala_lang ● Discord: https://discord.gg/scala ● Scala Contributors Forum: https://contributors.scala-lang.org/ ● Scala Users Forum: https://users.scala-lang.org/ ● LinkedIn: https://www.linkedin.com/company/scala-center 3 Find us online
  • 5. TASTy Query Elevator Pitch ● Cross platform (JS, JVM) ● Reason about and analyse APIs defined in Scala 3, Java, and Scala 2.13 ● Extract full information from TASTy files. ● Simple to use ● Independent of compiler 5
  • 6. A general purpose IR for Scala So… TASTy? 6
  • 7. 7 Compiler Pipeline Foo.scala parser typer pickler scalac backend ➢ Typed AST ➢ Binary format ➢ Signatures for downstream libraries ➢ inline bodies ➢ Lossy ➢ Erased types Foo.tasty �� Foo.class ☕
  • 8. TASTy Structure 8 0: PACKAGE(63) 2: TERMREFpkg 1 [<empty>] 4: TYPEDEF(59) 2 [Foo] 7: TEMPLATE(38) 9: PARAM(9) 3 [x] 12: TYPEREF 4 [String] 14: TERMREF 5 [Predef] 16: TERMREFpkg 6 [scala] 18: PRIVATE 19: LOCAL 20: APPLY(10) 22: SELECTin(8) 13 [<init>[Signed Signature(List(),java.lang.Object) @<init>]] 25: NEW 26: TYPEREF 11 [Object] 28: TERMREFpkg 10 [java[Qualified . lang]] 30: SHAREDtype 26 32: DEFDEF(13) 7 [<init>] 35: PARAM(5) 3 [x] 38: IDENTtpt 4 [String] 40: SHAREDtype 12 42: TYPEREF 14 [Unit] 44: SHAREDtype 16 46: STABLE 47: ANNOTATION(16) 49: TYPEREF 15 [SourceFile] 51: TERMREFpkg 19 [scala[Qualified . annotation][Qualified . internal]] 53: APPLY(10) 55: SELECTin(6) 22 [<init>[Signed Signature(List(java.lang.String),scala.annotation.internal.SourceFile) @<init>]] 58: NEW 59: SHAREDtype 49 61: SHAREDtype 49 63: STRINGconst 23 [Foo.scala] class Foo(x: String) package `<empty>` @scala.annotation.internal.SourceFile(“Foo.scala”) class Foo(private[this] val x: scala.Predef.String) extends java.lang.Object()
  • 9. 9 Why is TASTy useful as a format? ● Stores the whole program ● Stable with respect to dependencies ○ Method overloads are already resolved ○ Implicits are already resolved Foo.tasty ��
  • 10. Why do we need it? TASTy Query 10
  • 12. @main def app: Unit = println(Macros.foo()) ✅ my::app:2.7.2 12 object Utils: def asList(xs: Seq[Int]): List[Int] = xs.toList org::utils:1.0.0 object Macros: inline def foo(): String = Utils.asList(Seq(1, 2, 3)).sum.toString foo::macros:3.3. 5 Example Application: Code
  • 20. 20 Before object Macros: inline def foo(): String = Utils.asList(Seq(1, 2, 3)).sum.toString @main def app: Unit = println(Macros.foo()) object Utils: def asList(xs: Seq[Int]): List[Int] = xs.toList org::utils:1.0.0 my::app:2.7.2 foo::macros:3.3. 5 🤔 Seq[Int]
  • 21. org::utils:1.0.0 21 After object Macros: inline def foo(): String = Utils.asList(Seq(1, 2, 3)).sum.toString @main def app: Unit = println(Macros.foo()) object Utils: def asList(xs: Int*): List[Int] = xs.toList 🤯 org::utils:1.0.1 my::app:2.7.3 foo::macros:3.3. 5 ❌😭 ❌😭
  • 22. 22 -- [E007] Type Mismatch Error: app.scala:2:20 ---------------------------------- 2 | println(Macros.foo()) | ^^^^^^^^^^^^ | Found: Seq[Int] | Required: Int |----------------------------------------------------------------------------- |Inline stack trace |- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |This location contains code that was inlined from Macros.scala:3 3 | Utils.asList(Seq(1, 2, 3)).sum.toString | ^^^^^^^^^^^^ |----------------------------------------------------------------------------- | | longer explanation available when compiling with `-explain` 1 error found
  • 23. 23 So, What’s Happening? 1. Recompile my::app:2.7.3 against new dependency org::utils:1.0.1 . 2. def app calls inline def Macros.foo from foo::macros:3.3.5 . ○ ⚠ foo::macros:3.3.5 still depends on older org::utils:1.0.0 . 3. Compiler substitutes Macros.foo call by its inline body from TASTy. 4. Macros.foo body calls Utils.asList , which resolves to newer org::utils:1.0.1 . 5. Seq(1, 2, 3) argument not passed as varargs and so no longer type-checks! ○ org::utils:1.0.0 and org::utils:1.0.1 are not TASTy compatible!
  • 24. 24 TASTy Query Use Cases ● Validate API compatibility between releases ✅ ● Metals Debugger ✅ ● TASTy interpreter (for research) ✅ ● Custom Analyses
  • 26. 26 Goal: Analyse Inheritance in scala-library . class A extends B with C class B trait C A B C AnyRef
  • 27. 27 First Step: Building the Classpath ● Ordered sequence of entries ✅ ● Each entry is a .jar file or directory ✅ ● Inside each entry is .class/.tasty files, organised by package ✅ [0] my-library/target/scala-3.2.1/classes [1] maven2/org/scala-lang/scala3-library_3/3.2.1/scala3-library_3-3.2.1.jar [2] maven2/org/scala-lang/scala-library/2.13.10/scala-library-2.13.10.jar [3] jrt:/modules/java.base import java.nio.file.* val cpPaths = List( Paths.get("my-library/target/scala-3.2.1/classes"), Paths.get(".../scala3-library_3-3.2.1.jar"), Paths.get(".../scala-library-2.13.10.jar"), jrtFileSystem.getPath("modules/java.base") )
  • 28. 28 First Step: Read the Classpath import tastyquery.jdk.ClasspathLoaders import tastyquery.Classpaths.Classpath val classpath: Classpath = ClasspathLoaders.read(cpPaths) val lookup: Map[Path, Classpath.Entry] = cpPaths.zip(classpath.entries).toMap import java.nio.file.* val cpPaths = List(...) // from previous slide
  • 29. 29 First Step: Read the Classpath ● Pure, in-memory representation of classpath ✅ ● Each Entry stores .class/.tasty files found in its source path ✅ ● Platform agnostic (JS/JVM) ✅ Classpath.Entry Classpath
  • 30. 30 ● A Context wraps a Classpath ✅ ● Entry point to inspect definitions ✅ ● Summon a Context with ctx ✅ Second Step: Context import tastyquery.Contexts import tastyquery.Contexts.* Context given Context = Contexts.init(classpath)
  • 31. 31 Third Step: Query 🤔 how to find only the classes from scala-library ? val scalaLib: Classpath.Entry = lookup.filterKeys(_.toString.contains("scala-library")).values.head val scalaLibRoots: Iterable[Symbol] = ctx.findSymbolsByClasspathEntry(scalaLib) // top-level classes val lookup: Map[Path, Classpath.Entry] = … // from earlier slide import tastyquery.Symbols.*
  • 32. 32 Core Concepts: Data Symbols ● Unique identity for a definition ✅ ● Store all information about the definition ✅ ● Specialised for each kind of definition ✅ import tastyquery.Symbols.*
  • 33. DeclaringSymbol 33 Core Concepts: Data Symbols Symbol ClassSymbol TypeParamSymbol TypeMemberSymbol PackageSymbol TermSymbol TypeSymbol import tastyquery.Symbols.*
  • 34. 34 ClassSymbol Methods cls.parentClasses List[ClassSymbol] of the parents of the class. cls.fullName FullyQualifiedName of the class. cls.owner What symbol was cls declared in? cls.getDecls(name) Find all overloads in cls matching a Name . cls.declarations Find all symbols declared in cls . ClassSymbol
  • 35. 35 Comparison to the Compiler API ● Inspired by compiler ✅ ● Single “temporal” view ✅ ● Favor specialisation over abstraction ✅ TermSymbol declaredType Type TypeMemberSymbol bounds TypeBounds ClassSymbol parents List[Type] typeParams List[CTPSymbol]
  • 36. 36 Comparison to the Compiler API dotty.tools.dotc API Symbol info Type | TypeBounds | ClassInfo ❌ ● Inspired by compiler ✅ ● Single “temporal” view ✅ ● Favor specialisation over abstraction ✅
  • 37. 37 Third Step: Query 🤔 how to find only the classes in scala.collection.mutable ? val mutablePackage = ctx.findPackage("scala.collection.mutable") val mutableClasses: Iterable[ClassSymbol] = scalaLibRoots.collect { case cls: ClassSymbol if cls.owner == mutablePackage => cls } val scalaLibRoots: Iterable[Symbol] = … // from earlier slide
  • 39. 39 Computing inheritance graph of class A 1. Links := []; explore := {class A} 2. While explore is non-empty: a. remove class A from explore b. For each parent class P of A: i. add a link class A -> class P ii. add class P to explore 3. Return Links
  • 42. Symbols Names 42 Core Concepts: Data import tastyquery.Names.* import tastyquery.Symbols.* import tastyquery.Types.* import tastyquery.Trees.* Trees Types
  • 43. Names 43 Core Concepts: Data Name TermName ... TypeName SignedName Trees Types sym.name
  • 44. Names 44 Core Concepts: Data SignedName foo [ Signed @bar (1,java.lang.Object):java.lang.Object ] @targetName("bar") def foo[T](t: T): T def foo(x: Int, y: String): Int Trees Types sym.signedName
  • 45. Types 45 Core Concepts: Data Trees Type TermRef ... TypeRef TypeBounds sym.declaredType
  • 46. 46 Core Concepts: Data TypeTree Tree Trees Ident ... Select sym.tree
  • 48. 48 Types tp1.isSubType(tp2) Boolean is tp1 <:< tp2 by Scala’s type rules tp1.isSameType(tp2) Boolean is tp1 =:= tp2 by Scala’s type rules tp1.member(name) Find a (possibly inherited) member of tp1 called name . tp1.isRef(sym) Does tp1 reduce to a reference of sym ? val tp1: Type val tp2: Type val name: Name val sym: Symbol
  • 49. 49 Overrides f.overridenSymbol(cls) Which term/type in cls is overridden by f ? f.overridingSymbol(cls) Which term/type in cls overrides f ? f.allOverriddenSymbols Find all the terms/types overridden by f in parent classes. f.nextOverriddenSymbol Find the first term/type overridden by f in parent classes. val f: TermOrTypeSymbol val cls: ClassSymbol
  • 51. 51 Why Not Use… ● Scala 3 compiler’s tasty-inspector library? ● Scalameta?
  • 53. Summary ● TASTy Query will be critical for Scala ecosystem’s infrastructure ● Simple API to inspect definitions from all the classpath ● Cross platform ● Accessible for many kinds of user. 53