@@ -21,28 +21,19 @@ const joinRanges = (startRange, endRange) => {
2121 return [ startRange [ 0 ] , endRange [ 1 ] ] ;
2222} ;
2323
24- const ECMA_VERSION = 2017 ;
25-
26- const POSSIBLE_AST_OPTIONS = [ {
24+ const defaultParserOptions = {
2725 ranges : true ,
2826 locations : true ,
29- ecmaVersion : ECMA_VERSION ,
27+ ecmaVersion : 2017 ,
3028 sourceType : "module" ,
29+ onComment : null ,
3130 plugins : {
3231 dynamicImport : true
3332 }
34- } , {
35- ranges : true ,
36- locations : true ,
37- ecmaVersion : ECMA_VERSION ,
38- sourceType : "script" ,
39- plugins : {
40- dynamicImport : true
41- }
42- } ] ;
33+ } ;
4334
4435class Parser extends Tapable {
45- constructor ( options ) {
36+ constructor ( options , sourceType = "auto" ) {
4637 super ( ) ;
4738 this . hooks = {
4839 evaluateTypeof : new HookMap ( ( ) => new SyncBailHook ( [ "expression" ] ) ) ,
@@ -116,6 +107,7 @@ class Parser extends Tapable {
116107 }
117108 } ) ;
118109 this . options = options ;
110+ this . sourceType = sourceType ;
119111 this . scope = undefined ;
120112 this . state = undefined ;
121113 this . comments = undefined ;
@@ -1761,37 +1753,18 @@ class Parser extends Tapable {
17611753
17621754 parse ( source , initialState ) {
17631755 let ast ;
1764- let comments = [ ] ;
1756+ let comments ;
17651757 if ( typeof source === "object" && source !== null ) {
17661758 ast = source ;
17671759 comments = source . comments ;
1768- }
1769- for ( let i = 0 , len = POSSIBLE_AST_OPTIONS . length ; i < len ; i ++ ) {
1770- if ( ! ast ) {
1771- try {
1772- comments . length = 0 ;
1773- POSSIBLE_AST_OPTIONS [ i ] . onComment = comments ;
1774- ast = acorn . parse ( source , POSSIBLE_AST_OPTIONS [ i ] ) ;
1775- } catch ( e ) {
1776- // ignore the error
1777- }
1778- }
1779- }
1780- if ( ! ast ) {
1781- // for the error
1782- ast = acorn . parse ( source , {
1783- ranges : true ,
1784- locations : true ,
1785- ecmaVersion : ECMA_VERSION ,
1786- sourceType : "module" ,
1787- plugins : {
1788- dynamicImport : true
1789- } ,
1760+ } else {
1761+ comments = [ ] ;
1762+ ast = Parser . parse ( source , {
1763+ sourceType : this . sourceType ,
17901764 onComment : comments
17911765 } ) ;
17921766 }
1793- if ( ! ast || typeof ast !== "object" )
1794- throw new Error ( "Source couldn't be parsed" ) ;
1767+
17951768 const oldScope = this . scope ;
17961769 const oldState = this . state ;
17971770 const oldComments = this . comments ;
@@ -1817,17 +1790,10 @@ class Parser extends Tapable {
18171790 }
18181791
18191792 evaluate ( source ) {
1820- const ast = acorn . parse ( "(" + source + ")" , {
1821- ranges : true ,
1822- locations : true ,
1823- ecmaVersion : ECMA_VERSION ,
1824- sourceType : "module" ,
1825- plugins : {
1826- dynamicImport : true
1827- }
1793+ const ast = Parser . parse ( "(" + source + ")" , {
1794+ sourceType : this . sourceType ,
1795+ locations : false ,
18281796 } ) ;
1829- if ( ! ast || typeof ast !== "object" || ast . type !== "Program" )
1830- throw new Error ( "evaluate: Source couldn't be parsed" ) ;
18311797 if ( ast . body . length !== 1 || ast . body [ 0 ] . type !== "ExpressionStatement" )
18321798 throw new Error ( "evaluate: Source is not a expression" ) ;
18331799 return this . evaluateExpression ( ast . body [ 0 ] . expression ) ;
@@ -1885,8 +1851,41 @@ class Parser extends Tapable {
18851851 } ;
18861852 }
18871853
1888- }
1854+ static parse ( code , options ) {
1855+ const type = options . sourceType ;
1856+ const parserOptions = Object . assign ( Object . create ( null ) , defaultParserOptions , options ) ;
18891857
1890- Parser . ECMA_VERSION = ECMA_VERSION ;
1858+ if ( type === "auto" ) {
1859+ parserOptions . sourceType = "module" ;
1860+ }
1861+
1862+ let ast ;
1863+ let error ;
1864+ let threw = false ;
1865+ try {
1866+ ast = acorn . parse ( code , parserOptions ) ;
1867+ } catch ( e ) {
1868+ error = e ;
1869+ threw = true ;
1870+ }
1871+
1872+ if ( threw && type === "auto" ) {
1873+ parserOptions . sourceType = "script" ;
1874+ if ( Array . isArray ( parserOptions . onComment ) ) {
1875+ parserOptions . onComment . length = 0 ;
1876+ }
1877+ try {
1878+ ast = acorn . parse ( code , parserOptions ) ;
1879+ threw = false ;
1880+ } catch ( e ) { }
1881+ }
1882+
1883+ if ( threw ) {
1884+ throw error ;
1885+ }
1886+
1887+ return ast ;
1888+ }
1889+ }
18911890
18921891module . exports = Parser ;
0 commit comments