Files
parcoursup/node_modules/@riotjs/compiler/src/generators/javascript/index.js
lalBi94 7bc56c09b5 $
2023-03-05 13:23:23 +01:00

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
}