Implement Object.getOwnPropertyDescriptor
authorLars Knoll <lars.knoll@digia.com>
Tue, 11 Dec 2012 19:45:19 +0000 (20:45 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Tue, 11 Dec 2012 14:07:39 +0000 (15:07 +0100)
Change-Id: I800d3ebd93e41c7b0618e13ce8141d230b1bd58e
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
qv4ecmaobjects.cpp
qv4ecmaobjects_p.h

index 64c56bb..7932257 100644 (file)
@@ -586,8 +586,13 @@ Value ObjectPrototype::method_getPrototypeOf(ExecutionContext *ctx)
 
 Value ObjectPrototype::method_getOwnPropertyDescriptor(ExecutionContext *ctx)
 {
-    ctx->throwUnimplemented(QStringLiteral("Object.getOwnPropertyDescriptors"));
-    return Value::undefinedValue();
+    Value O = ctx->argument(0);
+    if (!O.isObject())
+        ctx->throwTypeError();
+
+    String *name = ctx->argument(1).toString(ctx);
+    PropertyDescriptor *desc = O.objectValue()->__getOwnProperty__(ctx, name);
+    return fromPropertyDescriptor(ctx, desc);
 }
 
 Value ObjectPrototype::method_getOwnPropertyNames(ExecutionContext *ctx)
@@ -929,6 +934,41 @@ void ObjectPrototype::toPropertyDescriptor(ExecutionContext *ctx, Value v, Prope
     }
 }
 
+
+Value ObjectPrototype::fromPropertyDescriptor(ExecutionContext *ctx, const PropertyDescriptor *desc)
+{
+    if (!desc)
+        return Value::undefinedValue();
+
+    ExecutionEngine *engine = ctx->engine;
+//    Let obj be the result of creating a new object as if by the expression new Object() where Object is the standard built-in constructor with that name.
+    Object *o = engine->newObject();
+
+    PropertyDescriptor pd;
+    pd.type = PropertyDescriptor::Data;
+    pd.writable = PropertyDescriptor::Set;
+    pd.enumberable = PropertyDescriptor::Set;
+    pd.configurable = PropertyDescriptor::Set;
+
+    if (desc->isData()) {
+        pd.value = desc->value;
+        o->__defineOwnProperty__(ctx, engine->identifier(QStringLiteral("value")), &pd);
+        pd.value = Value::fromBoolean(desc->writable == PropertyDescriptor::Set ? true : false);
+        o->__defineOwnProperty__(ctx, engine->identifier(QStringLiteral("writable")), &pd);
+    } else {
+        pd.value = desc->get ? Value::fromObject(desc->get) : Value::undefinedValue();
+        o->__defineOwnProperty__(ctx, engine->identifier(QStringLiteral("get")), &pd);
+        pd.value = desc->set ? Value::fromObject(desc->set) : Value::undefinedValue();
+        o->__defineOwnProperty__(ctx, engine->identifier(QStringLiteral("set")), &pd);
+    }
+    pd.value = Value::fromBoolean(desc->enumberable == PropertyDescriptor::Set ? true : false);
+    o->__defineOwnProperty__(ctx, engine->identifier(QStringLiteral("enumerable")), &pd);
+    pd.value = Value::fromBoolean(desc->configurable == PropertyDescriptor::Set ? true : false);
+    o->__defineOwnProperty__(ctx, engine->identifier(QStringLiteral("configurable")), &pd);
+
+    return Value::fromObject(o);
+}
+
 //
 // String
 //
index 5803633..e6ab1d7 100644 (file)
@@ -85,6 +85,7 @@ struct ObjectPrototype: Object
     static Value method_defineSetter(ExecutionContext *ctx);
 
     static void toPropertyDescriptor(ExecutionContext *ctx, Value v, PropertyDescriptor *desc);
+    static Value fromPropertyDescriptor(ExecutionContext *ctx, const PropertyDescriptor *desc);
 };
 
 struct StringCtor: FunctionObject