@@ -789,4 +789,93 @@ mod test {
789789 assert ! ( !is_react_hook_name( "user" ) ) ;
790790 assert ! ( !is_react_hook_name( "use_state" ) ) ;
791791 }
792+
793+ #[ test]
794+ fn test_is_es5_component ( ) {
795+ use oxc_parser:: Parser ;
796+ use oxc_semantic:: SemanticBuilder ;
797+ use oxc_span:: SourceType ;
798+
799+ // Returns true if any of the nodes in the code snippets are an es5 component.
800+ let cases: Vec < ( & str , bool ) > = vec ! [
801+ ( "createReactClass({})" , true ) ,
802+ ( "React.createReactClass({})" , true ) ,
803+ ( "createReactClass({ render() {} })" , true ) ,
804+ ( "/* createReactClass({ render() {} }) */" , false ) ,
805+ ( "// createReactClass({ render() {} })" , false ) ,
806+ ( "somethingElse({})" , false ) ,
807+ ( "React.somethingElse({})" , false ) ,
808+ ( "let x = 1;" , false ) ,
809+ ] ;
810+
811+ for ( source, expected) in cases {
812+ let allocator = Allocator :: default ( ) ;
813+ let source_type = SourceType :: jsx ( ) ;
814+ let parser_ret = Parser :: new ( & allocator, source, source_type) . parse ( ) ;
815+ assert ! ( parser_ret. errors. is_empty( ) , "Parse error in: {source}" ) ;
816+ let semantic =
817+ SemanticBuilder :: new ( ) . build ( allocator. alloc ( parser_ret. program ) ) . semantic ;
818+
819+ let found = semantic. nodes ( ) . iter ( ) . any ( |node| is_es5_component ( node) ) ;
820+ assert_eq ! ( found, expected, "Failed for: {source}" ) ;
821+ }
822+ }
823+
824+ #[ test]
825+ fn test_is_es6_component ( ) {
826+ use oxc_parser:: Parser ;
827+ use oxc_semantic:: SemanticBuilder ;
828+ use oxc_span:: SourceType ;
829+
830+ // Returns true if any of the nodes in the code snippets are an es6 component.
831+ let cases: Vec < ( & str , bool ) > = vec ! [
832+ ( "class Foo extends React.Component {}" , true ) ,
833+ ( "class Foo extends React.PureComponent {}" , true ) ,
834+ ( "class Foo extends Component {}" , true ) ,
835+ ( "class Foo extends PureComponent {}" , true ) ,
836+ ( "class Foo extends Bar {}" , false ) ,
837+ ( "/* class Foo extends PureComponent {} */" , false ) ,
838+ ( "// class Foo extends PureComponent {}" , false ) ,
839+ ( "class Foo {}" , false ) ,
840+ ( "function Foo() {}" , false ) ,
841+ ( "const Foo = () => {}" , false ) ,
842+ ( "const Component = () => {}" , false ) ,
843+ ( "let Component = () => {}" , false ) ,
844+ // Not an es6 component, this is a function component.
845+ (
846+ "
847+ export function Foo({ to, children }: { to: string; children: React.ReactNode }) {
848+ return (
849+ <Link className={linkClass} to={to}>
850+ {children}
851+ </Link>
852+ )
853+ }" ,
854+ false ,
855+ ) ,
856+ (
857+ r#"
858+ export const Bar = ({ ...props }: React.ComponentProps<'button'>) => {
859+ return (
860+ <button type="button" className={linkClass} {...props}>
861+ <Foo />
862+ </button>
863+ )
864+ }"# ,
865+ false ,
866+ ) ,
867+ ] ;
868+
869+ for ( source, expected) in cases {
870+ let allocator = Allocator :: default ( ) ;
871+ let source_type = SourceType :: tsx ( ) ;
872+ let parser_ret = Parser :: new ( & allocator, source, source_type) . parse ( ) ;
873+ assert ! ( parser_ret. errors. is_empty( ) , "Parse error in: {source}" ) ;
874+ let semantic =
875+ SemanticBuilder :: new ( ) . build ( allocator. alloc ( parser_ret. program ) ) . semantic ;
876+
877+ let found = semantic. nodes ( ) . iter ( ) . any ( |node| is_es6_component ( node) ) ;
878+ assert_eq ! ( found, expected, "Failed for: {source}" ) ;
879+ }
880+ }
792881}
0 commit comments