use of dyvilx.tools.compiler.ast.parameter.IParameter in project Dyvil by Dyvil.
the class CaseClassMetadata method resolveTypesPre.
@Override
public void resolveTypesPre(MarkerList markers, IContext context) {
super.resolveTypesPre(markers, context);
for (IParameter param : this.theClass.getParameters()) {
final ClassParameter classParameter = (ClassParameter) param;
if (classParameter.isOverride() || classParameter.getProperty() != null) {
// Ignore override class parameters and class parameters that already have a property
continue;
}
// Create a property with getter
final IProperty property = classParameter.createProperty();
property.getAttributes().addFlag(Modifiers.GENERATED);
property.initGetter();
if (!classParameter.hasModifier(Modifiers.FINAL)) {
// and setter, for non-final class parameters
property.initSetter();
}
}
}
use of dyvilx.tools.compiler.ast.parameter.IParameter in project Dyvil by Dyvil.
the class SimpleMethodVisitor method visitParameterAnnotation.
@Override
public AnnotationVisitor visitParameterAnnotation(int parameter, String type, boolean visible) {
final IParameter param = this.method.getExternalParameterList().get(parameter);
if (ModifierUtil.DYVIL_MODIFIERS.equals(type)) {
return new ModifierVisitor(param.getAttributes());
}
final String internal = ClassFormat.extendedToInternal(type);
return param.visitAnnotation(internal);
}
use of dyvilx.tools.compiler.ast.parameter.IParameter in project Dyvil by Dyvil.
the class LambdaOrTupleParser method parse.
@Override
public void parse(IParserManager pm, IToken token) {
final int type = token.type();
switch(this.mode) {
case OPEN_PARENTHESIS:
// ( ...
// ^
/*
* The new version of this parser tries to find the matching closing parenthesis instead of try-parsing the
* expression. If it finds that parenthesis token and the next token is a lambda arrow, we can assume that
* the expression is a lambda expression. Thus, we directly push a Parameter List Parser that may also
* produce syntax errors.
*/
final IToken closeParen = BracketMatcher.findMatch(token);
if (closeParen != null) {
final IToken next = closeParen.next();
final int nextType = next.type();
if (nextType == DyvilSymbols.ARROW_RIGHT || nextType == DyvilSymbols.DOUBLE_ARROW_RIGHT) {
// ( ... ) =>
// ( ... ) ->
// token closeParen next
final LambdaExpr lambdaExpr = new LambdaExpr(next);
pm.pushParser(new ParameterListParser(lambdaExpr));
this.value = lambdaExpr;
this.mode = PARAMETERS_END;
return;
}
}
// Fallthrough
case TUPLE:
// ( ... )
final TupleLikeExpr tupleExpr = new TupleLikeExpr(token);
pm.pushParser(new ArgumentListParser(tupleExpr));
this.value = tupleExpr;
this.mode = TUPLE_END;
return;
case TUPLE_END:
this.value.expandPosition(token);
this.consumer.setValue(this.value);
pm.popParser();
if (type != BaseSymbols.CLOSE_PARENTHESIS) {
pm.reparse();
pm.report(token, "tuple.close_paren");
}
return;
case PARAMETERS_END:
this.mode = TYPE_ARROW;
if (type != BaseSymbols.CLOSE_PARENTHESIS) {
pm.reparse();
pm.report(token, "lambda.close_paren");
}
return;
case SINGLE_PARAMETER:
if (Tokens.isIdentifier(type)) {
final LambdaExpr lambdaExpr = new LambdaExpr(token.next());
final IParameter parameter = lambdaExpr.createParameter(token.raw(), token.nameValue(), Types.UNKNOWN, new AttributeList());
lambdaExpr.getParameters().add(parameter);
this.value = lambdaExpr;
this.mode = TYPE_ARROW;
return;
}
// Fallthrough
case TYPE_ARROW:
if (this.value == null) {
this.value = new LambdaExpr(token.raw());
}
if (type == DyvilSymbols.ARROW_RIGHT) {
pm.pushParser(returnTypeParser((LambdaExpr) this.value));
this.mode = RETURN_ARROW;
return;
}
// Fallthrough
case RETURN_ARROW:
pm.pushParser(new ExpressionParser(((LambdaExpr) this.value)));
this.mode = END;
if (type != DyvilSymbols.DOUBLE_ARROW_RIGHT) {
pm.reparse();
pm.report(token, "lambda.arrow");
}
return;
case END:
pm.popParser(true);
this.consumer.setValue(this.value);
}
}
use of dyvilx.tools.compiler.ast.parameter.IParameter in project Dyvil by Dyvil.
the class ExternalClass method resolveField.
@Override
public IDataMember resolveField(Name name) {
final IParameter parameter = this.resolveClassParameter(name);
if (parameter != null) {
return parameter;
}
// Own fields
IDataMember field = this.body.getField(name);
if (field != null) {
return field;
}
this.resolveSuperTypes();
// Inherited Fields
if (this.superType != null) {
field = this.superType.resolveField(name);
if (field != null) {
return field;
}
}
return null;
}
use of dyvilx.tools.compiler.ast.parameter.IParameter in project Dyvil by Dyvil.
the class AbstractMethod method checkArguments.
@Override
public IValue checkArguments(MarkerList markers, SourcePosition position, IContext context, IValue receiver, ArgumentList arguments, GenericData genericData) {
final ParameterList parameters = this.getParameters();
if (receiver != null) {
final int mod = this.attributes.flags() & Modifiers.INFIX;
if (mod == Modifiers.INFIX && !receiver.isClassAccess() && !parameters.isEmpty()) {
// infix or extension method, declaring class implicit
final IParameter parameter = parameters.get(0);
final IType paramType = parameter.getCovariantType();
updateReceiverType(receiver, genericData);
receiver = TypeChecker.convertValue(receiver, paramType, genericData, markers, context, TypeChecker.markerSupplier("method.access.infix_type", this.name));
updateReceiverType(receiver, genericData);
for (int i = 1, count = parameters.size(); i < count; i++) {
arguments.checkValue(i - 1, parameters.get(i), genericData, position, markers, context);
}
if (genericData != null) {
this.checkTypeVarsInferred(markers, position, genericData);
}
return receiver;
}
updateReceiverType(receiver, genericData);
if ((mod & Modifiers.STATIC) != 0) {
if (!receiver.isClassAccess()) {
// static method called like instance method -> warning
markers.add(Markers.semanticError(position, "method.access.static", this.name));
} else if (this.getReceiverType().getTheClass() == this.enclosingClass && receiver.getType().getTheClass() != this.enclosingClass) {
// static method called on wrong type -> warning
markers.add(Markers.semantic(position, "method.access.static.type", this.name, this.enclosingClass.getFullName()));
}
receiver = receiver.asIgnoredClassAccess();
} else if (receiver.isClassAccess()) {
if (!receiver.getType().getTheClass().isObject()) {
// declaring class is not an object class -> error
markers.add(Markers.semanticError(position, "method.access.instance", this.name));
}
} else {
// normal instance method access
receiver = TypeChecker.convertValue(receiver, this.getReceiverType(), receiver.getType(), markers, context, TypeChecker.markerSupplier("method.access.receiver_type", this.name));
}
if (receiver != null) {
updateReceiverType(receiver, genericData);
}
} else if (!this.isStatic()) {
if (!context.isThisAvailable()) {
// called from static context -> error
markers.add(Markers.semantic(position, "method.access.instance", this.name));
} else {
// unqualified call
final IType receiverType = this.enclosingClass.getThisType();
receiver = new ThisExpr(position, receiverType, markers, context);
if (genericData != null) {
genericData.setFallbackTypeContext(receiverType);
}
if (!this.isNested() && !this.enclosingClass.isAnonymous()) {
markers.add(Markers.semantic(position, "method.access.unqualified", this.name.unqualified));
}
}
}
for (int i = 0, count = parameters.size(); i < count; i++) {
arguments.checkValue(i, parameters.get(i), genericData, position, markers, context);
}
if (genericData != null) {
this.checkTypeVarsInferred(markers, position, genericData);
}
return receiver;
}
Aggregations