use of dyvilx.tools.parsing.marker.Marker in project Dyvil by Dyvil.
the class AbstractMethod method checkTypeVarsInferred.
private void checkTypeVarsInferred(MarkerList markers, SourcePosition position, GenericData genericData) {
if (this.typeParameters == null) {
return;
}
final int count = this.typeParameters.size();
genericData.lock(count);
for (int i = 0; i < count; i++) {
final ITypeParameter typeParameter = this.typeParameters.get(i);
final IType typeArgument = genericData.resolveType(typeParameter);
if (typeArgument == null || typeArgument instanceof CovariantTypeVarType) {
final IType inferredType = typeParameter.getUpperBound();
markers.add(Markers.semantic(position, "method.typevar.infer", this.name, typeParameter.getName(), inferredType));
genericData.addMapping(typeParameter, inferredType);
} else if (!typeParameter.isAssignableFrom(typeArgument, genericData)) {
final Marker marker = Markers.semanticError(position, "method.typevar.incompatible", this.name, typeParameter.getName());
marker.addInfo(Markers.getSemantic("type.generic.argument", typeArgument));
marker.addInfo(Markers.getSemantic("type_parameter.declaration", typeParameter));
markers.add(marker);
}
}
}
use of dyvilx.tools.parsing.marker.Marker in project Dyvil by Dyvil.
the class CodeMethod method checkOverrideMethods.
private void checkOverrideMethods(MarkerList markers) {
if (this.checkNoOverride(markers)) {
return;
}
final ITypeContext typeContext = this.enclosingClass.getThisType();
this.filterOverrides(markers, typeContext);
if (this.checkNoOverride(markers)) {
return;
}
if (!this.isOverride() && !this.attributes.hasFlag(Modifiers.GENERATED)) {
markers.add(Markers.semantic(this.position, "method.overrides", this.name));
}
final boolean thisTypeResolved = this.type.isResolved();
for (IMethod overrideMethod : this.overrideMethods) {
ModifierUtil.checkOverride(this, overrideMethod, markers);
if (!thisTypeResolved) {
continue;
}
final IType superReturnType = overrideMethod.getType().getConcreteType(typeContext);
if (// avoid extra error
superReturnType != this.type && superReturnType.isResolved() && !Types.isSuperType(superReturnType.asParameterType(), this.type)) {
final Marker marker = Markers.semanticError(this.position, "method.override.type.incompatible", this.name);
marker.addInfo(Markers.getSemantic("method.type", this.type));
marker.addInfo(Markers.getSemantic("method.override.type", superReturnType));
addOverrideInfo(typeContext, overrideMethod, marker);
markers.add(marker);
}
}
}
use of dyvilx.tools.parsing.marker.Marker in project Dyvil by Dyvil.
the class CodeMethod method filterOverride.
private boolean filterOverride(IMethod candidate, MarkerList markers, ITypeContext typeContext) {
final String candidateInternalName = candidate.getInternalName();
final boolean sameName = this.name == candidate.getName();
final boolean sameInternalName = this.getInternalName().equals(candidateInternalName);
if (// same name but different internal name
sameName && !sameInternalName) {
if (this.name.qualified.equals(this.internalName)) // no AutoMangled or BytecodeName annotation, otherwise the user probably knows what they are doing and
// doesn't need a warning
{
final Marker marker = Markers.semantic(this.position, "method.override.mangled_mismatch", this.name, candidateInternalName);
marker.addInfo(Markers.getSemantic("method.override.mangled_mismatch.info", candidateInternalName));
markers.add(marker);
}
return true;
}
if (!sameName && sameInternalName) {
final Marker marker = Markers.semanticError(this.position, "method.override.mangled_clash", this.name, candidate.getName(), candidateInternalName);
marker.addInfo(Markers.getSemantic("method.override.mangled_clash.info"));
// hard error so it doesn't matter if we remove or not - bytecode will never be generated
return true;
}
// sameName && sameInternalName should be true
final IClass enclosingClass = candidate.getEnclosingClass();
boolean errors = true;
for (IMethod method : this.overrideMethods) {
if (method != candidate && method.getEnclosingClass() == enclosingClass) {
// If this method overrides two methods from the same class, we do not produce any parameter label errors
errors = false;
}
}
final ParameterList params = candidate.getParameters();
for (int i = 0, count = params.size(); i < count; i++) {
final IParameter thisParam = this.parameters.get(i);
final Name thisName = thisParam.getLabel();
final Name otherName = params.get(i).getLabel();
if (thisName == otherName || thisName == null || otherName == null) {
// Parameter labels match
continue;
}
if (errors) {
final Marker marker = Markers.semantic(thisParam.getPosition(), "method.override.parameter_label", i + 1, thisName, otherName);
addOverrideInfo(typeContext, candidate, marker);
markers.add(marker);
}
// This method does not properly override the candidate
return true;
}
return false;
}
use of dyvilx.tools.parsing.marker.Marker in project Dyvil by Dyvil.
the class CodeMethod method resolveTypes.
@Override
public void resolveTypes(MarkerList markers, IContext context) {
if (this.thisType != null) {
// Resolve the explicit receiver type, but do not expose type parameters of this method
this.thisType = this.thisType.resolveType(markers, context);
// Check the self type for compatibility
final IType thisType = this.thisType;
final IClass thisClass = thisType.getTheClass();
if (!this.isStatic() && thisClass != null && thisClass != this.enclosingClass) {
final Marker marker = Markers.semanticError(thisType.getPosition(), "method.this_type.incompatible", this.getName());
marker.addInfo(Markers.getSemantic("method.this_type", thisType));
marker.addInfo(Markers.getSemantic("method.enclosing_class", this.enclosingClass.getFullName()));
markers.add(marker);
}
} else {
this.thisType = this.enclosingClass.getThisType();
}
context = context.push(this);
if (this.typeParameters != null) {
this.typeParameters.resolveTypes(markers, context);
}
// Return type has to be resolved after type parameters
super.resolveTypes(markers, context);
this.parameters.resolveTypes(markers, context);
if (this.parameters.isLastVariadic()) {
this.attributes.addFlag(Modifiers.ACC_VARARGS);
}
if (this.exceptions != null) {
this.exceptions.resolveTypes(markers, context);
}
if (this.value != null) {
this.value.resolveTypes(markers, context);
}
context.pop();
}
use of dyvilx.tools.parsing.marker.Marker in project Dyvil by Dyvil.
the class CodeParameter method check.
@Override
public void check(MarkerList markers, IContext context) {
super.check(markers, context);
if (this.value != null) {
this.value.check(markers, context);
}
if (Types.isVoid(this.type)) {
markers.add(Markers.semanticError(this.position, "parameter.type.void"));
}
if (this.isVarargs() && !this.type.canExtract(ArrayType.class) && this.type.getAnnotation(ArrayExpr.LazyFields.ARRAY_CONVERTIBLE) == null) {
final Marker marker = Markers.semanticError(this.type.getPosition(), "parameter.varargs.incompatible", this.name);
marker.addInfo(Markers.getSemantic("parameter.type", this.type));
markers.add(marker);
}
}
Aggregations