1010//------------------------------------------------------------------------------
1111
1212const path = require ( "path" )
13- const SAXParser = require ( "parse5" ) . SAXParser
13+ const parse = require ( "./lib/parse" )
1414
1515//------------------------------------------------------------------------------
1616// Helpers
1717//------------------------------------------------------------------------------
1818
19- const LINE_TERMINATORS = / \r \n | \r | \n | \u2028 | \u2029 / g
20-
2119/**
2220 * Gets the specified parser.
2321 * If it's unspecified, this returns espree.
@@ -30,135 +28,44 @@ function getParser(options) {
3028 return require ( options . parser || "espree" )
3129}
3230
33- /**
34- * Calculates the end location.
35- *
36- * @param {string } raw - The text of the target token.
37- * @param {number } startLine - The start line of the target token.
38- * @param {number } startColumn - The start column of the target token.
39- * @returns {{line: number, column: number} } The end location.
40- * @private
41- */
42- function calcLocEnd ( raw , startLine , startColumn ) {
43- const lines = raw . split ( LINE_TERMINATORS )
44- const line = startLine + lines . length - 1
45- const column = ( lines . length === 1 )
46- ? startColumn + raw . length
47- : lines [ lines . length - 1 ] . length
48-
49- return { line, column}
50- }
51-
52- /**
53- * Creates the token with the given parameters.
54- *
55- * @param {string } value - The token value to create.
56- * @param {string } text - The whole text.
57- * @param {object } location - The location object of `parse5` module.
58- * @returns {object } The created token object.
59- * @private
60- */
61- function createToken ( value , text , location ) {
62- const type = "Punctuator"
63- const start = location . startOffset
64- const end = location . endOffset
65- const line = location . line
66- const column = location . col - 1
67- const range = [ start , end ]
68- const raw = text . slice ( start , end )
69- const loc = {
70- start : { line, column} ,
71- end : calcLocEnd ( raw , line , column ) ,
72- }
73-
74- return { type, value, raw, start, end, range, loc}
75- }
76-
77- /**
78- * Extracts the text of the 1st script element in the given text.
79- *
80- * @param {string } originalText - The whole text to extract.
81- * @returns {{text: string, offset: number} } The information of the 1st script.
82- * @private
83- */
84- function extractFirstScript ( originalText ) {
85- const parser = new SAXParser ( { locationInfo : true } )
86- let inTemplate = 0
87- let startToken = null
88- let endToken = null
89- let text = ""
90- let offset = 0
91-
92- parser . on ( "startTag" , ( name , attrs , selfClosing , location ) => {
93- if ( selfClosing ) {
94- return
95- }
96- if ( name === "template" ) {
97- inTemplate += 1
98- }
99- if ( inTemplate === 0 && name === "script" ) {
100- startToken = createToken ( "<script>" , originalText , location )
101- }
102- } )
103- parser . on ( "endTag" , ( name , location ) => {
104- if ( inTemplate > 0 && name === "template" ) {
105- inTemplate -= 1
106- }
107- if ( startToken != null && name === "script" ) {
108- endToken = createToken ( "</script>" , originalText , location )
109- parser . stop ( )
110- }
111- } )
112- parser . on ( "text" , ( _ , location ) => {
113- if ( startToken != null ) {
114- const start = location . startOffset
115- const countLines = location . line - 1
116- const lineTerminators = "\n" . repeat ( countLines )
117- const spaces = " " . repeat ( start - countLines )
118- const scriptText = originalText . slice ( start , location . endOffset )
119-
120- text = `${ spaces } ${ lineTerminators } ${ scriptText } `
121- offset = start
122- }
123- } )
124- parser . end ( originalText )
125-
126- return { startToken, endToken, text, offset}
127- }
128-
12931//------------------------------------------------------------------------------
13032// Exports
13133//------------------------------------------------------------------------------
13234
13335/**
134- * Parses the source code.
135- *
136- * If `options.filePath` is a `.vue` file, this extracts the first `<script>`
137- * element then parses it.
36+ * Provides the `parse` method for `.vue` files.
13837 *
139- * @memberof module:vue-eslint-parser
140- * @function parse
141- * @param {string } text - The source code to be parsed.
142- * @param {object } options - The option object for espree.
143- * @returns {ASTNode } The AST object as the result of parsing.
38+ * @module vue-eslint-parser
14439 */
145- module . exports . parse = function parse ( text , options ) {
146- const parser = getParser ( options )
147-
148- if ( path . extname ( options . filePath || "unknown.js" ) !== ".vue" ) {
149- return parser . parse ( text , options )
150- }
40+ module . exports = {
41+ /**
42+ * Parses the source code.
43+ *
44+ * If `options.filePath` is a `.vue` file, this extracts the first `<script>`
45+ * element then parses it.
46+ *
47+ * @param {string } text - The source code to be parsed.
48+ * @param {object } options - The option object for espree.
49+ * @returns {{ast: ASTNode} } The AST object as the result of parsing.
50+ */
51+ parse ( text , options ) {
52+ const parser = getParser ( options )
53+
54+ if ( path . extname ( options . filePath || "unknown.js" ) !== ".vue" ) {
55+ return parser . parse ( text , options )
56+ }
15157
152- const script = extractFirstScript ( text )
153- const ast = parser . parse ( script . text , options )
58+ const script = parse ( text )
59+ const ast = parser . parse ( script . text , options )
15460
155- ast . start = script . offset
156- if ( script . startToken ) {
157- ast . tokens . unshift ( script . startToken )
158- }
159- if ( script . endToken ) {
160- ast . tokens . push ( script . endToken )
161- }
61+ ast . start = script . offset
62+ if ( script . startToken ) {
63+ ast . tokens . unshift ( script . startToken )
64+ }
65+ if ( script . endToken ) {
66+ ast . tokens . push ( script . endToken )
67+ }
16268
163- return ast
69+ return ast
70+ } ,
16471}
0 commit comments