Current section

Files

Jump to
cleam src internal ast_type.gleam
Raw

src/internal/ast_type.gleam

import glance.{
type Module as AST, CustomType, Definition, Function, Module as AST, NamedType,
Public, TypeAlias, Variant,
}
import gleam/list
import gleam/option.{Some}
import gleam/string
import internal/ast.{FileAst, ModuleName, PublicType}
pub fn public_type(file_ast) {
let FileAst(ast) = file_ast
let AST(_, types, type_aliases, _, fns) = ast
{
use pub_type <- list.flat_map(types)
let Definition(_, CustomType(pub_type, is_public, _, _, sub_types)) =
pub_type
case is_public {
Public -> {
use sub_type <- list.filter_map(case list.length(sub_types) > 0 {
True -> sub_types
False -> [Variant(pub_type, [])]
})
let Variant(type_name, _) = sub_type
pub_type_if_not_returned_in_pub_fun(type_name, fns)
}
_ -> []
}
}
|> list.append({
use pub_type <- list.filter_map(type_aliases)
let Definition(_, TypeAlias(pub_type, is_public, ..)) = pub_type
case is_public {
Public -> Ok(PublicType(pub_type))
_ -> Error(Nil)
}
})
}
fn pub_type_if_not_returned_in_pub_fun(type_name, fns) {
let pub_fun_usage = {
use fun <- list.find_map(fns)
case fun {
Definition(_, Function(_, public, _, Some(NamedType(t_name, ..)), ..))
if public == Public && t_name == type_name
-> Ok(Nil)
_ -> Error(Nil)
}
}
case pub_fun_usage {
Ok(Nil) -> Error(Nil)
Error(Nil) -> Ok(PublicType(type_name))
}
}
pub fn is_pub_type_used(files_ast, pub_type_name, module_full_name) {
ast.is_pub_member_used(
files_ast,
pub_type_name,
module_full_name,
check_type_usage,
)
}
fn check_type_usage(statements, pub_type_name, module_name) {
let assert PublicType(pub_type_name) = pub_type_name
let ModuleName(module_name) = module_name
use statement <- list.find_map(statements)
let serialized_statement =
statement
|> string.inspect
case
serialized_statement
|> string.contains(
"FieldAccess(Variable(\""
<> module_name
<> "\"), \""
<> pub_type_name
<> "\")",
)
|| serialized_statement
|> string.contains(
"Some(NamedType(\""
<> pub_type_name
<> "\", Some(\""
<> module_name
<> "\")",
)
|| serialized_statement
|> string.contains(
"PatternConstructor(Some(\""
<> module_name
<> "\"), \""
<> pub_type_name
<> "\"",
)
{
True -> Ok(Nil)
False -> Error(Nil)
}
}