@@ -80,8 +80,14 @@ private function discover(callable $cb): array
8080 );
8181
8282 try {
83+ $ path = $ appPath .DIRECTORY_SEPARATOR .$ relativePath ;
84+
85+ if (! $ this ->fileHasClassLike ($ path )) {
86+ continue ;
87+ }
88+
8389 if (class_exists ($ className )) {
84- self ::$ classes [$ className ] = $ appPath . DIRECTORY_SEPARATOR . $ relativePath ;
90+ self ::$ classes [$ className ] = $ path ;
8591 }
8692 } catch (\Throwable ) {
8793 // Ignore exceptions and errors from class loading/reflection
@@ -98,6 +104,38 @@ private function discover(callable $cb): array
98104 return $ classes ;
99105 }
100106
107+ public function fileHasClassLike (string $ path ): bool
108+ {
109+ static $ cache = [];
110+
111+ if (isset ($ cache [$ path ])) {
112+ return $ cache [$ path ];
113+ }
114+
115+ $ code = file_get_contents ($ path );
116+ if ($ code === false ) {
117+ return $ cache [$ path ] = false ;
118+ }
119+
120+ if (stripos ($ code , 'class ' ) === false
121+ && stripos ($ code , 'interface ' ) === false
122+ && stripos ($ code , 'trait ' ) === false
123+ && stripos ($ code , 'enum ' ) === false ) {
124+ return $ cache [$ path ] = false ;
125+ }
126+
127+ $ tokens = token_get_all ($ code );
128+ foreach ($ tokens as $ token ) {
129+ if (is_array ($ token )) {
130+ if (in_array ($ token [0 ], [T_CLASS , T_INTERFACE , T_TRAIT , T_ENUM ], true )) {
131+ return $ cache [$ path ] = true ;
132+ }
133+ }
134+ }
135+
136+ return $ cache [$ path ] = false ;
137+ }
138+
101139 public function shouldEnforceStrictTypes (): bool
102140 {
103141 if (empty ($ this ->modelPaths )) {
0 commit comments