Skip to content

Commit 75b0126

Browse files
authored
Refactor: Sync Contributing section from Scala-lang Guide to Dotty website (#17459)
1 parent 8b15eb9 commit 75b0126

36 files changed

+1770
-259
lines changed
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
109 KB
Loading
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
layout: doc-page
3+
title: Contexts
4+
---
5+
6+
`dotc` has almost no global state (with the exception of the name table,
7+
which hashes strings into unique names). Instead, all
8+
essential bits of information that can vary over a compiler [run](./lifecycle.md) are collected
9+
in a `Context` (defined in [Contexts]).
10+
11+
Most methods in the compiler depend on an implicit anonymous `Context` parameter,
12+
and a typical definition looks like the following:
13+
```scala
14+
import dotty.tools.dotc.Contexts.{Context, ctx}
15+
16+
def doFoo(using Context): Unit =
17+
val current = ctx.run // access the Context parameter with `ctx`
18+
```
19+
20+
## Memory Leaks
21+
> **Careful:** Contexts can be heavy so beware of memory leaks
22+
23+
It is good practice to ensure that implicit contexts are not
24+
captured in closures or other long-lived objects, in order to avoid space leaks
25+
in the case where a closure can survive several compiler runs (e.g. a
26+
lazy completer for a library class that is never required). In that case, the
27+
convention is that the `Context` be an explicit parameter, to track its usage.
28+
29+
## Context Properties
30+
31+
| Context property | description |
32+
|-------------------|----------------------------------------|
33+
| `compilationUnit` | current compilation unit |
34+
| `phase` | current phase |
35+
| `run` | current run |
36+
| `period` | current period |
37+
| `settings` | the config passed to the compiler |
38+
| `reporter` | operations for logging errors/warnings |
39+
| `definitions` | the standard built in definitions |
40+
| `platform` | operations for the underlying platform |
41+
| `tree` | current tree |
42+
| `scope` | current scope |
43+
| `typer` | current typer |
44+
| `owner` | current owner symbol |
45+
| `outer` | outer Context |
46+
| `mode` | type checking mode |
47+
| `typerState` | |
48+
| `searchHistory` | |
49+
| `implicits` | |
50+
| ... | and so on |
51+
52+
53+
[Contexts]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/core/Contexts.scala
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
layout: index
3+
title: High Level Architecture
4+
---
5+
6+
This chapter of the guide describes the architecture and concepts of `dotc`,
7+
the Scala 3 compiler, including answers to questions such as:
8+
- "What are the transformations that happen to my code?"
9+
- "How do I run a compiler programatically?"
10+
- "What are symbols, denotations, names and types?"
11+
- "What is a compiler phase?"
12+
- "What is the compiler Context?"
13+
14+
and many more.
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
---
2+
layout: doc-page
3+
title: Compiler Overview
4+
---
5+
6+
At a high level, `dotc` is an interactive compiler (see [what is a compiler?](../index.md#what-is-a-compiler)),
7+
and can be invoked frequently, for example to answer questions for an IDE, provide REPL completions,
8+
or to manage incremental builds and more. Each of these use cases requires a customised
9+
workflow, but sharing a common core.
10+
11+
## Introducing the Compiler's Lifecycle
12+
13+
#### Core
14+
Customisation is provided by extending the [Compiler] class, which maintains an ordered
15+
list of [phases][Phases], and how to [run][Run] them. Each interaction with a compiler
16+
creates a new run, which is a complete iteration of the compiler's phases over a list
17+
of input sources. Each run has the capability to create new definitions or
18+
invalidate older ones, and `dotc` can [track these changes over time](../architecture/time.md).
19+
20+
#### Runs
21+
During a run, the input sources are converted to [compilation units][CompilationUnit] (i.e. the abstraction of
22+
compiler state associated with each input source); then iteratively: a single phase is applied to
23+
every compilation unit before progressing to the next phase.
24+
25+
#### Phases
26+
A phase is an abstract transformation over a compilation unit, it is usually responsible
27+
for transforming the trees and types representing the code of a source file. Some phases of
28+
the compiler are:
29+
- `parser`, which converts text that matches Scala's
30+
[syntax] into abstract syntax trees, ASTs
31+
- `typer`, which checks that trees conform to expected types
32+
- `erasure`, which retypes a more simplified program into one that has the same types as the JVM.
33+
- `genBCode`, the JVM backend, which converts erased compiler trees into Java bytecode format.
34+
35+
[You can read more about phases here](../architecture/phases.md#phase-categories).
36+
37+
#### Drivers
38+
39+
The core compiler also requires a lot of state to be initialised before use, such as [settings][ScalaSettings]
40+
and the [Context](../architecture/context.md). For convenience, the [Driver] class contains high level functions for
41+
configuring the compiler and invoking it programatically. The object [Main] inherits from `Driver`
42+
and is invoked by the `scalac` script.
43+
44+
## Code Structure
45+
46+
The code of the compiler is found in the package [dotty.tools],
47+
containing the following sub-packages:
48+
```scala
49+
tools // contains helpers and the `scala` generic runner
50+
├── backend // Compiler backends (currently JVM and JS)
51+
├── dotc // The main compiler, with subpackages:
52+
├── ast // Abstract syntax trees
53+
   ├── classpath
54+
   ├── config // Compiler configuration, settings, platform specific definitions.
55+
   ├── core // Core data structures and operations, with specific subpackages for:
56+
      ├── classfile // Reading of Java classfiles into core data structures
57+
      ├── tasty // Reading and writing of TASTY files to/from core data structures
58+
      └── unpickleScala2 // Reading of Scala2 symbol information into core data structures
59+
   ├── decompiler // pretty printing TASTY as code
60+
   ├── fromtasty // driver for recompilation from TASTY
61+
   ├── interactive // presentation compiler and code completions
62+
   ├── parsing // Scanner and parser
63+
   ├── plugins // compile plugin definitions
64+
   ├── printing // Pretty-printing trees, types and other data
65+
   ├── profile // internals for profiling the compiler
66+
   ├── quoted // internals for quoted reflection
67+
   ├── reporting // Reporting of error messages, warnings and other info.
68+
   ├── rewrites // Helpers for rewriting Scala 2's constructs into Scala 3's.
69+
   ├── sbt // Helpers for communicating with the Zinc compiler.
70+
   ├── semanticdb // Helpers for exporting semanticdb from trees.
71+
   ├── transform // Miniphases and helpers for tree transformations.
72+
   ├── typer // Type-checking
73+
   └── util // General purpose utility classes and modules.
74+
├── io // Helper modules for file access and classpath handling.
75+
├── repl // REPL driver and interaction with the terminal
76+
├── runner // helpers for the `scala` generic runner script
77+
└── scripting // scala runner for the -script argument
78+
```
79+
80+
81+
[Phases]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/core/Phases.scala
82+
[CompilationUnit]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/CompilationUnit.scala
83+
84+
[dotty.tools]: https://github.com/lampepfl/dotty/tree/master/compiler/src/dotty/tools
85+
[ScalaSettings]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
86+
[syntax]: https://docs.scala-lang.org/scala3/reference/syntax.html
87+
[Main]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/Main.scala
88+
[Driver]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/Driver.scala
89+
[Compiler]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/Compiler.scala
90+
[Run]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/Run.scala
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
---
2+
layout: doc-page
3+
title: Compiler Phases
4+
---
5+
6+
As described in the [compiler overview](lifecycle.md#phases), `dotc` is divided into a list of [phases][Phase],
7+
specified in the [Compiler] class.
8+
9+
#### Printing the phases of the Compiler
10+
11+
a flattened list of all the phases can be displayed by invoking
12+
the compiler with the `-Xshow-phases` flag:
13+
```
14+
$ scalac -Xshow-phases
15+
```
16+
17+
## Phase Groups
18+
19+
In class [Compiler] you can access the list of phases with the method `phases`:
20+
21+
```scala
22+
def phases: List[List[Phase]] =
23+
frontendPhases ::: picklerPhases ::: transformPhases ::: backendPhases
24+
```
25+
26+
You can see that phases are actually grouped into sublists, given by the signature
27+
`List[List[Phase]]`; that is, each sublist forms a phase group that is then *fused* into a
28+
single tree traversal when a [Run] is executed.
29+
30+
Phase fusion allows each phase of a group to be small and modular,
31+
(each performing a single function), while reducing the number of tree traversals
32+
and increasing performance.
33+
34+
Phases are able to be grouped together if they inherit from [MiniPhase].
35+
36+
## Phase Categories
37+
38+
Phases fall into four categories, allowing customisation by sub-classes of [Compiler]:
39+
40+
### `frontendPhases`
41+
In the main compiler these include [parser], [typer], [posttyper],
42+
[prepjsinterop] and phases for producing SemanticDB and communicating with the
43+
incremental compiler Zinc.
44+
The [parser] reads source programs and generates untyped abstract syntax trees, which
45+
in [typer] are then typechecked and transformed into typed abstract syntax trees.
46+
Following is [posttyper], performing checks and cleanups that require a fully typed program.
47+
In particular, it
48+
- creates super accessors representing `super` calls in traits
49+
- creates implementations of compiler-implemented methods,
50+
such as `equals` and `hashCode` for case classes.
51+
- marks [compilation units][CompilationUnit] that require inline expansion, or quote pickling
52+
- simplifies trees of erased definitions
53+
- checks variance of type parameters
54+
- mark parameters passed unchanged from subclass to superclass for later pruning.
55+
56+
### `picklerPhases`
57+
These phases start with [pickler], which serializes typed trees
58+
produced by the `frontendPhases` into TASTy format. Following is [inlining],
59+
which expand calls to inline methods, and [postInlining] providing implementations
60+
of the [Mirror] framework for inlined calls.
61+
Finally are [staging], which ensures that quotes conform to the
62+
[Phase Consistency Principle (PCP)][PCP], and [pickleQuotes] which converts quoted
63+
trees to embedded TASTy strings.
64+
65+
### `transformPhases`
66+
These phases are concerned with tranformation into lower-level forms
67+
suitable for the runtime system, with two sub-groupings:
68+
- High-level transformations: All phases from [firstTransform] to [erasure].
69+
Most of these phases transform syntax trees, expanding high-level constructs
70+
to more primitive ones.
71+
- An important transform phase is [patternMatcher], which converts match
72+
trees and patterns into lower level forms, as well as checking the
73+
exhaustivity of sealed types, and unreachability of pattern cases.
74+
- Some phases perform further checks on more primitive trees,
75+
e.g. [refchecks] verifies that no abstract methods exist in concrete classes,
76+
and [initChecker] checks that fields are not used before initialisation.
77+
- The last phase in the group, [erasure] translates all
78+
types into types supported directly by the JVM. To do this, it performs
79+
another type checking pass, but using the rules of the JVM's type system
80+
instead of Scala's.
81+
- Low-level transformations: All phases from `ElimErasedValueType` to
82+
`CollectSuperCalls`. These further transform trees until they are essentially a
83+
structured version of Java bytecode.
84+
85+
### `backendPhases`
86+
These map the transformed trees to Java classfiles or SJSIR files.
87+
88+
[CompilationUnit]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/CompilationUnit.scala
89+
[Compiler]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/Compiler.scala
90+
[Phase]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/core/Phases.scala
91+
[MiniPhase]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/MegaPhase.scala
92+
[Run]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/Run.scala
93+
[parser]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/parsing/ParserPhase.scala
94+
[typer]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/typer/TyperPhase.scala
95+
[posttyper]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/PostTyper.scala
96+
[prepjsinterop]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/sjs/PrepJSInterop.scala
97+
[pickler]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/Pickler.scala
98+
[inlining]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/Inlining.scala
99+
[postInlining]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/PostInlining.scala
100+
[staging]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/Staging.scala
101+
[pickleQuotes]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/PickleQuotes.scala
102+
[refchecks]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/typer/RefChecks.scala
103+
[initChecker]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/init/Checker.scala
104+
[firstTransform]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/FirstTransform.scala
105+
[patternMatcher]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/PatternMatcher.scala
106+
[erasure]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/Erasure.scala
107+
[Mirror]: https://github.com/lampepfl/dotty/blob/master/library/src/scala/deriving/Mirror.scala
108+
[PCP]: {{ site.scala3ref }}/metaprogramming/macros.html#the-phase-consistency-principle
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
---
2+
layout: doc-page
3+
title: Symbols
4+
---
5+
6+
As discussed previously, `dotc` [maintains time-indexed views](time.md) of various
7+
compiler artifacts. The following sections discuss how they are managed in the compiler.
8+
9+
## Symbols
10+
11+
Defined in [Symbols], a `Symbol` is a unique identifier for a definition (e.g. a method,
12+
type, or field). A `ClassSymbol` extends `Symbol` and represents either a
13+
`class`, or a `trait`, or an `object`. A `Symbol` can even refer to non-Scala entities,
14+
such as from the Java standard library.
15+
16+
## Definitions are Dynamic
17+
18+
Traditionally, compilers store context-dependent data in a _symbol table_.
19+
Where a symbol then is the central reference to address context-dependent data.
20+
`dotc` instead uses a phase-indexed function (known as
21+
a [Denotation][Denotations]) to compute views of definitions across phases,
22+
as many of attributes associated with definitions are phase-dependent. For example:
23+
- types are gradually simplified by several phases,
24+
- owners change in [lambdaLift] (local methods are lifted to an enclosing class)
25+
and [flatten] (when inner classes are moved to the top level)
26+
- Names are changed when private members need to be accessed from outside
27+
their class (for instance from a nested class or a class implementing
28+
a trait).
29+
30+
Additionally, symbols are not suitable to be used as a reference to
31+
a definition in another [compilation unit][CompilationUnit].
32+
In the context of incremental compilation, a symbol from
33+
an external compilation unit may be deleted or changed, making the reference
34+
stale. To counter this, `dotc` types trees of cross-module references with either
35+
a `TermRef` or `TypeRef`. A reference type contains a prefix type and a name.
36+
The denotation that the type refers to is established dynamically based on
37+
these fields.
38+
39+
## Denotations
40+
41+
On its own a `Symbol` has no structure. Its semantic meaning is given by being associated
42+
with a [Denotation][Denotations].
43+
44+
A denotation is the result of resolving a name during a given period, containing the information
45+
describing some entity (either a term or type), indexed by phase. Denotations usually have a
46+
reference to a selected symbol, but not always, for example if the denotation is overloaded,
47+
i.e. a `MultiDenotation`.
48+
49+
### SymDenotations
50+
All definition symbols will contain a `SymDenotation`. The denotation, in turn, contains:
51+
- a reverse link to the source symbol
52+
- a reference to the enclosing symbol that defined the source symbol:
53+
- for a local variable, the enclosing method
54+
- for a field or class, the enclosing class
55+
- a set of [flags], describing the definition (e.g. whether it's a trait or mutable).
56+
- the type of the definition (through the `info` method)
57+
- a [signature][Signature1], which uniquely identifies overloaded methods (or else `NotAMethod`).
58+
- and more.
59+
60+
A class symbol will instead be associated with a `ClassDenotation`, which extends `SymDenotation`
61+
with some additional fields specific for classes.
62+
63+
[Signature1]: https://github.com/lampepfl/dotty/blob/a527f3b1e49c0d48148ccfb2eb52e3302fc4a349/compiler/src/dotty/tools/dotc/core/Signature.scala#L9-L33
64+
[Symbols]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/core/Symbols.scala
65+
[flatten]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/Flatten.scala
66+
[lambdaLift]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/transform/LambdaLift.scala
67+
[CompilationUnit]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/CompilationUnit.scala
68+
[Denotations]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/core/Denotations.scala
69+
[SymDenotations]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/core/SymDenotations.scala
70+
[flags]: https://github.com/lampepfl/dotty/blob/master/compiler/src/dotty/tools/dotc/core/Flags.scala

0 commit comments

Comments
 (0)