Search in sources :

Example 1 with NamedType

use of dyvilx.tools.compiler.ast.type.raw.NamedType in project Dyvil by Dyvil.

the class FieldAccess method resolveAsType.

@Override
protected IValue resolveAsType(IContext context) {
    final IType parentType;
    if (this.receiver == null) {
        parentType = null;
    } else if (this.receiver.isClassAccess()) {
        parentType = this.receiver.getType();
    } else {
        return null;
    }
    final IType type = new NamedType(this.position, this.name, parentType).resolveType(null, context);
    return type != null ? new ClassAccess(this.position, type) : null;
}
Also used : NamedType(dyvilx.tools.compiler.ast.type.raw.NamedType) IType(dyvilx.tools.compiler.ast.type.IType)

Example 2 with NamedType

use of dyvilx.tools.compiler.ast.type.raw.NamedType in project Dyvil by Dyvil.

the class TypeParser method parse.

@Override
public void parse(IParserManager pm, IToken token) {
    final int type = token.type();
    switch(this.mode) {
        case NAME:
            {
                if ((this.flags & NAMED_ONLY) == 0) {
                    switch(type) {
                        case DyvilSymbols.AT:
                            Annotation a = new CodeAnnotation(token.raw());
                            pm.pushParser(new AnnotationParser(a));
                            this.type = new AnnotatedType(a);
                            this.mode = ANNOTATION_END;
                            return;
                        case BaseSymbols.OPEN_PARENTHESIS:
                            {
                                final TypeList arguments;
                                if (this.parentType != null) {
                                    final LambdaType lambdaType = new LambdaType();
                                    lambdaType.setExtension(true);
                                    this.type = lambdaType;
                                    arguments = lambdaType.getArguments();
                                    arguments.add(this.parentType);
                                } else {
                                    final TupleType tupleType = new TupleType();
                                    this.type = tupleType;
                                    arguments = tupleType.getArguments();
                                }
                                pm.pushParser(new TypeListParser(arguments));
                                this.mode = TUPLE_END;
                                return;
                            }
                        case BaseSymbols.OPEN_SQUARE_BRACKET:
                            {
                                final ArrayType arrayType = new ArrayType();
                                switch(token.next().type()) {
                                    case DyvilKeywords.FINAL:
                                        arrayType.setMutability(Mutability.IMMUTABLE);
                                        pm.skip();
                                        break;
                                    case DyvilKeywords.VAR:
                                        arrayType.setMutability(Mutability.MUTABLE);
                                        pm.skip();
                                        break;
                                }
                                this.mode = ARRAY_COLON;
                                this.type = arrayType;
                                pm.pushParser(new TypeParser(arrayType::setElementType));
                                return;
                            }
                        case DyvilSymbols.ARROW_RIGHT:
                            {
                                if ((this.flags & IGNORE_LAMBDA) != 0) {
                                    pm.popParser(true);
                                    return;
                                }
                                final LambdaType lambdaType = new LambdaType(token.raw());
                                final TypeList arguments = lambdaType.getArguments();
                                if (this.parentType != null) {
                                    arguments.add(this.parentType);
                                }
                                pm.pushParser(this.subParser(arguments));
                                this.type = lambdaType;
                                this.mode = LAMBDA_END;
                                return;
                            }
                        case DyvilKeywords.NULL:
                            this.type = Types.NULL;
                            this.mode = END;
                            return;
                        case DyvilSymbols.UNDERSCORE:
                            this.type = new WildcardType(token.raw(), Variance.COVARIANT);
                            this.mode = END;
                            return;
                        case Tokens.SYMBOL_IDENTIFIER:
                            final Name name = token.nameValue();
                            final int closeAngleIndex;
                            if ((this.flags & CLOSE_ANGLE) == 0 || (closeAngleIndex = name.unqualified.indexOf('>')) < 0) {
                                // SYMBOL_IDENTIFIER type
                                final PrefixType prefixType = new PrefixType(token.raw(), name);
                                pm.pushParser(this.subParser(prefixType.getArguments()).withFlags(IGNORE_OPERATOR | IGNORE_LAMBDA));
                                this.type = prefixType;
                                this.mode = END;
                                return;
                            }
                            if (closeAngleIndex == 0) {
                                // Token starts with a >
                                // Handles Type< > gracefully
                                pm.popParser(true);
                                return;
                            }
                            // strip the trailing > and reparse the first part of the token
                            // Handles Type<_> gracefully
                            pm.splitReparse(token, closeAngleIndex);
                            return;
                    }
                }
                if (!Tokens.isIdentifier(type)) {
                    if (isTerminator(type)) {
                        pm.popParser(true);
                        return;
                    }
                    pm.report(Markers.syntaxError(token, "type.invalid", token.toString()));
                    return;
                }
                final Name name = token.nameValue();
                final IToken next = token.next();
                if (isGenericStart(next, next.type())) {
                    this.type = new NamedGenericType(token.raw(), this.parentType, name);
                    this.mode = GENERICS;
                    return;
                }
                this.type = new NamedType(token.raw(), name, this.parentType);
                this.mode = END;
                return;
            }
        case TUPLE_END:
            {
                if (type != BaseSymbols.CLOSE_PARENTHESIS) {
                    pm.reparse();
                    pm.report(token, "type.tuple.close_paren");
                }
                final IToken nextToken = token.next();
                if (nextToken.type() == DyvilSymbols.ARROW_RIGHT) {
                    final LambdaType lambdaType;
                    if (this.type instanceof LambdaType) {
                        lambdaType = (LambdaType) this.type;
                    } else {
                        lambdaType = new LambdaType(nextToken.raw(), ((TupleType) this.type).getArguments());
                        this.type = lambdaType;
                    }
                    lambdaType.setPosition(nextToken);
                    this.mode = LAMBDA_END;
                    pm.skip();
                    pm.pushParser(this.subParser(lambdaType.getArguments()));
                    return;
                }
                if (this.parentType != null) {
                    pm.report(nextToken, "type.tuple.lambda_arrow");
                }
                this.type.expandPosition(token);
                this.mode = END;
                return;
            }
        case LAMBDA_END:
            this.type.expandPosition(token.prev());
            this.consumer.setType(this.type);
            pm.popParser(true);
            return;
        case ARRAY_COLON:
            if (type == BaseSymbols.COLON) {
                final MapType mapType = new MapType(this.type.getMutability(), ((ArrayType) this.type).getElementType());
                this.type = mapType;
                this.mode = ARRAY_END;
                pm.pushParser(new TypeParser(mapType.getArguments()));
                return;
            }
        // Fallthrough
        case ARRAY_END:
            this.type.expandPosition(token);
            this.mode = END;
            if (type != BaseSymbols.CLOSE_SQUARE_BRACKET) {
                pm.reparse();
                pm.report(token, "type.array.close_bracket");
            }
            return;
        case GENERICS:
            if (isGenericStart(token, type)) {
                pm.splitJump(token, 1);
                pm.pushParser(new TypeListParser(((GenericType) this.type).getArguments(), true));
                this.mode = GENERICS_END;
                return;
            }
            return;
        case ANNOTATION_END:
            this.mode = END;
            pm.pushParser(this.subParser((ITyped) this.type), true);
            return;
        case GENERICS_END:
            this.mode = END;
            if (isGenericEnd(token, type)) {
                pm.splitJump(token, 1);
                return;
            }
            pm.report(token, "type.generic.close_angle");
        // Fallthrough
        case END:
            {
                switch(type) {
                    case BaseSymbols.DOT:
                        pm.pushParser(new TypeParser(this, this.type, this.flags));
                        return;
                    case BaseSymbols.OPEN_SQUARE_BRACKET:
                        {
                            final IToken next = token.next();
                            if (next.type() == BaseSymbols.CLOSE_SQUARE_BRACKET) {
                                this.type = new ArrayType(this.type);
                                pm.report(Markers.syntaxWarning(token.to(next), "type.array.java"));
                                pm.skip();
                                return;
                            }
                            break;
                        }
                    case Tokens.SYMBOL_IDENTIFIER:
                        {
                            if ((this.flags & NAMED_ONLY) != 0) {
                                break;
                            }
                            if ((this.flags & CLOSE_ANGLE) != 0) {
                                final String string = token.stringValue();
                                int index = string.indexOf('>');
                                if (index == 0) {
                                    // ... >
                                    pm.splitJump(token, 1);
                                    break;
                                } else if (index > 0) {
                                    // ... SYMBOL>
                                    pm.splitJump(token, index);
                                    this.type = new PostfixType(token.raw(), Name.fromUnqualified(string.substring(0, index)), this.type);
                                    return;
                                }
                            }
                            final IToken next = token.next();
                            final boolean leftNeighbor = token.prev().isNeighboring(token);
                            final boolean rightNeighbor = token.isNeighboring(next);
                            if (isTerminator(next.type()) || leftNeighbor && !rightNeighbor) {
                                // type_OPERATOR
                                this.type = new PostfixType(token.raw(), token.nameValue(), this.type);
                                // move stays END
                                return;
                            }
                            if (leftNeighbor != rightNeighbor || (this.flags & IGNORE_OPERATOR) != 0) {
                                // type end
                                break;
                            }
                            // Parse part of an infix operator
                            // type SYMBOL type
                            // type_SYMBOL_type
                            final InfixTypeChain chain;
                            if (this.type.typeTag() == IType.INFIX_CHAIN) {
                                chain = (InfixTypeChain) this.type;
                            } else {
                                chain = new InfixTypeChain();
                                chain.addOperand(this.type);
                                this.type = chain;
                            }
                            chain.addOperator(token.nameValue(), token.raw());
                            pm.pushParser(this.subParser(chain::addOperand).withFlags(IGNORE_OPERATOR));
                            return;
                        }
                    case DyvilSymbols.ARROW_RIGHT:
                        // all these flags have to be unset
                        if (this.parentType == null && (this.flags & (NAMED_ONLY | IGNORE_OPERATOR | IGNORE_LAMBDA)) == 0) {
                            final LambdaType lambdaType = new LambdaType(token.raw(), this.type);
                            this.type = lambdaType;
                            this.mode = LAMBDA_END;
                            pm.pushParser(this.subParser(lambdaType.getArguments()));
                            return;
                        }
                        break;
                }
                if (this.type != null) {
                    this.consumer.setType(this.type);
                }
                pm.popParser(true);
            }
    }
}
Also used : CodeAnnotation(dyvilx.tools.compiler.ast.attribute.annotation.CodeAnnotation) AnnotationParser(dyvilx.tools.compiler.parser.annotation.AnnotationParser) NamedType(dyvilx.tools.compiler.ast.type.raw.NamedType) ITyped(dyvilx.tools.compiler.ast.type.ITyped) Name(dyvil.lang.Name) IToken(dyvilx.tools.parsing.token.IToken) TypeList(dyvilx.tools.compiler.ast.type.TypeList) CodeAnnotation(dyvilx.tools.compiler.ast.attribute.annotation.CodeAnnotation) Annotation(dyvilx.tools.compiler.ast.attribute.annotation.Annotation)

