mirror of
https://github.com/bendtherules/ask262.git
synced 2026-08-19 00:31:06 +00:00
Merge commit '6e92d2345e8231a44556ce7d416451f5f3e6c398' as 'engine262'
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
import { surroundingAgent } from '../host-defined/engine.mts';
|
||||
import {
|
||||
Value, NullValue, ObjectValue, type PropertyKeyValue, JSStringValue, BooleanValue,
|
||||
} from '../value.mts';
|
||||
import {
|
||||
StringValue,
|
||||
IsAnonymousFunctionDefinition,
|
||||
IsComputedPropertyKey,
|
||||
type FunctionDeclaration,
|
||||
} from '../static-semantics/all.mts';
|
||||
import { Evaluate, type PlainEvaluator, type ValueEvaluator } from '../evaluator.mts';
|
||||
import {
|
||||
Q, X,
|
||||
NormalCompletion,
|
||||
} from '../completion.mts';
|
||||
import { OutOfRange, kInternal } from '../helpers.mts';
|
||||
import type { ParseNode } from '../parser/ParseNode.mts';
|
||||
import { NamedEvaluation, MethodDefinitionEvaluation, Evaluate_PropertyName } from './all.mts';
|
||||
import {
|
||||
Assert,
|
||||
GetValue,
|
||||
CreateDataPropertyOrThrow,
|
||||
CopyDataProperties,
|
||||
DefineMethodProperty,
|
||||
} from '#self';
|
||||
|
||||
/** https://tc39.es/ecma262/#sec-object-initializer-runtime-semantics-propertydefinitionevaluation */
|
||||
// PropertyDefinitionList :
|
||||
// PropertyDefinitionList `,` PropertyDefinition
|
||||
export function* PropertyDefinitionEvaluation_PropertyDefinitionList(PropertyDefinitionList: ParseNode.PropertyDefinitionList, object: ObjectValue, enumerable: BooleanValue<true>): PlainEvaluator {
|
||||
for (const PropertyDefinition of PropertyDefinitionList) {
|
||||
Q(yield* PropertyDefinitionEvaluation_PropertyDefinition(PropertyDefinition, object, enumerable));
|
||||
}
|
||||
}
|
||||
|
||||
// PropertyDefinition :
|
||||
// `...` AssignmentExpression
|
||||
// IdentifierReference
|
||||
// PropertyName `:` AssignmentExpression
|
||||
function* PropertyDefinitionEvaluation_PropertyDefinition(PropertyDefinition: ParseNode.PropertyDefinitionLike, object: ObjectValue, enumerable: BooleanValue<true>) {
|
||||
switch (PropertyDefinition.type) {
|
||||
case 'IdentifierReference':
|
||||
return yield* PropertyDefinitionEvaluation_PropertyDefinition_IdentifierReference(PropertyDefinition, object, enumerable);
|
||||
case 'PropertyDefinition':
|
||||
break;
|
||||
case 'MethodDefinition':
|
||||
case 'GeneratorMethod':
|
||||
case 'AsyncMethod':
|
||||
case 'AsyncGeneratorMethod': {
|
||||
if (surroundingAgent.feature('decorators')) {
|
||||
const methodDefinition = Q(yield* MethodDefinitionEvaluation(PropertyDefinition, object));
|
||||
Q(yield* DefineMethodProperty(object, methodDefinition, true));
|
||||
return undefined;
|
||||
} else {
|
||||
return yield* MethodDefinitionEvaluation(PropertyDefinition, object, enumerable);
|
||||
}
|
||||
}
|
||||
default:
|
||||
throw new OutOfRange('PropertyDefinitionEvaluation_PropertyDefinition', PropertyDefinition);
|
||||
}
|
||||
// PropertyDefinition :
|
||||
// PropertyName `:` AssignmentExpression
|
||||
// `...` AssignmentExpression
|
||||
const { PropertyName, AssignmentExpression } = PropertyDefinition;
|
||||
if (!PropertyName) {
|
||||
// 1. Let exprValue be the result of evaluating AssignmentExpression.
|
||||
const exprValue = Q(yield* Evaluate(AssignmentExpression));
|
||||
// 2. Let fromValue be ? GetValue(exprValue).
|
||||
const fromValue = Q(yield* GetValue(exprValue));
|
||||
// 3. Let excludedNames be a new empty List.
|
||||
const excludedNames: PropertyKeyValue[] = [];
|
||||
// 4. Return ? CopyDataProperties(object, fromValue, excludedNames).
|
||||
return Q(yield* CopyDataProperties(object, fromValue, excludedNames));
|
||||
}
|
||||
// 1. Let propKey be the result of evaluating PropertyName.
|
||||
const propKey = Q(yield* Evaluate_PropertyName(PropertyName));
|
||||
// 3. If this PropertyDefinition is contained within a Script which is being evaluated for JSON.parse, then
|
||||
let isProtoSetter;
|
||||
if (surroundingAgent.runningExecutionContext?.HostDefined?.[kInternal]?.json) {
|
||||
isProtoSetter = false;
|
||||
} else if (!IsComputedPropertyKey(PropertyName) && (propKey as JSStringValue).stringValue() === '__proto__') { // 3. Else, If _propKey_ is the String value *"__proto__"* and if IsComputedPropertyKey(|PropertyName|) is *false*,
|
||||
// a. Let isProtoSetter be true.
|
||||
isProtoSetter = true;
|
||||
} else { // 4. Else,
|
||||
// a. Let isProtoSetter be false.
|
||||
isProtoSetter = false;
|
||||
}
|
||||
let propValue;
|
||||
// 5. If IsAnonymousFunctionDefinition(AssignmentExpression) is true and isProtoSetter is false, then
|
||||
if (IsAnonymousFunctionDefinition(AssignmentExpression) && !isProtoSetter) {
|
||||
// a. Let propValue be NamedEvaluation of AssignmentExpression with argument propKey.
|
||||
propValue = yield* NamedEvaluation(AssignmentExpression as FunctionDeclaration, propKey);
|
||||
} else { // 6. Else,
|
||||
// a. Let exprValueRef be the result of evaluating AssignmentExpression.
|
||||
const exprValueRef = Q(yield* Evaluate(AssignmentExpression));
|
||||
// b. Let propValue be ? GetValue(exprValueRef).
|
||||
propValue = Q(yield* GetValue(exprValueRef));
|
||||
}
|
||||
// 7. If isProtoSetter is true, then
|
||||
if (isProtoSetter) {
|
||||
// a. If Type(propValue) is either Object or Null, then
|
||||
if (propValue instanceof ObjectValue || propValue instanceof NullValue) {
|
||||
// i. Return object.[[SetPrototypeOf]](propValue).
|
||||
return yield* object.SetPrototypeOf(propValue);
|
||||
}
|
||||
// b. Return NormalCompletion(empty).
|
||||
return NormalCompletion(undefined);
|
||||
}
|
||||
// 8. Assert: enumerable is true.
|
||||
Assert(enumerable === Value.true);
|
||||
// 9. Assert: object is an ordinary, extensible object with no non-configurable properties.
|
||||
// 10. Return ! CreateDataPropertyOrThrow(object, propKey, propValue).
|
||||
return X(CreateDataPropertyOrThrow(object, propKey as PropertyKeyValue, X(propValue)));
|
||||
}
|
||||
|
||||
// PropertyDefinition : IdentifierReference
|
||||
function* PropertyDefinitionEvaluation_PropertyDefinition_IdentifierReference(IdentifierReference: ParseNode.IdentifierReference, object: ObjectValue, enumerable: BooleanValue<true>): ValueEvaluator {
|
||||
// 1. Let propName be StringValue of IdentifierReference.
|
||||
const propName = StringValue(IdentifierReference);
|
||||
// 2. Let exprValue be the result of evaluating IdentifierReference.
|
||||
const exprValue = Q(yield* Evaluate(IdentifierReference));
|
||||
// 3. Let propValue be ? GetValue(exprValue).
|
||||
const propValue = Q(yield* GetValue(exprValue));
|
||||
// 4. Assert: enumerable is true.
|
||||
Assert(enumerable === Value.true);
|
||||
// 5. Assert: object is an ordinary, extensible object with no non-configurable properties.
|
||||
// 6. Return ! CreateDataPropertyOrThrow(object, propName, propValue).
|
||||
return X(CreateDataPropertyOrThrow(object, propName, propValue));
|
||||
}
|
||||
Reference in New Issue
Block a user