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 103 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 179x 179x 179x 179x 179x 56x 56x 123x 123x 123x 179x 9x 9x 123x 123x 179x 35x 35x 34x 34x 35x 122x 122x 179x 59x 59x 59x 55x 55x 55x 55x 1x 1x 1x 1x 54x 54x 55x 59x 121x 121x 179x 7x 7x 179x 19x 19x 121x 179x 79x 79x 79x 79x 79x 79x 79x 61x 61x 79x 79x 4x 5x 5x 5x 4x 79x 50x 50x 79x 40x 40x 79x 121x 179x 9x 9x 121x 179x 34x 34x 121x 179x 1x 1x 179x 179x 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 static 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 = Let.runSyntax(letNode, input);
}
let forScopes = 0;
for (const forNode of node.findDirectExpressions(Expressions.For) || []) {
const scoped = For.runSyntax(forNode, input);
if (scoped === true) {
forScopes++;
}
}
const fields = new Set<string>();
for (const s of node.findDirectExpressions(Expressions.FieldAssignment)) {
FieldAssignment.runSyntax(s, input, targetType);
if (node.findDirectExpression(Expressions.ValueBodyLine) === undefined) {
// todo: refine, still needs to be checked when there are table lines
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 VoidType.get(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 = Source.runSyntax(s, input, type);
}
for (const s of node.findDirectExpression(Expressions.ValueBase)?.findDirectExpressions(Expressions.Source) || []) {
type = 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 VoidType.get(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,
Source.runSyntax(s, input);
}
}
for (const s of foo.findDirectExpressions(Expressions.FieldAssignment)) {
FieldAssignment.runSyntax(s, input, rowType);
}
for (const s of foo.findDirectExpressions(Expressions.Source)) {
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;
}
} |