Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 25x 25x 25x 25x 25x 25x 9x 9x 9x 9x 7x 7x 1x 1x 9x 2x 2x 2x 9x 22x 22x 25x 6x 6x 22x 22x 22x 22x 22x 22x 22x 2x 22x 20x 20x 20x 1x 20x 12x 12x 10x 10x 12x 1x 1x 12x 22x 22x 20x 25x 3x 3x 20x 20x 20x 1x 1x 20x 5x 5x 15x 15x 20x 20x 20x 20x 20x 20x 20x 6x 6x 6x 6x 3x 3x 3x 3x 12x 20x 1x 1x 11x 1x | import * as Expressions from "../../2_statements/expressions"; import {StatementNode} from "../../nodes"; import {CurrentScope} from "../_current_scope"; import {Source} from "../expressions/source"; import {Target} from "../expressions/target"; import {Dynamic} from "../expressions/dynamic"; import {ReferenceType} from "../_reference"; import {AnyType, GenericObjectReferenceType, ObjectReferenceType, VoidType} from "../../types/basic"; import {ClassDefinition} from "../../types"; import {StatementSyntax} from "../_statement_syntax"; import {IClassDefinition} from "../../types/_class_definition"; import {ObjectOriented} from "../_object_oriented"; export class CreateObject implements StatementSyntax { public runSyntax(node: StatementNode, scope: CurrentScope, filename: string): void { let cdef: IClassDefinition | undefined = undefined; // CREATE OBJECT, TYPE const type = node.findExpressionAfterToken("TYPE"); if (type && type.get() instanceof Expressions.ClassName) { const token = type.getFirstToken(); const name = token.getStr(); cdef = scope.findClassDefinition(name); if (cdef) { scope.addReference(token, cdef, ReferenceType.ObjectOrientedReference, filename); if (cdef.isAbstract() === true) { throw new Error(cdef.getName() + " is abstract, cannot be instantiated"); } } else if (scope.getDDIC().inErrorNamespace(name) === false) { scope.addReference(token, undefined, ReferenceType.ObjectOrientedVoidReference, filename, {ooName: name, ooType: "CLAS"}); } else { throw new Error("TYPE \"" + name + "\" not found"); } } // just recurse for (const s of node.findAllExpressions(Expressions.Source)) { new Source().runSyntax(s, scope, filename); } let first = true; for (const t of node.findAllExpressions(Expressions.Target)) { const found = new Target().runSyntax(t, scope, filename); if (first === true) { first = false; if (found instanceof VoidType) { continue; } else if (!(found instanceof ObjectReferenceType) && !(found instanceof AnyType) && !(found instanceof GenericObjectReferenceType)) { throw new Error("Target must be an object reference"); } else if (found instanceof GenericObjectReferenceType && type === undefined) { throw new Error("Generic type, cannot be instantiated"); } else if (found instanceof ObjectReferenceType) { const id = found.getIdentifier(); if (id instanceof ClassDefinition && cdef === undefined) { cdef = id; } if (type === undefined && id instanceof ClassDefinition && id.isAbstract() === true) { throw new Error(id.getName() + " is abstract, cannot be instantiated"); } } } } for (const t of node.findDirectExpressions(Expressions.Dynamic)) { new Dynamic().runSyntax(t, scope, filename); } this.validateParameters(cdef, node, scope); } private validateParameters(cdef: IClassDefinition | undefined, node: StatementNode, scope: CurrentScope) { if (cdef === undefined) { return; } const methodDef = new ObjectOriented(scope).searchMethodName(cdef, "CONSTRUCTOR"); const methodParameters = methodDef.method?.getParameters(); const allImporting = methodParameters?.getImporting() || []; const requiredImporting = new Set(methodParameters?.getRequiredParameters().map(i => i.getName().toUpperCase())); // todo, validate types for (const p of node.findDirectExpression(Expressions.ParameterListS)?.findAllExpressions(Expressions.ParameterS) || []) { const name = p.findDirectExpression(Expressions.ParameterName)?.concatTokens().toUpperCase(); if (name === undefined) { continue; } if (allImporting?.some(p => p.getName().toUpperCase() === name) === false) { throw new Error(`constructor parameter "${name}" does not exist`); } requiredImporting.delete(name); } for (const r of requiredImporting.values()) { throw new Error(`constructor parameter "${r}" must be supplied`); } } } |