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 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 167x 167x 167x 167x 167x 52x 52x 115x 115x 115x 167x 9x 9x 115x 115x 167x 34x 34x 33x 33x 34x 114x 114x 167x 48x 48x 48x 48x 48x 1x 1x 1x 1x 47x 47x 48x 113x 113x 167x 26x 26x 113x 167x 76x 76x 76x 76x 76x 76x 76x 58x 58x 76x 76x 4x 5x 5x 5x 4x 76x 47x 47x 76x 39x 39x 76x 113x 167x 9x 9x 113x 167x 33x 33x 113x 167x 1x 1x 167x 167x 1x | import {ExpressionNode} from "../../nodes"; import * as Expressions from "../../2_statements/expressions"; import {For} from "./for"; import {Source} from "./source"; import {AbstractType} from "../../types/basic/_abstract_type"; import {Let} from "./let"; import {FieldAssignment} from "./field_assignment"; import {AnyType, TableType, UnknownType, VoidType} from "../../types/basic"; import {CheckSyntaxKey, SyntaxInput, syntaxIssue} from "../_syntax_input"; export class ValueBody { public runSyntax( node: ExpressionNode | undefined, input: SyntaxInput, targetType: AbstractType | undefined): AbstractType | undefined { if (node === undefined) { return targetType; } let letScoped = false; const letNode = node.findDirectExpression(Expressions.Let); if (letNode) { letScoped = new Let().runSyntax(letNode, input); } let forScopes = 0; for (const forNode of node.findDirectExpressions(Expressions.For) || []) { const scoped = new For().runSyntax(forNode, input); if (scoped === true) { forScopes++; } } const fields = new Set<string>(); for (const s of node.findDirectExpressions(Expressions.FieldAssignment)) { new FieldAssignment().runSyntax(s, input, targetType); const fieldname = s.findDirectExpression(Expressions.FieldSub)?.concatTokens().toUpperCase(); if (fieldname) { if (fields.has(fieldname)) { const message = "Duplicate field assignment"; input.issues.push(syntaxIssue(input, s.getFirstToken(), message)); return new VoidType(CheckSyntaxKey); } fields.add(fieldname); } } let type: AbstractType | undefined = undefined; // todo, this is only correct if there is a single source in the body for (const s of node.findDirectExpressions(Expressions.Source)) { type = new Source().runSyntax(s, input, type); } for (const foo of node.findDirectExpressions(Expressions.ValueBodyLine)) { if (!(targetType instanceof TableType) && !(targetType instanceof UnknownType) && !(targetType instanceof AnyType) && targetType !== undefined && !(targetType instanceof VoidType)) { const message = "Value, not a table type"; input.issues.push(syntaxIssue(input, foo.getFirstToken(), message)); return new VoidType(CheckSyntaxKey); } let rowType: AbstractType | undefined = targetType; if (targetType instanceof TableType) { rowType = targetType.getRowType(); } for (const l of foo.findDirectExpressions(Expressions.ValueBodyLines)) { for (const s of l.findDirectExpressions(Expressions.Source)) { // LINES OF ?? todo, pass type, new Source().runSyntax(s, input); } } for (const s of foo.findDirectExpressions(Expressions.FieldAssignment)) { new FieldAssignment().runSyntax(s, input, rowType); } for (const s of foo.findDirectExpressions(Expressions.Source)) { new Source().runSyntax(s, input, rowType); } } if (letScoped === true) { input.scope.pop(node.getLastToken().getEnd()); } for (let i = 0; i < forScopes; i++) { input.scope.pop(node.getLastToken().getEnd()); } if (targetType?.isGeneric() && type) { return type; } return targetType ? targetType : type; } } |