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;
}
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);
}
}
}
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;
}
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;
}
Aggregations