/** * Gets the {@code prototype} property of this function type. This is equivalent to {@code * (ObjectType) getPropertyType("prototype")}. */ public ObjectType getPrototype() { // lazy initialization of the prototype field if (prototypeSlot == null) { String refName = getReferenceName(); if (refName == null) { // Someone is trying to access the prototype of a structural function. // We don't want to give real properties to this prototype, because // then it would propagate to all structural functions. setPrototypeNoCheck(registry.getNativeObjectType(JSTypeNative.UNKNOWN_TYPE), null); } else { setPrototype( new PrototypeObjectType( registry, getReferenceName() + ".prototype", registry.getNativeObjectType(OBJECT_TYPE), isNativeObjectType(), null), null); } } return (ObjectType) prototypeSlot.getType(); }
void setPrototypeBasedOn(ObjectType baseType, Node propertyNode) { // This is a bit weird. We need to successfully handle these // two cases: // Foo.prototype = new Bar(); // and // Foo.prototype = {baz: 3}; // In the first case, we do not want new properties to get // added to Bar. In the second case, we do want new properties // to get added to the type of the anonymous object. // // We handle this by breaking it into two cases: // // In the first case, we create a new PrototypeObjectType and set // its implicit prototype to the type being assigned. This ensures // that Bar will not get any properties of Foo.prototype, but properties // later assigned to Bar will get inherited properly. // // In the second case, we just use the anonymous object as the prototype. if (baseType.hasReferenceName() || isNativeObjectType() || baseType.isFunctionPrototypeType()) { baseType = new PrototypeObjectType(registry, getReferenceName() + ".prototype", baseType); } setPrototype(baseType, propertyNode); }