Skip to content
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
32 changes: 24 additions & 8 deletions crates/oxc_transformer/src/decorator/legacy/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,11 @@ impl<'a> LegacyDecoratorMetadata<'a, '_> {
name: &TSTypeName<'a>,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let serialized_type = self.serialize_entity_name_as_expression_fallback(name, ctx);
let Some(serialized_type) = self.serialize_entity_name_as_expression_fallback(name, ctx)
else {
// Reach here means the referent is a type symbol, so use `Object` as fallback.
return Self::global_object(ctx);
};
let binding = self.ctx.var_declarations.create_uid_var_based_on_node(&serialized_type, ctx);
let target = binding.create_write_target(ctx);
let assignment = ctx.ast.expression_assignment(
Expand All @@ -357,29 +361,35 @@ impl<'a> LegacyDecoratorMetadata<'a, '_> {
&mut self,
name: &TSTypeName<'a>,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
) -> Option<Expression<'a>> {
match name {
// `A` -> `typeof A !== "undefined" && A`
TSTypeName::IdentifierReference(ident) => {
let binding = MaybeBoundIdentifier::from_identifier_reference(ident, ctx);
if Self::is_type_symbol(binding.symbol_id, ctx) {
return None;
}
let flags = Self::get_reference_flags(&binding, ctx);
let ident1 = binding.create_expression(flags, ctx);
let ident2 = binding.create_expression(flags, ctx);
Self::create_checked_value(ident1, ident2, ctx)
Some(Self::create_checked_value(ident1, ident2, ctx))
}
TSTypeName::QualifiedName(qualified) => {
if let TSTypeName::IdentifierReference(ident) = &qualified.left {
// `A.B` -> `typeof A !== "undefined" && A.B`
let binding = MaybeBoundIdentifier::from_identifier_reference(ident, ctx);
if Self::is_type_symbol(binding.symbol_id, ctx) {
return None;
}
let flags = Self::get_reference_flags(&binding, ctx);
let ident1 = binding.create_expression(flags, ctx);
let ident2 = binding.create_expression(flags, ctx);
let member = create_property_access(SPAN, ident1, &qualified.right.name, ctx);
Self::create_checked_value(ident2, member, ctx)
Some(Self::create_checked_value(ident2, member, ctx))
} else {
// `A.B.C` -> `typeof A !== "undefined" && (_a = A.B) !== void 0 && _a.C`
let mut left =
self.serialize_entity_name_as_expression_fallback(&qualified.left, ctx);
self.serialize_entity_name_as_expression_fallback(&qualified.left, ctx)?;
let binding =
self.ctx.var_declarations.create_uid_var_based_on_node(&left, ctx);
let Expression::LogicalExpression(logical) = &mut left else { unreachable!() };
Expand All @@ -401,7 +411,7 @@ impl<'a> LegacyDecoratorMetadata<'a, '_> {

let object = binding.create_read_expression(ctx);
let member = create_property_access(SPAN, object, &qualified.right.name, ctx);
ctx.ast.expression_logical(SPAN, left, LogicalOperator::And, member)
Some(ctx.ast.expression_logical(SPAN, left, LogicalOperator::And, member))
}
}
}
Expand Down Expand Up @@ -500,15 +510,21 @@ impl<'a> LegacyDecoratorMetadata<'a, '_> {
a.content_eq(b)
}

#[inline]
fn is_type_symbol(symbol_id: Option<oxc_semantic::SymbolId>, ctx: &TraverseCtx<'a>) -> bool {
symbol_id.is_some_and(|symbol_id| ctx.scoping().symbol_flags(symbol_id).is_type())
}

