Revert "Reject abstract members in non-abstract classes" (#1688)

The changes made in this commit are good, but we're going to kick this out
to the next release.
This is because:

1. There's a couple more issues around the `abstract` modifier that is not
implemented yet, and need design considerations
2. These are breaking changes, and we want to minimize the amount of breakages
for users.
3. The main branch is still the develop branch for Pkl 0.32

We will apply a re-revert of this commit after Pkl 0.32 is released.
This commit is contained in:
Daniel Chao
2026-06-23 09:46:14 -07:00
committed by GitHub
parent 15f089b275
commit 1bf00b84ea
11 changed files with 3 additions and 70 deletions
@@ -1476,8 +1476,6 @@ public class AstBuilder extends AbstractAstBuilder<Object> {
var scope = (ModuleScope) symbolTable.getCurrentScope(); var scope = (ModuleScope) symbolTable.getCurrentScope();
scope.setModifiers(modifiers); scope.setModifiers(modifiers);
checkAbstractMembersAllowed(modifiers, mod.getProperties(), mod.getMethods());
// visit imports first so that we already have the object member name available // visit imports first so that we already have the object member name available
var imports = mod.getImports(); var imports = mod.getImports();
var importMembers = new ObjectMember[imports.size()]; var importMembers = new ObjectMember[imports.size()];
@@ -1722,7 +1720,6 @@ public class AstBuilder extends AbstractAstBuilder<Object> {
List<ClassProperty> properties = bodyNode != null ? bodyNode.getProperties() : List.of(); List<ClassProperty> properties = bodyNode != null ? bodyNode.getProperties() : List.of();
List<ClassMethod> methods = bodyNode != null ? bodyNode.getMethods() : List.of(); List<ClassMethod> methods = bodyNode != null ? bodyNode.getMethods() : List.of();
registerClassScopeNames(scope, properties, methods); registerClassScopeNames(scope, properties, methods);
checkAbstractMembersAllowed(modifiers, properties, methods);
var supertypeCtx = clazz.getSuperClass(); var supertypeCtx = clazz.getSuperClass();
@@ -1813,30 +1810,6 @@ public class AstBuilder extends AbstractAstBuilder<Object> {
}; };
} }
private void checkAbstractMembersAllowed(
int enclosingModifiers, List<ClassProperty> properties, List<ClassMethod> methods) {
if (VmModifier.isAbstract(enclosingModifiers)) {
return;
}
for (var property : properties) {
checkMemberNotAbstract(property.getModifiers());
}
for (var method : methods) {
checkMemberNotAbstract(method.getModifiers());
}
}
private void checkMemberNotAbstract(List<Modifier> modifiers) {
for (var modifier : modifiers) {
if (modifier.getValue() == ModifierValue.ABSTRACT) {
throw exceptionBuilder()
.evalError("abstractMemberInNonAbstractClass")
.withSourceSection(createSourceSection(modifier.span()))
.build();
}
}
}
private UnresolvedPropertyNode[] doVisitClassProperties( private UnresolvedPropertyNode[] doVisitClassProperties(
List<ClassProperty> propertyContexts, Set<String> propertyNames) { List<ClassProperty> propertyContexts, Set<String> propertyNames) {
var propertyNodes = new UnresolvedPropertyNode[propertyContexts.size()]; var propertyNodes = new UnresolvedPropertyNode[propertyContexts.size()];
@@ -286,11 +286,6 @@ External members cannot have a body.
abstractMemberCannotHaveBody=\ abstractMemberCannotHaveBody=\
Abstract members cannot have a body. Abstract members cannot have a body.
abstractMemberInNonAbstractClass=\
Cannot define an abstract member in a non-abstract class.\n\
\n\
A member can only be `abstract` if its enclosing class is also `abstract`.
methodNotDefined1=\ methodNotDefined1=\
Method `{0}` is not defined for argument type `{1}`. Method `{0}` is not defined for argument type `{1}`.
@@ -1,5 +0,0 @@
class Foo {
abstract bar: Int
}
res = new Foo { bar = 5 }
@@ -1 +0,0 @@
abstract foo: Int
@@ -1,5 +0,0 @@
class Foo {
abstract function bar(): Int
}
res = new Foo {}
@@ -1,8 +0,0 @@
–– Pkl Error ––
Cannot define an abstract member in a non-abstract class.
x | abstract bar: Int
^^^^^^^^
at abstractMemberInNonAbstractClass#Foo (file:///$snippetsDir/input/errors/abstractMemberInNonAbstractClass.pkl)
A member can only be `abstract` if its enclosing class is also `abstract`.
@@ -1,8 +0,0 @@
–– Pkl Error ––
Cannot define an abstract member in a non-abstract class.
x | abstract foo: Int
^^^^^^^^
at abstractMemberInNonAbstractModule (file:///$snippetsDir/input/errors/abstractMemberInNonAbstractModule.pkl)
A member can only be `abstract` if its enclosing class is also `abstract`.
@@ -1,8 +0,0 @@
–– Pkl Error ––
Cannot define an abstract member in a non-abstract class.
x | abstract function bar(): Int
^^^^^^^^
at abstractMethodInNonAbstractClass#Foo (file:///$snippetsDir/input/errors/abstractMethodInNonAbstractClass.pkl)
A member can only be `abstract` if its enclosing class is also `abstract`.
@@ -1,5 +1,5 @@
/// Module methods with different modifiers. /// Module methods with different modifiers.
abstract module com.package1.moduleMethodModifiers module com.package1.moduleMethodModifiers
/// Method with `abstract` modifier. /// Method with `abstract` modifier.
abstract function method1(arg: String): Boolean abstract function method1(arg: String): Boolean
@@ -32,7 +32,7 @@
</ul> </ul>
<div id="_overview" class="anchor"> </div> <div id="_overview" class="anchor"> </div>
<div id="_declaration" class="member"> <div id="_declaration" class="member">
<div class="member-signature">abstract module <span class="name-decl">com.package1.moduleMethodModifiers</span></div> <div class="member-signature">module <span class="name-decl">com.package1.moduleMethodModifiers</span></div>
<div class="doc-comment"><p>Module methods with different modifiers.</p></div> <div class="doc-comment"><p>Module methods with different modifiers.</p></div>
<dl class="member-info"> <dl class="member-info">
<dt class="">Module URI:</dt> <dt class="">Module URI:</dt>
@@ -32,7 +32,7 @@
</ul> </ul>
<div id="_overview" class="anchor"> </div> <div id="_overview" class="anchor"> </div>
<div id="_declaration" class="member"> <div id="_declaration" class="member">
<div class="member-signature">abstract module <span class="name-decl">com.package1.moduleMethodModifiers</span></div> <div class="member-signature">module <span class="name-decl">com.package1.moduleMethodModifiers</span></div>
<div class="doc-comment"><p>Module methods with different modifiers.</p></div> <div class="doc-comment"><p>Module methods with different modifiers.</p></div>
<dl class="member-info"> <dl class="member-info">
<dt class="">Module URI:</dt> <dt class="">Module URI:</dt>