mirror of
https://github.com/apple/pkl.git
synced 2026-04-22 08:18:32 +02:00
Fix default value for non-final module type (#1392)
This fixes an issue where the `module` type produces the wrong default value. Closes #1391
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
package org.pkl.core.ast;
|
package org.pkl.core.ast;
|
||||||
|
|
||||||
import com.oracle.truffle.api.frame.FrameDescriptor;
|
import com.oracle.truffle.api.frame.FrameDescriptor;
|
||||||
|
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||||
import com.oracle.truffle.api.source.SourceSection;
|
import com.oracle.truffle.api.source.SourceSection;
|
||||||
import org.pkl.core.ast.member.DefaultPropertyBodyNode;
|
import org.pkl.core.ast.member.DefaultPropertyBodyNode;
|
||||||
import org.pkl.core.runtime.VmExceptionBuilder;
|
import org.pkl.core.runtime.VmExceptionBuilder;
|
||||||
@@ -46,7 +47,8 @@ public abstract class MemberNode extends PklRootNode {
|
|||||||
return new VmExceptionBuilder().withSourceSection(getHeaderSection());
|
return new VmExceptionBuilder().withSourceSection(getHeaderSection());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUndefined() {
|
public boolean isUndefined(VirtualFrame frame) {
|
||||||
return bodyNode instanceof DefaultPropertyBodyNode propBodyNode && propBodyNode.isUndefined();
|
return bodyNode instanceof DefaultPropertyBodyNode propBodyNode
|
||||||
|
&& propBodyNode.isUndefined(frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -67,7 +67,7 @@ public final class InferParentWithinMethodNode extends ExpressionNode {
|
|||||||
|
|
||||||
var returnTypeDefaultValue =
|
var returnTypeDefaultValue =
|
||||||
returnTypeNode.createDefaultValue(
|
returnTypeNode.createDefaultValue(
|
||||||
language, method.getHeaderSection(), method.getQualifiedName());
|
frame, language, method.getHeaderSection(), method.getQualifiedName());
|
||||||
if (returnTypeDefaultValue != null) {
|
if (returnTypeDefaultValue != null) {
|
||||||
inferredParent = returnTypeDefaultValue;
|
inferredParent = returnTypeDefaultValue;
|
||||||
ownerNode = null;
|
ownerNode = null;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -75,7 +75,7 @@ public final class InferParentWithinObjectMethodNode extends ExpressionNode {
|
|||||||
|
|
||||||
Object defaultReturnTypeValue =
|
Object defaultReturnTypeValue =
|
||||||
returnTypeNode.createDefaultValue(
|
returnTypeNode.createDefaultValue(
|
||||||
language, member.getHeaderSection(), member.getQualifiedName());
|
frame, language, member.getHeaderSection(), member.getQualifiedName());
|
||||||
if (defaultReturnTypeValue != null) {
|
if (defaultReturnTypeValue != null) {
|
||||||
inferredParent = defaultReturnTypeValue;
|
inferredParent = defaultReturnTypeValue;
|
||||||
ownerNode = null;
|
ownerNode = null;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -18,6 +18,7 @@ package org.pkl.core.ast.expression.member;
|
|||||||
import com.oracle.truffle.api.CompilerDirectives;
|
import com.oracle.truffle.api.CompilerDirectives;
|
||||||
import com.oracle.truffle.api.dsl.NodeChild;
|
import com.oracle.truffle.api.dsl.NodeChild;
|
||||||
import com.oracle.truffle.api.dsl.Specialization;
|
import com.oracle.truffle.api.dsl.Specialization;
|
||||||
|
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||||
import com.oracle.truffle.api.source.SourceSection;
|
import com.oracle.truffle.api.source.SourceSection;
|
||||||
import org.pkl.core.ast.ExpressionNode;
|
import org.pkl.core.ast.ExpressionNode;
|
||||||
import org.pkl.core.runtime.*;
|
import org.pkl.core.runtime.*;
|
||||||
@@ -35,9 +36,9 @@ public abstract class InferParentWithinPropertyNode extends ExpressionNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Specialization(guards = "!owner.isPrototype()")
|
@Specialization(guards = "!owner.isPrototype()")
|
||||||
protected Object evalTypedObject(VmTyped owner) {
|
protected Object evalTypedObject(VirtualFrame frame, VmTyped owner) {
|
||||||
if (isLocalProperty) {
|
if (isLocalProperty) {
|
||||||
return getLocalPropertyDefaultValue(owner);
|
return getLocalPropertyDefaultValue(frame, owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -51,7 +52,7 @@ public abstract class InferParentWithinPropertyNode extends ExpressionNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Specialization(guards = "owner.isPrototype()")
|
@Specialization(guards = "owner.isPrototype()")
|
||||||
protected Object evalPrototype(VmTyped owner) {
|
protected Object evalPrototype(VirtualFrame frame, VmTyped owner) {
|
||||||
var property =
|
var property =
|
||||||
isLocalProperty
|
isLocalProperty
|
||||||
?
|
?
|
||||||
@@ -66,7 +67,7 @@ public abstract class InferParentWithinPropertyNode extends ExpressionNode {
|
|||||||
var typeNode = property.getTypeNode();
|
var typeNode = property.getTypeNode();
|
||||||
if (typeNode == null || typeNode.isUnknownType()) return VmDynamic.empty();
|
if (typeNode == null || typeNode.isUnknownType()) return VmDynamic.empty();
|
||||||
|
|
||||||
var result = typeNode.getDefaultValue();
|
var result = typeNode.getDefaultValue(frame);
|
||||||
if (result != null) return result;
|
if (result != null) return result;
|
||||||
|
|
||||||
// no default exists for this property type
|
// no default exists for this property type
|
||||||
@@ -76,18 +77,18 @@ public abstract class InferParentWithinPropertyNode extends ExpressionNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Specialization
|
@Specialization
|
||||||
protected Object eval(@SuppressWarnings("unused") VmDynamic owner) {
|
protected Object eval(VirtualFrame frame, @SuppressWarnings("unused") VmDynamic owner) {
|
||||||
if (isLocalProperty) {
|
if (isLocalProperty) {
|
||||||
return getLocalPropertyDefaultValue(owner);
|
return getLocalPropertyDefaultValue(frame, owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
return VmDynamic.empty();
|
return VmDynamic.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Specialization
|
@Specialization
|
||||||
protected Object eval(@SuppressWarnings("unused") VmListing owner) {
|
protected Object eval(VirtualFrame frame, @SuppressWarnings("unused") VmListing owner) {
|
||||||
if (isLocalProperty) {
|
if (isLocalProperty) {
|
||||||
return getLocalPropertyDefaultValue(owner);
|
return getLocalPropertyDefaultValue(frame, owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert ownPropertyName == Identifier.DEFAULT;
|
assert ownPropertyName == Identifier.DEFAULT;
|
||||||
@@ -96,9 +97,9 @@ public abstract class InferParentWithinPropertyNode extends ExpressionNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Specialization
|
@Specialization
|
||||||
protected Object eval(@SuppressWarnings("unused") VmMapping owner) {
|
protected Object eval(VirtualFrame frame, @SuppressWarnings("unused") VmMapping owner) {
|
||||||
if (isLocalProperty) {
|
if (isLocalProperty) {
|
||||||
return getLocalPropertyDefaultValue(owner);
|
return getLocalPropertyDefaultValue(frame, owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert ownPropertyName == Identifier.DEFAULT;
|
assert ownPropertyName == Identifier.DEFAULT;
|
||||||
@@ -106,13 +107,13 @@ public abstract class InferParentWithinPropertyNode extends ExpressionNode {
|
|||||||
return VmUtils.readMember(BaseModule.getMappingClass().getPrototype(), ownPropertyName);
|
return VmUtils.readMember(BaseModule.getMappingClass().getPrototype(), ownPropertyName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object getLocalPropertyDefaultValue(VmObjectLike owner) {
|
private Object getLocalPropertyDefaultValue(VirtualFrame frame, VmObjectLike owner) {
|
||||||
assert isLocalProperty;
|
assert isLocalProperty;
|
||||||
|
|
||||||
var member = owner.getMember(ownPropertyName);
|
var member = owner.getMember(ownPropertyName);
|
||||||
assert member != null;
|
assert member != null;
|
||||||
|
|
||||||
var defaultValue = member.getLocalPropertyDefaultValue();
|
var defaultValue = member.getLocalPropertyDefaultValue(frame);
|
||||||
if (defaultValue != null) return defaultValue;
|
if (defaultValue != null) return defaultValue;
|
||||||
|
|
||||||
// no default exists for this property type
|
// no default exists for this property type
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -38,14 +38,14 @@ public final class DefaultPropertyBodyNode extends ExpressionNode {
|
|||||||
this.typeNode = typeNode;
|
this.typeNode = typeNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUndefined() {
|
public boolean isUndefined(VirtualFrame frame) {
|
||||||
return typeNode == null || typeNode.getDefaultValue() == null;
|
return typeNode == null || typeNode.getDefaultValue(frame) == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object executeGeneric(VirtualFrame frame) {
|
public Object executeGeneric(VirtualFrame frame) {
|
||||||
if (typeNode != null) {
|
if (typeNode != null) {
|
||||||
var defaultValue = typeNode.getDefaultValue();
|
var defaultValue = typeNode.getDefaultValue(frame);
|
||||||
if (defaultValue != null) return defaultValue;
|
if (defaultValue != null) return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -45,11 +45,11 @@ public final class LocalTypedPropertyNode extends RegularMemberNode {
|
|||||||
this.unresolvedTypeNode = unresolvedTypeNode;
|
this.unresolvedTypeNode = unresolvedTypeNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable Object getDefaultValue() {
|
public @Nullable Object getDefaultValue(VirtualFrame frame) {
|
||||||
if (!defaultValueInitialized) {
|
if (!defaultValueInitialized) {
|
||||||
defaultValue =
|
defaultValue =
|
||||||
typeNode.createDefaultValue(
|
typeNode.createDefaultValue(
|
||||||
language, member.getHeaderSection(), member.getQualifiedName());
|
frame, language, member.getHeaderSection(), member.getQualifiedName());
|
||||||
defaultValueInitialized = true;
|
defaultValueInitialized = true;
|
||||||
}
|
}
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -17,6 +17,7 @@ package org.pkl.core.ast.member;
|
|||||||
|
|
||||||
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
|
import com.oracle.truffle.api.CompilerDirectives.CompilationFinal;
|
||||||
import com.oracle.truffle.api.RootCallTarget;
|
import com.oracle.truffle.api.RootCallTarget;
|
||||||
|
import com.oracle.truffle.api.frame.VirtualFrame;
|
||||||
import com.oracle.truffle.api.source.SourceSection;
|
import com.oracle.truffle.api.source.SourceSection;
|
||||||
import org.pkl.core.ast.ConstantNode;
|
import org.pkl.core.ast.ConstantNode;
|
||||||
import org.pkl.core.ast.MemberNode;
|
import org.pkl.core.ast.MemberNode;
|
||||||
@@ -102,14 +103,14 @@ public final class ObjectMember extends Member {
|
|||||||
return callTarget;
|
return callTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isUndefined() {
|
public boolean isUndefined(VirtualFrame frame) {
|
||||||
return getMemberNode() != null && getMemberNode().isUndefined();
|
return getMemberNode() != null && getMemberNode().isUndefined(frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable Object getLocalPropertyDefaultValue() {
|
public @Nullable Object getLocalPropertyDefaultValue(VirtualFrame frame) {
|
||||||
assert isProp() && isLocal();
|
assert isProp() && isLocal();
|
||||||
return getMemberNode() instanceof LocalTypedPropertyNode propertyNode
|
return getMemberNode() instanceof LocalTypedPropertyNode propertyNode
|
||||||
? propertyNode.getDefaultValue()
|
? propertyNode.getDefaultValue(frame)
|
||||||
: VmDynamic.empty();
|
: VmDynamic.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -64,11 +64,11 @@ public final class PropertyTypeNode extends PklRootNode {
|
|||||||
return typeNode.execute(frame, frame.getArguments()[2]);
|
return typeNode.execute(frame, frame.getArguments()[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public @Nullable Object getDefaultValue() {
|
public @Nullable Object getDefaultValue(VirtualFrame frame) {
|
||||||
if (!defaultValueInitialized) {
|
if (!defaultValueInitialized) {
|
||||||
defaultValue =
|
defaultValue =
|
||||||
typeNode.createDefaultValue(
|
typeNode.createDefaultValue(
|
||||||
VmLanguage.get(this), getSourceSection(), qualifiedPropertyName);
|
frame, VmLanguage.get(this), getSourceSection(), qualifiedPropertyName);
|
||||||
defaultValueInitialized = true;
|
defaultValueInitialized = true;
|
||||||
}
|
}
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2024 Apple Inc. and the Pkl project authors. All rights reserved.
|
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -26,6 +26,7 @@ import org.pkl.core.util.LateInit;
|
|||||||
/** Resolves `<type>` to the type's default value in `new <type> { ... }`. */
|
/** Resolves `<type>` to the type's default value in `new <type> { ... }`. */
|
||||||
public final class GetParentForTypeNode extends ExpressionNode {
|
public final class GetParentForTypeNode extends ExpressionNode {
|
||||||
@Child private UnresolvedTypeNode unresolvedTypeNode;
|
@Child private UnresolvedTypeNode unresolvedTypeNode;
|
||||||
|
@Child private TypeNode typeNode;
|
||||||
private final String qualifiedName;
|
private final String qualifiedName;
|
||||||
|
|
||||||
@CompilationFinal @LateInit Object defaultValue;
|
@CompilationFinal @LateInit Object defaultValue;
|
||||||
@@ -37,14 +38,24 @@ public final class GetParentForTypeNode extends ExpressionNode {
|
|||||||
this.qualifiedName = qualifiedName;
|
this.qualifiedName = qualifiedName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TypeNode getTypeNode(VirtualFrame frame) {
|
||||||
|
if (typeNode == null) {
|
||||||
|
CompilerDirectives.transferToInterpreterAndInvalidate();
|
||||||
|
typeNode = unresolvedTypeNode.execute(frame);
|
||||||
|
adoptChildren();
|
||||||
|
}
|
||||||
|
return typeNode;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object executeGeneric(VirtualFrame frame) {
|
public Object executeGeneric(VirtualFrame frame) {
|
||||||
if (defaultValue != null) return defaultValue;
|
if (defaultValue != null) return defaultValue;
|
||||||
|
|
||||||
CompilerDirectives.transferToInterpreterAndInvalidate();
|
CompilerDirectives.transferToInterpreterAndInvalidate();
|
||||||
|
|
||||||
var typeNode = unresolvedTypeNode.execute(frame);
|
var typeNode = getTypeNode(frame);
|
||||||
defaultValue = typeNode.createDefaultValue(VmLanguage.get(this), sourceSection, qualifiedName);
|
defaultValue =
|
||||||
|
typeNode.createDefaultValue(frame, VmLanguage.get(this), sourceSection, qualifiedName);
|
||||||
|
|
||||||
if (defaultValue != null) {
|
if (defaultValue != null) {
|
||||||
unresolvedTypeNode = null;
|
unresolvedTypeNode = null;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -116,6 +116,7 @@ public abstract class TypeNode extends PklNode {
|
|||||||
|
|
||||||
// method arguments are used when default value contains a root node
|
// method arguments are used when default value contains a root node
|
||||||
public @Nullable Object createDefaultValue(
|
public @Nullable Object createDefaultValue(
|
||||||
|
VirtualFrame frame,
|
||||||
VmLanguage language,
|
VmLanguage language,
|
||||||
// header section of the property or method that carries the type annotation
|
// header section of the property or method that carries the type annotation
|
||||||
SourceSection headerSection,
|
SourceSection headerSection,
|
||||||
@@ -473,6 +474,16 @@ public abstract class TypeNode extends PklNode {
|
|||||||
protected boolean acceptTypeNode(TypeNodeConsumer consumer) {
|
protected boolean acceptTypeNode(TypeNodeConsumer consumer) {
|
||||||
return consumer.accept(this);
|
return consumer.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable Object createDefaultValue(
|
||||||
|
VirtualFrame frame,
|
||||||
|
VmLanguage language,
|
||||||
|
SourceSection headerSection,
|
||||||
|
String qualifiedName) {
|
||||||
|
var moduleClass = ((VmTyped) getModuleNode.executeGeneric(frame)).getVmClass();
|
||||||
|
return TypeNode.createDefaultValue(moduleClass);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class StringLiteralTypeNode extends ObjectSlotTypeNode {
|
public static final class StringLiteralTypeNode extends ObjectSlotTypeNode {
|
||||||
@@ -504,7 +515,10 @@ public abstract class TypeNode extends PklNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object createDefaultValue(
|
public Object createDefaultValue(
|
||||||
VmLanguage language, SourceSection headerSection, String qualifiedName) {
|
VirtualFrame frame,
|
||||||
|
VmLanguage language,
|
||||||
|
SourceSection headerSection,
|
||||||
|
String qualifiedName) {
|
||||||
|
|
||||||
return literal;
|
return literal;
|
||||||
}
|
}
|
||||||
@@ -572,7 +586,10 @@ public abstract class TypeNode extends PklNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object createDefaultValue(
|
public Object createDefaultValue(
|
||||||
VmLanguage language, SourceSection headerSection, String qualifiedName) {
|
VirtualFrame frame,
|
||||||
|
VmLanguage language,
|
||||||
|
SourceSection headerSection,
|
||||||
|
String qualifiedName) {
|
||||||
|
|
||||||
return VmDynamic.empty();
|
return VmDynamic.empty();
|
||||||
}
|
}
|
||||||
@@ -622,7 +639,10 @@ public abstract class TypeNode extends PklNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable Object createDefaultValue(
|
public @Nullable Object createDefaultValue(
|
||||||
VmLanguage language, SourceSection headerSection, String qualifiedName) {
|
VirtualFrame frame,
|
||||||
|
VmLanguage language,
|
||||||
|
SourceSection headerSection,
|
||||||
|
String qualifiedName) {
|
||||||
|
|
||||||
return TypeNode.createDefaultValue(clazz);
|
return TypeNode.createDefaultValue(clazz);
|
||||||
}
|
}
|
||||||
@@ -691,7 +711,10 @@ public abstract class TypeNode extends PklNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable Object createDefaultValue(
|
public @Nullable Object createDefaultValue(
|
||||||
VmLanguage language, SourceSection headerSection, String qualifiedName) {
|
VirtualFrame frame,
|
||||||
|
VmLanguage language,
|
||||||
|
SourceSection headerSection,
|
||||||
|
String qualifiedName) {
|
||||||
|
|
||||||
return TypeNode.createDefaultValue(clazz);
|
return TypeNode.createDefaultValue(clazz);
|
||||||
}
|
}
|
||||||
@@ -734,10 +757,13 @@ public abstract class TypeNode extends PklNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable Object createDefaultValue(
|
public @Nullable Object createDefaultValue(
|
||||||
VmLanguage language, SourceSection headerSection, String qualifiedName) {
|
VirtualFrame frame,
|
||||||
|
VmLanguage language,
|
||||||
|
SourceSection headerSection,
|
||||||
|
String qualifiedName) {
|
||||||
|
|
||||||
return VmNull.withDefault(
|
return VmNull.withDefault(
|
||||||
elementTypeNode.createDefaultValue(language, headerSection, qualifiedName));
|
elementTypeNode.createDefaultValue(frame, language, headerSection, qualifiedName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -817,12 +843,15 @@ public abstract class TypeNode extends PklNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable Object createDefaultValue(
|
public @Nullable Object createDefaultValue(
|
||||||
VmLanguage language, SourceSection headerSection, String qualifiedName) {
|
VirtualFrame frame,
|
||||||
|
VmLanguage language,
|
||||||
|
SourceSection headerSection,
|
||||||
|
String qualifiedName) {
|
||||||
|
|
||||||
return defaultIndex == -1
|
return defaultIndex == -1
|
||||||
? null
|
? null
|
||||||
: elementTypeNodes[defaultIndex].createDefaultValue(
|
: elementTypeNodes[defaultIndex].createDefaultValue(
|
||||||
language, headerSection, qualifiedName);
|
frame, language, headerSection, qualifiedName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1021,9 +1050,11 @@ public abstract class TypeNode extends PklNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@TruffleBoundary
|
|
||||||
public @Nullable Object createDefaultValue(
|
public @Nullable Object createDefaultValue(
|
||||||
VmLanguage language, SourceSection headerSection, String qualifiedName) {
|
VirtualFrame frame,
|
||||||
|
VmLanguage language,
|
||||||
|
SourceSection headerSection,
|
||||||
|
String qualifiedName) {
|
||||||
|
|
||||||
return unionDefault;
|
return unionDefault;
|
||||||
}
|
}
|
||||||
@@ -1063,7 +1094,10 @@ public abstract class TypeNode extends PklNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object createDefaultValue(
|
public Object createDefaultValue(
|
||||||
VmLanguage language, SourceSection headerSection, String qualifiedName) {
|
VirtualFrame frame,
|
||||||
|
VmLanguage language,
|
||||||
|
SourceSection headerSection,
|
||||||
|
String qualifiedName) {
|
||||||
|
|
||||||
return VmList.EMPTY;
|
return VmList.EMPTY;
|
||||||
}
|
}
|
||||||
@@ -1152,7 +1186,10 @@ public abstract class TypeNode extends PklNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object createDefaultValue(
|
public Object createDefaultValue(
|
||||||
VmLanguage language, SourceSection headerSection, String qualifiedName) {
|
VirtualFrame frame,
|
||||||
|
VmLanguage language,
|
||||||
|
SourceSection headerSection,
|
||||||
|
String qualifiedName) {
|
||||||
|
|
||||||
return VmList.EMPTY;
|
return VmList.EMPTY;
|
||||||
}
|
}
|
||||||
@@ -1240,7 +1277,10 @@ public abstract class TypeNode extends PklNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final Object createDefaultValue(
|
public final Object createDefaultValue(
|
||||||
VmLanguage language, SourceSection headerSection, String qualifiedName) {
|
VirtualFrame frame,
|
||||||
|
VmLanguage language,
|
||||||
|
SourceSection headerSection,
|
||||||
|
String qualifiedName) {
|
||||||
|
|
||||||
return VmSet.EMPTY;
|
return VmSet.EMPTY;
|
||||||
}
|
}
|
||||||
@@ -1332,7 +1372,10 @@ public abstract class TypeNode extends PklNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object createDefaultValue(
|
public Object createDefaultValue(
|
||||||
VmLanguage language, SourceSection headerSection, String qualifiedName) {
|
VirtualFrame frame,
|
||||||
|
VmLanguage language,
|
||||||
|
SourceSection headerSection,
|
||||||
|
String qualifiedName) {
|
||||||
|
|
||||||
return VmMap.EMPTY;
|
return VmMap.EMPTY;
|
||||||
}
|
}
|
||||||
@@ -1586,45 +1629,48 @@ public abstract class TypeNode extends PklNode {
|
|||||||
return valueTypeCastNode;
|
return valueTypeCastNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
// either (if defaultMemberValue != null):
|
|
||||||
// x: Listing<Foo> // = new Listing {
|
|
||||||
// default = name -> new Foo {}
|
|
||||||
// }
|
|
||||||
// or (if defaultMemberValue == null):
|
|
||||||
// x: Listing<Int> // = new Listing {
|
|
||||||
// default = Undefined()
|
|
||||||
// }
|
|
||||||
@Override
|
|
||||||
@TruffleBoundary
|
@TruffleBoundary
|
||||||
public final Object createDefaultValue(
|
private Object newEmptyListingOrMapping() {
|
||||||
VmLanguage language, SourceSection headerSection, String qualifiedName) {
|
if (isListing()) {
|
||||||
|
return new VmListing(
|
||||||
if (valueTypeNode instanceof UnknownTypeNode) {
|
|
||||||
if (isListing()) {
|
|
||||||
return new VmListing(
|
|
||||||
VmUtils.createEmptyMaterializedFrame(),
|
|
||||||
BaseModule.getListingClass().getPrototype(),
|
|
||||||
EconomicMaps.create(),
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new VmMapping(
|
|
||||||
VmUtils.createEmptyMaterializedFrame(),
|
VmUtils.createEmptyMaterializedFrame(),
|
||||||
BaseModule.getMappingClass().getPrototype(),
|
BaseModule.getListingClass().getPrototype(),
|
||||||
EconomicMaps.create());
|
EconomicMaps.create(),
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return new VmMapping(
|
||||||
|
VmUtils.createEmptyMaterializedFrame(),
|
||||||
|
BaseModule.getMappingClass().getPrototype(),
|
||||||
|
EconomicMaps.create());
|
||||||
|
}
|
||||||
|
|
||||||
|
@TruffleBoundary
|
||||||
|
private Object newEmptyListingOrMapping(ObjectMember defaultMember) {
|
||||||
|
if (isListing()) {
|
||||||
|
return new VmListing(
|
||||||
|
VmUtils.createEmptyMaterializedFrame(),
|
||||||
|
BaseModule.getListingClass().getPrototype(),
|
||||||
|
EconomicMaps.of(Identifier.DEFAULT, defaultMember),
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new VmMapping(
|
||||||
|
VmUtils.createEmptyMaterializedFrame(),
|
||||||
|
BaseModule.getMappingClass().getPrototype(),
|
||||||
|
EconomicMaps.of(Identifier.DEFAULT, defaultMember));
|
||||||
|
}
|
||||||
|
|
||||||
|
@TruffleBoundary
|
||||||
|
private ObjectMember createDefaultMember(
|
||||||
|
SourceSection headerSection, String qualifiedName, @Nullable Object defaultMemberValue) {
|
||||||
var defaultMember =
|
var defaultMember =
|
||||||
new ObjectMember(
|
new ObjectMember(
|
||||||
headerSection,
|
headerSection,
|
||||||
headerSection,
|
headerSection,
|
||||||
VmModifier.HIDDEN,
|
VmModifier.HIDDEN,
|
||||||
Identifier.DEFAULT,
|
Identifier.DEFAULT,
|
||||||
qualifiedName + ".default");
|
VmUtils.concat(qualifiedName, ".default"));
|
||||||
|
|
||||||
var defaultMemberValue =
|
|
||||||
valueTypeNode.createDefaultValue(language, headerSection, qualifiedName);
|
|
||||||
|
|
||||||
if (defaultMemberValue == null) {
|
if (defaultMemberValue == null) {
|
||||||
defaultMember.initMemberNode(
|
defaultMember.initMemberNode(
|
||||||
new UntypedObjectMemberNode(
|
new UntypedObjectMemberNode(
|
||||||
@@ -1645,23 +1691,38 @@ public abstract class TypeNode extends PklNode {
|
|||||||
language,
|
language,
|
||||||
new FrameDescriptor(),
|
new FrameDescriptor(),
|
||||||
headerSection,
|
headerSection,
|
||||||
defaultMember.getQualifiedName() + ".<function>",
|
VmUtils.concat(defaultMember.getQualifiedName(), ".<function>"),
|
||||||
new ConstantValueNode(defaultMemberValue)),
|
new ConstantValueNode(defaultMemberValue)),
|
||||||
null));
|
null));
|
||||||
}
|
}
|
||||||
|
return defaultMember;
|
||||||
|
}
|
||||||
|
|
||||||
if (isListing()) {
|
// either (if defaultMemberValue != null):
|
||||||
return new VmListing(
|
// x: Listing<Foo> // = new Listing {
|
||||||
VmUtils.createEmptyMaterializedFrame(),
|
// default = name -> new Foo {}
|
||||||
BaseModule.getListingClass().getPrototype(),
|
// }
|
||||||
EconomicMaps.of(Identifier.DEFAULT, defaultMember),
|
// or (if defaultMemberValue == null):
|
||||||
0);
|
// x: Listing<Int> // = new Listing {
|
||||||
|
// default = Undefined()
|
||||||
|
// }
|
||||||
|
@Override
|
||||||
|
public final Object createDefaultValue(
|
||||||
|
VirtualFrame frame,
|
||||||
|
VmLanguage language,
|
||||||
|
SourceSection headerSection,
|
||||||
|
String qualifiedName) {
|
||||||
|
|
||||||
|
if (valueTypeNode instanceof UnknownTypeNode) {
|
||||||
|
return newEmptyListingOrMapping();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new VmMapping(
|
var defaultMemberValue =
|
||||||
VmUtils.createEmptyMaterializedFrame(),
|
valueTypeNode.createDefaultValue(frame, language, headerSection, qualifiedName);
|
||||||
BaseModule.getMappingClass().getPrototype(),
|
|
||||||
EconomicMaps.of(Identifier.DEFAULT, defaultMember));
|
var defaultMember = createDefaultMember(headerSection, qualifiedName, defaultMemberValue);
|
||||||
|
|
||||||
|
return newEmptyListingOrMapping(defaultMember);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void doEagerCheck(VirtualFrame frame, VmObject object) {
|
protected void doEagerCheck(VirtualFrame frame, VmObject object) {
|
||||||
@@ -2030,7 +2091,10 @@ public abstract class TypeNode extends PklNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable Object createDefaultValue(
|
public @Nullable Object createDefaultValue(
|
||||||
VmLanguage language, SourceSection headerSection, String qualifiedName) {
|
VirtualFrame frame,
|
||||||
|
VmLanguage language,
|
||||||
|
SourceSection headerSection,
|
||||||
|
String qualifiedName) {
|
||||||
|
|
||||||
CompilerDirectives.transferToInterpreter();
|
CompilerDirectives.transferToInterpreter();
|
||||||
throw exceptionBuilder()
|
throw exceptionBuilder()
|
||||||
@@ -2441,34 +2505,41 @@ public abstract class TypeNode extends PklNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@TruffleBoundary
|
@TruffleBoundary
|
||||||
|
private VmFunction newMixin(VmLanguage language, String qualifiedName) {
|
||||||
|
//noinspection ConstantConditions
|
||||||
|
return new VmFunction(
|
||||||
|
VmUtils.createEmptyMaterializedFrame(),
|
||||||
|
// Assumption: don't need to set the correct `thisValue`
|
||||||
|
// because it is guaranteed to be never accessed.
|
||||||
|
null,
|
||||||
|
1,
|
||||||
|
new IdentityMixinNode(
|
||||||
|
language,
|
||||||
|
new FrameDescriptor(),
|
||||||
|
getSourceSection(),
|
||||||
|
qualifiedName,
|
||||||
|
typeArgumentNodes.length == 1
|
||||||
|
?
|
||||||
|
// shouldn't need to deepCopy() this node because it isn't used as @Child
|
||||||
|
// anywhere else
|
||||||
|
typeArgumentNodes[0]
|
||||||
|
: null),
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public @Nullable Object createDefaultValue(
|
public @Nullable Object createDefaultValue(
|
||||||
VmLanguage language, SourceSection headerSection, String qualifiedName) {
|
VirtualFrame frame,
|
||||||
|
VmLanguage language,
|
||||||
|
SourceSection headerSection,
|
||||||
|
String qualifiedName) {
|
||||||
|
|
||||||
if (typeAlias == BaseModule.getMixinTypeAlias()) {
|
if (typeAlias == BaseModule.getMixinTypeAlias()) {
|
||||||
//noinspection ConstantConditions
|
return newMixin(language, qualifiedName);
|
||||||
return new VmFunction(
|
|
||||||
VmUtils.createEmptyMaterializedFrame(),
|
|
||||||
// Assumption: don't need to set the correct `thisValue`
|
|
||||||
// because it is guaranteed to be never accessed.
|
|
||||||
null,
|
|
||||||
1,
|
|
||||||
new IdentityMixinNode(
|
|
||||||
language,
|
|
||||||
new FrameDescriptor(),
|
|
||||||
getSourceSection(),
|
|
||||||
qualifiedName,
|
|
||||||
typeArgumentNodes.length == 1
|
|
||||||
?
|
|
||||||
// shouldn't need to deepCopy() this node because it isn't used as @Child
|
|
||||||
// anywhere else
|
|
||||||
typeArgumentNodes[0]
|
|
||||||
: null),
|
|
||||||
null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return aliasedTypeNode.createDefaultValue(language, headerSection, qualifiedName);
|
return aliasedTypeNode.createDefaultValue(frame, language, headerSection, qualifiedName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -2593,9 +2664,12 @@ public abstract class TypeNode extends PklNode {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable Object createDefaultValue(
|
public @Nullable Object createDefaultValue(
|
||||||
VmLanguage language, SourceSection headerSection, String qualifiedName) {
|
VirtualFrame frame,
|
||||||
|
VmLanguage language,
|
||||||
|
SourceSection headerSection,
|
||||||
|
String qualifiedName) {
|
||||||
|
|
||||||
return childNode.createDefaultValue(language, headerSection, qualifiedName);
|
return childNode.createDefaultValue(frame, language, headerSection, qualifiedName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SourceSection getBaseTypeSection() {
|
public SourceSection getBaseTypeSection() {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -184,7 +184,10 @@ public final class MirrorFactories {
|
|||||||
property ->
|
property ->
|
||||||
property.getProperty().isAbstract()
|
property.getProperty().isAbstract()
|
||||||
|| property.getProperty().isExternal()
|
|| property.getProperty().isExternal()
|
||||||
|| property.getProperty().getInitializer().isUndefined()
|
|| property
|
||||||
|
.getProperty()
|
||||||
|
.getInitializer()
|
||||||
|
.isUndefined(VmUtils.createEmptyMaterializedFrame())
|
||||||
? VmNull.withoutDefault()
|
? VmNull.withoutDefault()
|
||||||
:
|
:
|
||||||
// get default from prototype because it's cached there
|
// get default from prototype because it's cached there
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved.
|
* Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -909,4 +909,9 @@ public final class VmUtils {
|
|||||||
return frame.getArguments().length != 4
|
return frame.getArguments().length != 4
|
||||||
|| frame.getArguments()[3] != VmUtils.SKIP_TYPECHECK_MARKER;
|
|| frame.getArguments()[3] != VmUtils.SKIP_TYPECHECK_MARKER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TruffleBoundary
|
||||||
|
public static String concat(String str1, String str2) {
|
||||||
|
return str1 + str2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
20
pkl-core/src/test/files/LanguageSnippetTests/input/types/moduleType2.pkl
vendored
Normal file
20
pkl-core/src/test/files/LanguageSnippetTests/input/types/moduleType2.pkl
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
open module Foo
|
||||||
|
|
||||||
|
prop: String
|
||||||
|
|
||||||
|
myself: module?
|
||||||
|
|
||||||
|
class Bar extends module {
|
||||||
|
prop2: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
output {
|
||||||
|
value = new Bar {
|
||||||
|
prop = "hi"
|
||||||
|
prop2 = 15
|
||||||
|
myself {
|
||||||
|
prop = "hi again"
|
||||||
|
prop2 = 15
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
pkl-core/src/test/files/LanguageSnippetTests/output/types/moduleType2.pcf
vendored
Normal file
7
pkl-core/src/test/files/LanguageSnippetTests/output/types/moduleType2.pcf
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
prop = "hi"
|
||||||
|
myself {
|
||||||
|
prop = "hi again"
|
||||||
|
myself = null
|
||||||
|
prop2 = 15
|
||||||
|
}
|
||||||
|
prop2 = 15
|
||||||
Reference in New Issue
Block a user