in base/src/main/java/org/arend/naming/resolving/visitor/DefinitionResolveNameVisitor.java [614:723]
public Void visitClass(Concrete.ClassDefinition def, Scope scope) {
if (def.getStage().ordinal() >= Concrete.Stage.RESOLVED.ordinal()) {
return null;
}
if (myResolverListener != null && myReportDefinitionBeforeResolve) {
myResolverListener.beforeDefinitionResolved(def);
}
scope = new PrivateFilteredScope(scope);
myLocalErrorReporter = new ConcreteProxyErrorReporter(def);
if (myResolveTypeClassReferences) {
if (def.getStage() == Concrete.Stage.NOT_RESOLVED) {
for (Concrete.ClassElement element : def.getElements()) {
if (element instanceof Concrete.ClassField) {
resolveTypeClassReference(((Concrete.ClassField) element).getParameters(), ((Concrete.ClassField) element).getResultType(), scope, true);
}
}
}
def.setTypeClassReferencesResolved();
return null;
}
checkNameAndPrecedence(def);
if (def.isRecord() && def.withoutClassifying()) {
myErrorReporter.report(new ParsingError(ParsingError.Kind.CLASSIFYING_FIELD_IN_RECORD, def));
}
List<Concrete.ClassField> classFields = new ArrayList<>();
for (Concrete.ClassElement element : def.getElements()) {
if (element instanceof Concrete.ClassField) {
classFields.add((Concrete.ClassField) element);
}
}
Map<String, TCReferable> fieldNames = new HashMap<>();
for (Concrete.ClassField field : classFields) {
TCReferable ref = field.getData();
TCReferable oldRef = fieldNames.putIfAbsent(ref.textRepresentation(), ref);
if (oldRef != null) {
myLocalErrorReporter.report(new DuplicateNameError(GeneralError.Level.ERROR, ref, oldRef));
}
}
resolveSuperClasses(def, scope, true);
List<Referable> context = new ArrayList<>();
ExpressionResolveNameVisitor exprVisitor = new ExpressionResolveNameVisitor(myReferableConverter, scope, context, myLocalErrorReporter, myResolverListener, visitLevelParameters(def.getPLevelParameters()), visitLevelParameters(def.getHLevelParameters()));
Concrete.Expression previousType = null;
for (int i = 0; i < classFields.size(); i++) {
Concrete.ClassField field = classFields.get(i);
checkNameAndPrecedence(field);
Concrete.Expression fieldType = field.getResultType();
if (fieldType == previousType && field.getParameters().isEmpty()) {
field.setResultType(classFields.get(i - 1).getResultType());
field.setResultTypeLevel(classFields.get(i - 1).getResultTypeLevel());
} else {
try (Utils.ContextSaver ignore = new Utils.ContextSaver(context)) {
previousType = field.getParameters().isEmpty() ? fieldType : null;
exprVisitor.visitParameters(field.getParameters(), null);
field.setResultType(fieldType.accept(exprVisitor, null));
if (field.getResultTypeLevel() != null) {
field.setResultTypeLevel(field.getResultTypeLevel().accept(exprVisitor, null));
}
}
}
}
for (Concrete.ClassElement element : def.getElements()) {
if (element instanceof Concrete.ClassFieldImpl) {
Referable ref = def.getData();
if (!(ref instanceof ClassReferable)) {
ref = ref.getUnderlyingReferable();
}
if (ref instanceof ClassReferable) {
exprVisitor.visitClassFieldImpl((Concrete.ClassFieldImpl) element, (ClassReferable) ref);
}
} else if (element instanceof Concrete.OverriddenField field) {
Referable ref = def.getData().getUnderlyingReferable();
if (!(ref instanceof ClassReferable)) {
ref = ref.getUnderlyingReferable();
}
if (ref instanceof ClassReferable) {
exprVisitor.visitClassFieldReference(field, field.getOverriddenField(), (ClassReferable) ref);
}
try (Utils.ContextSaver ignore = new Utils.ContextSaver(context)) {
exprVisitor.visitParameters(field.getParameters(), null);
field.setResultType(field.getResultType().accept(exprVisitor, null));
if (field.getResultTypeLevel() != null) {
field.setResultTypeLevel(field.getResultTypeLevel().accept(exprVisitor, null));
}
}
}
}
if ((def.isRecord() || def.withoutClassifying()) && def.isForcedClassifyingField()) {
myLocalErrorReporter.report(new ParsingError(def.isRecord() ? ParsingError.Kind.CLASSIFYING_FIELD_IN_RECORD : ParsingError.Kind.CLASSIFYING_IGNORED, def));
def.setClassifyingField(def.getClassifyingField(), false);
}
def.setResolved();
SyntacticDesugarVisitor.desugar(def, myLocalErrorReporter);
if (myResolverListener != null) {
myResolverListener.definitionResolved(def);
}
return null;
}