From e3e86c0c3ffb7c575351cda6bac46af73a22fe06 Mon Sep 17 00:00:00 2001 From: Dan Chao Date: Fri, 12 Jun 2026 15:25:51 -0700 Subject: [PATCH 1/2] Enforce that abstract members are implemented This adds a check that abstract members must be implemented. If any members lack an implementation, an error is thrown describing the missing members. Also: we have a bug in `pkl:base`; class `Set` does not implement all members of class `Collection`. --- .../java/org/pkl/core/runtime/VmClass.java | 97 +++++++++++++++++++ .../org/pkl/core/errorMessages.properties | 7 ++ .../input-helper/classes/AbstractModule.pkl | 3 + .../errors/abstractMethodNotImplemented1.pkl | 9 ++ .../errors/abstractMethodNotImplemented2.pkl | 9 ++ .../errors/abstractMethodNotImplemented3.pkl | 1 + .../errors/abstractMethodNotImplemented4.pkl | 10 ++ .../errors/abstractMethodNotImplemented1.err | 10 ++ .../errors/abstractMethodNotImplemented2.err | 12 +++ .../errors/abstractMethodNotImplemented3.err | 6 ++ .../errors/abstractMethodNotImplemented4.err | 10 ++ stdlib/base.pkl | 12 +++ 12 files changed, 186 insertions(+) create mode 100644 pkl-core/src/test/files/LanguageSnippetTests/input-helper/classes/AbstractModule.pkl create mode 100644 pkl-core/src/test/files/LanguageSnippetTests/input/errors/abstractMethodNotImplemented1.pkl create mode 100644 pkl-core/src/test/files/LanguageSnippetTests/input/errors/abstractMethodNotImplemented2.pkl create mode 100644 pkl-core/src/test/files/LanguageSnippetTests/input/errors/abstractMethodNotImplemented3.pkl create mode 100644 pkl-core/src/test/files/LanguageSnippetTests/input/errors/abstractMethodNotImplemented4.pkl create mode 100644 pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented1.err create mode 100644 pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented2.err create mode 100644 pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented3.err create mode 100644 pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented4.err diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmClass.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmClass.java index 68614aa86..ac7bb2c2a 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmClass.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmClass.java @@ -22,6 +22,7 @@ import com.oracle.truffle.api.frame.FrameDescriptor; import com.oracle.truffle.api.source.SourceSection; import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; import java.util.function.*; import org.graalvm.collections.*; import org.jspecify.annotations.Nullable; @@ -33,6 +34,7 @@ import org.pkl.core.ast.*; import org.pkl.core.ast.member.*; import org.pkl.core.ast.type.TypeNode; +import org.pkl.core.runtime.VmExceptionBuilder.MultilineValue; import org.pkl.core.util.CollectionUtils; import org.pkl.core.util.EconomicMaps; import org.pkl.core.util.LateInit; @@ -84,6 +86,13 @@ public final class VmClass extends VmValue { private final Object allHiddenPropertyNamesLock = new Object(); + @GuardedBy("finalizersLock") + private @Nullable List __finalizers = null; + + private final Object finalizersLock = new Object(); + + private final AtomicInteger uninitializedSuperclassCount = new AtomicInteger(0); + // Helps to overcome recursive initialization issues // between classes and annotations in pkl.base. @CompilationFinal private volatile boolean isInitialized; @@ -150,6 +159,56 @@ public void initSupertype(TypeNode supertypeNode, VmClass superclass) { prototype.lateInitParent(superclass.getPrototype()); } + @TruffleBoundary + private void checkAbstractMethods() { + if (this.isAbstract()) return; + // minimize allocations in the non-error case + if (!hasAbstractMethod()) return; + var abstractMethods = getAbstractMethods(); + if (abstractMethods.size() == 1) { + throw new VmExceptionBuilder() + .evalError( + "noImplementationForAbstractMethod", + getDisplayName(), + abstractMethods.get(0).getName().toString()) + .withSourceSection(getHeaderSection()) + .build(); + } + var methodList = new ArrayList(abstractMethods.size()); + for (var method : abstractMethods) { + methodList.add(method.getCallSignature()); + } + throw new VmExceptionBuilder() + .evalError( + "noImplementationForAbstractMethods", getDisplayName(), MultilineValue.of(methodList)) + .withSourceSection(getHeaderSection()) + .build(); + } + + private boolean hasAbstractMethod() { + var methodCursor = getAllMethods().getEntries(); + while (methodCursor.advance()) { + var method = methodCursor.getValue(); + if (method.isAbstract()) { + return true; + } + } + return false; + } + + private List getAbstractMethods() { + assert this.superclass != null; + var result = new ArrayList(); + var methodCursor = getAllMethods().getEntries(); + while (methodCursor.advance()) { + var method = methodCursor.getValue(); + if (method.isAbstract()) { + result.add(method); + } + } + return result; + } + @TruffleBoundary public void addProperty(ClassProperty property) { prototype.addProperty(property.getInitializer()); @@ -190,8 +249,46 @@ public void addMethods(Iterable methods) { } } + private void onInitialized(Runnable runnable) { + synchronized (finalizersLock) { + if (this.__finalizers == null) { + this.__finalizers = new ArrayList<>(); + } + this.__finalizers.add(runnable); + } + } + // Note: Superclasses may not have finished their initialization when this method is called. public void notifyInitialized() { + var sc = superclass; + var isAllInitialized = true; + var uninitializedCount = 0; + while (sc != null) { + if (!sc.isInitialized) { + sc.onInitialized( + () -> { + var count = uninitializedSuperclassCount.decrementAndGet(); + if (count == 0) { + checkAbstractMethods(); + } + }); + uninitializedCount++; + isAllInitialized = false; + } + sc = sc.superclass; + } + uninitializedSuperclassCount.set(uninitializedCount); + if (isAllInitialized) { + checkAbstractMethods(); + } + lock: + synchronized (finalizersLock) { + if (__finalizers == null) break lock; + for (var finalizer : __finalizers) { + finalizer.run(); + } + this.__finalizers = null; + } isInitialized = true; } diff --git a/pkl-core/src/main/resources/org/pkl/core/errorMessages.properties b/pkl-core/src/main/resources/org/pkl/core/errorMessages.properties index b1e52a977..f75b8fbbf 100644 --- a/pkl-core/src/main/resources/org/pkl/core/errorMessages.properties +++ b/pkl-core/src/main/resources/org/pkl/core/errorMessages.properties @@ -1208,3 +1208,10 @@ invalidReferenceTypeAnnotationWithConstraint=\ cannotInstallPackageWithNoCache=\ Cannot install package to module cache dir when module cache is disabled. + +noImplementationForAbstractMethod=\ +Class `{0}` should either be declared `abstract`, or should implement method `{1}`. + +noImplementationForAbstractMethods=\ +Class `{0}` should either be declared `abstract`, or implement the following methods:\n\ +{1} diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input-helper/classes/AbstractModule.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input-helper/classes/AbstractModule.pkl new file mode 100644 index 000000000..ab2e65b43 --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/input-helper/classes/AbstractModule.pkl @@ -0,0 +1,3 @@ +abstract module Foo + +abstract function bar(): Int diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input/errors/abstractMethodNotImplemented1.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/abstractMethodNotImplemented1.pkl new file mode 100644 index 000000000..4498fff19 --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/abstractMethodNotImplemented1.pkl @@ -0,0 +1,9 @@ +abstract class AbstractMethod { + abstract function foo(): Int +} + +class MyClass extends AbstractMethod { +} + +foo: MyClass + diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input/errors/abstractMethodNotImplemented2.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/abstractMethodNotImplemented2.pkl new file mode 100644 index 000000000..8a7dca4b5 --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/abstractMethodNotImplemented2.pkl @@ -0,0 +1,9 @@ +abstract class AbstractMethods { + abstract function foo(): Int + abstract function bar(): Int +} + +class MyClass extends AbstractMethods { +} + +foo: MyClass diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input/errors/abstractMethodNotImplemented3.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/abstractMethodNotImplemented3.pkl new file mode 100644 index 000000000..d84a1a6e3 --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/abstractMethodNotImplemented3.pkl @@ -0,0 +1 @@ +extends "../../input-helper/classes/AbstractModule.pkl" diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input/errors/abstractMethodNotImplemented4.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/abstractMethodNotImplemented4.pkl new file mode 100644 index 000000000..dd4b5f5ff --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/abstractMethodNotImplemented4.pkl @@ -0,0 +1,10 @@ +abstract class AbstractMethod { + abstract function foo(): Int +} + +abstract class AbstractIntermediate extends AbstractMethod + +class MyClass extends AbstractIntermediate { +} + +foo: MyClass diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented1.err b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented1.err new file mode 100644 index 000000000..401229353 --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented1.err @@ -0,0 +1,10 @@ +–– Pkl Error –– +Class `abstractMethodNotImplemented1#MyClass` should either be declared `abstract`, or should implement method `foo`. + +x | class MyClass extends AbstractMethod { + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +at abstractMethodNotImplemented1#MyClass (file:///$snippetsDir/input/errors/abstractMethodNotImplemented1.pkl) + +x | foo: MyClass + ^^^^^^^ +at abstractMethodNotImplemented1 (file:///$snippetsDir/input/errors/abstractMethodNotImplemented1.pkl) diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented2.err b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented2.err new file mode 100644 index 000000000..7d1312926 --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented2.err @@ -0,0 +1,12 @@ +–– Pkl Error –– +Class `abstractMethodNotImplemented2#MyClass` should either be declared `abstract`, or implement the following methods: +foo() +bar() + +x | class MyClass extends AbstractMethods { + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +at abstractMethodNotImplemented2#MyClass (file:///$snippetsDir/input/errors/abstractMethodNotImplemented2.pkl) + +x | foo: MyClass + ^^^^^^^ +at abstractMethodNotImplemented2 (file:///$snippetsDir/input/errors/abstractMethodNotImplemented2.pkl) diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented3.err b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented3.err new file mode 100644 index 000000000..76679da72 --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented3.err @@ -0,0 +1,6 @@ +–– Pkl Error –– +Class `abstractMethodNotImplemented3` should either be declared `abstract`, or should implement method `bar`. + +x | extends "../../input-helper/classes/AbstractModule.pkl" + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +at abstractMethodNotImplemented3 (file:///$snippetsDir/input/errors/abstractMethodNotImplemented3.pkl) diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented4.err b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented4.err new file mode 100644 index 000000000..bc7a0a916 --- /dev/null +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented4.err @@ -0,0 +1,10 @@ +–– Pkl Error –– +Class `abstractMethodNotImplemented4#MyClass` should either be declared `abstract`, or should implement method `foo`. + +x | class MyClass extends AbstractIntermediate { + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +at abstractMethodNotImplemented4#MyClass (file:///$snippetsDir/input/errors/abstractMethodNotImplemented4.pkl) + +xx | foo: MyClass + ^^^^^^^ +at abstractMethodNotImplemented4 (file:///$snippetsDir/input/errors/abstractMethodNotImplemented4.pkl) diff --git a/stdlib/base.pkl b/stdlib/base.pkl index ee3e94ef2..7cbc10093 100644 --- a/stdlib/base.pkl +++ b/stdlib/base.pkl @@ -3549,6 +3549,18 @@ external class Set extends Collection { /// The difference of this set and [other]. external function difference(other: Set): Set + + function indexOf(_): Int = throw("Set does not implement `indexOf`") + function indexOfOrNull(_): Int? = throw("Set does not implement `indexOfOrNull`") + + function lastIndexOf(_): Int = throw("Set does not implement `lastIndexOf`") + function lastIndexOfOrNull(_): Int? = throw("Set does not implement `lastIndexOfOrNull`") + + function findIndex(_): Int = throw("Set does not implement `findIndex`") + function findIndexOrNull(_): Int? = throw("Set does not implement `findIndexOrNull`") + + function findLastIndex(_): Int = throw("Set does not implement `findLastIndex`") + function findLastIndexOrNull(_): Int? = throw("Set does not implement `findLastIndexOrNull`") } /// Creates a map containing the given alternating [keysAndValues]. From 8caadbc3133426fb62a97c97aff040165dc78a07 Mon Sep 17 00:00:00 2001 From: Jen Basch Date: Fri, 31 Jul 2026 10:27:39 -0700 Subject: [PATCH 2/2] use VmLocalContext to track class init --- .../org/pkl/core/ast/member/ClassNode.java | 56 ++++++++++-------- .../java/org/pkl/core/runtime/VmClass.java | 59 ++++--------------- .../org/pkl/core/runtime/VmLocalContext.java | 30 ++++++++++ .../errors/abstractMethodNotImplemented1.pkl | 1 - .../errors/abstractMethodNotImplemented1.err | 4 -- .../errors/abstractMethodNotImplemented2.err | 4 -- .../errors/abstractMethodNotImplemented4.err | 4 -- stdlib/base.pkl | 12 ---- 8 files changed, 73 insertions(+), 97 deletions(-) diff --git a/pkl-core/src/main/java/org/pkl/core/ast/member/ClassNode.java b/pkl-core/src/main/java/org/pkl/core/ast/member/ClassNode.java index 79a6f4cb3..ed5e3989d 100644 --- a/pkl-core/src/main/java/org/pkl/core/ast/member/ClassNode.java +++ b/pkl-core/src/main/java/org/pkl/core/ast/member/ClassNode.java @@ -123,37 +123,45 @@ public VmClass executeGeneric(VirtualFrame frame) { typeParameters, prototype); - if (unresolvedSupertypeNode != null) { - var supertypeNode = unresolvedSupertypeNode.execute(frame); - var superclass = supertypeNode.getVmClass(); + var localContext = VmLanguage.get(this).localContext.get(); + localContext.beginClassInit(cachedClass); - checkSupertype(supertypeNode, superclass); - cachedClass.initSupertype(supertypeNode, superclass); - } + try { + if (unresolvedSupertypeNode != null) { + var supertypeNode = unresolvedSupertypeNode.execute(frame); + var superclass = supertypeNode.getVmClass(); - // The superclass resolved above may not itself have completed the below initializations yet. - // That's because these initializations may have indirectly or directly triggered - // resolution of this class, in which case the `resolveSuperclass()` call above - // will have returned the partially initialized `cachedClass` of the superclass. - // As a consequence, initializations that require a fully initialized class hierarchy - // are done lazily in VmClass rather than here. - // A fully initialized class hierarchy is only required for initialization of internal caches, - // which is guaranteed to succeed (no impact on eager vs. lazy error reporting) and easy to - // defer. + checkSupertype(supertypeNode, superclass); + cachedClass.initSupertype(supertypeNode, superclass); + } - VmUtils.evaluateAnnotations(frame, annotationNodes, annotations); + // The superclass resolved above may not itself have completed the below initializations yet. + // That's because these initializations may have indirectly or directly triggered + // resolution of this class, in which case the `resolveSuperclass()` call above + // will have returned the partially initialized `cachedClass` of the superclass. + // As a consequence, initializations that require a fully initialized class hierarchy + // are done lazily in VmClass rather than here. + // A fully initialized class hierarchy is only required for initialization of internal caches, + // which is guaranteed to succeed (no impact on eager vs. lazy error reporting) and easy to + // defer. - for (var node : unresolvedPropertyNodes) { - cachedClass.addProperty(node.execute(frame, cachedClass)); - } + VmUtils.evaluateAnnotations(frame, annotationNodes, annotations); - for (var node : unresolvedMethodNodes) { - cachedClass.addMethod(node.execute(frame, cachedClass)); - } + for (var node : unresolvedPropertyNodes) { + cachedClass.addProperty(node.execute(frame, cachedClass)); + } - cachedClass.notifyInitialized(); + for (var node : unresolvedMethodNodes) { + cachedClass.addMethod(node.execute(frame, cachedClass)); + } - return cachedClass; + cachedClass.onOwnClassInitialized(); + localContext.endClassInit(); + return cachedClass; + } catch (Throwable e) { + localContext.clearClassInitState(); + throw e; + } } private void checkSupertype(TypeNode supertypeNode, @Nullable VmClass superclass) { diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmClass.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmClass.java index ac7bb2c2a..a78d2b3d1 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmClass.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmClass.java @@ -22,7 +22,6 @@ import com.oracle.truffle.api.frame.FrameDescriptor; import com.oracle.truffle.api.source.SourceSection; import java.util.*; -import java.util.concurrent.atomic.AtomicInteger; import java.util.function.*; import org.graalvm.collections.*; import org.jspecify.annotations.Nullable; @@ -86,13 +85,6 @@ public final class VmClass extends VmValue { private final Object allHiddenPropertyNamesLock = new Object(); - @GuardedBy("finalizersLock") - private @Nullable List __finalizers = null; - - private final Object finalizersLock = new Object(); - - private final AtomicInteger uninitializedSuperclassCount = new AtomicInteger(0); - // Helps to overcome recursive initialization issues // between classes and annotations in pkl.base. @CompilationFinal private volatile boolean isInitialized; @@ -249,49 +241,20 @@ public void addMethods(Iterable methods) { } } - private void onInitialized(Runnable runnable) { - synchronized (finalizersLock) { - if (this.__finalizers == null) { - this.__finalizers = new ArrayList<>(); - } - this.__finalizers.add(runnable); - } - } - - // Note: Superclasses may not have finished their initialization when this method is called. - public void notifyInitialized() { - var sc = superclass; - var isAllInitialized = true; - var uninitializedCount = 0; - while (sc != null) { - if (!sc.isInitialized) { - sc.onInitialized( - () -> { - var count = uninitializedSuperclassCount.decrementAndGet(); - if (count == 0) { - checkAbstractMethods(); - } - }); - uninitializedCount++; - isAllInitialized = false; - } - sc = sc.superclass; - } - uninitializedSuperclassCount.set(uninitializedCount); - if (isAllInitialized) { - checkAbstractMethods(); - } - lock: - synchronized (finalizersLock) { - if (__finalizers == null) break lock; - for (var finalizer : __finalizers) { - finalizer.run(); - } - this.__finalizers = null; - } + /** + * Called when this class itself has been initialized. + * + *

Superclasses may not have been initialized yet. + */ + public void onOwnClassInitialized() { isInitialized = true; } + /** Called when the entire class hierarchy is completely initialized, including superclasses. */ + public void onFullyInitialized() { + checkAbstractMethods(); + } + public int getTypeParameterCount() { return typeParameters.size(); } diff --git a/pkl-core/src/main/java/org/pkl/core/runtime/VmLocalContext.java b/pkl-core/src/main/java/org/pkl/core/runtime/VmLocalContext.java index f3f799ce8..36c213277 100644 --- a/pkl-core/src/main/java/org/pkl/core/runtime/VmLocalContext.java +++ b/pkl-core/src/main/java/org/pkl/core/runtime/VmLocalContext.java @@ -15,6 +15,9 @@ */ package org.pkl.core.runtime; +import java.util.ArrayDeque; +import java.util.Deque; + /** A per-context thread-local value that can be used to influence execution. */ public class VmLocalContext { private boolean shouldEagerTypecheck = false; @@ -22,6 +25,12 @@ public class VmLocalContext { /** Whether we are currently inside a type test ({@code is} check). */ private boolean inTypeTest = false; + /** The number of classes currently being initialized. */ + private int classDepth = 0; + + /** The classes currently being initialized. */ + private final Deque pendingClasses = new ArrayDeque<>(); + /** * Number of active {@link VmValueTracker} instances. Used to determine if instrumentation is * already active. @@ -48,6 +57,27 @@ public boolean isInTypeTest() { return inTypeTest; } + public void beginClassInit(VmClass vmClass) { + classDepth++; + pendingClasses.add(vmClass); + } + + public void endClassInit() { + classDepth--; + if (classDepth > 0) { + return; + } + while (!pendingClasses.isEmpty()) { + var clazz = pendingClasses.pop(); + clazz.onFullyInitialized(); + } + } + + public void clearClassInitState() { + pendingClasses.clear(); + classDepth = 0; + } + public void enterTracker() { activeTrackerDepth++; instrumentationEverUsed = true; diff --git a/pkl-core/src/test/files/LanguageSnippetTests/input/errors/abstractMethodNotImplemented1.pkl b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/abstractMethodNotImplemented1.pkl index 4498fff19..7f8838864 100644 --- a/pkl-core/src/test/files/LanguageSnippetTests/input/errors/abstractMethodNotImplemented1.pkl +++ b/pkl-core/src/test/files/LanguageSnippetTests/input/errors/abstractMethodNotImplemented1.pkl @@ -6,4 +6,3 @@ class MyClass extends AbstractMethod { } foo: MyClass - diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented1.err b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented1.err index 401229353..f3cba3348 100644 --- a/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented1.err +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented1.err @@ -3,8 +3,4 @@ Class `abstractMethodNotImplemented1#MyClass` should either be declared `abstrac x | class MyClass extends AbstractMethod { ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -at abstractMethodNotImplemented1#MyClass (file:///$snippetsDir/input/errors/abstractMethodNotImplemented1.pkl) - -x | foo: MyClass - ^^^^^^^ at abstractMethodNotImplemented1 (file:///$snippetsDir/input/errors/abstractMethodNotImplemented1.pkl) diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented2.err b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented2.err index 7d1312926..2c6cd8b89 100644 --- a/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented2.err +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented2.err @@ -5,8 +5,4 @@ bar() x | class MyClass extends AbstractMethods { ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -at abstractMethodNotImplemented2#MyClass (file:///$snippetsDir/input/errors/abstractMethodNotImplemented2.pkl) - -x | foo: MyClass - ^^^^^^^ at abstractMethodNotImplemented2 (file:///$snippetsDir/input/errors/abstractMethodNotImplemented2.pkl) diff --git a/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented4.err b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented4.err index bc7a0a916..4a3b1ca53 100644 --- a/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented4.err +++ b/pkl-core/src/test/files/LanguageSnippetTests/output/errors/abstractMethodNotImplemented4.err @@ -3,8 +3,4 @@ Class `abstractMethodNotImplemented4#MyClass` should either be declared `abstrac x | class MyClass extends AbstractIntermediate { ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -at abstractMethodNotImplemented4#MyClass (file:///$snippetsDir/input/errors/abstractMethodNotImplemented4.pkl) - -xx | foo: MyClass - ^^^^^^^ at abstractMethodNotImplemented4 (file:///$snippetsDir/input/errors/abstractMethodNotImplemented4.pkl) diff --git a/stdlib/base.pkl b/stdlib/base.pkl index 7cbc10093..ee3e94ef2 100644 --- a/stdlib/base.pkl +++ b/stdlib/base.pkl @@ -3549,18 +3549,6 @@ external class Set extends Collection { /// The difference of this set and [other]. external function difference(other: Set): Set - - function indexOf(_): Int = throw("Set does not implement `indexOf`") - function indexOfOrNull(_): Int? = throw("Set does not implement `indexOfOrNull`") - - function lastIndexOf(_): Int = throw("Set does not implement `lastIndexOf`") - function lastIndexOfOrNull(_): Int? = throw("Set does not implement `lastIndexOfOrNull`") - - function findIndex(_): Int = throw("Set does not implement `findIndex`") - function findIndexOrNull(_): Int? = throw("Set does not implement `findIndexOrNull`") - - function findLastIndex(_): Int = throw("Set does not implement `findLastIndex`") - function findLastIndexOrNull(_): Int? = throw("Set does not implement `findLastIndexOrNull`") } /// Creates a map containing the given alternating [keysAndValues].