use of dyvilx.tools.compiler.ast.field.IProperty in project Dyvil by Dyvil.
the class ParameterListParser method parse.
@Override
public void parse(IParserManager pm, IToken token) {
final int type = token.type();
switch(this.mode) {
case DECLARATOR:
switch(type) {
case BaseSymbols.SEMICOLON:
if (token.isInferred()) {
return;
}
break;
case DyvilKeywords.LET:
this.attributes.addFlag(Modifiers.FINAL);
// Fallthrough
case DyvilKeywords.VAR:
this.mode = NAME;
return;
case DyvilKeywords.THIS:
if (token.next().type() != BaseSymbols.COLON) {
pm.report(token, "parameter.identifier");
this.mode = SEPARATOR;
return;
}
// this : TYPE
this.mode = TYPE_ASCRIPTION;
// the colon
pm.skip();
pm.pushParser(new TypeParser(t -> this.setThisType(t, token, pm)));
return;
case DyvilSymbols.AT:
final Annotation annotation = new CodeAnnotation(token.raw());
this.attributes.add(annotation);
pm.pushParser(new AnnotationParser(annotation));
return;
}
final Modifier modifier;
if ((modifier = ModifierParser.parseModifier(token, pm)) != null) {
this.attributes.add(modifier);
return;
}
if (BaseSymbols.isCloseBracket(type)) {
pm.popParser(true);
return;
}
// Fallthrough
case NAME:
final Name name;
if (Tokens.isIdentifier(type)) {
name = token.nameValue();
} else if (type == BaseSymbols.UNDERSCORE) {
name = null;
} else if (Tokens.isKeyword(type)) {
name = Name.fromRaw(token.stringValue());
} else {
if (BaseSymbols.isCloseBracket(type)) {
pm.popParser(true);
}
if (type == Tokens.EOF) {
pm.popParser();
}
this.mode = SEPARATOR;
pm.report(token, "parameter.identifier");
return;
}
this.parameter = this.consumer.createParameter(token.raw(), name, this.type, this.attributes);
this.mode = INTERNAL_NAME;
return;
case INTERNAL_NAME:
this.mode = VARARGS_AFTER_NAME;
// overwrite the internal name if necessary
if (Tokens.isIdentifier(type)) {
// IDENTIFIER IDENTIFIER : TYPE
this.parameter.setName(token.nameValue());
return;
} else if (type == BaseSymbols.UNDERSCORE) {
// IDENTIFIER _ : TYPE
this.parameter.setName(null);
return;
}
// Fallthrough
case VARARGS_AFTER_NAME:
if (type == DyvilSymbols.ELLIPSIS) {
this.flags |= VARARGS;
this.mode = TYPE_ASCRIPTION;
return;
}
// Fallthrough
case TYPE_ASCRIPTION:
case VARARGS_AFTER_POST_TYPE:
// continue with the remaining cases (DEFAULT_VALUE, PROPERTY, ...).
if (this.mode == VARARGS_AFTER_POST_TYPE) {
// case (2)
if (type == DyvilSymbols.ELLIPSIS) {
this.setTypeVarargs();
this.mode = DEFAULT_VALUE;
return;
}
} else /* case (1) */
if (type == BaseSymbols.COLON) {
this.mode = VARARGS_AFTER_POST_TYPE;
final TypeParser parser = new TypeParser(this);
if (this.hasFlag(LAMBDA_ARROW_END)) {
parser.withFlags(TypeParser.IGNORE_LAMBDA);
}
pm.pushParser(parser);
return;
}
// Fallthrough
case DEFAULT_VALUE:
if (type == BaseSymbols.EQUALS) {
this.mode = PROPERTY;
pm.pushParser(new ExpressionParser(this.parameter));
return;
}
// Fallthrough
case PROPERTY:
if (type == BaseSymbols.OPEN_CURLY_BRACKET && this.hasFlag(ALLOW_PROPERTIES)) {
final IProperty property = this.parameter.createProperty();
pm.pushParser(new PropertyBodyParser(property), true);
this.mode = SEPARATOR;
return;
}
// Fallthrough
case SEPARATOR:
this.mode = DECLARATOR;
if (this.parameter != null) {
if (this.hasFlag(VARARGS)) {
this.parameter.setVarargs();
}
this.parameter.setType(this.type);
this.consumer.getParameters().add(this.parameter);
}
this.reset();
switch(type) {
case DyvilSymbols.ARROW_RIGHT:
case DyvilSymbols.DOUBLE_ARROW_RIGHT:
if (!this.hasFlag(LAMBDA_ARROW_END)) {
// produce a syntax error
break;
}
// Fallthrough
case BaseSymbols.CLOSE_PARENTHESIS:
case BaseSymbols.CLOSE_CURLY_BRACKET:
case BaseSymbols.CLOSE_SQUARE_BRACKET:
pm.reparse();
// Fallthrough
case Tokens.EOF:
pm.popParser();
return;
case BaseSymbols.COMMA:
case BaseSymbols.SEMICOLON:
return;
}
pm.report(token, "parameter.separator");
}
}
use of dyvilx.tools.compiler.ast.field.IProperty in project Dyvil by Dyvil.
the class FieldParser method initProperty.
private IProperty initProperty() {
final IProperty prop;
if (this.dataMember == null) {
prop = this.consumer.createProperty(this.position, this.name, this.type, this.attributes);
this.property = prop;
} else {
prop = this.dataMember.createProperty();
}
return prop;
}
use of dyvilx.tools.compiler.ast.field.IProperty in project Dyvil by Dyvil.
the class ClassBody method addField.
public void addField(IField field) {
field.setEnclosingClass(this.enclosingClass);
final int index = this.fieldCount++;
if (index >= this.fields.length) {
IField[] temp = new IField[index * 2];
System.arraycopy(this.fields, 0, temp, 0, index);
this.fields = temp;
}
this.fields[index] = field;
final IProperty property = field.getProperty();
if (property != null) {
this.addToCache(property);
}
if (!(field instanceof EnumConstant)) {
return;
}
final EnumConstant enumConst = (EnumConstant) field;
// set enum constant index
for (int i = index - 1; i >= 0; i--) {
final IField fieldI = this.fields[i];
if (fieldI instanceof EnumConstant) {
enumConst.setIndex(((EnumConstant) fieldI).getIndex() + 1);
return;
}
}
enumConst.setIndex(0);
}
use of dyvilx.tools.compiler.ast.field.IProperty in project Dyvil by Dyvil.
the class ClassBody method allProperties.
public Iterable<IProperty> allProperties() {
final ArrayList.Builder<IProperty> builder = new ArrayList.Builder<>(this.propertyCount + this.fieldCount);
builder.addAll(this.properties());
for (int i = 0; i < this.fieldCount; i++) {
final IProperty property = this.fields[i].getProperty();
if (property != null) {
builder.add(property);
}
}
return builder.build();
}
use of dyvilx.tools.compiler.ast.field.IProperty in project Dyvil by Dyvil.
the class ClassBody method getMethodMatches.
public void getMethodMatches(MatchList<IMethod> list, IValue receiver, Name name, ArgumentList arguments) {
if (name == null) {
for (IMethod method : this.methods()) {
method.checkMatch(list, receiver, null, arguments);
}
for (IProperty property : this.allProperties()) {
property.checkMatch(list, receiver, null, arguments);
}
return;
}
final MethodLink[] cache = this.getNamedMethodCache();
if (cache.length == 0) {
// no methods
return;
}
final int hash = hash(name);
final int index = hash & (cache.length - 1);
for (MethodLink link = cache[index]; link != null; link = link.next) {
if (link.hash == hash) {
link.method.checkMatch(list, receiver, name, arguments);
}
}
return;
}
Aggregations