/** * Copyright 2013 Douglas Campos, and individual contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.dynjs.parser.ast; import java.lang.invoke.CallSite; import java.util.ArrayList; import java.util.List; import org.dynjs.parser.CodeVisitor; import org.dynjs.parser.js.Position; import org.dynjs.runtime.*; import org.dynjs.runtime.builtins.types.BuiltinObject; import org.dynjs.runtime.linker.DynJSBootstrapper; public class ObjectLiteralExpression extends BaseExpression { private final List<PropertyAssignment> propertyAssignments; private final List<CallSite> assignmentGets; public ObjectLiteralExpression(Position position, final List<PropertyAssignment> propertyAssignments) { super(position); this.propertyAssignments = propertyAssignments; this.assignmentGets = new ArrayList<>(); for ( PropertyAssignment each : propertyAssignments ) { this.assignmentGets.add(DynJSBootstrapper.factory().createGet( each.getPosition() ) ); } } public List<PropertyAssignment> getPropertyAssignments() { return this.propertyAssignments; } public List<FunctionDeclaration> getFunctionDeclarations() { List<FunctionDeclaration> decls = new ArrayList<>(); for ( PropertyAssignment each : this.propertyAssignments ) { if ( each instanceof NamedValue ) { decls.addAll ( ((NamedValue) each).getExpr().getFunctionDeclarations() ); } } return decls; } @Override public Object interpret(ExecutionContext context, boolean debug) { DynObject obj = BuiltinObject.newObject(context); int numAssignments = this.propertyAssignments.size(); //for (PropertyAssignment each : assignments) { for ( int i = 0 ; i < numAssignments ; ++i ) { PropertyAssignment each = this.propertyAssignments.get(i); CallSite eachGet = assignmentGets.get(i); Object ref = each.interpret( context, debug ); String debugName = each.getName(); if (ref instanceof Reference) { debugName = ((Reference) ref).getReferencedName(); } Object value = getValue(eachGet, context, ref); Object original = obj.getOwnProperty(context, each.getName()); if (each.getName().equals("__proto__")) { obj.put(context, each.getName(), value, false); } else { PropertyDescriptor desc = null; if (each instanceof PropertyGet) { desc = PropertyDescriptor.newPropertyDescriptorForObjectInitializerGet(original, debugName, (JSFunction) value); } else if (each instanceof PropertySet) { desc = PropertyDescriptor.newPropertyDescriptorForObjectInitializerSet(original, debugName, (JSFunction) value); } else { desc = PropertyDescriptor.newPropertyDescriptorForObjectInitializer(debugName, value); } obj.defineOwnProperty(context, each.getName(), desc, false); } } return(obj); } public String toString() { StringBuilder buf = new StringBuilder(); buf.append("{ "); boolean first = true; for (PropertyAssignment each : this.propertyAssignments) { if (!first) { buf.append(", "); } first = false; buf.append(each.toString()); } buf.append(" }"); return buf.toString(); } public int getSizeMetric() { int size = 0; for ( PropertyAssignment each : this.propertyAssignments ) { size += each.getSizeMetric(); } return size + 5; } @Override public Object accept(Object context, CodeVisitor visitor, boolean strict) { return visitor.visit( context, this, strict ); } }