mirror of
https://github.com/enso-org/enso.git
synced 2024-12-22 13:41:39 +03:00
Fix a bug with compiler metadata (#838)
1. The metadata objects weren't being duplicated when duplicating the IR. This meant that the later passes would write metadata multiples times into one store (reference), causing wrong behaviour at codegen time.
This commit is contained in:
parent
1f46a3f9a1
commit
2f404b7f08
@ -29,6 +29,8 @@ The various components of Enso's syntax are described below:
|
||||
- [**Encoding:**](./encoding.md) The source encoding of Enso files.
|
||||
- [**Naming:**](./naming.md) The naming of Enso language constructs.
|
||||
- [**Layout Rules:**](./layout.md) The layout rules for Enso code.
|
||||
- [**Imports and Exports:**](./imports.md) The syntax and rules for importing
|
||||
modules and exporting module functions.
|
||||
- [**Literals:**](./literals.md) The syntax for Enso literals.
|
||||
- [**Assignment:**](./assignment.md) The syntax for various forms of assignment
|
||||
expression in Enso.
|
||||
|
@ -3,7 +3,7 @@ layout: developer-doc
|
||||
title: Assignment Expressions
|
||||
category: syntax
|
||||
tags: [syntax, assignment]
|
||||
order: 5
|
||||
order: 6
|
||||
---
|
||||
|
||||
# Assignment Expressions
|
||||
|
@ -3,7 +3,7 @@ layout: developer-doc
|
||||
title: Comments
|
||||
category: syntax
|
||||
tags: [syntax, comments]
|
||||
order: 12
|
||||
order: 13
|
||||
---
|
||||
|
||||
# Comments
|
||||
|
@ -3,7 +3,7 @@ layout: developer-doc
|
||||
title: Function Arguments
|
||||
category: syntax
|
||||
tags: [syntax, functions]
|
||||
order: 10
|
||||
order: 11
|
||||
---
|
||||
|
||||
# Function Arguments
|
||||
|
@ -3,7 +3,7 @@ layout: developer-doc
|
||||
title: Defining Functions
|
||||
category: syntax
|
||||
tags: [syntax, functions]
|
||||
order: 9
|
||||
order: 10
|
||||
---
|
||||
|
||||
# Defining Functions
|
||||
|
118
docs/syntax/imports.md
Normal file
118
docs/syntax/imports.md
Normal file
@ -0,0 +1,118 @@
|
||||
---
|
||||
layout: developer-doc
|
||||
title: Imports and Exports
|
||||
category: syntax
|
||||
tags: [syntax, imports, modules]
|
||||
order: 4
|
||||
---
|
||||
|
||||
# Imports and Exports
|
||||
In order to properly modularise and work with Enso code, the language provides
|
||||
a robust mechanism for importing code from modules, and also re-exporting that
|
||||
code from modules.
|
||||
|
||||
<!-- MarkdownTOC levels="2,3" autolink="true" -->
|
||||
|
||||
- [Import Syntax](#import-syntax)
|
||||
- [Visibility of Imported Bindings](#visibility-of-imported-bindings)
|
||||
- [Export Syntax](#export-syntax)
|
||||
- [Visibility of Export Bindings](#visibility-of-export-bindings)
|
||||
|
||||
<!-- /MarkdownTOC -->
|
||||
|
||||
## Import Syntax
|
||||
Importing a module is a way to bring its contents into scope in the current
|
||||
module. Imports in Enso appear as follows:
|
||||
|
||||
- They start with the `import` keyword.
|
||||
- The `import` keyword is followed by a module path (e.g. `Base.Vector.Unsafe`).
|
||||
|
||||
From there, Enso imports are broken up into four main categories:
|
||||
|
||||
1. **Unqualified Imports:** These import all symbols from the module into the
|
||||
current scope, and consist only of the `import` keyword and a module path.
|
||||
Imported items are imported accessible without qualification.
|
||||
2. **Qualified Imports:** These import all symbols from the module into the
|
||||
current scope with symbols qualified under a name _different_ from the
|
||||
module name. It consists of the `import` keyword followed by a module path
|
||||
followed by the `as` keyword, followed by a referent name.
|
||||
3. **Restricted Imports:** These import only the specific symbols from the
|
||||
module into the current scope. They consist of the `import` keyword, followed
|
||||
by a module path, followed by the `only` keyword, followed by a
|
||||
space-separated list of symbols.
|
||||
4. **Hiding Imports:** These are the inverse of restricted imports, and import
|
||||
_all_ symbols other than the named ones into the current scope. They consist
|
||||
of the `import` keyword, followed by a module path, followed by the keyword
|
||||
`only`, followed by a space-separated list of symbols.
|
||||
|
||||
The qualified import syntax can be combined with the restricted and hiding
|
||||
import syntaxes.
|
||||
|
||||
By way of example, the following code uses a variety of import types:
|
||||
|
||||
```ruby
|
||||
import A # unqualified
|
||||
import B as T # qualified
|
||||
import C only symbol_1 symbol_2 # restricted
|
||||
import D hiding symbol_1 symbol_2 # hiding
|
||||
import E as U only symbol_3 # qualified + restricted
|
||||
import F as V hiding symbol_4 # qualified + hiding
|
||||
```
|
||||
Imports in Enso _may_ introduce ambiguous symbols, but this is not an error
|
||||
until one of the ambiguous symbols is _used_ in Enso code.
|
||||
|
||||
### Visibility of Imported Bindings
|
||||
When importing a module `X` into the current module `Y`, the bindings from `X`
|
||||
made available by the import (see above) become available in `Y`. However, Enso
|
||||
does not re-export imported bindings from a module by default, so the imported
|
||||
bindings from `X` are not visible in a module _importing_ `Y`.
|
||||
|
||||
## Export Syntax
|
||||
In order to allow for easy composition and aggregation of code, Enso provides
|
||||
its users with a mechanism to _export_ imported elements from modules. They
|
||||
appear in Enso as follows:
|
||||
|
||||
- They start with the `export` keyword.
|
||||
- The `export` keyword is followed by a module name (e.g. `My_Module`) that is
|
||||
available in the current scope.
|
||||
- The _current_ module is implicitly exported unqualified.
|
||||
|
||||
From there, Enso exports are broken up into four main categories:
|
||||
|
||||
1. **Unqualified Exports:** These export all symbols from the named module as
|
||||
if they were defined in the exporting module. They consist of the `export`
|
||||
keyword, followed by a visible module name.
|
||||
2. **Qualified Exports:** These export all symbols from the module as if they
|
||||
were defined in a module nested within the exporting module. It consists of
|
||||
the `export` keyword, followed by a module name, followed by the `as`
|
||||
keyword, followed by another module name.
|
||||
3. **Restricted Exports:** These export only the specified symbols from the
|
||||
exporting module, as if they were defined in the exporting module. It
|
||||
consists of the `export` keyword, followed by a module name, followed by the
|
||||
`only` keyword, and then a space-separated list of symbols.
|
||||
4. **Hiding Exports:** These export all symbols from the module _except_ those
|
||||
explicitly specified. It consists of the `export` keyword, followed by a
|
||||
module name, followed by the `hiding` keyword, and then a space-separated
|
||||
list of symbols.
|
||||
|
||||
The qualified export syntax can be combined with the restricted and hiding
|
||||
export syntaxes.
|
||||
|
||||
By way of example, the following code uses a variety of export types:
|
||||
|
||||
```ruby
|
||||
export A
|
||||
export B as X
|
||||
export C only symbol_1
|
||||
export D hiding symbol_1
|
||||
export E as Y only symbol_1
|
||||
export F as Y hiding symbol_1
|
||||
```
|
||||
|
||||
In essence, an export allows the user to `paste` the contents of the module
|
||||
being exported into the module declaring the export. This means that exports
|
||||
that create name clashes need to be resolved at the _export_ site.
|
||||
|
||||
### Visibility of Export Bindings
|
||||
Bindings exported from a module `X` are available in an identical fashion to
|
||||
bindings that are _defined_ in the module `X`.
|
@ -3,7 +3,7 @@ layout: developer-doc
|
||||
title: Literals
|
||||
category: syntax
|
||||
tags: [syntax, literals]
|
||||
order: 4
|
||||
order: 5
|
||||
---
|
||||
|
||||
# Literals
|
||||
|
@ -3,7 +3,7 @@ layout: developer-doc
|
||||
title: The Enso Macro Syntax
|
||||
category: syntax
|
||||
tags: [syntax, macro]
|
||||
order: 7
|
||||
order: 8
|
||||
---
|
||||
|
||||
# The Enso Macro Syntax
|
||||
|
@ -3,7 +3,7 @@ layout: developer-doc
|
||||
title: Projections and Field Access
|
||||
category: syntax
|
||||
tags: [syntax, projections, field-access, pattern-matching]
|
||||
order: 11
|
||||
order: 12
|
||||
---
|
||||
|
||||
# Projections and Field Access
|
||||
|
@ -3,7 +3,7 @@ layout: developer-doc
|
||||
title: Enso Top-Level Syntax
|
||||
category: syntax
|
||||
tags: [syntax, top-level, file]
|
||||
order: 8
|
||||
order: 9
|
||||
---
|
||||
|
||||
# Enso Top-Level Syntax
|
||||
|
@ -3,7 +3,7 @@ layout: developer-doc
|
||||
title: Types and Type Signatures
|
||||
category: syntax
|
||||
tags: [syntax, types]
|
||||
order: 6
|
||||
order: 7
|
||||
---
|
||||
|
||||
# Types and Type Signatures
|
||||
@ -319,18 +319,48 @@ sometimes the case that it is necessary to indicate that certain fields should
|
||||
not be touched (as this might break invariants and such like). To this end, we
|
||||
propose an explicit mechanism for access modification that works as follows:
|
||||
|
||||
- We provide explicit access modifiers that, at the definition site, start an
|
||||
indented block. These are `private` and `unsafe`.
|
||||
- All members in the block have the access modifier attributed to them.
|
||||
- By default, accessing any member under an access modifier will be an error.
|
||||
- To use members under an access modifier, you use the syntax `use <mod>`, where
|
||||
`<mod>` is a modifier. This syntax 'takes' an expression, including blocks,
|
||||
within which the user may access members qualified by the modifier `<mod>`.
|
||||
- We have a set of access modifiers, namely `private` and `unsafe`.
|
||||
- We can place these modifiers before a top-level definition.
|
||||
|
||||
```ruby
|
||||
type MyAtomType
|
||||
type MyAtom a
|
||||
|
||||
is_foo : Boolean
|
||||
is_foo = ...
|
||||
|
||||
private private_method a b = ...
|
||||
|
||||
unsafe unsafe_method a b = ...
|
||||
```
|
||||
|
||||
- By default, accessing any member under an access modifier is an error when
|
||||
performed from another module.
|
||||
- To use members protected by an access modifier, you must _import_ that access
|
||||
modifier from the file in which you want to access those elements.
|
||||
|
||||
```ruby
|
||||
import private Base.Vector
|
||||
import unsafe Base.Atom
|
||||
```
|
||||
|
||||
- These modified imports are available in _all_ scopes, so it is possible to
|
||||
limit the scope in which you have access to the modified definitions.
|
||||
|
||||
```ruby
|
||||
function_using_modifiers v x =
|
||||
import private Base.Vector
|
||||
import unsafe Base.Atom
|
||||
|
||||
v.mutate_at_index 0 (_ -> x)
|
||||
x = MyAtom.mutate_field name="sum" (with = x -> x + 20)
|
||||
x + 20
|
||||
```
|
||||
|
||||
While `private` works as you might expect, coming from other languages, the
|
||||
`unsafe` annotation has additional restrictions:
|
||||
|
||||
- It must be explicitly imported from `Std.Unsafe`.
|
||||
- It must be explicitly imported from `Base.Unsafe`.
|
||||
- When you use `unsafe`, you must write a documentation comment on its usage
|
||||
that contains a section `Safety` that describes why this usage of unsafe is
|
||||
valid.
|
||||
|
@ -23,13 +23,43 @@ provides an explicit mechanism for access modification.
|
||||
## Access Modification
|
||||
Access modifiers in Enso work as follows:
|
||||
|
||||
- We provide explicit access modifiers that, at the definition site, start an
|
||||
indented block.
|
||||
- All members in the block have the access modifier attributed to them.
|
||||
- By default, accessing any member under an access modifier will be an error.
|
||||
- To use members under an access modifier, you use the syntax `use <mod>`, where
|
||||
`<mod>` is a modifier. This syntax 'takes' an expression, including blocks,
|
||||
within which the user may access members qualified by the modifier `<mod>`.
|
||||
- We have a set of access modifiers, namely `private` and `unsafe`.
|
||||
- We can place these modifiers before a top-level definition.
|
||||
|
||||
```ruby
|
||||
type MyAtomType
|
||||
type MyAtom a
|
||||
|
||||
is_foo : Boolean
|
||||
is_foo = ...
|
||||
|
||||
private private_method a b = ...
|
||||
|
||||
unsafe unsafe_method a b = ...
|
||||
```
|
||||
|
||||
- By default, accessing any member under an access modifier is an error when
|
||||
performed from another module.
|
||||
- To use members protected by an access modifier, you must _import_ that access
|
||||
modifier from the file in which you want to access those elements.
|
||||
|
||||
```ruby
|
||||
import private Base.Vector
|
||||
import unsafe Base.Atom
|
||||
```
|
||||
|
||||
- These modified imports are available in _all_ scopes, so it is possible to
|
||||
limit the scope in which you have access to the modified definitions.
|
||||
|
||||
```ruby
|
||||
function_using_modifiers v x =
|
||||
import private Base.Vector
|
||||
import unsafe Base.Atom
|
||||
|
||||
v.mutate_at_index 0 (_ -> x)
|
||||
x = MyAtom.mutate_field name="sum" (with = x -> x + 20)
|
||||
x + 20
|
||||
```
|
||||
|
||||
> The actionables for this section are:
|
||||
>
|
||||
@ -40,13 +70,13 @@ The `private` modifier acts to hide implementation details from clients of the
|
||||
API. It is:
|
||||
|
||||
- Available by default in the `Base` library.
|
||||
- Able to be overridden using the above-described mechanism.
|
||||
- Able to be avoided using the above-described mechanism.
|
||||
|
||||
## Unsafe
|
||||
While `private` works as you might expect, coming from other languages, the
|
||||
`unsafe` annotation has additional restrictions:
|
||||
|
||||
- It must be explicitly imported from `Std.Unsafe`.
|
||||
- It must be explicitly imported from `Base.Unsafe`.
|
||||
- When you use `unsafe`, you must write a documentation comment on its usage
|
||||
that contains a section `Safety` that describes why this usage of unsafe is
|
||||
valid.
|
||||
|
@ -37,16 +37,16 @@ most languages, Enso provides an _import_ mechanism for this. Enso has four
|
||||
different kinds of imports that may be combined freely, all of which take a
|
||||
module path as their first argument.
|
||||
|
||||
1. **Unqualified Imports:** These import all symbols from the module into the
|
||||
current scope (`import M`).
|
||||
2. **Qualified Imports:** These import all symbols from the module into the
|
||||
current scope with symbols qualified under a name _different_ from the
|
||||
module name (`import M as T`).
|
||||
3. **Restricted Imports:** These import only the specific symbols from the
|
||||
module into the current scope (`import M only sym1 sym2`).
|
||||
4. **Hiding Imports:** These are the inverse of restricted imports, and import
|
||||
_all_ symbols other than the named ones into the current scope
|
||||
(`import M hiding sym1 sym2`),
|
||||
1. **Unqualified Imports:** These import all symbols from the module into the
|
||||
current scope (`import M`).
|
||||
2. **Qualified Imports:** These import all symbols from the module into the
|
||||
current scope with symbols qualified under a name _different_ from the
|
||||
module name (`import M as T`).
|
||||
3. **Restricted Imports:** These import only the specific symbols from the
|
||||
module into the current scope (`import M only sym1 sym2`).
|
||||
4. **Hiding Imports:** These are the inverse of restricted imports, and import
|
||||
_all_ symbols other than the named ones into the current scope
|
||||
(`import M hiding sym1 sym2`),
|
||||
|
||||
Imports may introduce ambiguous symbols, but this is not an error until one of
|
||||
the ambiguous symbols is used in user code.
|
||||
@ -58,15 +58,15 @@ mechanism. Similarly to imports, this has four kinds, all of which take a module
|
||||
path as their first argument, and all of which _may_ introduce the module it
|
||||
exports into scope (if it is not already imported).
|
||||
|
||||
1. **Unqualified Exports:** These export all symbols from the module as if they
|
||||
were defined in the exporting module (`export X`).
|
||||
2. **Qualified Exports:** These export all symbols from the module as if they
|
||||
were defined in another module accessible in the exporting module
|
||||
(`export X as Y`).
|
||||
3. **Restricted Exports:** These export only the specified symbols from the
|
||||
module as if they were defined in the exporting module (`export X only sym`)
|
||||
4. **Hiding Exports:** These export all symbols from the module except those
|
||||
explicitly specified (`export X hiding sym1 sym2`).
|
||||
1. **Unqualified Exports:** These export all symbols from the module as if they
|
||||
were defined in the exporting module (`export X`).
|
||||
2. **Qualified Exports:** These export all symbols from the module as if they
|
||||
were defined in another module accessible in the exporting module
|
||||
(`export X as Y`).
|
||||
3. **Restricted Exports:** These export only the specified symbols from the
|
||||
module as if they were defined in the exporting module (`export X only sym`)
|
||||
4. **Hiding Exports:** These export all symbols from the module except those
|
||||
explicitly specified (`export X hiding sym1 sym2`).
|
||||
|
||||
Exports effectively act to 'paste' the contents of the exported module into the
|
||||
module declaring the export. This means that exports that create name clashes
|
||||
|
@ -818,11 +818,16 @@ object AstToIr {
|
||||
* @param imp the import to translate
|
||||
* @return the [[IR]] representation of `imp`
|
||||
*/
|
||||
def translateImport(imp: AST.Import): Module.Scope.Import.Module = {
|
||||
Module.Scope.Import.Module(
|
||||
imp.path.map(t => t.name).reduceLeft((l, r) => l + "." + r),
|
||||
getIdentifiedLocation(imp)
|
||||
)
|
||||
def translateImport(imp: AST.Import): Module.Scope.Import = {
|
||||
imp.path match {
|
||||
case AstView.ModulePath(segments) =>
|
||||
IR.Module.Scope.Import.Module(
|
||||
segments.map(_.name).mkString("."),
|
||||
getIdentifiedLocation(imp.path)
|
||||
)
|
||||
case _ =>
|
||||
IR.Error.Syntax(imp, IR.Error.Syntax.InvalidImport)
|
||||
}
|
||||
}
|
||||
|
||||
/** Translates an arbitrary invalid expression from the [[AST]] representation
|
||||
|
@ -405,6 +405,23 @@ object AstView {
|
||||
}
|
||||
}
|
||||
|
||||
object ModulePath {
|
||||
|
||||
/** Matches on a module path of the form `A.B.C...`, as seen in an import.
|
||||
*
|
||||
* @param ast the structure to try and match on
|
||||
* @return the list of segments in the module path
|
||||
*/
|
||||
def unapply(ast: AST): Option[List[AST.Ident]] = ast match {
|
||||
case AST.Ident.Cons.any(name) => Some(List(name))
|
||||
case OperatorDot(left, AST.Ident.Cons.any(name)) => left match {
|
||||
case ModulePath(elems) => Some(elems :+ name)
|
||||
case _ => None
|
||||
}
|
||||
case _ => None
|
||||
}
|
||||
}
|
||||
|
||||
object SuspendDefaultsOperator {
|
||||
|
||||
/** Matches on a usage of the `...` 'suspend defaults' operator.
|
||||
|
@ -147,6 +147,7 @@ class IrToTruffle(
|
||||
)
|
||||
case i: Import.Module =>
|
||||
this.moduleScope.addImport(context.getCompiler.processImport(i.name))
|
||||
case _: Error =>
|
||||
}
|
||||
|
||||
// Register the atoms and their constructors in scope
|
||||
|
@ -2,12 +2,8 @@ package org.enso.compiler.core
|
||||
|
||||
import java.util.UUID
|
||||
|
||||
import org.enso.compiler.core.IR.{
|
||||
DiagnosticStorage,
|
||||
Expression,
|
||||
IdentifiedLocation
|
||||
}
|
||||
import org.enso.compiler.core.ir.MetadataStorage
|
||||
import org.enso.compiler.core.IR.{Expression, IdentifiedLocation}
|
||||
import org.enso.compiler.core.ir.{DiagnosticStorage, MetadataStorage}
|
||||
import org.enso.compiler.core.ir.MetadataStorage.MetadataPair
|
||||
import org.enso.compiler.exception.CompilerError
|
||||
import org.enso.compiler.pass.IRPass
|
||||
@ -228,10 +224,11 @@ object IR {
|
||||
keepDiagnostics: Boolean = true
|
||||
): Empty =
|
||||
copy(
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
diagnostics = if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
id = randomId
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
override def setLocation(location: Option[IdentifiedLocation]): Empty =
|
||||
@ -315,10 +312,11 @@ object IR {
|
||||
bindings = bindings.map(
|
||||
_.duplicate(keepLocations, keepMetadata, keepDiagnostics)
|
||||
),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
diagnostics = if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
id = randomId
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
override def setLocation(location: Option[IdentifiedLocation]): Module =
|
||||
@ -440,9 +438,10 @@ object IR {
|
||||
): Module =
|
||||
copy(
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -540,9 +539,10 @@ object IR {
|
||||
): Polyglot =
|
||||
copy(
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -637,9 +637,10 @@ object IR {
|
||||
_.duplicate(keepLocations, keepMetadata, keepDiagnostics)
|
||||
),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -742,9 +743,10 @@ object IR {
|
||||
_.duplicate(keepLocations, keepMetadata, keepDiagnostics)
|
||||
),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -858,9 +860,11 @@ object IR {
|
||||
body =
|
||||
body.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy
|
||||
else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -970,9 +974,11 @@ object IR {
|
||||
body =
|
||||
body.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy
|
||||
else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -1119,9 +1125,10 @@ object IR {
|
||||
returnValue =
|
||||
returnValue.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -1215,9 +1222,10 @@ object IR {
|
||||
expression =
|
||||
expression.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -1304,9 +1312,10 @@ object IR {
|
||||
): Number =
|
||||
copy(
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -1373,9 +1382,10 @@ object IR {
|
||||
): Text =
|
||||
copy(
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -1495,10 +1505,11 @@ object IR {
|
||||
typePointer.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
methodName =
|
||||
methodName.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
diagnostics = if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
id = randomId
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
override def mapExpressions(
|
||||
@ -1633,9 +1644,10 @@ object IR {
|
||||
): Blank =
|
||||
copy(
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -1703,9 +1715,10 @@ object IR {
|
||||
): Literal =
|
||||
copy(
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -1770,9 +1783,10 @@ object IR {
|
||||
): This =
|
||||
copy(
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -1837,9 +1851,10 @@ object IR {
|
||||
): Here =
|
||||
copy(
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -1934,9 +1949,10 @@ object IR {
|
||||
signature =
|
||||
signature.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -2020,9 +2036,10 @@ object IR {
|
||||
context =
|
||||
context.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -2099,12 +2116,13 @@ object IR {
|
||||
keepMetadata: Boolean = true,
|
||||
keepDiagnostics: Boolean = true
|
||||
): Error = copy(
|
||||
typed = typed.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
error = error.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
diagnostics = if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
id = randomId
|
||||
typed = typed.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
error = error.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
override def setLocation(location: Option[IdentifiedLocation]): Error =
|
||||
@ -2201,9 +2219,10 @@ object IR {
|
||||
memberType.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
value = value.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -2294,9 +2313,10 @@ object IR {
|
||||
right =
|
||||
right.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -2379,9 +2399,10 @@ object IR {
|
||||
left = left.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
right = right.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -2462,9 +2483,10 @@ object IR {
|
||||
left = left.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
right = right.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -2544,9 +2566,10 @@ object IR {
|
||||
left = left.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
right = right.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -2628,9 +2651,10 @@ object IR {
|
||||
right =
|
||||
right.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -2715,9 +2739,10 @@ object IR {
|
||||
right =
|
||||
right.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -2843,11 +2868,12 @@ object IR {
|
||||
arguments = arguments.map(
|
||||
_.duplicate(keepLocations, keepMetadata, keepDiagnostics)
|
||||
),
|
||||
body = body.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
diagnostics = if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
id = randomId
|
||||
body = body.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
override def setLocation(location: Option[IdentifiedLocation]): Lambda =
|
||||
@ -2951,11 +2977,12 @@ object IR {
|
||||
arguments = arguments.map(
|
||||
_.duplicate(keepLocations, keepMetadata, keepDiagnostics)
|
||||
),
|
||||
body = body.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
diagnostics = if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
id = randomId
|
||||
body = body.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
override def setLocation(location: Option[IdentifiedLocation]): Binding =
|
||||
@ -3092,10 +3119,11 @@ object IR {
|
||||
defaultValue = defaultValue.map(
|
||||
_.duplicate(keepLocations, keepMetadata, keepDiagnostics)
|
||||
),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
diagnostics = if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
id = randomId
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
override def setLocation(
|
||||
@ -3212,10 +3240,11 @@ object IR {
|
||||
arguments = arguments.map(
|
||||
_.duplicate(keepLocations, keepMetadata, keepDiagnostics)
|
||||
),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
diagnostics = if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
id = randomId
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
override def setLocation(location: Option[IdentifiedLocation]): Prefix =
|
||||
@ -3289,11 +3318,12 @@ object IR {
|
||||
keepMetadata: Boolean = true,
|
||||
keepDiagnostics: Boolean = true
|
||||
): Force = copy(
|
||||
target = target.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
diagnostics = if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
id = randomId
|
||||
target = target.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
override def setLocation(location: Option[IdentifiedLocation]): Force =
|
||||
@ -3384,9 +3414,10 @@ object IR {
|
||||
_.duplicate(keepLocations, keepMetadata, keepDiagnostics)
|
||||
),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -3465,9 +3496,10 @@ object IR {
|
||||
_.duplicate(keepLocations, keepMetadata, keepDiagnostics)
|
||||
),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -3563,9 +3595,10 @@ object IR {
|
||||
operator.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
right = right.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -3660,9 +3693,10 @@ object IR {
|
||||
operator =
|
||||
operator.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -3738,9 +3772,10 @@ object IR {
|
||||
operator =
|
||||
operator.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -3818,9 +3853,10 @@ object IR {
|
||||
operator.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
arg = arg.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -3950,11 +3986,12 @@ object IR {
|
||||
): Specified = copy(
|
||||
name =
|
||||
name.map(_.duplicate(keepLocations, keepMetadata, keepDiagnostics)),
|
||||
value = value.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
diagnostics = if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
id = randomId
|
||||
value = value.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
override def setLocation(
|
||||
@ -4053,12 +4090,14 @@ object IR {
|
||||
): Expr = copy(
|
||||
scrutinee =
|
||||
scrutinee.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
branches =
|
||||
branches.map(_.duplicate(keepLocations, keepMetadata, keepDiagnostics)),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
diagnostics = if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
id = randomId
|
||||
branches = branches.map(
|
||||
_.duplicate(keepLocations, keepMetadata, keepDiagnostics)
|
||||
),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
override def setLocation(location: Option[IdentifiedLocation]): Expr =
|
||||
@ -4146,10 +4185,11 @@ object IR {
|
||||
pattern.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
expression =
|
||||
expression.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
diagnostics = if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
id = randomId
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
override def setLocation(location: Option[IdentifiedLocation]): Branch =
|
||||
@ -4244,11 +4284,12 @@ object IR {
|
||||
keepMetadata: Boolean = true,
|
||||
keepDiagnostics: Boolean = true
|
||||
): Name = copy(
|
||||
name = name.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
diagnostics = if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
id = randomId
|
||||
name = name.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
override def mapExpressions(fn: Expression => Expression): Name = {
|
||||
@ -4327,10 +4368,11 @@ object IR {
|
||||
constructor.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
fields =
|
||||
fields.map(_.duplicate(keepLocations, keepMetadata, keepDiagnostics)),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
diagnostics = if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
id = randomId
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
/** Checks if the constructor pattern has been desugared.
|
||||
@ -4457,9 +4499,10 @@ object IR {
|
||||
): Documentation =
|
||||
copy(
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -4549,10 +4592,11 @@ object IR {
|
||||
keepMetadata: Boolean = true,
|
||||
keepDiagnostics: Boolean = true
|
||||
): Definition = copy(
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
diagnostics = if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
id = randomId
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
override def setLocation(
|
||||
@ -4749,6 +4793,7 @@ object IR {
|
||||
) extends Error
|
||||
with Diagnostic.Kind.Interactive
|
||||
with IR.Module.Scope.Definition
|
||||
with IR.Module.Scope.Import
|
||||
with IRKind.Primitive {
|
||||
override protected var id: Identifier = randomId
|
||||
|
||||
@ -4779,9 +4824,10 @@ object IR {
|
||||
keepDiagnostics: Boolean = true
|
||||
): Syntax =
|
||||
copy(
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -4834,6 +4880,11 @@ object IR {
|
||||
s"Cannot define a pattern outside a pattern context."
|
||||
}
|
||||
|
||||
case object InvalidImport extends Reason {
|
||||
override def explanation: String =
|
||||
s"Imports must have a valid module path."
|
||||
}
|
||||
|
||||
case object InvalidStandaloneSignature extends Reason {
|
||||
override def explanation: String =
|
||||
s"Invalid stand-alone signature expression."
|
||||
@ -4938,10 +4989,11 @@ object IR {
|
||||
keepMetadata: Boolean = true,
|
||||
keepDiagnostics: Boolean = true
|
||||
): InvalidIR = copy(
|
||||
ir = ir.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
diagnostics = if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
id = randomId
|
||||
ir = ir.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
passData = if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
override def setLocation(
|
||||
@ -5027,9 +5079,10 @@ object IR {
|
||||
keepDiagnostics: Boolean = true
|
||||
): ThisArg = copy(
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -5106,9 +5159,10 @@ object IR {
|
||||
methodName =
|
||||
methodName.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -5190,9 +5244,10 @@ object IR {
|
||||
atomName =
|
||||
atomName.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
location = if (keepLocations) location else None,
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -5266,9 +5321,10 @@ object IR {
|
||||
): Binding = copy(
|
||||
invalidBinding = invalidBinding
|
||||
.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -5376,10 +5432,11 @@ object IR {
|
||||
keepMetadata: Boolean = true,
|
||||
keepDiagnostics: Boolean = true
|
||||
): TypeSignature = copy(
|
||||
ir = ir.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
passData = if (keepMetadata) passData else MetadataStorage(),
|
||||
ir = ir.duplicate(keepLocations, keepMetadata, keepDiagnostics),
|
||||
passData =
|
||||
if (keepMetadata) passData.duplicate else MetadataStorage(),
|
||||
diagnostics =
|
||||
if (keepDiagnostics) diagnostics else DiagnosticStorage(),
|
||||
if (keepDiagnostics) diagnostics.copy else DiagnosticStorage(),
|
||||
id = randomId
|
||||
)
|
||||
|
||||
@ -5463,130 +5520,6 @@ object IR {
|
||||
}
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
// === Diagnostics Storage ==================================================
|
||||
// ==========================================================================
|
||||
|
||||
/** Storage for diagnostics in IR nodes.
|
||||
*
|
||||
* @param initDiagnostics the initial diagnostics
|
||||
*/
|
||||
sealed class DiagnosticStorage(initDiagnostics: Seq[Diagnostic] = Seq()) {
|
||||
private var diagnostics: List[Diagnostic] = initDiagnostics.toList
|
||||
|
||||
/** Adds a new diagnostic to the storage
|
||||
*
|
||||
* @param diagnostic the new diagnostic to store
|
||||
*/
|
||||
def add(diagnostic: Diagnostic): Unit = {
|
||||
diagnostics = diagnostic :: diagnostics
|
||||
}
|
||||
|
||||
/** Adds new diagnostics to the storage.
|
||||
*
|
||||
* @param newDiagnostics the new diagnostics to store
|
||||
*/
|
||||
def add(newDiagnostics: Seq[Diagnostic]): Unit = {
|
||||
diagnostics = newDiagnostics.toList ::: diagnostics
|
||||
}
|
||||
|
||||
/** Applies the function `f` across the diagnostic storage, producing a
|
||||
* result sequence.
|
||||
*
|
||||
* @param f the function to apply
|
||||
* @tparam R the result type of `f`
|
||||
* @return the sequence that results from applying `f` over the storage
|
||||
*/
|
||||
def map[R](f: IR.Diagnostic => R): Seq[R] = {
|
||||
diagnostics.map(f)
|
||||
}
|
||||
|
||||
/** Applies the function `f` across the diagnostic storage in place.
|
||||
*
|
||||
* @param f the function to apply
|
||||
*/
|
||||
def mapInPlace(f: IR.Diagnostic => IR.Diagnostic): Unit = {
|
||||
diagnostics = diagnostics.map(f)
|
||||
}
|
||||
|
||||
/** Performs a collection operation on the diagnostics storage, producing
|
||||
* a new sequence.
|
||||
*
|
||||
* @param pf the partial function to apply
|
||||
* @tparam R the result type of the partial function
|
||||
* @return the result of collecting across the storage with `pf`
|
||||
*/
|
||||
def collect[R](pf: PartialFunction[IR.Diagnostic, R]): Seq[R] = {
|
||||
diagnostics.collect(pf)
|
||||
}
|
||||
|
||||
/** Filters the elements of the diagnostic storage using the predicate.
|
||||
*
|
||||
* @param pred the predicate to filter with
|
||||
* @return a new diagnostic storage instance containing elements matching
|
||||
* `pred`
|
||||
*/
|
||||
def filter(pred: IR.Diagnostic => Boolean): DiagnosticStorage = {
|
||||
new DiagnosticStorage(diagnostics.filter(pred))
|
||||
}
|
||||
|
||||
/** Filters the elements of the diagnostic storage in place using the
|
||||
* predicate.
|
||||
*
|
||||
* @param pred the predicate to filter with
|
||||
*/
|
||||
def filterInPlace(pred: IR.Diagnostic => Boolean): Unit = {
|
||||
diagnostics = diagnostics.filter(pred)
|
||||
}
|
||||
|
||||
/** Performs a left fold over the diagnostic storage to produce a result.
|
||||
*
|
||||
* @param init the starting value
|
||||
* @param op the operator to use to fold
|
||||
* @tparam L the result type of the fold
|
||||
* @return the result of folding over the storage using `op` starting wit
|
||||
* `init`
|
||||
*/
|
||||
def foldLeft[L](init: L)(op: (L, IR.Diagnostic) => L): L = {
|
||||
diagnostics.foldLeft(init)(op)
|
||||
}
|
||||
|
||||
/** Checks two diagnostics storages for equality.
|
||||
*
|
||||
* @param obj the object to check against `this`
|
||||
* @return `true` if `this == obj`, otherwise `false`
|
||||
*/
|
||||
override def equals(obj: Any): Boolean = obj match {
|
||||
case that: DiagnosticStorage => this.diagnostics == that.diagnostics
|
||||
case _ => false
|
||||
}
|
||||
|
||||
/** Creates a string representation of `this` diagnostic storage.
|
||||
*
|
||||
* @return the string representation of `this`
|
||||
*/
|
||||
override def toString: String =
|
||||
s"DiagnosticStorage(diagnostics = $diagnostics)"
|
||||
|
||||
/** Creates a list of the diagnostics contained in the diagnostics storage.
|
||||
*
|
||||
* @return a list of the diagnostics in the storage
|
||||
*/
|
||||
def toList: List[IR.Diagnostic] = {
|
||||
diagnostics
|
||||
}
|
||||
}
|
||||
object DiagnosticStorage {
|
||||
|
||||
/** Creates a new instance of the diagnostics storage.
|
||||
*
|
||||
* @param initDiagnostics the initial diagnostics to construct it with
|
||||
* @return a new diagnostics storage instance
|
||||
*/
|
||||
def apply(initDiagnostics: Seq[Diagnostic] = Seq()): DiagnosticStorage =
|
||||
new DiagnosticStorage(initDiagnostics)
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
// === Useful Extension Methods =============================================
|
||||
// ==========================================================================
|
||||
@ -5658,12 +5591,12 @@ object IR {
|
||||
|
||||
/** Adds extension methods for working with lists of [[IR]].
|
||||
*
|
||||
* @param sequence the list
|
||||
* @param list the list
|
||||
* @tparam T the concrete IR type
|
||||
*/
|
||||
implicit class ListAsIr[T <: IR](sequence: List[T]) {
|
||||
implicit class ListAsIr[T <: IR](list: List[T]) {
|
||||
|
||||
/** Calls [[IR.duplicate]] on the elemtsn in [[sequence]].
|
||||
/** Calls [[IR.duplicate]] on the elements in [[list]].
|
||||
*
|
||||
* @param keepLocations whether or not locations should be kept in the
|
||||
* duplicated IR
|
||||
@ -5671,14 +5604,14 @@ object IR {
|
||||
* the duplicated IR
|
||||
* @param keepDiagnostics whether or not the diagnostics should be kept in
|
||||
* the duplicated IR
|
||||
* @return a duplicate of [[sequence]]
|
||||
* @return a duplicate of [[list]]
|
||||
*/
|
||||
def duplicate(
|
||||
keepLocations: Boolean = true,
|
||||
keepMetadata: Boolean = true,
|
||||
keepDiagnostics: Boolean = true
|
||||
): List[T] = {
|
||||
sequence
|
||||
list
|
||||
.map(_.duplicate(keepLocations, keepMetadata, keepDiagnostics))
|
||||
.asInstanceOf[List[T]]
|
||||
}
|
||||
|
@ -0,0 +1,134 @@
|
||||
package org.enso.compiler.core.ir
|
||||
|
||||
import org.enso.compiler.core.IR
|
||||
import org.enso.compiler.core.IR.Diagnostic
|
||||
|
||||
/** Storage for diagnostics in IR nodes.
|
||||
*
|
||||
* @param initDiagnostics the initial diagnostics
|
||||
*/
|
||||
sealed class DiagnosticStorage(initDiagnostics: Seq[Diagnostic] = Seq()) {
|
||||
private var diagnostics: List[Diagnostic] = initDiagnostics.toList
|
||||
|
||||
/** Adds a new diagnostic to the storage
|
||||
*
|
||||
* @param diagnostic the new diagnostic to store
|
||||
*/
|
||||
def add(diagnostic: Diagnostic): Unit = {
|
||||
diagnostics = diagnostic :: diagnostics
|
||||
}
|
||||
/** Adds new diagnostics to the storage.
|
||||
*
|
||||
* @param newDiagnostics the new diagnostics to store
|
||||
*/
|
||||
def add(newDiagnostics: Seq[Diagnostic]): Unit = {
|
||||
diagnostics = newDiagnostics.toList ::: diagnostics
|
||||
}
|
||||
|
||||
/** Applies the function `f` across the diagnostic storage, producing a
|
||||
* result sequence.
|
||||
*
|
||||
* @param f the function to apply
|
||||
* @tparam R the result type of `f`
|
||||
* @return the sequence that results from applying `f` over the storage
|
||||
*/
|
||||
def map[R](f: IR.Diagnostic => R): Seq[R] = {
|
||||
diagnostics.map(f)
|
||||
}
|
||||
|
||||
/** Applies the function `f` across the diagnostic storage in place.
|
||||
*
|
||||
* @param f the function to apply
|
||||
*/
|
||||
def mapInPlace(f: IR.Diagnostic => IR.Diagnostic): Unit = {
|
||||
diagnostics = diagnostics.map(f)
|
||||
}
|
||||
|
||||
/** Performs a collection operation on the diagnostics storage, producing
|
||||
* a new sequence.
|
||||
*
|
||||
* @param pf the partial function to apply
|
||||
* @tparam R the result type of the partial function
|
||||
* @return the result of collecting across the storage with `pf`
|
||||
*/
|
||||
def collect[R](pf: PartialFunction[IR.Diagnostic, R]): Seq[R] = {
|
||||
diagnostics.collect(pf)
|
||||
}
|
||||
|
||||
/** Filters the elements of the diagnostic storage using the predicate.
|
||||
*
|
||||
* @param pred the predicate to filter with
|
||||
* @return a new diagnostic storage instance containing elements matching
|
||||
* `pred`
|
||||
*/
|
||||
def filter(pred: IR.Diagnostic => Boolean): DiagnosticStorage = {
|
||||
new DiagnosticStorage(diagnostics.filter(pred))
|
||||
}
|
||||
|
||||
/** Filters the elements of the diagnostic storage in place using the
|
||||
* predicate.
|
||||
*
|
||||
* @param pred the predicate to filter with
|
||||
*/
|
||||
def filterInPlace(pred: IR.Diagnostic => Boolean): Unit = {
|
||||
diagnostics = diagnostics.filter(pred)
|
||||
}
|
||||
|
||||
/** Performs a left fold over the diagnostic storage to produce a result.
|
||||
*
|
||||
* @param init the starting value
|
||||
* @param op the operator to use to fold
|
||||
* @tparam L the result type of the fold
|
||||
* @return the result of folding over the storage using `op` starting wit
|
||||
* `init`
|
||||
*/
|
||||
def foldLeft[L](init: L)(op: (L, IR.Diagnostic) => L): L = {
|
||||
diagnostics.foldLeft(init)(op)
|
||||
}
|
||||
|
||||
/** Checks two diagnostics storages for equality.
|
||||
*
|
||||
* @param obj the object to check against `this`
|
||||
* @return `true` if `this == obj`, otherwise `false`
|
||||
*/
|
||||
override def equals(obj: Any): Boolean = obj match {
|
||||
case that: DiagnosticStorage => this.diagnostics == that.diagnostics
|
||||
case _ => false
|
||||
}
|
||||
|
||||
/** Creates a string representation of `this` diagnostic storage.
|
||||
*
|
||||
* @return the string representation of `this`
|
||||
*/
|
||||
override def toString: String =
|
||||
s"DiagnosticStorage(diagnostics = $diagnostics)"
|
||||
|
||||
/** Creates a list of the diagnostics contained in the diagnostics storage.
|
||||
*
|
||||
* @return a list of the diagnostics in the storage
|
||||
*/
|
||||
def toList: List[IR.Diagnostic] = {
|
||||
diagnostics
|
||||
}
|
||||
|
||||
/** Creates a shallow copy of `this`.
|
||||
*
|
||||
* This means that the diagnostic objects contained in `this` and the copy
|
||||
* are the same objects.
|
||||
*
|
||||
* @return a shallow copy of this
|
||||
*/
|
||||
def copy: DiagnosticStorage = {
|
||||
DiagnosticStorage(this.diagnostics)
|
||||
}
|
||||
}
|
||||
object DiagnosticStorage {
|
||||
|
||||
/** Creates a new instance of the diagnostics storage.
|
||||
*
|
||||
* @param initDiagnostics the initial diagnostics to construct it with
|
||||
* @return a new diagnostics storage instance
|
||||
*/
|
||||
def apply(initDiagnostics: Seq[Diagnostic] = Seq()): DiagnosticStorage =
|
||||
new DiagnosticStorage(initDiagnostics)
|
||||
}
|
@ -13,9 +13,9 @@ import org.enso.compiler.pass.IRPass
|
||||
class MetadataStorage(
|
||||
startingMeta: Seq[MetadataPair[_]] = Seq()
|
||||
) {
|
||||
private val pairs: Seq[(IRPass, Any)] =
|
||||
startingMeta.map(_.asPair.asInstanceOf[(IRPass, Any)])
|
||||
private var metadata: Map[IRPass, Any] = Map(pairs: _*)
|
||||
private var metadata: Map[IRPass, Any] = Map(
|
||||
startingMeta.map(_.asPair.asInstanceOf[(IRPass, Any)]): _*
|
||||
)
|
||||
|
||||
/** Adds a metadata pair to the node metadata.
|
||||
*
|
||||
@ -112,6 +112,19 @@ class MetadataStorage(
|
||||
}
|
||||
|
||||
override def toString: String = metadata.toString()
|
||||
|
||||
/** Creates a deep copy of `this`.
|
||||
*
|
||||
* @return a deep copy of `this`
|
||||
*/
|
||||
def duplicate: MetadataStorage = {
|
||||
val res = MetadataStorage()
|
||||
res.metadata = this.metadata.map {
|
||||
case (pass, meta) => (pass, meta.asInstanceOf[IRPass.Metadata].duplicate)
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
}
|
||||
object MetadataStorage extends MetadataStorageSyntax {
|
||||
|
||||
|
@ -128,12 +128,22 @@ object IRPass {
|
||||
throw new CompilerError(s"Cannot cast $this to the requested type.")
|
||||
)
|
||||
}
|
||||
|
||||
/** Creates a duplicate of this metadata.
|
||||
*
|
||||
* This method should employ deep-copy semantics where appropriate.
|
||||
*
|
||||
* @return a duplicate of this metadata.
|
||||
*/
|
||||
def duplicate: Metadata
|
||||
}
|
||||
object Metadata {
|
||||
|
||||
/** An empty metadata type for passes that do not create any metadata. */
|
||||
sealed case class Empty() extends Metadata {
|
||||
override val metadataName: String = "Empty"
|
||||
|
||||
override def duplicate: Empty = Empty()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -608,6 +608,8 @@ case object AliasAnalysis extends IRPass {
|
||||
*/
|
||||
sealed case class Root(override val graph: Graph) extends Scope {
|
||||
override val metadataName: String = "AliasAnalysis.Info.Scope.Root"
|
||||
|
||||
override def duplicate: IRPass.Metadata = this.copy()
|
||||
}
|
||||
|
||||
/** Aliasing information about a child scope.
|
||||
@ -618,6 +620,8 @@ case object AliasAnalysis extends IRPass {
|
||||
sealed case class Child(override val graph: Graph, scope: Graph.Scope)
|
||||
extends Scope {
|
||||
override val metadataName: String = "AliasAnalysis.Info.Scope.Child"
|
||||
|
||||
override def duplicate: IRPass.Metadata = this.copy()
|
||||
}
|
||||
}
|
||||
|
||||
@ -630,6 +634,8 @@ case object AliasAnalysis extends IRPass {
|
||||
sealed case class Occurrence(override val graph: Graph, id: Graph.Id)
|
||||
extends Info {
|
||||
override val metadataName: String = "AliasAnalysis.Info.Occurrence"
|
||||
|
||||
override def duplicate: IRPass.Metadata = this.copy()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -203,6 +203,8 @@ case object CachePreferenceAnalysis extends IRPass {
|
||||
/** @return weights as the Java collection */
|
||||
def asJavaWeights: util.Map[IR.ExternalId, java.lang.Double] =
|
||||
weights.asJava.asInstanceOf[util.Map[IR.ExternalId, java.lang.Double]]
|
||||
|
||||
override def duplicate: IRPass.Metadata = copy()
|
||||
}
|
||||
|
||||
/** Weight constants */
|
||||
|
@ -726,6 +726,8 @@ case object DataflowAnalysis extends IRPass {
|
||||
|
||||
combinedModule
|
||||
}
|
||||
|
||||
override def duplicate: IRPass.Metadata = copy()
|
||||
}
|
||||
object DependencyInfo {
|
||||
|
||||
|
@ -68,5 +68,8 @@ case object GatherDiagnostics extends IRPass {
|
||||
|
||||
/** The name of the metadata as a string. */
|
||||
override val metadataName: String = "GatherDiagnostics.Diagnostics"
|
||||
|
||||
override def duplicate: IRPass.Metadata =
|
||||
this.copy(diagnostics.map(identity))
|
||||
}
|
||||
}
|
||||
|
@ -423,6 +423,8 @@ case object TailCall extends IRPass {
|
||||
final case object Tail extends TailPosition {
|
||||
override val metadataName: String = "TailCall.TailPosition.Tail"
|
||||
override def isTail: Boolean = true
|
||||
|
||||
override def duplicate: IRPass.Metadata = Tail
|
||||
}
|
||||
|
||||
/** The expression is not in a tail position and cannot be tail call
|
||||
@ -431,6 +433,8 @@ case object TailCall extends IRPass {
|
||||
final case object NotTail extends TailPosition {
|
||||
override val metadataName: String = "TailCall.TailPosition.NotTail"
|
||||
override def isTail: Boolean = false
|
||||
|
||||
override def duplicate: IRPass.Metadata = NotTail
|
||||
}
|
||||
|
||||
/** Implicitly converts a boolean to a [[TailPosition]] value.
|
||||
|
@ -237,18 +237,12 @@ case object ComplexType extends IRPass {
|
||||
)
|
||||
|
||||
val newSig =
|
||||
signature.map(sig =>
|
||||
sig
|
||||
.copy(typed =
|
||||
methodRef.duplicate(keepMetadata = false, keepDiagnostics = false)
|
||||
)
|
||||
.duplicate(keepMetadata = false, keepDiagnostics = false)
|
||||
)
|
||||
signature.map(sig => sig.copy(typed = methodRef.duplicate()).duplicate())
|
||||
|
||||
val binding = Method.Binding(
|
||||
methodRef.duplicate(keepMetadata = false, keepDiagnostics = false),
|
||||
methodRef.duplicate(),
|
||||
args,
|
||||
body.duplicate(keepMetadata = false, keepDiagnostics = false),
|
||||
body.duplicate(),
|
||||
location
|
||||
)
|
||||
|
||||
|
@ -180,10 +180,7 @@ case object NestedPatternMatch extends IRPass {
|
||||
val scrutineeBinding =
|
||||
IR.Expression.Binding(scrutineeBindingName, scrutineeExpression, None)
|
||||
|
||||
val caseExprScrutinee = scrutineeBindingName.duplicate(
|
||||
keepDiagnostics = false,
|
||||
keepMetadata = false
|
||||
)
|
||||
val caseExprScrutinee = scrutineeBindingName.duplicate()
|
||||
|
||||
val processedBranches = branches.zipWithIndex.map {
|
||||
case (branch, ix) =>
|
||||
@ -240,7 +237,8 @@ case object NestedPatternMatch extends IRPass {
|
||||
val newName = freshNameSupply.newName()
|
||||
val newField = Pattern.Name(newName, None)
|
||||
val nestedScrutinee =
|
||||
newName.duplicate(keepDiagnostics = false, keepMetadata = false)
|
||||
newName.duplicate()
|
||||
newName.duplicate()
|
||||
|
||||
val newFields =
|
||||
fields.take(nestedPosition) ++ (newField :: fields.drop(
|
||||
@ -249,7 +247,7 @@ case object NestedPatternMatch extends IRPass {
|
||||
|
||||
val newPattern = cons.copy(
|
||||
fields =
|
||||
newFields.duplicate(keepDiagnostics = false, keepMetadata = false)
|
||||
newFields.duplicate()
|
||||
)
|
||||
|
||||
val newExpression = generateNestedCase(
|
||||
@ -261,10 +259,8 @@ case object NestedPatternMatch extends IRPass {
|
||||
)
|
||||
|
||||
val partDesugaredBranch = IR.Case.Branch(
|
||||
pattern = newPattern
|
||||
.duplicate(keepDiagnostics = false, keepMetadata = false),
|
||||
expression = newExpression
|
||||
.duplicate(keepDiagnostics = false, keepMetadata = false),
|
||||
pattern = newPattern.duplicate(),
|
||||
expression = newExpression.duplicate(),
|
||||
None
|
||||
)
|
||||
|
||||
@ -321,15 +317,15 @@ case object NestedPatternMatch extends IRPass {
|
||||
remainingBranches: List[IR.Case.Branch]
|
||||
): IR.Expression = {
|
||||
val fallbackCase = IR.Case.Expr(
|
||||
topLevelScrutineeExpr.duplicate(keepDiagnostics = false),
|
||||
remainingBranches.duplicate(keepMetadata = false),
|
||||
topLevelScrutineeExpr.duplicate(),
|
||||
remainingBranches.duplicate(),
|
||||
None
|
||||
)
|
||||
|
||||
val patternBranch =
|
||||
IR.Case.Branch(
|
||||
pattern.duplicate(keepDiagnostics = false),
|
||||
currentBranchExpr.duplicate(keepMetadata = false),
|
||||
pattern.duplicate(),
|
||||
currentBranchExpr.duplicate(),
|
||||
None
|
||||
)
|
||||
val fallbackBranch = IR.Case.Branch(
|
||||
@ -339,7 +335,7 @@ case object NestedPatternMatch extends IRPass {
|
||||
)
|
||||
|
||||
IR.Case.Expr(
|
||||
nestedScrutinee.duplicate(keepDiagnostics = false, keepMetadata = false),
|
||||
nestedScrutinee.duplicate(),
|
||||
List(patternBranch, fallbackBranch),
|
||||
None
|
||||
)
|
||||
|
@ -96,11 +96,7 @@ case object SectionsToBinOp extends IRPass {
|
||||
val rightCallArg =
|
||||
IR.CallArgument.Specified(None, rightArgName, None, None)
|
||||
val rightDefArg = IR.DefinitionArgument.Specified(
|
||||
rightArgName.duplicate(
|
||||
keepLocations = false,
|
||||
keepDiagnostics = false,
|
||||
keepMetadata = false
|
||||
),
|
||||
rightArgName.duplicate(),
|
||||
None,
|
||||
suspended = false,
|
||||
None
|
||||
@ -111,11 +107,7 @@ case object SectionsToBinOp extends IRPass {
|
||||
val leftCallArg =
|
||||
IR.CallArgument.Specified(None, leftArgName, None, None)
|
||||
val leftDefArg = IR.DefinitionArgument.Specified(
|
||||
leftArgName.duplicate(
|
||||
keepLocations = false,
|
||||
keepDiagnostics = false,
|
||||
keepMetadata = false
|
||||
),
|
||||
leftArgName.duplicate(),
|
||||
None,
|
||||
suspended = false,
|
||||
None
|
||||
@ -162,11 +154,7 @@ case object SectionsToBinOp extends IRPass {
|
||||
val leftCallArg =
|
||||
IR.CallArgument.Specified(None, leftArgName, None, None)
|
||||
val leftDefArg = IR.DefinitionArgument.Specified(
|
||||
leftArgName.duplicate(
|
||||
keepLocations = false,
|
||||
keepDiagnostics = false,
|
||||
keepMetadata = false
|
||||
),
|
||||
leftArgName.duplicate(),
|
||||
None,
|
||||
suspended = false,
|
||||
None
|
||||
@ -176,11 +164,7 @@ case object SectionsToBinOp extends IRPass {
|
||||
val rightCallArg =
|
||||
IR.CallArgument.Specified(None, rightArgName, None, None)
|
||||
val rightDefArg = IR.DefinitionArgument.Specified(
|
||||
rightArgName.duplicate(
|
||||
keepLocations = false,
|
||||
keepDiagnostics = false,
|
||||
keepMetadata = false
|
||||
),
|
||||
rightArgName.duplicate(),
|
||||
None,
|
||||
suspended = false,
|
||||
None
|
||||
@ -232,11 +216,7 @@ case object SectionsToBinOp extends IRPass {
|
||||
IR.CallArgument.Specified(None, leftArgName, None, None)
|
||||
val leftDefArg =
|
||||
IR.DefinitionArgument.Specified(
|
||||
leftArgName.duplicate(
|
||||
keepLocations = false,
|
||||
keepMetadata = false,
|
||||
keepDiagnostics = false
|
||||
),
|
||||
leftArgName.duplicate(),
|
||||
None,
|
||||
suspended = false,
|
||||
None
|
||||
@ -248,11 +228,7 @@ case object SectionsToBinOp extends IRPass {
|
||||
val rightCallArg =
|
||||
IR.CallArgument.Specified(None, rightArgName, None, None)
|
||||
val rightDefArg = IR.DefinitionArgument.Specified(
|
||||
rightArgName.duplicate(
|
||||
keepLocations = false,
|
||||
keepMetadata = false,
|
||||
keepDiagnostics = false
|
||||
),
|
||||
rightArgName.duplicate(),
|
||||
None,
|
||||
suspended = false,
|
||||
None
|
||||
|
@ -197,22 +197,32 @@ case object ApplicationSaturation extends IRPass {
|
||||
sealed case class Over(additionalArgCount: Int) extends CallSaturation {
|
||||
override val metadataName: String =
|
||||
"ApplicationSaturation.CallSaturation.Over"
|
||||
|
||||
override def duplicate: IRPass.Metadata = copy()
|
||||
}
|
||||
sealed case class Exact(helper: CodegenHelper) extends CallSaturation {
|
||||
override val metadataName: String =
|
||||
"ApplicationSaturation.CallSaturation.Exact"
|
||||
|
||||
override def duplicate: IRPass.Metadata = copy()
|
||||
}
|
||||
sealed case class ExactButByName() extends CallSaturation {
|
||||
override val metadataName: String =
|
||||
"ApplicationSaturation.CallSaturation.ExactButByName"
|
||||
|
||||
override def duplicate: IRPass.Metadata = ExactButByName()
|
||||
}
|
||||
sealed case class Partial(unappliedArgCount: Int) extends CallSaturation {
|
||||
override val metadataName: String =
|
||||
"ApplicationSaturation.CallSaturation.Partial"
|
||||
|
||||
override def duplicate: IRPass.Metadata = copy()
|
||||
}
|
||||
sealed case class Unknown() extends CallSaturation {
|
||||
override val metadataName: String =
|
||||
"ApplicationSaturation.CallSaturation.Unknown"
|
||||
|
||||
override def duplicate: IRPass.Metadata = Unknown()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,5 +142,7 @@ case object DocumentationComments extends IRPass {
|
||||
*/
|
||||
sealed case class Doc(documentation: String) extends IRPass.Metadata {
|
||||
override val metadataName: String = "DocumentationComments.Doc"
|
||||
|
||||
override def duplicate: IRPass.Metadata = copy(documentation.map(identity))
|
||||
}
|
||||
}
|
||||
|
@ -324,12 +324,16 @@ case object IgnoredBindings extends IRPass {
|
||||
case object Ignored extends State {
|
||||
override val metadataName: String = "IgnoredBindings.State.Ignored"
|
||||
override val isIgnored: Boolean = true
|
||||
|
||||
override def duplicate: IRPass.Metadata = Ignored
|
||||
}
|
||||
|
||||
/** States that the binding is not ignored. */
|
||||
case object NotIgnored extends State {
|
||||
override val metadataName: String = "IgnoredBindings.State.NotIgnored"
|
||||
override val isIgnored: Boolean = false
|
||||
|
||||
override def duplicate: IRPass.Metadata = NotIgnored
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -205,5 +205,8 @@ case object TypeSignatures extends IRPass {
|
||||
*/
|
||||
case class Signature(signature: IR.Expression) extends IRPass.Metadata {
|
||||
override val metadataName: String = "TypeSignatures.Signature"
|
||||
|
||||
override def duplicate: IRPass.Metadata =
|
||||
this.copy(signature = signature.duplicate())
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
package org.enso.compiler.test.core
|
||||
package org.enso.compiler.test.core.ir
|
||||
|
||||
import org.enso.compiler.core
|
||||
import org.enso.compiler.core.IR
|
||||
import org.enso.compiler.core.ir.DiagnosticStorage
|
||||
import org.enso.compiler.test.CompilerTest
|
||||
import org.enso.syntax.text.AST
|
||||
|
||||
class IRTest extends CompilerTest {
|
||||
class DiagnosticStorageTest extends CompilerTest {
|
||||
|
||||
// === Test Configuration ===================================================
|
||||
|
||||
@ -22,14 +22,14 @@ class IRTest extends CompilerTest {
|
||||
|
||||
"The IR diagnostics storage" should {
|
||||
"allow adding diagnostic results" in {
|
||||
val diagnostics = new IR.DiagnosticStorage
|
||||
val diagnostics = new DiagnosticStorage
|
||||
|
||||
diagnostics.add(mkDiagnostic("a"))
|
||||
diagnostics.toList should contain(mkDiagnostic("a"))
|
||||
}
|
||||
|
||||
"allow adding lists of diagnostic results" in {
|
||||
val diagnostics = new IR.DiagnosticStorage
|
||||
val diagnostics = new DiagnosticStorage
|
||||
|
||||
diagnostics.add(
|
||||
List(
|
||||
@ -44,7 +44,7 @@ class IRTest extends CompilerTest {
|
||||
}
|
||||
|
||||
"mapping across the diagnostics to produce a new sequence" in {
|
||||
val diagnostics = new IR.DiagnosticStorage(
|
||||
val diagnostics = new DiagnosticStorage(
|
||||
List(
|
||||
mkDiagnostic("a"),
|
||||
mkDiagnostic("b"),
|
||||
@ -56,7 +56,7 @@ class IRTest extends CompilerTest {
|
||||
}
|
||||
|
||||
"mapping across the diagnostics in place" in {
|
||||
val diagnostics = new IR.DiagnosticStorage(
|
||||
val diagnostics = new DiagnosticStorage(
|
||||
List(
|
||||
mkDiagnostic("a"),
|
||||
mkDiagnostic("b"),
|
||||
@ -83,7 +83,7 @@ class IRTest extends CompilerTest {
|
||||
val err =
|
||||
IR.Error.Syntax(AST.Blank(), IR.Error.Syntax.UnsupportedSyntax("aa"))
|
||||
|
||||
val diagnostics = new IR.DiagnosticStorage(
|
||||
val diagnostics = new DiagnosticStorage(
|
||||
List(
|
||||
mkDiagnostic("a"),
|
||||
mkDiagnostic("b"),
|
||||
@ -98,7 +98,7 @@ class IRTest extends CompilerTest {
|
||||
}
|
||||
|
||||
"filtering the diagnostics" in {
|
||||
val diagnostics = new IR.DiagnosticStorage(
|
||||
val diagnostics = new DiagnosticStorage(
|
||||
List(
|
||||
mkDiagnostic("aa"),
|
||||
mkDiagnostic("ba"),
|
||||
@ -106,7 +106,7 @@ class IRTest extends CompilerTest {
|
||||
)
|
||||
)
|
||||
|
||||
val result = new core.IR.DiagnosticStorage(
|
||||
val result = new DiagnosticStorage(
|
||||
List(mkDiagnostic("aa"), mkDiagnostic("ba"))
|
||||
)
|
||||
|
||||
@ -118,7 +118,7 @@ class IRTest extends CompilerTest {
|
||||
}
|
||||
|
||||
"filtering the diagnostics in place" in {
|
||||
val diagnostics = new IR.DiagnosticStorage(
|
||||
val diagnostics = new DiagnosticStorage(
|
||||
List(
|
||||
mkDiagnostic("aa"),
|
||||
mkDiagnostic("ba"),
|
||||
@ -138,7 +138,7 @@ class IRTest extends CompilerTest {
|
||||
}
|
||||
|
||||
"folding over the diagnostics" in {
|
||||
val diagnostics = new IR.DiagnosticStorage(
|
||||
val diagnostics = new DiagnosticStorage(
|
||||
List(
|
||||
mkDiagnostic("a"),
|
||||
mkDiagnostic("b"),
|
@ -32,6 +32,8 @@ class MetadataStorageTest extends CompilerTest {
|
||||
|
||||
sealed case class Metadata1() extends IRPass.Metadata {
|
||||
override val metadataName: String = "TestPass1.Metadata1"
|
||||
|
||||
override def duplicate: IRPass.Metadata = Metadata1()
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,6 +56,8 @@ class MetadataStorageTest extends CompilerTest {
|
||||
|
||||
sealed case class Metadata2() extends IRPass.Metadata {
|
||||
override val metadataName: String = "TestPass2.Metadata2"
|
||||
|
||||
override def duplicate: IRPass.Metadata = Metadata2()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ class RuntimeServerTest
|
||||
.allowExperimentalOptions(true)
|
||||
.allowAllAccess(true)
|
||||
.option(RuntimeOptions.PACKAGES_PATH, pkg.root.getAbsolutePath)
|
||||
.option(RuntimeOptions.LOG_LEVEL, "FINE")
|
||||
.option(RuntimeOptions.LOG_LEVEL, "WARNING")
|
||||
.option(RuntimeServerInfo.ENABLE_OPTION, "true")
|
||||
.out(out)
|
||||
.serverTransport { (uri, peer) =>
|
||||
|
@ -339,7 +339,7 @@ object Shape extends ShapeImplicit {
|
||||
with Phantom
|
||||
final case class Documented[T](doc: Doc, emptyLinesBetween: Int, ast: T)
|
||||
extends SpacelessAST[T]
|
||||
final case class Import[T](path: List1[AST.Cons]) extends SpacelessAST[T]
|
||||
final case class Import[T](path: AST) extends SpacelessAST[T]
|
||||
final case class JavaImport[T](path: List1[AST.Ident]) extends SpacelessAST[T]
|
||||
final case class Mixfix[T](name: List1[AST.Ident], args: List1[T])
|
||||
extends SpacelessAST[T]
|
||||
@ -351,6 +351,8 @@ object Shape extends ShapeImplicit {
|
||||
extends SpacelessAST[T]
|
||||
final case class Foreign[T](indent: Int, lang: String, code: List[String])
|
||||
extends SpacelessAST[T]
|
||||
final case class Modified[T](modifier: String, definition: T)
|
||||
extends SpacelessAST[T]
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Companion objects /////////////////////////////////////////////////////////
|
||||
@ -954,7 +956,7 @@ object Shape extends ShapeImplicit {
|
||||
implicit def ftor: Functor[Import] = semi.functor
|
||||
implicit def fold: Foldable[Import] = semi.foldable
|
||||
implicit def repr[T]: Repr[Import[T]] =
|
||||
t => R + ("import " + t.path.map(_.repr.build()).toList.mkString("."))
|
||||
t => R + "import" + t.path.repr.build()
|
||||
|
||||
// FIXME: How to make it automatic for non-spaced AST?
|
||||
implicit def ozip[T]: OffsetZip[Import, T] = _.map(Index.Start -> _)
|
||||
@ -1043,6 +1045,18 @@ object Shape extends ShapeImplicit {
|
||||
implicit def ozip[T]: OffsetZip[Foreign, T] = _.map(Index.Start -> _)
|
||||
implicit def span[T]: HasSpan[Foreign[T]] = _ => 0
|
||||
}
|
||||
|
||||
object Modified {
|
||||
implicit def ftor: Functor[Modified] = semi.functor
|
||||
implicit def fold: Foldable[Modified] = semi.foldable
|
||||
implicit def repr[T: Repr]: Repr[Modified[T]] = t => {
|
||||
R + t.modifier + t.definition.repr.build()
|
||||
}
|
||||
// FIXME: How to make it automatic for non-spaced AST?
|
||||
implicit def ozip[T]: OffsetZip[Modified, T] = _.map(Index.Start -> _)
|
||||
implicit def span[T]: HasSpan[Modified[T]] = _ => 0
|
||||
}
|
||||
|
||||
//// Implicits ////
|
||||
|
||||
object implicits {
|
||||
@ -1117,6 +1131,7 @@ sealed trait ShapeImplicit {
|
||||
case s: TypesetLiteral[T] => s.repr
|
||||
case s: Def[T] => s.repr
|
||||
case s: Foreign[T] => s.repr
|
||||
case s: Modified[T] => s.repr
|
||||
}
|
||||
implicit def ozip[T: HasSpan]: OffsetZip[Shape, T] = {
|
||||
case s: Unrecognized[T] => OffsetZip[Unrecognized, T].zipWithOffset(s)
|
||||
@ -1156,6 +1171,7 @@ sealed trait ShapeImplicit {
|
||||
case s: TypesetLiteral[T] => OffsetZip[TypesetLiteral, T].zipWithOffset(s)
|
||||
case s: Def[T] => OffsetZip[Def, T].zipWithOffset(s)
|
||||
case s: Foreign[T] => OffsetZip[Foreign, T].zipWithOffset(s)
|
||||
case s: Modified[T] => OffsetZip[Modified, T].zipWithOffset(s)
|
||||
}
|
||||
|
||||
implicit def span[T: HasSpan]: HasSpan[Shape[T]] = {
|
||||
@ -1196,6 +1212,7 @@ sealed trait ShapeImplicit {
|
||||
case s: TypesetLiteral[T] => s.span()
|
||||
case s: Def[T] => s.span()
|
||||
case s: Foreign[T] => s.span()
|
||||
case s: Modified[T] => s.span()
|
||||
}
|
||||
}
|
||||
|
||||
@ -2297,11 +2314,9 @@ object AST {
|
||||
type Import = ASTOf[Shape.Import]
|
||||
|
||||
object Import {
|
||||
def apply(path: List1[Cons]): Import = Shape.Import[AST](path)
|
||||
def apply(head: Cons): Import = Import(head, List())
|
||||
def apply(head: Cons, tail: List[Cons]): Import = Import(List1(head, tail))
|
||||
def apply(head: Cons, tail: Cons*): Import = Import(head, tail.toList)
|
||||
def unapply(t: AST): Option[List1[Cons]] =
|
||||
def apply(path: AST): Import =
|
||||
Shape.Import[AST](path)
|
||||
def unapply(t: AST): Option[AST] =
|
||||
Unapply[Import].run(t => t.path)(t)
|
||||
val any = UnapplyByType[Import]
|
||||
}
|
||||
@ -2399,6 +2414,25 @@ object AST {
|
||||
val any = UnapplyByType[Foreign]
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// Modified ////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
type Modified = ASTOf[Shape.Modified]
|
||||
object Modified {
|
||||
def apply(modifier: String, definition: AST): Modified = {
|
||||
Shape.Modified(modifier, definition)
|
||||
}
|
||||
def unapply(t: AST): Option[(String, AST)] = {
|
||||
Unapply[Modified].run(t => (t.modifier, t.definition))(t)
|
||||
}
|
||||
val any = UnapplyByType[Modified]
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//// Main ////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
def main(): Unit = {
|
||||
val v1 = Ident.Var("foo")
|
||||
// val v1_ = v1: AST
|
||||
|
@ -1,18 +1,17 @@
|
||||
package org.enso.syntax.text.ast.meta
|
||||
|
||||
import org.enso.data.List1
|
||||
import org.enso.data.Shifted
|
||||
import org.enso.data.{List1, Shifted}
|
||||
import org.enso.syntax.text.AST
|
||||
import org.enso.syntax.text.AST.Macro.Definition
|
||||
import org.enso.syntax.text.AST.Opr
|
||||
import org.enso.syntax.text.AST.Var
|
||||
import org.enso.syntax.text.AST.{Opr, Var}
|
||||
import org.enso.syntax.text.ast.Repr
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import scala.annotation.{nowarn, tailrec}
|
||||
|
||||
/** It contains definitions of built-in macros, like if-then-else or (-). These
|
||||
* macros might get moved to stdlib in the future.
|
||||
*/
|
||||
@nowarn("cat=unused")
|
||||
object Builtin {
|
||||
|
||||
val registry: Registry = {
|
||||
@ -119,34 +118,6 @@ object Builtin {
|
||||
}
|
||||
}
|
||||
|
||||
val imp = Definition(
|
||||
Var("import") -> Pattern
|
||||
.SepList(Pattern.Cons(), AST.Opr("."): AST, "expected module name")
|
||||
) { ctx =>
|
||||
ctx.body match {
|
||||
case List(s1) =>
|
||||
import Pattern.Match._
|
||||
s1.body match {
|
||||
case Seq(_, (headMatch, Many(_, tailMatch))) =>
|
||||
def unwrapSeg(lseg: Pattern.Match): AST.Cons =
|
||||
lseg.toStream match {
|
||||
case List(Shifted(_, AST.Cons.any(t))) => t
|
||||
case _ => internalError
|
||||
}
|
||||
|
||||
val head = unwrapSeg(headMatch)
|
||||
val tail = tailMatch.map {
|
||||
case Seq(_, (Tok(_, Shifted(_, AST.Opr("."))), seg)) =>
|
||||
unwrapSeg(seg)
|
||||
case _ => internalError
|
||||
}
|
||||
AST.Import(head, tail)
|
||||
case _ => internalError
|
||||
}
|
||||
case _ => internalError
|
||||
}
|
||||
}
|
||||
|
||||
val if_then = Definition(
|
||||
Var("if") -> Pattern.Expr(allowBlocks = false),
|
||||
Var("then") -> Pattern.Expr()
|
||||
@ -201,6 +172,8 @@ object Builtin {
|
||||
|
||||
val nonSpacedExpr = Pattern.Any(Some(false)).many1.build
|
||||
|
||||
// NOTE: The macro engine currently resolves ahead of all operators, meaning
|
||||
// that `->` doesn't obey the right precedence (e.g. with respect to `:`).
|
||||
val arrow = Definition(
|
||||
Some(nonSpacedExpr.or(Pattern.ExprUntilOpr("->"))),
|
||||
Opr("->") -> Pattern.NonSpacedExpr().or(Pattern.Expr())
|
||||
@ -259,7 +232,7 @@ object Builtin {
|
||||
}
|
||||
|
||||
val freeze = Definition(
|
||||
Var("freeze") -> Pattern.Expr()
|
||||
Var("freeze") -> (Pattern.Var() :: Pattern.Block())
|
||||
) { ctx =>
|
||||
ctx.body match {
|
||||
case List(s1) =>
|
||||
@ -293,6 +266,50 @@ object Builtin {
|
||||
}
|
||||
}
|
||||
|
||||
val `import` = {
|
||||
Definition(
|
||||
Var("import") -> Pattern.Expr()
|
||||
) { ctx =>
|
||||
ctx.body match {
|
||||
case List(s1) =>
|
||||
s1.body.toStream match {
|
||||
case List(expr) =>
|
||||
AST.Import(expr.wrapped)
|
||||
case _ => internalError
|
||||
}
|
||||
case _ => internalError
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val privateDef = {
|
||||
Definition(Var("private") -> Pattern.Expr()) { ctx =>
|
||||
ctx.body match {
|
||||
case List(s1) =>
|
||||
s1.body.toStream match {
|
||||
case List(expr) =>
|
||||
AST.Modified("private", expr.wrapped)
|
||||
case _ => internalError
|
||||
}
|
||||
case _ => internalError
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val unsafeDef = {
|
||||
Definition(Var("unsafe") -> Pattern.Expr()) { ctx =>
|
||||
ctx.body match {
|
||||
case List(s1) =>
|
||||
s1.body.toStream match {
|
||||
case List(expr) =>
|
||||
AST.Modified("unsafe", expr.wrapped)
|
||||
case _ => internalError
|
||||
}
|
||||
case _ => internalError
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO
|
||||
// We may want to better represent empty AST. Moreover, there should be a
|
||||
// way to generate multiple top-level entities from macros (like multiple
|
||||
@ -304,6 +321,8 @@ object Builtin {
|
||||
Definition(Opr("#") -> Pattern.Expr().tag("disable")) { _ => AST.Blank() }
|
||||
|
||||
Registry(
|
||||
privateDef,
|
||||
unsafeDef,
|
||||
group,
|
||||
sequenceLiteral,
|
||||
typesetLiteral,
|
||||
@ -311,7 +330,7 @@ object Builtin {
|
||||
if_then,
|
||||
if_then_else,
|
||||
polyglotJavaImport,
|
||||
imp,
|
||||
`import`,
|
||||
defn,
|
||||
arrow,
|
||||
foreign,
|
||||
|
@ -346,8 +346,6 @@ class ParserTest extends AnyFlatSpec with Matchers {
|
||||
"(" ?= amb("(", List(List(")")))
|
||||
"((" ?= amb_group(group_())
|
||||
|
||||
"import Std . Math .Vector".stripMargin ?= Import("Std", "Math", "Vector")
|
||||
|
||||
"""type Maybe a
|
||||
| type Just val:a
|
||||
| type Nothing""".stripMargin ?= {
|
||||
|
Loading…
Reference in New Issue
Block a user