Example 3 with NamedType

use of dyvilx.tools.compiler.ast.type.raw.NamedType in project Dyvil by Dyvil.

the class IType method readType.

static IType readType(DataInput dis) throws IOException {
    int tag = dis.readUnsignedByte();
    IType type;
    switch(tag) {
        case UNKNOWN:
            return Types.UNKNOWN;
        case NULL:
            return Types.NULL;
        case NONE:
            return Types.NONE;
        case ANY:
            return Types.ANY;
        case PRIMITIVE:
            return PrimitiveType.fromTypecode(dis.readByte());
        case CLASS:
            type = new ClassType();
            break;
        case PACKAGE:
            type = new PackageType();
            break;
        case GENERIC:
            type = new ClassGenericType();
            break;
        case TUPLE:
            type = new TupleType();
            break;
        case LAMBDA:
            type = new LambdaType();
            break;
        case ARRAY:
            type = new ArrayType();
            break;
        case MAP:
            type = new MapType();
            break;
        case OPTIONAL:
            type = new NullableType();
            break;
        case IMPLICIT_OPTIONAL:
            type = new ImplicitNullableType();
            break;
        case REFERENCE:
            type = new ReferenceType();
            break;
        case ANNOTATED:
            type = new AnnotatedType();
            break;
        case TYPE_VAR:
            type = new NamedType();
            break;
        case WILDCARD_TYPE:
            type = new WildcardType();
            break;
        case MISSING_TAG:
            return null;
        default:
            throw new Error("Cannot decode TypeTag " + tag);
    }
    type.read(dis);
    return type;
}
Also used : NamedType(dyvilx.tools.compiler.ast.type.raw.NamedType) ClassType(dyvilx.tools.compiler.ast.type.raw.ClassType) ReferenceType(dyvilx.tools.compiler.ast.reference.ReferenceType) PackageType(dyvilx.tools.compiler.ast.type.raw.PackageType) ClassGenericType(dyvilx.tools.compiler.ast.type.generic.ClassGenericType)

