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

fix(es/resolver): Resolve interfaces correctly #6387

Merged
merged 5 commits into from Nov 9, 2022
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 13 additions & 0 deletions crates/swc_ecma_codegen/src/lib.rs
Expand Up @@ -1231,6 +1231,19 @@ where
emit!(node.super_type_params);
}

if !node.implements.is_empty() {
space!();
keyword!("implements");

space!();

self.emit_list(
node.span,
Some(&node.implements),
ListFormat::ClassHeritageClauses,
)?;
}

formatting_space!();

punct!("{");
Expand Down
11 changes: 9 additions & 2 deletions crates/swc_ecma_transforms_base/src/resolver/mod.rs
Expand Up @@ -519,13 +519,20 @@ impl<'a> VisitMut for Resolver<'a> {

typed_ref!(visit_mut_ts_this_type_or_ident, TsThisTypeOrIdent);

typed_ref!(visit_mut_ts_expr_with_type_args, TsExprWithTypeArgs);

visit_mut_obj_and_computed!();

// TODO: How should I handle this?
typed!(visit_mut_ts_namespace_export_decl, TsNamespaceExportDecl);

fn visit_mut_ts_expr_with_type_args(&mut self, n: &mut TsExprWithTypeArgs) {
if self.config.handle_types {
let old = self.in_type;
self.in_type = true;
n.visit_mut_children_with(self);
self.in_type = old;
}
}

fn visit_mut_export_specifier(&mut self, s: &mut ExportSpecifier) {
let old = self.ident_type;
self.ident_type = IdentType::Ref;
Expand Down
@@ -0,0 +1,24 @@
// @target: esnext
// @declaration: true

interface Mixin1 {
mixinMethod(): void;
}

abstract class AbstractBase {
abstract abstractBaseMethod(): void;
}

function Mixin2<TBase extends abstract new (...args: any[]) => any>(baseClass: TBase) {
// must be `abstract` because we cannot know *all* of the possible abstract members that need to be
// implemented for this to be concrete.
abstract class MixinClass extends baseClass implements Mixin1 {
mixinMethod(): void {}
static staticMixinMethod(): void {}
}
return MixinClass;
}

class DerivedFromAbstract2 extends Mixin2(AbstractBase) {
abstractBaseMethod() {}
}
@@ -0,0 +1,16 @@
interface Mixin1__1 {
mixinMethod__0(): void;
}
class AbstractBase__1 {
abstractBaseMethod(): void;
}
function Mixin2__1<TBase__2 extends abstract new (...args: any[]) => any>(baseClass__2: TBase__2) {
class MixinClass__2 extends baseClass__2 implements Mixin1__1 {
mixinMethod(): void {}
static staticMixinMethod(): void {}
}
return MixinClass__2;
}
class DerivedFromAbstract2__1 extends Mixin2__1(AbstractBase__1) {
abstractBaseMethod() {}
}
@@ -1,5 +1,5 @@
import { Nullable__1 } from "nullable";
import { Component__1 } from "react";
class Foo__1 {
class Foo__1 implements Component__1<Nullable__1> {
}
new Foo__1();
@@ -1,4 +1,4 @@
class PartWriter__1 {
class PartWriter__1 implements Deno.Writer {
constructor(private writer__3: Deno.Writer, readonly boundary__3: string, public headers__3: Headers, isFirstBoundary__3: boolean){
let buf__3 = "";
if (isFirstBoundary__3) {
Expand Down