1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
use std::borrow::Cow;
use stc_ts_errors::ErrorKind;
use stc_ts_types::{TsExpr, Type, TypeElement, TypeLit};
use stc_utils::{cache::Freeze, dev_span};
use swc_common::{Span, TypeEq, DUMMY_SP};
use crate::{
analyzer::{assign::AssignOpts, Analyzer},
VResult,
};
impl Analyzer<'_, '_> {
pub(super) fn report_error_for_wrong_interface_inheritance(&mut self, span: Span, body: &[TypeElement], parent: &[TsExpr]) {
let _tracing = dev_span!("report_error_for_wrong_interface_inheritance");
if self.config.is_builtin || self.config.is_dts {
return;
}
if body.is_empty() {
return;
}
for p in parent.iter() {
let res: VResult<()> = try {
let parent = self.type_of_ts_entity_name(span, &p.expr, p.type_args.as_deref())?;
let parent = self.normalize(None, Cow::Owned(parent), Default::default())?.freezed();
if matches!(
parent.normalize(),
Type::Mapped(..)
| Type::Tuple(..)
| Type::Function(..)
| Type::Constructor(..)
| Type::Array(..)
| Type::Enum(..)
| Type::Namespace(..)
| Type::Module(..)
) {
continue;
}
self.assign_with_opts(
&mut Default::default(),
&parent,
&Type::TypeLit(TypeLit {
span: DUMMY_SP,
members: body.to_vec(),
metadata: Default::default(),
tracker: Default::default(),
}),
AssignOpts {
span,
allow_unknown_rhs: Some(true),
allow_missing_fields: true,
allow_assignment_of_param: true,
skip_call_and_constructor_elem: true,
treat_array_as_interfaces: true,
..Default::default()
},
)?;
};
if let Err(err) = res {
self.storage
.report(ErrorKind::InvalidInterfaceInheritance { span, cause: box err }.into());
return;
}
}
}
pub(crate) fn report_error_for_conflicting_parents(&mut self, span: Span, parent: &[TsExpr]) {
let _tracing = dev_span!("report_error_for_conflicting_parents");
if self.config.is_builtin || self.config.is_dts {
return;
}
for (i, p1) in parent.iter().enumerate() {
let res: VResult<()> = try {
let p1_type = self.type_of_ts_entity_name(span, &p1.expr, p1.type_args.as_deref())?.freezed();
for (j, p2) in parent.iter().enumerate() {
if i <= j {
continue;
}
if p1.type_eq(p2) {
continue;
}
let p2 = self.type_of_ts_entity_name(span, &p2.expr, p2.type_args.as_deref())?.freezed();
if let Err(err) = self.assign_with_opts(
&mut Default::default(),
&p1_type,
&p2,
AssignOpts {
span,
use_missing_fields_for_class: true,
allow_unknown_rhs: Some(true),
..Default::default()
},
) {
match &*err {
ErrorKind::MissingFields { .. } => {}
ErrorKind::Errors { errors, .. }
if errors.iter().all(|err| matches!(&**err, ErrorKind::MissingFields { .. })) => {}
ErrorKind::ObjectAssignFailed { .. } => {}
_ => self.storage.report(err.convert(|err| ErrorKind::InterfaceNotCompatible { span })),
}
}
}
};
}
}
}