Example 4 with NamedType

use of dyvilx.tools.compiler.ast.type.raw.NamedType in project Dyvil by Dyvil.

the class ObjectSurrogate method resolve.

@Override
public Pattern resolve(MarkerList markers, IContext context) {
    if (this.type.typeTag() == IType.NAMED) {
        NamedType namedType = (NamedType) this.type;
        final Name name = namedType.getName();
        IType parent = namedType.getParent();
        if (parent != null) {
            parent = parent.resolveType(markers, context);
            namedType.setParent(parent);
            IDataMember dataMember = parent.resolveField(name);
            if (dataMember != null) {
                return new FieldPattern(this.position, dataMember).resolve(markers, context);
            }
        } else {
            IDataMember dataMember = context.resolveField(name);
            if (dataMember != null) {
                return new FieldPattern(this.position, dataMember).resolve(markers, context);
            }
        }
    }
    this.type = this.type.resolveType(markers, context);
    final IClass theClass = this.type.getTheClass();
    if (theClass != null && !theClass.hasModifier(Modifiers.OBJECT_CLASS)) {
        markers.add(Markers.semanticError(this.position, "pattern.object", theClass.getName()));
    }
    return this;
}
Also used : NamedType(dyvilx.tools.compiler.ast.type.raw.NamedType) IClass(dyvilx.tools.compiler.ast.classes.IClass) IDataMember(dyvilx.tools.compiler.ast.field.IDataMember) Name(dyvil.lang.Name) IType(dyvilx.tools.compiler.ast.type.IType)

Aggregations

NamedType (dyvilx.tools.compiler.ast.type.raw.NamedType)4 Name (dyvil.lang.Name)2 IType (dyvilx.tools.compiler.ast.type.IType)2 Annotation (dyvilx.tools.compiler.ast.attribute.annotation.Annotation)1 CodeAnnotation (dyvilx.tools.compiler.ast.attribute.annotation.CodeAnnotation)1 IClass (dyvilx.tools.compiler.ast.classes.IClass)1 IDataMember (dyvilx.tools.compiler.ast.field.IDataMember)1 ReferenceType (dyvilx.tools.compiler.ast.reference.ReferenceType)1 ITyped (dyvilx.tools.compiler.ast.type.ITyped)1 TypeList (dyvilx.tools.compiler.ast.type.TypeList)1 ClassGenericType (dyvilx.tools.compiler.ast.type.generic.ClassGenericType)1 ClassType (dyvilx.tools.compiler.ast.type.raw.ClassType)1 PackageType (dyvilx.tools.compiler.ast.type.raw.PackageType)1 AnnotationParser (dyvilx.tools.compiler.parser.annotation.AnnotationParser)1 IToken (dyvilx.tools.parsing.token.IToken)1