Skip to content

Commit 8555286

Browse files
committed
Implement indexing for infix declarations
1 parent a8af6d2 commit 8555286

File tree

4 files changed

+64
-2
lines changed

4 files changed

+64
-2
lines changed

crates/indexing/src/algorithm.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ fn index_declaration(state: &mut IndexState, declaration: cst::Declaration) {
2525
match declaration {
2626
cst::Declaration::ValueSignature(s) => index_value_signature(state, s),
2727
cst::Declaration::ValueEquation(e) => index_value_equation(state, e),
28-
cst::Declaration::InfixDeclaration(_) => todo!(),
28+
cst::Declaration::InfixDeclaration(i) => index_infix(state, i),
2929
cst::Declaration::TypeRoleDeclaration(r) => index_type_role(state, r),
3030
cst::Declaration::ClassSignature(s) => index_class_signature(state, s),
3131
cst::Declaration::ClassDeclaration(d) => index_class_declaration(state, d),
@@ -97,6 +97,35 @@ fn index_value_equation(state: &mut IndexState, equation: cst::ValueEquation) {
9797
}
9898
}
9999

100+
fn index_infix(state: &mut IndexState, infix: cst::InfixDeclaration) {
101+
let type_token = infix.type_token();
102+
let operator_token = infix.operator_token();
103+
104+
let declaration = cst::Declaration::InfixDeclaration(infix);
105+
let declaration_id = state.source_map.insert_declaration(&declaration);
106+
107+
let Some(operator_token) = operator_token else { return };
108+
let operator = operator_token.text();
109+
110+
if type_token.is_none() {
111+
if let Some((_, item_id)) = state.nominal.expr_get_mut(operator) {
112+
let duplicate = Duplicate::Declaration(declaration_id);
113+
state.errors.push(IndexingError::DuplicateExprItem { item_id, duplicate });
114+
} else {
115+
let operator: SmolStr = operator.into();
116+
state.nominal.insert_expr(operator, ExprItem::Operator(declaration_id));
117+
}
118+
} else {
119+
if let Some((_, item_id)) = state.nominal.type_get_mut(operator) {
120+
let duplicate = Duplicate::Declaration(declaration_id);
121+
state.errors.push(IndexingError::DuplicateTypeItem { item_id, duplicate });
122+
} else {
123+
let operator: SmolStr = operator.into();
124+
state.nominal.insert_type(operator, TypeItem::Operator(declaration_id));
125+
}
126+
}
127+
}
128+
100129
fn index_type_role(state: &mut IndexState, role: cst::TypeRoleDeclaration) {
101130
let name_token = role.name_token();
102131

@@ -108,7 +137,7 @@ fn index_type_role(state: &mut IndexState, role: cst::TypeRoleDeclaration) {
108137

109138
if let Some((item, item_id)) = state.nominal.type_get_mut(name) {
110139
match item {
111-
TypeItem::Class(_) | TypeItem::Synonym(_) => {
140+
TypeItem::Class(_) | TypeItem::Synonym(_) | TypeItem::Operator(_) => {
112141
state.errors.push(IndexingError::InvalidRoleDeclaration {
113142
item_id: Some(item_id),
114143
declaration: declaration_id,

crates/indexing/src/indexes.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ pub enum ExprItem {
3838
Method(ClassMemberId),
3939
Value(ValueGroupId),
4040
Foreign(DeclarationId),
41+
Operator(DeclarationId),
4142
}
4243

4344
pub type TypeItemId = Id<TypeItem>;
@@ -49,6 +50,7 @@ pub enum TypeItem {
4950
Newtype(TypeGroupId),
5051
Synonym(TypeGroupId),
5152
Foreign(TypeGroupId),
53+
Operator(DeclarationId),
5254
}
5355

5456
/// Mapping from names to module items.

crates/indexing/tests/indexing.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ fn valid_module() {
3737
"foreign import unit :: Unit",
3838
"derive instance eqBoolean :: Eq Boolean",
3939
"derive newtype instance eqId :: Eq Id",
40+
"infix 5 eq as ==",
41+
"infix 5 type Plus as +",
4042
]);
4143

4244
assert!(index.errors.is_empty());
@@ -556,3 +558,26 @@ fn duplicate_derive_declaration() {
556558
]
557559
);
558560
}
561+
562+
#[test]
563+
fn duplicate_operator() {
564+
let (_, index) = index(&[
565+
"infix 5 eq as ==",
566+
"infix 5 eq as ==",
567+
"infix 5 type Plus as +",
568+
"infix 5 type Plus as +",
569+
]);
570+
assert_eq!(
571+
&index.errors,
572+
&[
573+
IndexingError::DuplicateExprItem {
574+
item_id: Id::from_raw(0),
575+
duplicate: Duplicate::Declaration(Id::from_raw(1)),
576+
},
577+
IndexingError::DuplicateTypeItem {
578+
item_id: Id::from_raw(0),
579+
duplicate: Duplicate::Declaration(Id::from_raw(3)),
580+
},
581+
]
582+
);
583+
}

crates/syntax/src/cst.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,3 +316,9 @@ has_token!(
316316
TypeRoleDeclaration
317317
| name_token() -> UPPER
318318
);
319+
320+
has_token!(
321+
InfixDeclaration
322+
| type_token() -> TYPE
323+
| operator_token() -> OPERATOR
324+
);

0 commit comments

Comments
 (0)