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

feat(isolated-declarations): add ts error code to the error message #3755

Merged
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
7 changes: 2 additions & 5 deletions crates/oxc_isolated_declarations/src/declaration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ use oxc_allocator::Box;
#[allow(clippy::wildcard_imports)]
use oxc_ast::ast::*;
use oxc_ast::{syntax_directed_operations::BoundNames, Visit};
use oxc_diagnostics::OxcDiagnostic;
use oxc_span::{GetSpan, SPAN};
use oxc_syntax::scope::ScopeFlags;

use crate::{
diagnostics::{
binding_element_export, inferred_type_of_expression, signature_computed_property_name,
variable_must_have_explicit_type,
},
IsolatedDeclarations,
};
Expand Down Expand Up @@ -82,10 +82,7 @@ impl<'a> IsolatedDeclarations<'a> {
if init.is_none() && binding_type.is_none() {
binding_type = Some(self.ast.ts_unknown_keyword(SPAN));
if !decl.init.as_ref().is_some_and(Expression::is_function) {
self.error(
OxcDiagnostic::error("Variable must have an explicit type annotation with --isolatedDeclarations.")
.with_label(decl.id.span()),
);
self.error(variable_must_have_explicit_type(decl.id.span()));
}
}
}
Expand Down
111 changes: 75 additions & 36 deletions crates/oxc_isolated_declarations/src/diagnostics.rs
Original file line number Diff line number Diff line change
@@ -1,102 +1,141 @@
use oxc_diagnostics::OxcDiagnostic;
use oxc_span::{Atom, Span};

