UNPKG

@liam-hq/cli

Version:

Command-line tool designed to generate a web application that displays ER diagrams. See https://liambx.com/docs/cli

2,026 lines (1,867 loc) 3.25 MB
#!/usr/bin/env node import { createRequire } from 'node:module'; import { Command } from 'commander'; import pkg from '@prisma/internals'; import { readFile } from 'node:fs/promises'; import { fileURLToPath, URL as URL$1 } from 'node:url'; import tty from 'node:tty'; import fs, { existsSync, mkdirSync, cpSync } from 'node:fs'; import path, { resolve, dirname, relative } from 'node:path'; import { glob } from 'glob'; import { exit } from 'node:process'; import inquirer from 'inquirer'; // Helper function to handle autoincrement types function getAutoincrementType(typeName) { switch (typeName) { case 'Int': return 'serial'; case 'SmallInt': return 'smallserial'; case 'BigInt': return 'bigserial'; default: return typeName.toLowerCase(); } } // Helper function to handle native types function handleNativeType(nativeTypeName, nativeTypeArgs, defaultValue) { // Check for autoincrement if (typeof defaultValue === 'string' && defaultValue.includes('autoincrement()')) { return getAutoincrementType(nativeTypeName); } // Handle type with arguments if (nativeTypeArgs.length > 0) { return `${nativeTypeName.toLowerCase()}(${nativeTypeArgs.join(',')})`; } // Special case for DoublePrecision if (nativeTypeName === 'DoublePrecision') { return 'double precision'; } return nativeTypeName.toLowerCase(); } // Helper function to map Prisma types to PostgreSQL types function mapPrismaTypeToPostgres(type) { switch (type) { case 'String': return 'text'; case 'Boolean': return 'boolean'; case 'Int': return 'integer'; case 'BigInt': return 'bigint'; case 'Float': return 'double precision'; case 'DateTime': return 'timestamp(3)'; case 'Json': return 'jsonb'; case 'Decimal': return 'decimal(65,30)'; case 'Bytes': return 'bytea'; default: return type; } } // ref: https://www.prisma.io/docs/orm/reference/prisma-schema-reference#model-field-scalar-types function convertToPostgresColumnType(type, nativeType, defaultValue) { // If native type is provided, use it if (nativeType) { const [nativeTypeName, nativeTypeArgs] = nativeType; return handleNativeType(nativeTypeName, nativeTypeArgs, defaultValue); } // Handle autoincrement without native type if (typeof defaultValue === 'string' && defaultValue.includes('autoincrement()')) { return getAutoincrementType(type); } // Special case for uuid default value if (typeof defaultValue === 'string' && defaultValue.includes('uuid')) { return 'uuid'; } // Map Prisma type to PostgreSQL type return mapPrismaTypeToPostgres(type); } // NOTE: Workaround for CommonJS module import issue with @prisma/internals // CommonJS module can not support all module.exports as named exports const { getDMMF } = pkg; const getFieldRenamedRelationship = (relationship, tableFieldsRenaming) => { const mappedPrimaryColumnName = tableFieldsRenaming[relationship.primaryTableName]?.[relationship.primaryColumnName]; if (mappedPrimaryColumnName) { relationship.primaryColumnName = mappedPrimaryColumnName; } const mappedForeignColumnName = tableFieldsRenaming[relationship.foreignTableName]?.[relationship.foreignColumnName]; if (mappedForeignColumnName) { relationship.foreignColumnName = mappedForeignColumnName; } return relationship; }; const getFieldRenamedIndex = (index, tableFieldsRenaming) => { const fieldsRenaming = tableFieldsRenaming[index.model]; if (!fieldsRenaming) return index; const newFields = index.fields.map((field) => ({ ...field, name: fieldsRenaming[field.name] ?? field.name, })); return { ...index, fields: newFields }; }; /** * Build a mapping of field renamings from model fields */ function buildFieldRenamingMap(models) { const tableFieldRenaming = {}; for (const model of models) { for (const field of model.fields) { if (field.dbName) { const tableName = model.dbName || model.name; const fieldConversions = tableFieldRenaming[tableName] ?? {}; fieldConversions[field.name] = field.dbName; tableFieldRenaming[tableName] = fieldConversions; } } } return tableFieldRenaming; } function processModelField(field, model, tableFieldRenaming) { if (field.relationName) return { column: null, constraint: null }; const defaultValue = extractDefaultValue$2(field); const fieldName = tableFieldRenaming[model.dbName || model.name]?.[field.name] ?? field.name; const column = { name: fieldName, type: convertToPostgresColumnType(field.type, field.nativeType, defaultValue), default: defaultValue, notNull: field.isRequired, unique: field.isId || field.isUnique, primary: field.isId, comment: field.documentation ?? null, check: null, }; let constraint = null; if (field.isId) { const constraintName = `PRIMARY_${fieldName}`; constraint = { type: 'PRIMARY KEY', name: constraintName, columnName: fieldName, }; } else if (field.isUnique) { // to avoid duplicate with PRIMARY KEY constraint, it doesn't create constraint object with `field.isId` const constraintName = `UNIQUE_${fieldName}`; constraint = { type: 'UNIQUE', name: constraintName, columnName: fieldName, }; } return { column: [fieldName, column], constraint: constraint ? [constraint.name, constraint] : null, }; } /** * Process a model and create a table */ function processModel(model, tableFieldRenaming) { const columns = {}; const constraints = {}; for (const field of model.fields) { const { column, constraint } = processModelField(field, model, tableFieldRenaming); if (column) { columns[column[0]] = column[1]; } if (constraint) { constraints[constraint[0]] = constraint[1]; } } return { name: model.dbName || model.name, columns, comment: model.documentation ?? null, indexes: {}, constraints, }; } /** * Process all models and create tables */ function processTables(models, tableFieldRenaming) { const tables = {}; for (const model of models) { tables[model.dbName || model.name] = processModel(model, tableFieldRenaming); } return tables; } /** * Get Primary Table Name */ function getPrimaryTableNameByType(fieldType, models) { return models.find((model) => model.name === fieldType)?.dbName ?? fieldType; } /** * Process a relationship field */ function processRelationshipField(field, model, models, existingRelationships, tableFieldRenaming) { if (!field.relationName) return { relationship: null, constraint: null }; const existingRelationship = existingRelationships[field.relationName]; const isTargetField = field.relationToFields?.[0] && (field.relationToFields?.length ?? 0) > 0 && field.relationFromFields?.[0] && (field.relationFromFields?.length ?? 0) > 0; // Get the primary table name const primaryTableName = isTargetField && getPrimaryTableNameByType(field.type, models); // Get the column names with fallback to empty string const primaryColumnName = field.relationToFields?.[0] ?? ''; const foreignColumnName = field.relationFromFields?.[0] ?? ''; const _relationship = isTargetField ? { name: field.relationName, primaryTableName: primaryTableName || field.type, primaryColumnName, foreignTableName: model.dbName || model.name, foreignColumnName, cardinality: existingRelationship?.cardinality ?? 'ONE_TO_MANY', updateConstraint: 'NO_ACTION', deleteConstraint: normalizeConstraintName$2(field.relationOnDelete ?? ''), } : { name: field.relationName, primaryTableName: existingRelationship?.primaryTableName ?? '', primaryColumnName: existingRelationship?.primaryColumnName ?? '', foreignTableName: existingRelationship?.foreignTableName ?? '', foreignColumnName: existingRelationship?.foreignColumnName ?? '', cardinality: field.isList ? 'ONE_TO_MANY' : 'ONE_TO_ONE', updateConstraint: 'NO_ACTION', deleteConstraint: 'NO_ACTION', }; const relationship = getFieldRenamedRelationship(_relationship, tableFieldRenaming); const constraint = { type: 'FOREIGN KEY', name: relationship.name, columnName: relationship.foreignColumnName, targetTableName: relationship.primaryTableName, targetColumnName: relationship.primaryColumnName, updateConstraint: relationship.updateConstraint, deleteConstraint: relationship.deleteConstraint, }; return { relationship, constraint }; } /** * Process a single model's relationships */ function processModelRelationships(model, models, tables, tableFieldRenaming, processedManyToManyRelations, manyToManyRelations, existingRelationships) { const relationships = { ...existingRelationships, }; for (const field of model.fields) { if (!field.relationName) continue; // Skip many-to-many relations as they're handled separately if (detectAndStoreManyToManyRelation(field, model, models, processedManyToManyRelations, manyToManyRelations)) { continue; } // Process regular relationship const { relationship, constraint } = processRelationshipField(field, model, models, relationships, tableFieldRenaming); // Add relationship to collection if (relationship) { relationships[relationship.name] = relationship; } // Add constraint to table if (constraint && relationship) { const table = tables[relationship.foreignTableName]; if (table) { table.constraints[constraint.name] = constraint; } } } return relationships; } /** * Process relationships for all models */ function processRelationships$1(models, tables, tableFieldRenaming, processedManyToManyRelations, manyToManyRelations) { let relationships = {}; // Process each model's relationships for (const model of models) { relationships = processModelRelationships(model, models, tables, tableFieldRenaming, processedManyToManyRelations, manyToManyRelations, relationships); } return relationships; } /** * Process indexes for all models */ function processIndexes$1(indexes, models, tables, tableFieldRenaming) { const updatedIndexes = indexes.map((index) => { const model = models.find((m) => m.name === index.model); return model ? { model: model.dbName ?? model.name, type: index.type, isDefinedOnField: index.isDefinedOnField, fields: index.fields, } : index; }); for (const index of updatedIndexes) { const table = tables[index.model]; if (!table) continue; const indexInfo = extractIndex(getFieldRenamedIndex(index, tableFieldRenaming)); if (!indexInfo) continue; table.indexes[indexInfo.name] = indexInfo; } } /** * Process many-to-many relationships */ function processManyToManyRelationships(manyToManyRelations, tables, models) { const relationships = {}; for (const relation of manyToManyRelations) { const table_A = tables[relation.model1]; const table_B = tables[relation.model2]; // Skip if both tables are undefined if (table_A === undefined && table_B === undefined) continue; // Get primary key info for model1 if table_A exists const model1PrimaryKeyInfo = table_A ? getPrimaryKeyInfo(table_A, models) : null; // Get primary key info for model2 if table_B exists const model2PrimaryKeyInfo = table_B ? getPrimaryKeyInfo(table_B, models) : null; if (model1PrimaryKeyInfo && model2PrimaryKeyInfo) { const model1PrimaryKeyColumnType = convertToPostgresColumnType(model1PrimaryKeyInfo.type, null, null); const model2PrimaryKeyColumnType = convertToPostgresColumnType(model2PrimaryKeyInfo.type, null, null); const joinTableName = createManyToManyJoinTableName(relation.model1, relation.model2); // Create join table tables[joinTableName] = createManyToManyJoinTable(joinTableName, model1PrimaryKeyColumnType, model2PrimaryKeyColumnType); // Add relationships for the join table const joinTableRelationships = createManyToManyRelationships(joinTableName, relation.model1, model1PrimaryKeyInfo.name, relation.model2, model2PrimaryKeyInfo.name); // Add the relationships to the global relationships object Object.assign(relationships, joinTableRelationships); } } return relationships; } /** * Main function to parse a Prisma schema */ async function parsePrismaSchema(schemaString) { const dmmf = await getDMMF({ datamodel: schemaString }); const tableGroups = {}; const errors = []; // Track many-to-many relationships for later processing const processedManyToManyRelations = new Set(); const manyToManyRelations = []; // Build field renaming map const tableFieldRenaming = buildFieldRenamingMap(dmmf.datamodel.models); // Process models and create tables const tables = processTables(dmmf.datamodel.models, tableFieldRenaming); // Process relationships const relationships = processRelationships$1(dmmf.datamodel.models, tables, tableFieldRenaming, processedManyToManyRelations, manyToManyRelations); // Process indexes processIndexes$1(dmmf.datamodel.indexes, dmmf.datamodel.models, tables, tableFieldRenaming); // Process many-to-many relationships const manyToManyRelationships = processManyToManyRelationships(manyToManyRelations, tables, dmmf.datamodel.models); // Merge relationships Object.assign(relationships, manyToManyRelationships); return { value: { tables, relationships, tableGroups, }, errors: errors, }; } function extractIndex(index) { switch (index.type) { case 'id': return { name: `${index.model}_pkey`, unique: true, columns: index.fields.map((field) => field.name), type: '', }; case 'unique': return { name: `${index.model}_${index.fields.map((field) => field.name).join('_')}_key`, unique: true, columns: index.fields.map((field) => field.name), type: '', }; case 'normal': return { name: `${index.model}_${index.fields.map((field) => field.name).join('_')}_idx`, unique: false, columns: index.fields.map((field) => field.name), type: index.algorithm ?? '', }; // NOTE: fulltext index is not supported for postgres // ref: https://www.prisma.io/docs/orm/prisma-schema/data-model/indexes#full-text-indexes-mysql-and-mongodb case 'fulltext': return null; default: return null; } } function extractDefaultValue$2(field) { const value = field.default?.valueOf(); const defaultValue = value === undefined ? null : value; // NOTE: When `@default(autoincrement())` is specified, `defaultValue` becomes an object // like `{"name":"autoincrement","args":[]}` (DMMF.FieldDefault). // This function handles both primitive types (`string | number | boolean`) and objects, // returning a string like `name(args)` for objects. // Note: `FieldDefaultScalar[]` is not supported. if (typeof defaultValue === 'object' && defaultValue !== null) { if ('name' in defaultValue && 'args' in defaultValue) { return `${defaultValue.name}(${defaultValue.args})`; } } return typeof defaultValue === 'string' || typeof defaultValue === 'number' || typeof defaultValue === 'boolean' ? defaultValue : null; } function normalizeConstraintName$2(constraint) { // ref: https://www.prisma.io/docs/orm/prisma-schema/data-model/relations/referential-actions switch (constraint) { case 'Cascade': return 'CASCADE'; case 'Restrict': return 'RESTRICT'; case 'SetNull': return 'SET_NULL'; case 'SetDefault': return 'SET_DEFAULT'; default: return 'NO_ACTION'; } } /** * Creates the name for a many-to-many join table */ function createManyToManyJoinTableName(model1, model2) { return `_${model1}To${model2}`; } /** * Creates a join table for a many-to-many relationship */ function createManyToManyJoinTable(joinTableName, table_A_ColumnType, table_B_ColumnType) { return { name: joinTableName, constraints: {}, columns: { A: { name: 'A', type: table_A_ColumnType, default: null, notNull: true, unique: false, primary: false, comment: null, check: null, }, B: { name: 'B', type: table_B_ColumnType, default: null, notNull: true, unique: false, primary: false, comment: null, check: null, }, }, comment: null, indexes: { [`${joinTableName}_AB_pkey`]: { name: `${joinTableName}_AB_pkey`, unique: true, columns: ['A', 'B'], type: '', }, [`${joinTableName}_B_index`]: { name: `${joinTableName}_B_index`, unique: false, columns: ['B'], type: '', }, }, }; } /** * Creates relationships for a many-to-many join table */ function createManyToManyRelationships(joinTableName, model1, primaryColumnNameOfA, model2, primaryColumnNameOfB) { return { [`${joinTableName}_A_fkey`]: { name: `${joinTableName}_A_fkey`, primaryTableName: model1, primaryColumnName: primaryColumnNameOfA, foreignTableName: joinTableName, foreignColumnName: 'A', cardinality: 'ONE_TO_MANY', updateConstraint: 'CASCADE', deleteConstraint: 'CASCADE', }, [`${joinTableName}_B_fkey`]: { name: `${joinTableName}_B_fkey`, primaryTableName: model2, primaryColumnName: primaryColumnNameOfB, foreignTableName: joinTableName, foreignColumnName: 'B', cardinality: 'ONE_TO_MANY', updateConstraint: 'CASCADE', deleteConstraint: 'CASCADE', }, }; } /** * Detects if a field is part of a many-to-many relation and stores it for later processing */ function isManyToManyField(field) { return (field.isList && (!field.relationFromFields || field.relationFromFields.length === 0) && (!field.relationToFields || field.relationToFields.length === 0)); } function findRelatedField(field, model, models) { const relatedModel = models.find((m) => m.name === field.type); if (!relatedModel) return undefined; return relatedModel.fields.find((f) => f.relationName === field.relationName && f.isList && f.type === model.name); } function getSortedModelPair(model1, model2) { return model1.localeCompare(model2) < 0 ? [model1, model2] : [model2, model1]; } function storeManyToManyRelation(model1, model2, field1, field2, processedRelations, manyToManyRelations) { const [sortedModel1, sortedModel2] = getSortedModelPair(model1, model2); const relationId = `${sortedModel1}_${sortedModel2}`; if (!processedRelations.has(relationId)) { processedRelations.add(relationId); manyToManyRelations.push({ model1: sortedModel1, model2: sortedModel2, field1: field1, field2: field2, }); } } function detectAndStoreManyToManyRelation(field, model, models, processedRelations, manyToManyRelations) { if (!isManyToManyField(field)) return false; const relatedField = findRelatedField(field, model, models); if (!relatedField) return false; storeManyToManyRelation(model.name, field.type, field, relatedField, processedRelations, manyToManyRelations); return true; } function getPrimaryKeyInfo(table, models) { const tableName = table?.name; const model = models.find((m) => m.name === tableName); if (!model) { return null; // or throw an error if model is required } const tableIndexes = table?.indexes; const primaryKeyIndex = tableIndexes[`${tableName}_pkey`]; const primaryKeyColumnName = primaryKeyIndex?.columns[0]; if (!primaryKeyColumnName) { return null; // no primary key found } // Find the field in the model that matches the primary key column name const primaryKeyField = model.fields.find((field) => field.name === primaryKeyColumnName || field.dbName === primaryKeyColumnName); return primaryKeyField; } const processor$3 = (str) => parsePrismaSchema(str); /*----------------------------------------------------------------------------*/ /* This file is generated by the templates/template.rb script and should not */ /* be modified manually. See */ /* templates/javascript/src/visitor.js.erb */ /* if you are looking to modify the */ /* template */ /*----------------------------------------------------------------------------*/ /** * A class that knows how to walk down the tree. None of the individual visit * methods are implemented on this visitor, so it forces the consumer to * implement each one that they need. For a default implementation that * continues walking the tree, see the `Visitor` class. * */ class BasicVisitor { /** * Calls `accept` on the given node if it is not `null`, which in turn should * call back into this visitor by calling the appropriate `visit*` method. * * @param {nodes.Node} node */ visit(node) { node?.accept(this); } /** * Visits each node in `nodes` by calling `accept` on each one. * * @param {nodes.Node[]} nodes */ visitAll(nodes) { nodes.forEach((node) => { node?.accept(this); }); } /** * Visits the child nodes of `node` by calling `accept` on each one. * * @param {nodes.Node} node */ visitChildNodes(node) { node.compactChildNodes().forEach((childNode) => { childNode.accept(this); }); } } /** * A visitor is a class that provides a default implementation for every accept * method defined on the nodes. This means it can walk a tree without the * caller needing to define any special handling. This allows you to handle a * subset of the tree, while still walking the whole tree. * * For example, to find all of the method calls that call the `foo` method, you * could write: * * @example * class FooCalls extends Visitor { * visitCallNode(node) { * if (node.name === "foo") { * // Do something with the node * } * * // Call super so that the visitor continues walking the tree * super.visitCallNode(node); * } * } * */ class Visitor extends BasicVisitor { /** * Visit a AliasGlobalVariableNode node. * * @param {nodes.AliasGlobalVariableNode} node */ visitAliasGlobalVariableNode(node) { this.visitChildNodes(node); } /** * Visit a AliasMethodNode node. * * @param {nodes.AliasMethodNode} node */ visitAliasMethodNode(node) { this.visitChildNodes(node); } /** * Visit a AlternationPatternNode node. * * @param {nodes.AlternationPatternNode} node */ visitAlternationPatternNode(node) { this.visitChildNodes(node); } /** * Visit a AndNode node. * * @param {nodes.AndNode} node */ visitAndNode(node) { this.visitChildNodes(node); } /** * Visit a ArgumentsNode node. * * @param {nodes.ArgumentsNode} node */ visitArgumentsNode(node) { this.visitChildNodes(node); } /** * Visit a ArrayNode node. * * @param {nodes.ArrayNode} node */ visitArrayNode(node) { this.visitChildNodes(node); } /** * Visit a ArrayPatternNode node. * * @param {nodes.ArrayPatternNode} node */ visitArrayPatternNode(node) { this.visitChildNodes(node); } /** * Visit a AssocNode node. * * @param {nodes.AssocNode} node */ visitAssocNode(node) { this.visitChildNodes(node); } /** * Visit a AssocSplatNode node. * * @param {nodes.AssocSplatNode} node */ visitAssocSplatNode(node) { this.visitChildNodes(node); } /** * Visit a BackReferenceReadNode node. * * @param {nodes.BackReferenceReadNode} node */ visitBackReferenceReadNode(node) { this.visitChildNodes(node); } /** * Visit a BeginNode node. * * @param {nodes.BeginNode} node */ visitBeginNode(node) { this.visitChildNodes(node); } /** * Visit a BlockArgumentNode node. * * @param {nodes.BlockArgumentNode} node */ visitBlockArgumentNode(node) { this.visitChildNodes(node); } /** * Visit a BlockLocalVariableNode node. * * @param {nodes.BlockLocalVariableNode} node */ visitBlockLocalVariableNode(node) { this.visitChildNodes(node); } /** * Visit a BlockNode node. * * @param {nodes.BlockNode} node */ visitBlockNode(node) { this.visitChildNodes(node); } /** * Visit a BlockParameterNode node. * * @param {nodes.BlockParameterNode} node */ visitBlockParameterNode(node) { this.visitChildNodes(node); } /** * Visit a BlockParametersNode node. * * @param {nodes.BlockParametersNode} node */ visitBlockParametersNode(node) { this.visitChildNodes(node); } /** * Visit a BreakNode node. * * @param {nodes.BreakNode} node */ visitBreakNode(node) { this.visitChildNodes(node); } /** * Visit a CallAndWriteNode node. * * @param {nodes.CallAndWriteNode} node */ visitCallAndWriteNode(node) { this.visitChildNodes(node); } /** * Visit a CallNode node. * * @param {nodes.CallNode} node */ visitCallNode(node) { this.visitChildNodes(node); } /** * Visit a CallOperatorWriteNode node. * * @param {nodes.CallOperatorWriteNode} node */ visitCallOperatorWriteNode(node) { this.visitChildNodes(node); } /** * Visit a CallOrWriteNode node. * * @param {nodes.CallOrWriteNode} node */ visitCallOrWriteNode(node) { this.visitChildNodes(node); } /** * Visit a CallTargetNode node. * * @param {nodes.CallTargetNode} node */ visitCallTargetNode(node) { this.visitChildNodes(node); } /** * Visit a CapturePatternNode node. * * @param {nodes.CapturePatternNode} node */ visitCapturePatternNode(node) { this.visitChildNodes(node); } /** * Visit a CaseMatchNode node. * * @param {nodes.CaseMatchNode} node */ visitCaseMatchNode(node) { this.visitChildNodes(node); } /** * Visit a CaseNode node. * * @param {nodes.CaseNode} node */ visitCaseNode(node) { this.visitChildNodes(node); } /** * Visit a ClassNode node. * * @param {nodes.ClassNode} node */ visitClassNode(node) { this.visitChildNodes(node); } /** * Visit a ClassVariableAndWriteNode node. * * @param {nodes.ClassVariableAndWriteNode} node */ visitClassVariableAndWriteNode(node) { this.visitChildNodes(node); } /** * Visit a ClassVariableOperatorWriteNode node. * * @param {nodes.ClassVariableOperatorWriteNode} node */ visitClassVariableOperatorWriteNode(node) { this.visitChildNodes(node); } /** * Visit a ClassVariableOrWriteNode node. * * @param {nodes.ClassVariableOrWriteNode} node */ visitClassVariableOrWriteNode(node) { this.visitChildNodes(node); } /** * Visit a ClassVariableReadNode node. * * @param {nodes.ClassVariableReadNode} node */ visitClassVariableReadNode(node) { this.visitChildNodes(node); } /** * Visit a ClassVariableTargetNode node. * * @param {nodes.ClassVariableTargetNode} node */ visitClassVariableTargetNode(node) { this.visitChildNodes(node); } /** * Visit a ClassVariableWriteNode node. * * @param {nodes.ClassVariableWriteNode} node */ visitClassVariableWriteNode(node) { this.visitChildNodes(node); } /** * Visit a ConstantAndWriteNode node. * * @param {nodes.ConstantAndWriteNode} node */ visitConstantAndWriteNode(node) { this.visitChildNodes(node); } /** * Visit a ConstantOperatorWriteNode node. * * @param {nodes.ConstantOperatorWriteNode} node */ visitConstantOperatorWriteNode(node) { this.visitChildNodes(node); } /** * Visit a ConstantOrWriteNode node. * * @param {nodes.ConstantOrWriteNode} node */ visitConstantOrWriteNode(node) { this.visitChildNodes(node); } /** * Visit a ConstantPathAndWriteNode node. * * @param {nodes.ConstantPathAndWriteNode} node */ visitConstantPathAndWriteNode(node) { this.visitChildNodes(node); } /** * Visit a ConstantPathNode node. * * @param {nodes.ConstantPathNode} node */ visitConstantPathNode(node) { this.visitChildNodes(node); } /** * Visit a ConstantPathOperatorWriteNode node. * * @param {nodes.ConstantPathOperatorWriteNode} node */ visitConstantPathOperatorWriteNode(node) { this.visitChildNodes(node); } /** * Visit a ConstantPathOrWriteNode node. * * @param {nodes.ConstantPathOrWriteNode} node */ visitConstantPathOrWriteNode(node) { this.visitChildNodes(node); } /** * Visit a ConstantPathTargetNode node. * * @param {nodes.ConstantPathTargetNode} node */ visitConstantPathTargetNode(node) { this.visitChildNodes(node); } /** * Visit a ConstantPathWriteNode node. * * @param {nodes.ConstantPathWriteNode} node */ visitConstantPathWriteNode(node) { this.visitChildNodes(node); } /** * Visit a ConstantReadNode node. * * @param {nodes.ConstantReadNode} node */ visitConstantReadNode(node) { this.visitChildNodes(node); } /** * Visit a ConstantTargetNode node. * * @param {nodes.ConstantTargetNode} node */ visitConstantTargetNode(node) { this.visitChildNodes(node); } /** * Visit a ConstantWriteNode node. * * @param {nodes.ConstantWriteNode} node */ visitConstantWriteNode(node) { this.visitChildNodes(node); } /** * Visit a DefNode node. * * @param {nodes.DefNode} node */ visitDefNode(node) { this.visitChildNodes(node); } /** * Visit a DefinedNode node. * * @param {nodes.DefinedNode} node */ visitDefinedNode(node) { this.visitChildNodes(node); } /** * Visit a ElseNode node. * * @param {nodes.ElseNode} node */ visitElseNode(node) { this.visitChildNodes(node); } /** * Visit a EmbeddedStatementsNode node. * * @param {nodes.EmbeddedStatementsNode} node */ visitEmbeddedStatementsNode(node) { this.visitChildNodes(node); } /** * Visit a EmbeddedVariableNode node. * * @param {nodes.EmbeddedVariableNode} node */ visitEmbeddedVariableNode(node) { this.visitChildNodes(node); } /** * Visit a EnsureNode node. * * @param {nodes.EnsureNode} node */ visitEnsureNode(node) { this.visitChildNodes(node); } /** * Visit a FalseNode node. * * @param {nodes.FalseNode} node */ visitFalseNode(node) { this.visitChildNodes(node); } /** * Visit a FindPatternNode node. * * @param {nodes.FindPatternNode} node */ visitFindPatternNode(node) { this.visitChildNodes(node); } /** * Visit a FlipFlopNode node. * * @param {nodes.FlipFlopNode} node */ visitFlipFlopNode(node) { this.visitChildNodes(node); } /** * Visit a FloatNode node. * * @param {nodes.FloatNode} node */ visitFloatNode(node) { this.visitChildNodes(node); } /** * Visit a ForNode node. * * @param {nodes.ForNode} node */ visitForNode(node) { this.visitChildNodes(node); } /** * Visit a ForwardingArgumentsNode node. * * @param {nodes.ForwardingArgumentsNode} node */ visitForwardingArgumentsNode(node) { this.visitChildNodes(node); } /** * Visit a ForwardingParameterNode node. * * @param {nodes.ForwardingParameterNode} node */ visitForwardingParameterNode(node) { this.visitChildNodes(node); } /** * Visit a ForwardingSuperNode node. * * @param {nodes.ForwardingSuperNode} node */ visitForwardingSuperNode(node) { this.visitChildNodes(node); } /** * Visit a GlobalVariableAndWriteNode node. * * @param {nodes.GlobalVariableAndWriteNode} node */ visitGlobalVariableAndWriteNode(node) { this.visitChildNodes(node); } /** * Visit a GlobalVariableOperatorWriteNode node. * * @param {nodes.GlobalVariableOperatorWriteNode} node */ visitGlobalVariableOperatorWriteNode(node) { this.visitChildNodes(node); } /** * Visit a GlobalVariableOrWriteNode node. * * @param {nodes.GlobalVariableOrWriteNode} node */ visitGlobalVariableOrWriteNode(node) { this.visitChildNodes(node); } /** * Visit a GlobalVariableReadNode node. * * @param {nodes.GlobalVariableReadNode} node */ visitGlobalVariableReadNode(node) { this.visitChildNodes(node); } /** * Visit a GlobalVariableTargetNode node. * * @param {nodes.GlobalVariableTargetNode} node */ visitGlobalVariableTargetNode(node) { this.visitChildNodes(node); } /** * Visit a GlobalVariableWriteNode node. * * @param {nodes.GlobalVariableWriteNode} node */ visitGlobalVariableWriteNode(node) { this.visitChildNodes(node); } /** * Visit a HashNode node. * * @param {nodes.HashNode} node */ visitHashNode(node) { this.visitChildNodes(node); } /** * Visit a HashPatternNode node. * * @param {nodes.HashPatternNode} node */ visitHashPatternNode(node) { this.visitChildNodes(node); } /** * Visit a IfNode node. * * @param {nodes.IfNode} node */ visitIfNode(node) { this.visitChildNodes(node); } /** * Visit a ImaginaryNode node. * * @param {nodes.ImaginaryNode} node */ visitImaginaryNode(node) { this.visitChildNodes(node); } /** * Visit a ImplicitNode node. * * @param {nodes.ImplicitNode} node */ visitImplicitNode(node) { this.visitChildNodes(node); } /** * Visit a ImplicitRestNode node. * * @param {nodes.ImplicitRestNode} node */ visitImplicitRestNode(node) { this.visitChildNodes(node); } /** * Visit a InNode node. * * @param {nodes.InNode} node */ visitInNode(node) { this.visitChildNodes(node); } /** * Visit a IndexAndWriteNode node. * * @param {nodes.IndexAndWriteNode} node */ visitIndexAndWriteNode(node) { this.visitChildNodes(node); } /** * Visit a IndexOperatorWriteNode node. * * @param {nodes.IndexOperatorWriteNode} node */ visitIndexOperatorWriteNode(node) { this.visitChildNodes(node); } /** * Visit a IndexOrWriteNode node. * * @param {nodes.IndexOrWriteNode} node */ visitIndexOrWriteNode(node) { this.visitChildNodes(node); } /** * Visit a IndexTargetNode node. * * @param {nodes.IndexTargetNode} node */ visitIndexTargetNode(node) { this.visitChildNodes(node); } /** * Visit a InstanceVariableAndWriteNode node. * * @param {nodes.InstanceVariableAndWriteNode} node */ visitInstanceVariableAndWriteNode(node) { this.visitChildNodes(node); } /** * Visit a InstanceVariableOperatorWriteNode node. * * @param {nodes.InstanceVariableOperatorWriteNode} node */ visitInstanceVariableOperatorWriteNode(node) { this.visitChildNodes(node); } /** * Visit a InstanceVariableOrWriteNode node. * * @param {nodes.InstanceVariableOrWriteNode} node */ visitInstanceVariableOrWriteNode(node) { this.visitChildNodes(node); } /** * Visit a InstanceVariableReadNode node. * * @param {nodes.InstanceVariableReadNode} node */ visitInstanceVariableReadNode(node) { this.visitChildNodes(node); } /** * Visit a InstanceVariableTargetNode node. * * @param {nodes.InstanceVariableTargetNode} node */ visitInstanceVariableTargetNode(node) { this.visitChildNodes(node); } /** * Visit a InstanceVariableWriteNode node. * * @param {nodes.InstanceVariableWriteNode} node */ visitInstanceVariableWriteNode(node) { this.visitChildNodes(node); } /** * Visit a IntegerNode node. * * @param {nodes.IntegerNode} node */ visitIntegerNode(node) { this.visitChildNodes(node); } /** * Visit a InterpolatedMatchLastLineNode node. * * @param {nodes.InterpolatedMatchLastLineNode} node */ visitInterpolatedMatchLastLineNode(node) { this.visitChildNodes(node); } /** * Visit a InterpolatedRegularExpressionNode node. * * @param {nodes.InterpolatedRegularExpressionNode} node */ visitInterpolatedRegularExpressionNode(node) { this.visitChildNodes(node); } /** * Visit a InterpolatedStringNode node. * * @param {nodes.InterpolatedStringNode} node */ visitInterpolatedStringNode(node) { this.visitChildNodes(node); } /** * Visit a InterpolatedSymbolNode node. * * @param {nodes.InterpolatedSymbolNode} node */ visitInterpolatedSymbolNode(node) { this.visitChildNodes(node); } /** * Visit a InterpolatedXStringNode node. * * @param {nodes.InterpolatedXStringNode} node */ visitInterpolatedXStringNode(node) { this.visitChildNodes(node); } /** * Visit a ItLocalVariableReadNode node. * * @param {nodes.ItLocalVariableReadNode} node */ visitItLocalVariableReadNode(node) { this.visitChildNodes(node); } /** * Visit a ItParametersNode node. * * @param {nodes.ItParametersNode} node */ visitItParametersNode(node) { this.visitChildNodes(node); } /** * Visit a KeywordHashNode node. * * @param {nodes.KeywordHashNode} node */ visitKeywordHashNode(node) { this.visitChildNodes(node); } /** * Visit a KeywordRestParameterNode node. * * @param {nodes.KeywordRestParameterNode} node */ visitKeywordRestParameterNode(node) { this.visitChildNodes(node); } /** * Visit a LambdaNode node. * * @param {nodes.LambdaNode} node */ visitLambdaNode(node) { this.visitChildNodes(node); } /** * Visit a LocalVariableAndWriteNode node. * * @param {nodes.LocalVariableAndWriteNode} node */ visitLocalVariableAndWriteNode(node) { this.visitChildNodes(node); } /** * Visit a LocalVariableOperatorWriteNode node. * * @param {nodes.LocalVariableOperatorWriteNode} node */ visitLocalVariableOperatorWriteNode(node) { this.visitChildNodes(node); } /** * Visit a LocalVariableOrWriteNode node. * * @param {nodes.LocalVariableOrWriteNode} node */ visitLocalVariableOrWriteNode(node) { this.visitChildNodes(node); } /** * Visit a LocalVariableReadNode node. * * @param {nodes.LocalVariableReadNode} node */ visitLocalVariableReadNode(node) { this.visitChildNodes(node); } /** * Visit a LocalVariableTargetNode node. * * @param {nodes.LocalVariableTargetNode} node */ visitLocalVariableTargetNode(node) { this.visitChildNodes(node); } /** * Visit a LocalVariableWriteNode node. * * @param {nodes.LocalVariableWriteNode} node */ visitLocalVariableWriteNode(node) { this.visitChildNodes(node); } /** * Visit a MatchLastLineNode node. * * @param {nodes.MatchLastLineNode} node */ visitMatchLastLineNode(node) { this.visitChildNodes(node); } /** * Visit a MatchPredicateNode node. * * @param {nodes.MatchPredicateNode} node */ visitMatchPredicateNode(node) { this.visitChildNodes(node); } /** * Visit a MatchRequiredNode node. * * @param {nodes.MatchRequiredNode} node */ visitMatchRequiredNode(node) { this.visitChildNodes(node); } /** * Visit a MatchWriteNode node. * * @param {nodes.MatchWriteNode} node */ visitMatchWriteNode(node) { this.visitChildNodes(node); } /** * Visit a MissingNode node. * * @param {nodes.MissingNode} node */ visitMissingNode(node) { this.visitChildNodes(node); } /** * Visit a ModuleNode node. * * @param {nodes.ModuleNode} node */ visitModuleNode(node) { this.visitChildNodes(node); } /** * Visit a MultiTargetNode node. * * @param {nodes.MultiTargetNode} node */ visitMultiTargetNode(node) { this.visitChildNodes(node); } /** * Visit a MultiWriteNode node. * * @param {nodes.MultiWriteNode} node */ visitMultiWriteNode(node) { this.visitChildNodes(node); } /** * Visit a NextNode node. * * @param {nodes.NextNode} node */ visitNextNode(node) { this.visitChildNodes(node); } /** * Visit a NilNode node. * * @param {nodes.NilNode} node */ visitNilNode(node) { this.visitChildNodes(node); } /** * Visit a NoKeywordsParameterNode node. * * @param {nodes.NoKeywordsParameterNode} node */ visitNoKeywordsParameterNode(node) { this.visitChildNodes(node); } /** * Visit a NumberedParametersNode node. * * @param {nodes.NumberedParametersNode} node */ visitNumberedParametersNode(node) { this.visitChildNodes(node); } /** * Visit a NumberedReferenceReadNode node. * * @param {nodes.NumberedReferenceReadNode} node */ visitNumberedReferenceReadNode(node) { this.visitChildNodes(node); } /** * Visit a OptionalKeywordParameterNode node. * * @param {nodes.OptionalKeywordParameterNode} node */ visitOptionalKeywordParameterNode(node) { this.visitChildNodes(node); } /** * Visit a OptionalParameterNode node. * * @param {nodes.OptionalParameterNode} node */ visitOptionalParameterNode(node) { this.visitChildNodes(node); } /** * Visit a OrNode node. * * @param {nodes.OrNode} node */ visitOrNode(node) { this.visitChildNodes(node); } /** * Visit a ParametersNode node. * * @param {nodes.ParametersNode} node */ visitParametersNode(node) { this.visitChildNodes(node); } /** * Visit a ParenthesesNode node. * * @param {nodes.ParenthesesNode} node */ visitParenthesesNode(node) { this.visitChildNodes(node); } /** * Visit a PinnedExpressionNode node. * * @param {nodes.PinnedExpressionNode} node */ visitPinnedExpressionNode(node) { this.visitChildNodes(node); } /** * Visit a PinnedVariableNode node. * * @param {nodes.PinnedVariableNode} node */ visitPinnedVariableNode(node) { this.visitChildNodes(node); } /** * Visit a PostExecutionNode node. * * @param {nodes.PostExecutionNode} node */ visitPostExecutionNode(node) { this.visitChildNodes(node); } /** * Visit a PreExecutionNode node. * * @param {nodes.PreExecutionNode} node */ visitPreExecutionNode(node) { this.visitChildNodes(node); } /** * Visit a ProgramNode node. * * @param {nodes.ProgramNode} node */ visitProgramNode(node) { this.visitChildNodes(node); } /** * Visit a RangeNode node. * * @param {nodes.RangeNode} node */ visitRangeNode(node) { this.visitChildNodes(node); } /** * Visit a RationalNode node. * * @param {nodes.RationalNode} node */ visitRationalNode(node) { this.visitChildNodes(node); } /** * Visit a RedoNode node. * * @param {nodes.RedoNode} node */ visitRedoNode(node) { this.visitChildNodes(node); } /** * Visit a RegularExpressionNode node. * * @param {nodes.RegularExpressionNode} node */ visitRegularExpressionNode(node) { this.visitChildNodes(node); } /** * Visit a RequiredKeywordParameterNode node. * * @param {nodes.RequiredKeywordParameterNode} node */ visitRequiredKeywordParameterNode(node) { this.visitChildNodes(node); } /** * Visit a RequiredParameterNode node. * * @param {nodes.RequiredParameterNode} node */ visitRequiredParameterNode(node) { this.visitChildNodes(node); } /** * Visit a RescueModifierNode node. * * @param {nodes.RescueModifierNode} node */ visitRescueModifierNode(node) { this.visitChildNodes(node); } /** * Visit a RescueNode node. * * @param {nodes.RescueNode} node */ visitRescueNode(node) { this.visitChildNodes(node); } /** * Visit a RestParameterNode node. * * @param {nodes.RestParameterNode} node */ visitRestParameterNode(node) { this.visitChildNodes(node); } /** * Visit a RetryNode node. * * @param {nodes.RetryNode} node */ visitRetryNode(node) { this.visitChildNodes(node); } /** * Visit a ReturnNode node. * * @param {nodes.ReturnNode} node */ visitReturnNode(node) { this.visitChildNodes(node); } /** * Visit a SelfNode node. * * @param {nodes.SelfNode} node */ visitSelfNode(node) { this.visitChildNodes(node); } /** * Visit a ShareableConstantNode node. * * @param {nodes.ShareableConstantNode} node */ visitShareableConstantNode(node) { this.visitChildNodes(node); } /** * Visit a SingletonClassNode node. * * @param {nodes.SingletonClassNode} node */ visitSingletonClassNode(node) { this.visitChildNodes(node); } /** * Visit a SourceEncodingNode node. * * @param {nodes.SourceEncodingNode} node */ visitSourceEncodingNode(node) { this.visitChildNodes(node); } /** * Visit a SourceFileNode node. * * @param {nodes.SourceFileNode} node */ visitSourceFileNode(node) { this.visitChildNodes(node); } /** * Visit a SourceLineNode node. * * @param {nodes.SourceLineNode} node */ visitSourceLineNode(node) { this.visitChildNodes(node); } /** * Visit a SplatNode node. * * @param {nodes.SplatNode} node */ visitSplatNode(node) { this.visitChildNodes(node); } /** * Visit a StatementsNode node. * * @param {nodes.StatementsNode} node */ visitStatementsNode(node) { this.visitChildNodes(node); } /** * Visit a StringNode node. * * @param {nodes.StringNode} node */ visitStringNode(node) { this.visitChildNodes(node); } /** * Visit a SuperNode node. * * @param {nodes.SuperNode} node */ visitSuperNode(node) { this.visitChildNodes(node); } /** * Visit a SymbolNode node. * * @param {nodes.SymbolNode} node */ visitSymbolNode(node) { this.visitChildNodes(node); } /** * Visit a TrueNode node. * * @param {nodes.TrueNode} node */ visitTrueNode(node) { this.visitChildNodes(node); } /** * Visit a UndefNode node. * * @param {nodes.UndefNode} node */ visitUndefNode(node) { this.visitChildNodes(node); } /** * Visit a UnlessNode node. * * @param {nodes.UnlessNode} node */ visitUnlessNode(node) { this.visitChildNodes(node); } /** * Visit a UntilNode node. * * @param {nodes.UntilNode} node */ visitUntilNode(node) { this.visitChildNodes(node); } /** * Visit a WhenNode node. * * @param {nodes.WhenNode} node */ visitWhenNode(node) { this.visitChildNodes(node); } /** * Visit a WhileNode node. * * @param {nodes.WhileNode} node */ visitWhileNode(node) { this.visitChildNodes(node); } /** * Visit a XStringNode node. * * @param {nodes.XStringNode} node */ visitXStringNode(node) { this.visitChildNodes(node); } /** * Visit a YieldNode node. * * @param {nodes.YieldNode} node */ visitYieldNode(node) { this.visitChildNodes(node); } } /*----------------------------------------------------------------------------*/ /* This file is generated by the templates/template.rb script and should not */ /* be modified manually. See */ /* templates/javascript/src/nodes.js.erb *