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 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 946x 946x 946x 946x 946x 946x 946x 697x 697x 698x 697x 697x 1x 1x 697x 946x 946x 697x 697x 697x 1x 1x 1x 1x 697x 945x 945x 946x 946x 944x 946x 944x 946x 248x 248x 248x 944x 946x 5x 946x 14x 14x 14x 14x 946x 946x 1x | import * as Expressions from "../../2_statements/expressions";
import {StatementNode} from "../../nodes";
import {Source} from "../expressions/source";
import {Target} from "../expressions/target";
import {InlineData} from "../expressions/inline_data";
import {AbstractType} from "../../types/basic/_abstract_type";
import {StatementSyntax} from "../_statement_syntax";
import {TypeUtils} from "../_type_utils";
import {SyntaxInput, syntaxIssue} from "../_syntax_input";
import {Dereference} from "../expressions/dereference";
import {IdentifierMeta} from "../../types/_typed_identifier";
export class Move implements StatementSyntax {
public runSyntax(node: StatementNode, input: SyntaxInput): void {
const targets = node.findDirectExpressions(Expressions.Target);
const firstTarget = targets[0];
const inline = firstTarget?.findDirectExpression(Expressions.InlineData);
let targetType: AbstractType | undefined = undefined;
if (inline === undefined) {
targetType = firstTarget ? Target.runSyntax(firstTarget, input) : undefined;
for (const t of targets) {
if (t === firstTarget) {
continue;
}
Target.runSyntax(t, input);
}
}
if (inline === undefined && firstTarget !== undefined) {
// hmm, does this do the scoping correctly? handle constants etc? todo
const found = input.scope.findVariable(firstTarget.concatTokens());
if (found && found.getMeta().includes(IdentifierMeta.ReadOnly)) {
const message = `"${firstTarget.concatTokens()}" cannot be modified, it is readonly`;
input.issues.push(syntaxIssue(input, firstTarget.getFirstToken(), message));
return;
}
}
const source = node.findDirectExpression(Expressions.Source);
let sourceType = source ? Source.runSyntax(source, input, targetType) : undefined;
if (sourceType === undefined) {
const message = "No source type determined";
input.issues.push(syntaxIssue(input, node.getFirstToken(), message));
return;
}
if (node.findDirectExpression(Expressions.Dereference)) {
sourceType = Dereference.runSyntax(node, sourceType, input);
}
if (inline) {
InlineData.runSyntax(inline, input, sourceType);
targetType = sourceType;
}
if (node.findDirectTokenByText("?=")) {
if (new TypeUtils(input.scope).isCastable(sourceType, targetType) === false) {
const message = "Incompatible types";
input.issues.push(syntaxIssue(input, node.getFirstToken(), message));
return;
}
} else if (new TypeUtils(input.scope).isAssignableNew(sourceType, targetType, source) === false) {
const message = "Incompatible types";
input.issues.push(syntaxIssue(input, node.getFirstToken(), message));
return;
}
}
} |