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 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 14x 14x 14x 14x 14x 14x 14x 14x 14x 14x 2x 14x 14x 14x 12x 12x 12x 8x 8x 4x 4x 4x 12x 4x 4x 12x 12x 1x 12x 12x 13x 13x 14x 13x 13x 13x 1x | import {ExpressionNode} from "../../nodes";
import {DataReference, GenericObjectReferenceType, ObjectReferenceType, UnknownType, VoidType} from "../../types/basic";
import * as Expressions from "../../2_statements/expressions";
import {AbstractType} from "../../types/basic/_abstract_type";
import {Source} from "./source";
import {TypeUtils} from "../_type_utils";
import {BasicTypes} from "../basic_types";
import {ReferenceType} from "../_reference";
import {CheckSyntaxKey, SyntaxInput, syntaxIssue} from "../_syntax_input";
export class Cast {
public static runSyntax(node: ExpressionNode, input: SyntaxInput, targetType: AbstractType | undefined): AbstractType {
const sourceNode = node.findDirectExpression(Expressions.Source);
if (sourceNode === undefined) {
const message = "Cast, source node not found";
input.issues.push(syntaxIssue(input, node.getFirstToken(), message));
return VoidType.get(CheckSyntaxKey);
}
const sourceType = Source.runSyntax(sourceNode, input);
let tt: AbstractType | undefined = undefined;
const typeExpression = node.findDirectExpression(Expressions.TypeNameOrInfer);
const typeName = typeExpression?.concatTokens();
if (typeName === undefined) {
const message = "Cast, child TypeNameOrInfer not found";
input.issues.push(syntaxIssue(input, node.getFirstToken(), message));
return VoidType.get(CheckSyntaxKey);
} else if (typeName === "#" && targetType) {
tt = targetType;
} else if (typeName === "#") {
const message = "Cast, todo, infer type";
input.issues.push(syntaxIssue(input, node.getFirstToken(), message));
return VoidType.get(CheckSyntaxKey);
}
if (tt === undefined && typeExpression) {
const basic = new BasicTypes(input);
tt = basic.parseType(typeExpression);
if (tt === undefined || tt instanceof VoidType || tt instanceof UnknownType) {
const found = input.scope.findObjectDefinition(typeName);
if (found) {
tt = new ObjectReferenceType(found, {qualifiedName: typeName});
input.scope.addReference(typeExpression.getFirstToken(), found, ReferenceType.ObjectOrientedReference, input.filename);
}
} else {
tt = new DataReference(tt, typeName);
}
if (tt === undefined && input.scope.getDDIC().inErrorNamespace(typeName) === false) {
tt = VoidType.get(typeName);
} else if (typeName.toUpperCase() === "OBJECT") {
return new GenericObjectReferenceType();
} else if (tt === undefined) {
// todo, this should be an UnknownType instead?
const message = "Type \"" + typeName + "\" not found in scope, Cast";
input.issues.push(syntaxIssue(input, typeExpression.getFirstToken(), message));
return VoidType.get(CheckSyntaxKey);
}
}
Source.addIfInferred(node, input, tt);
if (new TypeUtils(input.scope).isCastable(sourceType, tt) === false) {
const message = "Cast, incompatible types";
input.issues.push(syntaxIssue(input, node.getFirstToken(), message));
return VoidType.get(CheckSyntaxKey);
}
return tt!;
}
} |