(schema: Schema.Top, path: string, portable: Map<SchemaAST.AST, boolean>)
| 808 | } |
| 809 | |
| 810 | function assertPortable(schema: Schema.Top, path: string, portable: Map<SchemaAST.AST, boolean>) { |
| 811 | const visiting = new Set<SchemaAST.AST>() |
| 812 | const taggedError = taggedErrorFields(schema) |
| 813 | const visit = (ast: SchemaAST.AST): boolean => { |
| 814 | const cached = portable.get(ast) |
| 815 | if (cached !== undefined) return cached |
| 816 | if (visiting.has(ast)) return true |
| 817 | visiting.add(ast) |
| 818 | const result = visitCurrent(ast) |
| 819 | visiting.delete(ast) |
| 820 | portable.set(ast, result) |
| 821 | return result |
| 822 | } |
| 823 | const visitCurrent = (ast: SchemaAST.AST): boolean => { |
| 824 | if (!annotationsPortable(ast.annotations)) return false |
| 825 | if (!checksPortable(ast.checks) || ("encodingChecks" in ast && !checksPortable(ast.encodingChecks))) return false |
| 826 | if (SchemaAST.isDeclaration(ast)) { |
| 827 | return generationPortable(ast.annotations?.generation) && ast.typeParameters.every(visit) |
| 828 | } |
| 829 | if (ast.encoding !== undefined && ast.annotations?.generation === undefined) return false |
| 830 | if (SchemaAST.isSuspend(ast)) return visit(ast.thunk()) |
| 831 | if (SchemaAST.isUnion(ast)) return ast.types.every(visit) |
| 832 | if (SchemaAST.isArrays(ast)) { |
| 833 | return ast.elements.every(visit) && ast.rest.every(visit) |
| 834 | } |
| 835 | if (SchemaAST.isObjects(ast)) { |
| 836 | return ( |
| 837 | ast.propertySignatures.every((field) => visit(field.type)) && |
| 838 | ast.indexSignatures.every((index) => visit(index.parameter) && visit(index.type)) |
| 839 | ) |
| 840 | } |
| 841 | if (SchemaAST.isTemplateLiteral(ast)) return ast.parts.every(visit) |
| 842 | return true |
| 843 | } |
| 844 | if (taggedError !== undefined && SchemaAST.isDeclaration(schema.ast)) { |
| 845 | if ( |
| 846 | schema.ast.checks !== undefined || |
| 847 | ("encodingChecks" in schema.ast && !checksPortable(schema.ast.encodingChecks)) || |
| 848 | schema.ast.typeParameters.some((ast) => ast.checks !== undefined) || |
| 849 | !schema.ast.typeParameters.every(visit) |
| 850 | ) { |
| 851 | throw new GenerationError({ reason: `Unportable schema: ${path}` }) |
| 852 | } |
| 853 | return |
| 854 | } |
| 855 | if (!visit(schema.ast)) throw new GenerationError({ reason: `Unportable schema: ${path}` }) |
| 856 | } |
| 857 | |
| 858 | function checksPortable(checks: SchemaAST.Checks | undefined): boolean { |
| 859 | if (checks === undefined) return true |
no test coverage detected