fn get_reference_flags(
binding: &MaybeBoundIdentifier<'a>,
ctx: &TraverseCtx<'a>,
) -> ReferenceFlags {
if let Some(symbol_id) = binding.symbol_id {
let flags = ctx.scoping().symbol_flags(symbol_id);
// Type symbols have filtered out in [`serialize_entity_name_as_expression_fallback`].
debug_assert!(ctx.scoping().symbol_flags(symbol_id).is_value());
// `design::*type` would be called by `reflect-metadata` APIs, use `Read` flag
// to avoid TypeScript remove it because only used as types.
if flags.is_value() { ReferenceFlags::Read } else { ReferenceFlags::Type }
ReferenceFlags::Read
} else {
// Unresolved reference
ReferenceFlags::Type | ReferenceFlags::Read
Expand Down
40 changes: 11 additions & 29 deletions tasks/coverage/snapshots/semantic_typescript.snap
Original file line number Diff line number Diff line change
Expand Up @@ -36082,19 +36082,13 @@ after transform: ScopeId(0): [ScopeId(1), ScopeId(2)]
rebuilt : ScopeId(0): [ScopeId(1)]
Symbol span mismatch for "BulkEditPreviewProvider":
after transform: SymbolId(1): Span { start: 106, end: 129 }
rebuilt : SymbolId(6): Span { start: 0, end: 0 }
rebuilt : SymbolId(5): Span { start: 0, end: 0 }
Symbol reference IDs mismatch for "BulkEditPreviewProvider":
after transform: SymbolId(1): [ReferenceId(0), ReferenceId(12), ReferenceId(14), ReferenceId(16), ReferenceId(18)]
rebuilt : SymbolId(6): [ReferenceId(7), ReferenceId(9), ReferenceId(11), ReferenceId(22)]
after transform: SymbolId(1): [ReferenceId(0), ReferenceId(8), ReferenceId(10), ReferenceId(12), ReferenceId(14)]
rebuilt : SymbolId(5): [ReferenceId(7), ReferenceId(9), ReferenceId(11), ReferenceId(18)]
Symbol span mismatch for "BulkEditPreviewProvider":
after transform: SymbolId(5): Span { start: 0, end: 0 }
rebuilt : SymbolId(7): Span { start: 106, end: 129 }
Reference symbol mismatch for "IFoo":
after transform: SymbolId(0) "IFoo"
rebuilt : <None>
Reference symbol mismatch for "IFoo":
after transform: SymbolId(0) "IFoo"
rebuilt : <None>
after transform: SymbolId(4): Span { start: 0, end: 0 }
rebuilt : SymbolId(6): Span { start: 106, end: 129 }
Reference symbol mismatch for "IFoo":
after transform: SymbolId(0) "IFoo"
rebuilt : <None>
Expand Down Expand Up @@ -36695,35 +36689,23 @@ rebuilt : ["Function", "Object", "decorator"]

semantic Error: tasks/coverage/typescript/tests/cases/conformance/decorators/decoratorMetadataWithTypeOnlyImport.ts
Bindings mismatch:
after transform: ScopeId(0): ["MyComponent", "Service", "_decorate", "_decorateMetadata", "_ref", "decorator"]
rebuilt : ScopeId(0): ["MyComponent", "_decorate", "_decorateMetadata", "_ref"]
after transform: ScopeId(0): ["MyComponent", "Service", "_decorate", "_decorateMetadata", "decorator"]
rebuilt : ScopeId(0): ["MyComponent", "_decorate", "_decorateMetadata"]
Symbol span mismatch for "MyComponent":
after transform: SymbolId(2): Span { start: 89, end: 100 }
rebuilt : SymbolId(3): Span { start: 0, end: 0 }
rebuilt : SymbolId(2): Span { start: 0, end: 0 }
Symbol span mismatch for "MyComponent":
after transform: SymbolId(7): Span { start: 0, end: 0 }
rebuilt : SymbolId(4): Span { start: 89, end: 100 }
after transform: SymbolId(6): Span { start: 0, end: 0 }
rebuilt : SymbolId(3): Span { start: 89, end: 100 }
Reference symbol mismatch for "decorator":
after transform: SymbolId(1) "decorator"
rebuilt : <None>
Reference symbol mismatch for "decorator":
after transform: SymbolId(1) "decorator"
rebuilt : <None>
Reference symbol mismatch for "Service":
after transform: SymbolId(0) "Service"
rebuilt : <None>
Reference flags mismatch for "Service":
after transform: ReferenceId(3): ReferenceFlags(Type)
rebuilt : ReferenceId(14): ReferenceFlags(Read)
Reference symbol mismatch for "Service":
after transform: SymbolId(0) "Service"
rebuilt : <None>
Reference flags mismatch for "Service":
after transform: ReferenceId(4): ReferenceFlags(Type)
rebuilt : ReferenceId(15): ReferenceFlags(Read)
Unresolved references mismatch:
after transform: ["Function", "Object"]
rebuilt : ["Function", "Object", "Service", "decorator"]
rebuilt : ["Function", "Object", "decorator"]

semantic Error: tasks/coverage/typescript/tests/cases/conformance/decorators/decoratorMetadataWithTypeOnlyImport2.ts
Symbol flags mismatch for "Services":
Expand Down
14 changes: 7 additions & 7 deletions tasks/transform_conformance/snapshots/oxc.snap.md
Original file line number Diff line number Diff line change
Expand Up @@ -438,22 +438,22 @@ rebuilt : SymbolId(3): Span { start: 87, end: 94 }

* oxc/metadata/imports/input.ts
Bindings mismatch:
after transform: ScopeId(0): ["Bar", "Cls", "Foo", "_ref", "dec"]
after transform: ScopeId(0): ["Bar", "Cls", "Foo", "Zoo", "_ref", "dec"]
rebuilt : ScopeId(0): ["Cls", "Foo", "_ref"]
Scope children mismatch:
after transform: ScopeId(0): [ScopeId(1), ScopeId(2)]
rebuilt : ScopeId(0): [ScopeId(1)]
Symbol reference IDs mismatch for "Foo":
after transform: SymbolId(0): [ReferenceId(2), ReferenceId(3), ReferenceId(8), ReferenceId(9)]
rebuilt : SymbolId(0): [ReferenceId(7), ReferenceId(8)]
after transform: SymbolId(0): [ReferenceId(2), ReferenceId(3), ReferenceId(12), ReferenceId(13)]
rebuilt : SymbolId(0): [ReferenceId(9), ReferenceId(10)]
Symbol span mismatch for "Cls":
after transform: SymbolId(6): Span { start: 135, end: 138 }
after transform: SymbolId(7): Span { start: 145, end: 148 }
rebuilt : SymbolId(2): Span { start: 0, end: 0 }
Symbol span mismatch for "Cls":
after transform: SymbolId(10): Span { start: 0, end: 0 }
rebuilt : SymbolId(3): Span { start: 135, end: 138 }
after transform: SymbolId(13): Span { start: 0, end: 0 }
rebuilt : SymbolId(3): Span { start: 145, end: 148 }
Reference symbol mismatch for "dec":
after transform: SymbolId(2) "dec"
after transform: SymbolId(3) "dec"
rebuilt : <None>
Unresolved references mismatch:
after transform: ["Object", "PropertyDescriptor", "babelHelpers", "console"]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Foo, Bar } from "mod";
import { Foo, Bar, type Zoo } from "mod";

declare function dec(
target: any,
Expand All @@ -7,7 +7,7 @@ declare function dec(
): void;

class Cls {
constructor(@dec param: Foo, param2: Foo | Bar) {
console.log(param, param2);
constructor(@dec param: Foo, param2: Foo | Bar, param3: Zoo, param4: Zoo.o.o) {
console.log(param, param2, param3, param4);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { Foo } from "mod";
var _ref;

let Cls = class Cls {
constructor(param, param2) {
console.log(param, param2);
constructor(param, param2, param3, param4) {
console.log(param, param2, param3, param4);
}
};

Expand All @@ -14,6 +14,8 @@ Cls = babelHelpers.decorate(
? _ref
: Object,
Object,
Object,
Object,
]),
babelHelpers.decorateParam(0, dec),
],
Expand Down
Loading