pub fn method_must_have_explicit_return_type(span: Span) -> OxcDiagnostic {
pub fn function_must_have_explicit_return_type(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(
"Method must have an explicit return type annotation with --isolatedDeclarations.",
"TS9007: Function must have an explicit return type annotation with --isolatedDeclarations.",
)
.with_label(span)
}

pub fn function_must_have_explicit_return_type(span: Span) -> OxcDiagnostic {
pub fn method_must_have_explicit_return_type(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(
"Function must have an explicit return type annotation with --isolatedDeclarations.",
"TS9008: Method must have an explicit return type annotation with --isolatedDeclarations.",
)
.with_label(span)
}

pub fn accessor_must_have_explicit_return_type(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(
"At least one accessor must have an explicit return type annotation with --isolatedDeclarations.",
"TS9009: At least one accessor must have an explicit return type annotation with --isolatedDeclarations.",
)
.with_label(span)
}

pub fn property_must_have_explicit_type(span: Span) -> OxcDiagnostic {
pub fn variable_must_have_explicit_type(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(
"Property must have an explicit type annotation with --isolatedDeclarations.",
"TS9010: Variable must have an explicit type annotation with --isolatedDeclarations.",
)
.with_label(span)
}

pub fn type_containing_private_name(name: &Atom<'_>, span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!(
"Type containing private name '{name}' can't be used with --isolatedDeclarations."
))
pub fn parameter_must_have_explicit_type(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(
"TS9011: Parameter must have an explicit type annotation with --isolatedDeclarations.",
)
.with_label(span)
}

pub fn computed_property_name(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error("Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.")
pub fn property_must_have_explicit_type(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(
"TS9012: Property must have an explicit type annotation with --isolatedDeclarations.",
)
.with_label(span)
}

pub fn inferred_type_of_expression(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error("TS9013: Expression type can't be inferred with --isolatedDeclarations.")
.with_label(span)
}

pub fn signature_computed_property_name(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error("Computed properties must be number or string literals, variables or dotted expressions with --isolatedDeclarations.")
OxcDiagnostic::error("TS9014: Computed properties must be number or string literals, variables or dotted expressions with --isolatedDeclarations.")
.with_label(span)
}

pub fn enum_member_initializers(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error("Enum member initializers must be computable without references to external symbols with --isolatedDeclarations.")
.with_label(span)
pub fn object_with_spread_assignments(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(
"TS9015: Objects that contain spread assignments can't be inferred with --isolatedDeclarations.",
)
.with_label(span)
}

pub fn extends_clause_expression(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error("Extends clause can't contain an expression with --isolatedDeclarations.")
.with_label(span)
pub fn shorthand_property(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(
"TS9016: Objects that contain shorthand properties can't be inferred with --isolatedDeclarations.",
)
.with_label(span)
}

pub fn default_export_inferred(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error("Default exports can't be inferred with --isolatedDeclarations.")
pub fn array_inferred(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error("TS9017: Only const arrays can be inferred with --isolatedDeclarations.")
.with_label(span)
}

pub fn array_inferred(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error("Arrays can't be inferred with --isolatedDeclarations.").with_label(span)
pub fn arrays_with_spread_elements(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(
"TS9018: Arrays with spread elements can't inferred with --isolatedDeclarations.",
)
.with_label(span)
}

pub fn shorthand_property(span: Span) -> OxcDiagnostic {
pub fn binding_element_export(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(
"Objects that contain shorthand properties can't be inferred with --isolatedDeclarations.",
"TS9019: Binding elements can't be exported directly with --isolatedDeclarations.",
)
.with_label(span)
}

pub fn inferred_type_of_expression(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error("Expression type can't be inferred with --isolatedDeclarations.")
pub fn enum_member_initializers(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error("TS9020: Enum member initializers must be computable without references to external symbols with --isolatedDeclarations.")
.with_label(span)
}

pub fn inferred_type_of_class_expression(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error("Class expression type can't be inferred with --isolatedDeclarations.")
.with_label(span)
pub fn extends_clause_expression(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(
"TS9021: Extends clause can't contain an expression with --isolatedDeclarations.",
)
.with_label(span)
}

pub fn parameter_must_have_explicit_type(span: Span) -> OxcDiagnostic {
pub fn inferred_type_of_class_expression(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(
"Parameter must have an explicit type annotation with --isolatedDeclarations.",
"TS9022: Inference from class expressions is not supported with --isolatedDeclarations.",
)
.with_label(span)
}

pub fn implicitly_adding_undefined_to_type(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(
"Declaration emit for this parameter requires implicitly adding undefined to it's type. This is not supported with --isolatedDeclarations.",
"TS9025: Declaration emit for this parameter requires implicitly adding undefined to it's type. This is not supported with --isolatedDeclarations.",
)
.with_label(span)
}

pub fn binding_element_export(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error("Binding elements can't be exported directly with --isolatedDeclarations.")
#[allow(dead_code)]
pub fn function_with_assigning_properties(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(
"TS9023: Assigning properties to functions without declaring them is not supported with --isolatedDeclarations. Add an explicit declaration for the properties assigned to this function.",
)
.with_label(span)
}

// TS9026: Declaration emit for this file requires preserving this import for augmentations. This is not supported with --isolatedDeclarations.
// This error requires cross-file checking, which we cannot support.

pub fn default_export_inferred(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error("TS9037: Default exports can't be inferred with --isolatedDeclarations.")
.with_label(span)
}

pub fn computed_property_name(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error("TS9038: Computed property names on class or object literals cannot be inferred with --isolatedDeclarations.")
.with_label(span)
}

pub fn type_containing_private_name(name: &Atom<'_>, span: Span) -> OxcDiagnostic {
OxcDiagnostic::error(format!(
"TS9039: Type containing private name '{name}' can't be used with --isolatedDeclarations."
))
.with_label(span)
}
10 changes: 4 additions & 6 deletions crates/oxc_isolated_declarations/src/inferrer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ use oxc_ast::ast::{
ArrowFunctionExpression, BindingPatternKind, Expression, FormalParameter, Function, Statement,
TSType, TSTypeAnnotation,
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_span::{GetSpan, SPAN};

use crate::{
diagnostics::{array_inferred, inferred_type_of_class_expression},
diagnostics::{
array_inferred, inferred_type_of_class_expression, parameter_must_have_explicit_type,
},
return_type::FunctionReturnType,
IsolatedDeclarations,
};
Expand Down Expand Up @@ -79,10 +80,7 @@ impl<'a> IsolatedDeclarations<'a> {
} else {
if let Expression::TSAsExpression(expr) = &pattern.right {
if !expr.type_annotation.is_keyword_or_literal() {
self.error(
OxcDiagnostic::error("Parameter must have an explicit type annotation with --isolatedDeclarations.")
.with_label(expr.type_annotation.span())
);
self.error(parameter_must_have_explicit_type(expr.type_annotation.span()));
}
}

Expand Down
131 changes: 64 additions & 67 deletions crates/oxc_isolated_declarations/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ use oxc_ast::ast::{
ObjectExpression, ObjectPropertyKind, TSLiteral, TSMethodSignatureKind, TSTupleElement, TSType,
TSTypeOperatorOperator,
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_span::{GetSpan, Span, SPAN};

use crate::{
diagnostics::{
function_must_have_explicit_return_type, inferred_type_of_expression, shorthand_property,
arrays_with_spread_elements, function_must_have_explicit_return_type,
inferred_type_of_expression, object_with_spread_assignments, shorthand_property,
},
function::get_function_span,
IsolatedDeclarations,
Expand Down Expand Up @@ -78,60 +78,61 @@ impl<'a> IsolatedDeclarations<'a> {
is_const: bool,
) -> TSType<'a> {
let members =
self.ast.new_vec_from_iter(expr.properties.iter().filter_map(|property| match property {
ObjectPropertyKind::ObjectProperty(object) => {
if self.report_property_key(&object.key, object.computed) {
return None;
}

if object.shorthand {
self.error(shorthand_property(object.span));
return None;
}

if let Expression::FunctionExpression(function) = &object.value {
if !is_const && object.method {
let return_type = self.infer_function_return_type(function);
let params = self.transform_formal_parameters(&function.params);
return Some(self.ast.ts_method_signature(
self.ast.new_vec_from_iter(expr.properties.iter().filter_map(
|property| match property {
ObjectPropertyKind::ObjectProperty(object) => {
if self.report_property_key(&object.key, object.computed) {
return None;
}

if object.shorthand {
self.error(shorthand_property(object.span));
return None;
}

if let Expression::FunctionExpression(function) = &object.value {
if !is_const && object.method {
let return_type = self.infer_function_return_type(function);
let params = self.transform_formal_parameters(&function.params);
return Some(self.ast.ts_method_signature(
object.span,
self.ast.copy(&object.key),
object.computed,
false,
TSMethodSignatureKind::Method,
self.ast.copy(&function.this_param),
params,
return_type,
self.ast.copy(&function.type_parameters),
));
}
}

let type_annotation = self.infer_type_from_expression(&object.value);

if type_annotation.is_none() {
self.error(inferred_type_of_expression(object.value.span()));
return None;
}

let property_signature = self.ast.ts_property_signature(
object.span,
self.ast.copy(&object.key),
object.computed,
false,
TSMethodSignatureKind::Method,
self.ast.copy(&function.this_param),
params,
return_type,
self.ast.copy(&function.type_parameters),
));
false,
is_const,
self.ast.copy(&object.key),
type_annotation.map(|type_annotation| {
self.ast.ts_type_annotation(SPAN, type_annotation)
}),
);
Some(property_signature)
}
}

let type_annotation = self.infer_type_from_expression(&object.value);

if type_annotation.is_none() {
self.error(inferred_type_of_expression(object.value.span()));
return None;
}

let property_signature = self.ast.ts_property_signature(
object.span,
false,
false,
is_const,
self.ast.copy(&object.key),
type_annotation
.map(|type_annotation| self.ast.ts_type_annotation(SPAN, type_annotation)),
);
Some(property_signature)
},
ObjectPropertyKind::SpreadProperty(spread) => {
self.error(OxcDiagnostic::error(
"Objects that contain spread assignments can't be inferred with --isolatedDeclarations.",
).with_label(spread.span));
None
}
}));
ObjectPropertyKind::SpreadProperty(spread) => {
self.error(object_with_spread_assignments(spread.span));
None
}
},
));
self.ast.ts_type_literal(SPAN, members)
}

Expand All @@ -141,21 +142,17 @@ impl<'a> IsolatedDeclarations<'a> {
is_const: bool,
) -> TSType<'a> {
let element_types =
self.ast.new_vec_from_iter(expr.elements.iter().filter_map(|element| {
match element {
ArrayExpressionElement::SpreadElement(spread) => {
self.error(OxcDiagnostic::error(
"Arrays with spread elements can't inferred with --isolatedDeclarations.",
).with_label(spread.span));
None
},
ArrayExpressionElement::Elision(elision) => {
Some(TSTupleElement::from(self.ast.ts_undefined_keyword(elision.span)))
},
_ => {
Some(TSTupleElement::from(self.transform_expression_to_ts_type(element.to_expression())))
}
self.ast.new_vec_from_iter(expr.elements.iter().filter_map(|element| match element {
ArrayExpressionElement::SpreadElement(spread) => {
self.error(arrays_with_spread_elements(spread.span));
None
}
ArrayExpressionElement::Elision(elision) => {
Some(TSTupleElement::from(self.ast.ts_undefined_keyword(elision.span)))
}
_ => Some(TSTupleElement::from(
self.transform_expression_to_ts_type(element.to_expression()),
)),
}));

let ts_type = self.ast.ts_tuple_type(SPAN, element_types);
Expand Down
Loading