@@ -1969,6 +1969,44 @@ function createModel(response: Response, model: any): any {
19691969  return  model ; 
19701970} 
19711971
1972+ const mightHaveStaticConstructor = /\bclass\b.*\bstatic\b/;
1973+ 
1974+ function getInferredFunctionApproximate(code: string): () =>  void  { 
1975+   let  slicedCode ; 
1976+   if  ( code . startsWith ( 'Object.defineProperty(' ) ) { 
1977+     slicedCode  =  code . slice ( 'Object.defineProperty(' . length ) ; 
1978+   }  else if (code.startsWith('(')) { 
1979+     slicedCode  =  code . slice ( 1 ) ; 
1980+   }  else { 
1981+     slicedCode  =  code ; 
1982+   } 
1983+   if (slicedCode.startsWith('async function')) { 
1984+     const  idx  =  slicedCode . indexOf ( '(' ,  14 ) ; 
1985+     if  ( idx  !==  - 1 ) { 
1986+       const  name  =  slicedCode . slice ( 14 ,  idx ) . trim ( ) ; 
1987+       // eslint-disable-next-line no-eval 
1988+       return  ( 0 ,  eval ) ( '({'  +  JSON . stringify ( name )  +  ':async function(){}})' ) [ 
1989+         name 
1990+       ] ; 
1991+     } 
1992+   }  else  if  ( slicedCode . startsWith ( 'function ') )  { 
1993+     const  idx  =  slicedCode . indexOf ( '(' ,  8 ) ; 
1994+     if  ( idx  !==  - 1 ) { 
1995+       const  name  =  slicedCode . slice ( 8 ,  idx ) . trim ( ) ; 
1996+       // eslint-disable-next-line no-eval 
1997+       return  ( 0 ,  eval ) ( '({'  +  JSON . stringify ( name )  +  ':function(){}})' ) [ name ] ; 
1998+     } 
1999+   }  else  if  ( slicedCode . startsWith ( 'class ') )  { 
2000+     const  idx  =  slicedCode . indexOf ( '{' ,  5 ) ; 
2001+     if  ( idx  !==  - 1 ) { 
2002+       const  name  =  slicedCode . slice ( 5 ,  idx ) . trim ( ) ; 
2003+       // eslint-disable-next-line no-eval 
2004+       return  ( 0 ,  eval ) ( '({'  +  JSON . stringify ( name )  +  ':class{}})' ) [ name ] ; 
2005+     } 
2006+   } 
2007+   return  function  ( )  { } ;
2008+ } 
2009+ 
19722010function  parseModelString ( 
19732011  response : Response , 
19742012  parentObject : Object , 
@@ -2158,41 +2196,37 @@ function parseModelString(
21582196          // This should not compile to eval() because then it has local scope access. 
21592197          const  code  =  value . slice ( 2 ) ; 
21602198          try  { 
2161-             // eslint-disable-next-line no-eval 
2162-             return  ( 0 ,  eval ) ( code ) ; 
2199+             // If this might be a class constructor with a static initializer or 
2200+             // static constructor then don't eval it. It might cause unexpected 
2201+             // side-effects. Instead, fallback to parsing out the function type 
2202+             // and name. 
2203+             if  ( ! mightHaveStaticConstructor . test ( code ) )  { 
2204+               // eslint-disable-next-line no-eval 
2205+               return  ( 0 ,  eval ) ( code ) ; 
2206+             } 
21632207          }  catch  ( x )  { 
2164-             // We currently use this to express functions so we fail parsing it, 
2165-             // let's just return a blank function as a place holder. 
2166-             if  ( code . startsWith ( '(async function' ) )  { 
2167-               const  idx  =  code . indexOf ( '(' ,  15 ) ; 
2168-               if  ( idx  !==  - 1 )  { 
2169-                 const  name  =  code . slice ( 15 ,  idx ) . trim ( ) ; 
2170-                 // eslint-disable-next-line no-eval 
2171-                 return  ( 0 ,  eval ) ( 
2172-                   '({'  +  JSON . stringify ( name )  +  ':async function(){}})' , 
2173-                 ) [ name ] ; 
2174-               } 
2175-             }  else  if  ( code . startsWith ( '(function' ) )  { 
2176-               const  idx  =  code . indexOf ( '(' ,  9 ) ; 
2177-               if  ( idx  !==  - 1 )  { 
2178-                 const  name  =  code . slice ( 9 ,  idx ) . trim ( ) ; 
2179-                 // eslint-disable-next-line no-eval 
2180-                 return  ( 0 ,  eval ) ( 
2181-                   '({'  +  JSON . stringify ( name )  +  ':function(){}})' , 
2182-                 ) [ name ] ; 
2183-               } 
2184-             }  else  if  ( code . startsWith ( '(class' ) )  { 
2185-               const  idx  =  code . indexOf ( '{' ,  6 ) ; 
2208+             // Fallthrough to fallback case. 
2209+           } 
2210+           // We currently use this to express functions so we fail parsing it, 
2211+           // let's just return a blank function as a place holder. 
2212+           let  fn ; 
2213+           try  { 
2214+             fn  =  getInferredFunctionApproximate ( code ) ; 
2215+             if  ( code . startsWith ( 'Object.defineProperty(' ) )  { 
2216+               const  DESCRIPTOR  =  ', "name ", { value :"'; 
2217+               const  idx  =  code . lastIndexOf ( DESCRIPTOR ) ; 
21862218              if  ( idx  !==  - 1 )  { 
2187-                 const  name  =  code . slice ( 6 ,   idx ) . trim ( ) ; 
2188-                 // eslint-disable-next-line no-eval 
2189-                 return   ( 0 ,   eval ) ( '({'   +   JSON . stringify ( name )   +   ':class{}})' ) [ 
2190-                    name 
2191-                 ] ; 
2219+                 const  name  =  JSON . parse ( 
2220+                    code . slice ( idx   +   DESCRIPTOR . length   -   1 ,   code . length   -   2 ) , 
2221+                 ) ; 
2222+                 // $FlowFixMe[cannot-write] 
2223+                 Object . defineProperty ( fn ,   'name' ,   { value :  name } ) ; 
21922224              } 
21932225            } 
2194-             return  function  ( )  { } ; 
2226+           }  catch  ( _ )  { 
2227+             fn  =  function  ( )  { } ; 
21952228          } 
2229+           return  fn ; 
21962230        } 
21972231        // Fallthrough 
21982232      } 
0 commit comments