74 lines
3.2 KiB
JavaScript
74 lines
3.2 KiB
JavaScript
import {
|
|
addComponentInterfaceToExportedObject,
|
|
createDefaultExportFromLegacySyntax,
|
|
extendTagProperty,
|
|
filterNonExportDefaultStatements, findAllExportNamedDeclarations,
|
|
findAllImportDeclarations, findComponentInterface,
|
|
findExportDefaultStatement,
|
|
getProgramBody
|
|
} from './utils'
|
|
import addLinesOffset from '../../utils/add-lines-offset'
|
|
import generateAST from '../../utils/generate-ast'
|
|
import getPreprocessorTypeByAttribute from '../../utils/get-preprocessor-type-by-attribute'
|
|
import isEmptySourcemap from '../../utils/is-empty-sourcemap'
|
|
import {isNil} from '@riotjs/util/checks'
|
|
import {isThisExpressionStatement} from '../../utils/ast-nodes-checks'
|
|
import preprocess from '../../utils/preprocess-node'
|
|
import sourcemapToJSON from '../../utils/sourcemap-as-json'
|
|
|
|
/**
|
|
* Generate the component javascript logic
|
|
* @param { Object } sourceNode - node generated by the riot compiler
|
|
* @param { string } source - original component source code
|
|
* @param { Object } meta - compilation meta information
|
|
* @param { AST } ast - current AST output
|
|
* @returns { AST } the AST generated
|
|
*/
|
|
export default function javascript(sourceNode, source, meta, ast) {
|
|
const preprocessorName = getPreprocessorTypeByAttribute(sourceNode)
|
|
const javascriptNode = addLinesOffset(sourceNode.text.text, source, sourceNode)
|
|
const { options } = meta
|
|
const preprocessorOutput = preprocess('javascript', preprocessorName, meta, {
|
|
...sourceNode,
|
|
text: javascriptNode
|
|
})
|
|
const inputSourceMap = sourcemapToJSON(preprocessorOutput.map)
|
|
const generatedAst = generateAST(preprocessorOutput.code, {
|
|
sourceFileName: options.file,
|
|
inputSourceMap: isEmptySourcemap(inputSourceMap) ? null : inputSourceMap
|
|
})
|
|
const generatedAstBody = getProgramBody(generatedAst)
|
|
const exportDefaultNode = findExportDefaultStatement(generatedAstBody)
|
|
const isLegacyRiotSyntax = isNil(exportDefaultNode)
|
|
const outputBody = getProgramBody(ast)
|
|
const componentInterface = findComponentInterface(generatedAstBody)
|
|
|
|
// throw in case of mixed component exports
|
|
if (exportDefaultNode && generatedAstBody.some(isThisExpressionStatement))
|
|
throw new Error('You can\t use "export default {}" and root this statements in the same component')
|
|
|
|
// add to the ast the "private" javascript content of our tag script node
|
|
outputBody.unshift(
|
|
...(
|
|
// for the legacy riot syntax we need to move all the import and (named) export statements outside of the function body
|
|
isLegacyRiotSyntax ?
|
|
[...findAllImportDeclarations(generatedAstBody), ...findAllExportNamedDeclarations(generatedAstBody)] :
|
|
// modern riot syntax will hoist all the private stuff outside of the export default statement
|
|
filterNonExportDefaultStatements(generatedAstBody)
|
|
))
|
|
|
|
// create the public component export properties from the root this statements
|
|
if (isLegacyRiotSyntax) extendTagProperty(
|
|
ast,
|
|
createDefaultExportFromLegacySyntax(generatedAstBody)
|
|
)
|
|
|
|
// convert the export default adding its content to the component property exported
|
|
if (exportDefaultNode) extendTagProperty(ast, exportDefaultNode)
|
|
|
|
return componentInterface ?
|
|
// add the component interface to the component object exported
|
|
addComponentInterfaceToExportedObject(ast, componentInterface) :
|
|
ast
|
|
}
|