Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

First pass at usage refactor #3560

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 38 additions & 49 deletions compiler-core/src/analyse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,10 @@ impl<'a, A> ModuleAnalyzer<'a, A> {
has_erlang_external: false,
has_javascript_external: false,
};

let variable_index = environment.register_variable();
let old_referencing_source = environment.referencing_source_indices.clone();
environment.referencing_source_indices = vec![variable_index];
let mut expr_typer = ExprTyper::new(environment, definition, &mut self.problems);
let typed_expr = expr_typer.infer_const(&annotation, *value);
let type_ = typed_expr.type_();
Expand Down Expand Up @@ -410,18 +414,11 @@ impl<'a, A> ModuleAnalyzer<'a, A> {
type_.clone(),
publicity,
Deprecation::NotDeprecated,
Some(variable_index),
);
environment.referencing_source_indices = old_referencing_source;
environment.insert_module_value(name.clone(), variant);

if publicity.is_private() {
environment.init_usage(
name.clone(),
EntityKind::PrivateConstant,
location,
&mut self.problems,
);
}

Definition::ModuleConstant(ModuleConstant {
documentation: doc,
location,
Expand Down Expand Up @@ -463,7 +460,7 @@ impl<'a, A> ModuleAnalyzer<'a, A> {
let target = environment.target;
let body_location = body.last().location();
let preregistered_fn = environment
.get_variable(&name)
.get_variable(&name, &location)
.expect("Could not find preregistered type for function");
let field_map = preregistered_fn.field_map().cloned();
let preregistered_type = preregistered_fn.type_.clone();
Expand Down Expand Up @@ -508,6 +505,15 @@ impl<'a, A> ModuleAnalyzer<'a, A> {
.map(|(a, t)| a.set_type(t.clone()))
.collect_vec();

let variable_index = environment
.scope
.get(&name)
.expect("function already registered")
.0
.expect("function already registered");
let old_referencing_source = environment.referencing_source_indices.clone();
environment.referencing_source_indices = vec![variable_index];

// Infer the type using the preregistered args + return types as a starting point
let result = environment.in_new_scope(&mut self.problems, |environment, problems| {
let mut expr_typer = ExprTyper::new(environment, definition, problems);
Expand Down Expand Up @@ -624,7 +630,9 @@ impl<'a, A> ModuleAnalyzer<'a, A> {
preregistered_type.clone(),
publicity,
deprecation.clone(),
Some(variable_index),
);
environment.referencing_source_indices = old_referencing_source;

Definition::Function(Function {
documentation: doc,
Expand Down Expand Up @@ -833,7 +841,7 @@ impl<'a, A> ModuleAnalyzer<'a, A> {
self.check_name_case(name_location, &name, Named::CustomTypeVariant);

let preregistered_fn = environment
.get_variable(&name)
.get_variable(&name, &location)
.expect("Could not find preregistered type for function");
let preregistered_type = preregistered_fn.type_.clone();

Expand Down Expand Up @@ -870,7 +878,7 @@ impl<'a, A> ModuleAnalyzer<'a, A> {
)
.collect();
let typed_parameters = environment
.get_type_constructor(&None, &name)
.get_type_constructor(&None, &name, &location)
.expect("Could not find preregistered type constructor ")
.parameters
.clone();
Expand Down Expand Up @@ -1017,25 +1025,18 @@ impl<'a, A> ModuleAnalyzer<'a, A> {
},
);

if value_constructor_publicity.is_private() {
environment.init_usage(
constructor.name.clone(),
EntityKind::PrivateTypeConstructor(name.clone()),
constructor.location,
&mut self.problems,
);
}

constructors_data.push(TypeValueConstructor {
name: constructor.name.clone(),
parameters: fields,
});
let variable_index = environment.register_variable();
environment.insert_variable(
constructor.name.clone(),
constructor_info,
type_,
value_constructor_publicity,
deprecation.clone(),
Some(variable_index),
);

environment.value_names.named_constructor_in_scope(
Expand Down Expand Up @@ -1131,14 +1132,6 @@ impl<'a, A> ModuleAnalyzer<'a, A> {
});
}

if publicity.is_private() {
environment.init_usage(
name.clone(),
EntityKind::PrivateType,
*location,
&mut self.problems,
);
};
Ok(())
}

Expand Down Expand Up @@ -1198,16 +1191,6 @@ impl<'a, A> ModuleAnalyzer<'a, A> {
};
let result = tryblock();
self.record_if_error(result);

// Register the type for detection of dead code.
if publicity.is_private() {
environment.init_usage(
name.clone(),
EntityKind::PrivateType,
*location,
&mut self.problems,
);
};
}

fn make_type_vars(
Expand Down Expand Up @@ -1305,21 +1288,15 @@ impl<'a, A> ModuleAnalyzer<'a, A> {
location: *location,
implementations: *implementations,
};
let variable_index = environment.register_variable();
environment.insert_variable(
name.clone(),
variant,
type_,
*publicity,
deprecation.clone(),
Some(variable_index),
);
if publicity.is_private() {
environment.init_usage(
name.clone(),
EntityKind::PrivateFunction,
*location,
&mut self.problems,
);
};
Ok(())
}

Expand Down Expand Up @@ -1422,7 +1399,7 @@ fn analyse_type_alias(t: UntypedTypeAlias, environment: &mut Environment<'_>) ->
// analysis aims to be fault tolerant to get the best possible feedback for
// the programmer in the language server, so the analyser gets here even
// though there was previously errors.
let type_ = match environment.get_type_constructor(&None, &alias) {
let type_ = match environment.get_type_constructor(&None, &alias, &location) {
Ok(constructor) => constructor.type_.clone(),
Err(_) => environment.new_generic_var(),
};
Expand Down Expand Up @@ -1529,12 +1506,18 @@ fn generalise_module_constant(
module: module_name.clone(),
implementations,
};
let variable_index = environment
.scope
.get(&name)
.expect("constant already exists")
.0;
environment.insert_variable(
name.clone(),
variant.clone(),
type_.clone(),
publicity,
deprecation.clone(),
variable_index,
);

environment.insert_module_value(
Expand Down Expand Up @@ -1586,7 +1569,7 @@ fn generalise_function(

// Lookup the inferred function information
let function = environment
.get_variable(&name)
.get_variable(&name, &location)
.expect("Could not find preregistered type for function");
let field_map = function.field_map().cloned();
let type_ = function.type_.clone();
Expand All @@ -1609,12 +1592,18 @@ fn generalise_function(
location,
implementations,
};
let variable_index = environment
.scope
.get(&name)
.expect("function already exists")
.0;
environment.insert_variable(
name.clone(),
variant.clone(),
type_.clone(),
publicity,
deprecation.clone(),
variable_index,
);
environment.insert_module_value(
name.clone(),
Expand Down
37 changes: 8 additions & 29 deletions compiler-core/src/analyse/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ use crate::{
ast::{SrcSpan, UnqualifiedImport, UntypedImport},
build::Origin,
type_::{
EntityKind, Environment, Error, ModuleInterface, Problems, UnusedModuleAlias,
ValueConstructorVariant,
Environment, Error, ModuleInterface, Problems, UnusedModuleAlias, ValueConstructorVariant,
},
};

Expand Down Expand Up @@ -100,15 +99,7 @@ impl<'context, 'problems> Importer<'context, 'problems> {
.insert_type_constructor(imported_name.clone(), type_info)
{
self.problems.error(e);
return;
}

self.environment.init_usage(
imported_name.clone(),
EntityKind::ImportedType,
import.location,
self.problems,
);
}

fn register_unqualified_value(&mut self, import: &UnqualifiedImport, module: &ModuleInterface) {
Expand All @@ -130,12 +121,14 @@ impl<'context, 'problems> Importer<'context, 'problems> {
})
}

let variable_index = self.environment.register_variable();
self.environment.insert_variable(
used_name.clone(),
value.variant.clone(),
value.type_.clone(),
value.publicity,
value.deprecation.clone(),
Some(variable_index),
);
&value.variant
}
Expand All @@ -151,26 +144,12 @@ impl<'context, 'problems> Importer<'context, 'problems> {
}
};

match variant {
ValueConstructorVariant::Record { name, module, .. } => {
self.environment.init_usage(
used_name.clone(),
EntityKind::ImportedConstructor,
location,
self.problems,
);
self.environment.value_names.named_constructor_in_scope(
module.clone(),
name.clone(),
used_name.clone(),
);
}
_ => self.environment.init_usage(
if let ValueConstructorVariant::Record { name, module, .. } = variant {
self.environment.value_names.named_constructor_in_scope(
module.clone(),
name.clone(),
used_name.clone(),
EntityKind::ImportedValue,
location,
self.problems,
),
);
};

// Check if value already was imported
Expand Down
2 changes: 2 additions & 0 deletions compiler-core/src/ast/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,14 @@ fn compile_expression(src: &str) -> TypedStatement {
module: "mymod".into(),
constructor_index: 0,
};
let variable_index = environment.register_variable();
environment.insert_variable(
"Cat".into(),
variant,
type_::fn_(vec![type_::string(), type_::int()], cat_type.clone()),
Publicity::Public,
Deprecation::NotDeprecated,
Some(variable_index),
);

environment.insert_accessors(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
source: compiler-core/src/erlang/tests.rs
assertion_line: 275
expression: "pub type State{ Start(Int) End(Int) }\n pub fn build(constructor : fn(Int) -> a) -> a { constructor(1) }\n pub fn main() { build(End) }"
---
-module(my@mod).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
source: compiler-core/src/erlang/tests.rs
assertion_line: 284
expression: "fn go(x xx, y yy) { xx }\npub fn x() { go(x: 1, y: 2) go(y: 3, x: 4) }"
---
-module(my@mod).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
source: compiler-core/src/erlang/tests.rs
assertion_line: 208
expression: "pub fn second(list) { case list { [x, y] -> y z -> 1 } }\npub fn tail(list) { case list { [x, ..xs] -> xs z -> list } }\n "
---
-module(my@mod).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
source: compiler-core/src/erlang/tests.rs
assertion_line: 343
expression: "\npub fn factory(f, i) {\n f(i)\n}\n\npub type Box {\n Box(i: Int)\n}\n\npub fn main() {\n factory(Box, 0)\n}\n"
---
-module(my@mod).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
source: compiler-core/src/erlang/tests.rs
assertion_line: 241
expression: "pub type Pair(x, y) { Pair(x: x, y: y) } pub fn x() { Pair(1, 2) Pair(3., 4.) }"
---
-module(my@mod).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
source: compiler-core/src/erlang/tests.rs
assertion_line: 516
expression: "fn id(x) {\n x\n}\n\npub fn bool_expr(x, y) {\n y || x |> id\n}"
---
-module(my@mod).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
source: compiler-core/src/erlang/tests.rs
assertion_line: 444
expression: "\nfn id(x) {\n x\n}\n\npub fn main() {\n id(id)\n}\n"
---
-module(my@mod).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
source: compiler-core/src/erlang/tests/consts.rs
assertion_line: 53
expression: "\nfn identity(a: a) -> a {\na\n}\n\nconst id = identity\n\npub fn main(){\n let num = id(1)\n let word = id(\"Word\")\n}"
---
-module(my@mod).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
source: compiler-core/src/erlang/tests/consts.rs
assertion_line: 70
expression: "\n fn identity(a) {\n a\n }\n\n pub const id = identity\n "
---
-module(my@mod).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
source: compiler-core/src/erlang/tests/consts.rs
assertion_line: 100
expression: "\n fn identity(a) {\n a\n }\n\n pub type Mapper(b) {\n Mapper(fn(b) -> b)\n }\n\n pub type Funcs(b) {\n Funcs(mapper: Mapper(b))\n }\n\n pub const id_mapper = Funcs(Mapper(identity))\n "
---
-module(my@mod).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
source: compiler-core/src/erlang/tests/consts.rs
assertion_line: 83
expression: "\n fn identity(a) {\n a\n }\n\n pub type Mapper(b) {\n Mapper(fn(b) -> b)\n }\n\n pub const id_mapper = Mapper(identity)\n "
---
-module(my@mod).
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
---
source: compiler-core/src/erlang/tests/consts.rs
assertion_line: 168
expression: "\n fn identity(a) {\n a\n }\n\n pub type Mapper(b) {\n Mapper(fn(b) -> b)\n }\n\n @internal\n pub const id_mapper = Mapper(identity)\n "
---
-module(my@mod).
Expand Down
Loading
Loading