use of dyvilx.tools.compiler.ast.classes.ClassBody in project Dyvil by Dyvil.
the class EnumClassMetadata method createValuesArray.
private IValue createValuesArray() {
final ArrayExpr arrayExpr = new ArrayExpr();
arrayExpr.setElementType(this.theClass.getClassType());
final ClassBody body = this.theClass.getBody();
if (body != null) {
final ArgumentList values = arrayExpr.getValues();
for (IField enumConstant : body.enumConstants()) {
values.add(new FieldAccess(enumConstant));
}
}
return arrayExpr;
}
use of dyvilx.tools.compiler.ast.classes.ClassBody in project Dyvil by Dyvil.
the class InterfaceMetadata method getFunctionalMethod.
@Override
public IMethod getFunctionalMethod() {
if (this.functionalMethodSearched) {
return this.functionalMethod;
}
this.functionalMethodSearched = true;
final ClassBody body = this.theClass.getBody();
if (body == null) {
return null;
}
for (IMethod method : body.allMethods()) {
if (method.isFunctional()) {
if (this.functionalMethod != null) {
// duplicate detected
return this.functionalMethod = null;
}
this.functionalMethod = method;
}
}
return this.functionalMethod;
}
use of dyvilx.tools.compiler.ast.classes.ClassBody in project Dyvil by Dyvil.
the class ClassDeclarationParser method parse.
@Override
public void parse(IParserManager pm, IToken token) {
int type = token.type();
switch(this.mode) {
case NAME:
if (!Tokens.isIdentifier(type)) {
pm.report(token, "class.identifier");
return;
}
final Name name = token.nameValue();
if (name.qualified.indexOf('$') >= 0) {
pm.report(Markers.syntaxError(token, "class.identifier.invalid", name, name.qualified));
}
this.theClass = this.consumer.createClass(token.raw(), name, this.classAttributes);
this.mode = GENERICS;
return;
case GENERICS:
if (type == BaseSymbols.SEMICOLON && token.isInferred() && TypeParser.isGenericStart(token.next())) {
// allow an implicit semicolon / line break between name and generic argument list
return;
}
if (TypeParser.isGenericStart(token, type)) {
pm.splitJump(token, 1);
pm.pushParser(new TypeParameterListParser(this.theClass));
this.mode = GENERICS_END;
return;
}
// Fallthrough
case PARAMETERS:
final Modifier modifier = ModifierParser.parseModifier(token, pm);
if (modifier != null) {
this.theClass.getConstructorAttributes().add(modifier);
return;
}
if (type == DyvilSymbols.AT) {
final Annotation annotation = new CodeAnnotation(token.raw());
this.theClass.getConstructorAttributes().add(annotation);
pm.pushParser(new AnnotationParser(annotation));
return;
}
if (type == BaseSymbols.OPEN_PARENTHESIS) {
pm.pushParser(new ParameterListParser(this.theClass).withFlags(ParameterListParser.ALLOW_PROPERTIES));
this.mode = PARAMETERS_END;
return;
}
// Fallthrough
case EXTENDS:
if (type == DyvilKeywords.EXTENDS) {
if (this.theClass.isInterface()) {
pm.pushParser(new TypeListParser(this));
this.mode = BODY;
return;
}
pm.pushParser(new TypeParser(this));
this.mode = EXTENDS_PARAMETERS;
return;
}
// Fallthrough
case IMPLEMENTS:
if (type == DyvilKeywords.IMPLEMENTS) {
pm.pushParser(new TypeListParser(this));
this.mode = BODY;
if (this.theClass.isInterface()) {
pm.report(token, "class.interface.implements");
return;
}
return;
}
// Fallthrough
case BODY:
if (type == BaseSymbols.OPEN_CURLY_BRACKET) {
ClassBody body = new ClassBody(this.theClass);
this.theClass.setBody(body);
pm.pushParser(new ClassBodyParser(body), true);
this.mode = BODY_END;
return;
}
if (BaseSymbols.isTerminator(type)) {
if (token.isInferred()) {
switch(token.next().type()) {
case DyvilKeywords.EXTENDS:
this.mode = EXTENDS;
return;
case DyvilKeywords.IMPLEMENTS:
this.mode = IMPLEMENTS;
return;
case BaseSymbols.OPEN_SQUARE_BRACKET:
this.mode = GENERICS;
return;
case BaseSymbols.OPEN_PARENTHESIS:
this.mode = PARAMETERS;
return;
}
}
pm.popParser(true);
this.consumer.addClass(this.theClass);
return;
}
this.mode = BODY_END;
pm.report(token, "class.body.separator");
return;
case GENERICS_END:
this.mode = PARAMETERS;
if (TypeParser.isGenericEnd(token, type)) {
pm.splitJump(token, 1);
return;
}
pm.reparse();
pm.report(token, "generic.close_angle");
return;
case PARAMETERS_END:
this.mode = EXTENDS;
if (type != BaseSymbols.CLOSE_PARENTHESIS) {
pm.reparse();
pm.report(token, "class.parameters.close_paren");
}
return;
case BODY_END:
pm.popParser();
this.consumer.addClass(this.theClass);
if (type != BaseSymbols.CLOSE_CURLY_BRACKET) {
pm.reparse();
pm.report(token, "class.body.close_brace");
}
return;
case EXTENDS_PARAMETERS_END:
this.mode = IMPLEMENTS;
if (type != BaseSymbols.CLOSE_PARENTHESIS) {
pm.reparse();
pm.report(token, "class.extends.close_paren");
}
return;
case EXTENDS_PARAMETERS:
if (type == BaseSymbols.OPEN_PARENTHESIS) {
ArgumentListParser.parseArguments(pm, token.next(), this.theClass::setSuperConstructorArguments);
this.mode = EXTENDS_PARAMETERS_END;
return;
}
this.mode = IMPLEMENTS;
pm.reparse();
}
}
use of dyvilx.tools.compiler.ast.classes.ClassBody in project Dyvil by Dyvil.
the class ClassConstructorCall method toString.
@Override
public void toString(@NonNull String indent, @NonNull StringBuilder buffer) {
super.toString(indent, buffer);
ClassBody body = this.nestedClass.getBody();
if (body != null) {
body.toString(indent, buffer);
} else {
buffer.append(" {}");
}
}
use of dyvilx.tools.compiler.ast.classes.ClassBody in project Dyvil by Dyvil.
the class ExternalClass method visit.
public void visit(int access, String name, String signature, String superName, String[] interfaces) {
this.attributes = readModifiers(access);
this.internalName = name;
this.body = new ClassBody(this);
if (interfaces != null) {
this.interfaces = new TypeList(interfaces.length);
}
int index = name.lastIndexOf('$');
if (index == -1) {
index = name.lastIndexOf('/');
}
if (index == -1) {
this.name = Name.fromQualified(name);
this.thePackage = Package.rootPackage;
this.fullName = name;
} else {
this.name = Name.fromQualified(name.substring(index + 1));
// Do not set 'fullName' here
this.thePackage = Package.rootPackage.resolveInternalPackage(name.substring(0, index));
}
if (signature != null) {
ClassFormat.readClassSignature(signature, this);
} else {
this.superType = superName != null ? ClassFormat.internalToType(superName) : null;
if (interfaces != null) {
for (String internal : interfaces) {
this.interfaces.add(ClassFormat.internalToType(internal));
}
}
}
}
Aggregations