mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 838691 part 2. Add codegen support for calling a function to determine whether a property should be exposed in a WebIDL binding. r=peterv
This commit is contained in:
parent
5cee1946fc
commit
09220020af
@ -999,6 +999,27 @@ class CGClassHasInstanceHook(CGAbstractStaticMethod):
|
|||||||
def isChromeOnly(m):
|
def isChromeOnly(m):
|
||||||
return m.getExtendedAttribute("ChromeOnly")
|
return m.getExtendedAttribute("ChromeOnly")
|
||||||
|
|
||||||
|
class MemberCondition:
|
||||||
|
"""
|
||||||
|
An object representing the condition for a member to actually be
|
||||||
|
exposed. Either pref or func or both can be None. If not None,
|
||||||
|
they should be strings that have the pref name or function name.
|
||||||
|
"""
|
||||||
|
def __init__(self, pref, func):
|
||||||
|
assert pref is None or isinstance(pref, str)
|
||||||
|
assert func is None or isinstance(func, str)
|
||||||
|
self.pref = pref
|
||||||
|
if func is None:
|
||||||
|
self.func = "nullptr"
|
||||||
|
else:
|
||||||
|
self.func = "&" + func
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
return self.pref == other.pref and self.func == other.func
|
||||||
|
|
||||||
|
def __ne__(self, other):
|
||||||
|
return not self.__eq__(other)
|
||||||
|
|
||||||
class PropertyDefiner:
|
class PropertyDefiner:
|
||||||
"""
|
"""
|
||||||
A common superclass for defining things on prototype objects.
|
A common superclass for defining things on prototype objects.
|
||||||
@ -1042,17 +1063,24 @@ class PropertyDefiner:
|
|||||||
return str
|
return str
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getControllingPref(interfaceMember):
|
def getStringAttr(member, name):
|
||||||
prefName = interfaceMember.getExtendedAttribute("Pref")
|
attr = member.getExtendedAttribute(name)
|
||||||
if prefName is None:
|
if attr is None:
|
||||||
return None
|
return None
|
||||||
# It's a list of strings
|
# It's a list of strings
|
||||||
assert(len(prefName) is 1)
|
assert(len(attr) is 1)
|
||||||
assert(prefName[0] is not None)
|
assert(attr[0] is not None)
|
||||||
return prefName[0]
|
return attr[0]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def getControllingCondition(interfaceMember):
|
||||||
|
return MemberCondition(PropertyDefiner.getStringAttr(interfaceMember,
|
||||||
|
"Pref"),
|
||||||
|
PropertyDefiner.getStringAttr(interfaceMember,
|
||||||
|
"Func"))
|
||||||
|
|
||||||
def generatePrefableArray(self, array, name, specTemplate, specTerminator,
|
def generatePrefableArray(self, array, name, specTemplate, specTerminator,
|
||||||
specType, getPref, getDataTuple, doIdArrays):
|
specType, getCondition, getDataTuple, doIdArrays):
|
||||||
"""
|
"""
|
||||||
This method generates our various arrays.
|
This method generates our various arrays.
|
||||||
|
|
||||||
@ -1067,8 +1095,8 @@ class PropertyDefiner:
|
|||||||
|
|
||||||
specType is the actual typename of our spec
|
specType is the actual typename of our spec
|
||||||
|
|
||||||
getPref is a callback function that takes an array entry and returns
|
getCondition is a callback function that takes an array entry and
|
||||||
the corresponding pref value.
|
returns the corresponding MemberCondition.
|
||||||
|
|
||||||
getDataTuple is a callback function that takes an array entry and
|
getDataTuple is a callback function that takes an array entry and
|
||||||
returns a tuple suitable for substitution into specTemplate.
|
returns a tuple suitable for substitution into specTemplate.
|
||||||
@ -1081,34 +1109,35 @@ class PropertyDefiner:
|
|||||||
# pref control is added to members while still allowing us to define all
|
# pref control is added to members while still allowing us to define all
|
||||||
# the members in the smallest number of JSAPI calls.
|
# the members in the smallest number of JSAPI calls.
|
||||||
assert(len(array) is not 0)
|
assert(len(array) is not 0)
|
||||||
lastPref = getPref(array[0]) # So we won't put a specTerminator
|
lastCondition = getCondition(array[0]) # So we won't put a specTerminator
|
||||||
# at the very front of the list.
|
# at the very front of the list.
|
||||||
specs = []
|
specs = []
|
||||||
prefableSpecs = []
|
prefableSpecs = []
|
||||||
|
|
||||||
prefableTemplate = ' { true, nullptr, &%s[%d] }'
|
prefableTemplate = ' { true, %s, &%s[%d] }'
|
||||||
prefCacheTemplate = '&%s[%d].enabled'
|
prefCacheTemplate = '&%s[%d].enabled'
|
||||||
def switchToPref(props, pref):
|
def switchToCondition(props, condition):
|
||||||
# Remember the info about where our pref-controlled
|
# Remember the info about where our pref-controlled
|
||||||
# booleans live.
|
# booleans live.
|
||||||
if pref is not None:
|
if condition.pref is not None:
|
||||||
props.prefCacheData.append(
|
props.prefCacheData.append(
|
||||||
(pref, prefCacheTemplate % (name, len(prefableSpecs)))
|
(condition.pref,
|
||||||
|
prefCacheTemplate % (name, len(prefableSpecs)))
|
||||||
)
|
)
|
||||||
# Set up pointers to the new sets of specs inside prefableSpecs
|
# Set up pointers to the new sets of specs inside prefableSpecs
|
||||||
prefableSpecs.append(prefableTemplate %
|
prefableSpecs.append(prefableTemplate %
|
||||||
(name + "_specs", len(specs)))
|
(condition.func, name + "_specs", len(specs)))
|
||||||
|
|
||||||
switchToPref(self, lastPref)
|
switchToCondition(self, lastCondition)
|
||||||
|
|
||||||
for member in array:
|
for member in array:
|
||||||
curPref = getPref(member)
|
curCondition = getCondition(member)
|
||||||
if lastPref != curPref:
|
if lastCondition != curCondition:
|
||||||
# Terminate previous list
|
# Terminate previous list
|
||||||
specs.append(specTerminator)
|
specs.append(specTerminator)
|
||||||
# And switch to our new pref
|
# And switch to our new pref
|
||||||
switchToPref(self, curPref)
|
switchToCondition(self, curCondition)
|
||||||
lastPref = curPref
|
lastCondition = curCondition
|
||||||
# And the actual spec
|
# And the actual spec
|
||||||
specs.append(specTemplate % getDataTuple(member))
|
specs.append(specTemplate % getDataTuple(member))
|
||||||
specs.append(specTerminator)
|
specs.append(specTerminator)
|
||||||
@ -1162,7 +1191,7 @@ class MethodDefiner(PropertyDefiner):
|
|||||||
"methodInfo": not m.isStatic(),
|
"methodInfo": not m.isStatic(),
|
||||||
"length": methodLength(m),
|
"length": methodLength(m),
|
||||||
"flags": "JSPROP_ENUMERATE",
|
"flags": "JSPROP_ENUMERATE",
|
||||||
"pref": PropertyDefiner.getControllingPref(m) }
|
"condition": PropertyDefiner.getControllingCondition(m) }
|
||||||
if isChromeOnly(m):
|
if isChromeOnly(m):
|
||||||
self.chrome.append(method)
|
self.chrome.append(method)
|
||||||
else:
|
else:
|
||||||
@ -1175,7 +1204,7 @@ class MethodDefiner(PropertyDefiner):
|
|||||||
"nativeName": "JS_ArrayIterator",
|
"nativeName": "JS_ArrayIterator",
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"flags": "JSPROP_ENUMERATE",
|
"flags": "JSPROP_ENUMERATE",
|
||||||
"pref": None })
|
"condition": MemberCondition(None, None) })
|
||||||
|
|
||||||
if (not descriptor.interface.parent and not static and
|
if (not descriptor.interface.parent and not static and
|
||||||
descriptor.nativeOwnership == 'nsisupports' and
|
descriptor.nativeOwnership == 'nsisupports' and
|
||||||
@ -1184,7 +1213,7 @@ class MethodDefiner(PropertyDefiner):
|
|||||||
"methodInfo": False,
|
"methodInfo": False,
|
||||||
"length": 1,
|
"length": 1,
|
||||||
"flags": "0",
|
"flags": "0",
|
||||||
"pref": None })
|
"condition": MemberCondition(None, None) })
|
||||||
|
|
||||||
if not static:
|
if not static:
|
||||||
stringifier = descriptor.operations['Stringifier']
|
stringifier = descriptor.operations['Stringifier']
|
||||||
@ -1193,7 +1222,7 @@ class MethodDefiner(PropertyDefiner):
|
|||||||
"nativeName": stringifier.identifier.name,
|
"nativeName": stringifier.identifier.name,
|
||||||
"length": 0,
|
"length": 0,
|
||||||
"flags": "JSPROP_ENUMERATE",
|
"flags": "JSPROP_ENUMERATE",
|
||||||
"pref": PropertyDefiner.getControllingPref(stringifier) }
|
"condition": PropertyDefiner.getControllingCondition(stringifier) }
|
||||||
if isChromeOnly(stringifier):
|
if isChromeOnly(stringifier):
|
||||||
self.chrome.append(toStringDesc)
|
self.chrome.append(toStringDesc)
|
||||||
else:
|
else:
|
||||||
@ -1212,8 +1241,8 @@ class MethodDefiner(PropertyDefiner):
|
|||||||
if len(array) == 0:
|
if len(array) == 0:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def pref(m):
|
def condition(m):
|
||||||
return m["pref"]
|
return m["condition"]
|
||||||
|
|
||||||
def specData(m):
|
def specData(m):
|
||||||
accessor = m.get("nativeName", m["name"])
|
accessor = m.get("nativeName", m["name"])
|
||||||
@ -1229,7 +1258,7 @@ class MethodDefiner(PropertyDefiner):
|
|||||||
' JS_FNINFO("%s", %s, %s, %s, %s)',
|
' JS_FNINFO("%s", %s, %s, %s, %s)',
|
||||||
' JS_FS_END',
|
' JS_FS_END',
|
||||||
'JSFunctionSpec',
|
'JSFunctionSpec',
|
||||||
pref, specData, doIdArrays)
|
condition, specData, doIdArrays)
|
||||||
|
|
||||||
class AttrDefiner(PropertyDefiner):
|
class AttrDefiner(PropertyDefiner):
|
||||||
def __init__(self, descriptor, name, static, unforgeable=False):
|
def __init__(self, descriptor, name, static, unforgeable=False):
|
||||||
@ -1304,7 +1333,7 @@ class AttrDefiner(PropertyDefiner):
|
|||||||
' { "%s", 0, %s, %s, %s}',
|
' { "%s", 0, %s, %s, %s}',
|
||||||
' { 0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }',
|
' { 0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER }',
|
||||||
'JSPropertySpec',
|
'JSPropertySpec',
|
||||||
PropertyDefiner.getControllingPref, specData, doIdArrays)
|
PropertyDefiner.getControllingCondition, specData, doIdArrays)
|
||||||
|
|
||||||
class ConstDefiner(PropertyDefiner):
|
class ConstDefiner(PropertyDefiner):
|
||||||
"""
|
"""
|
||||||
@ -1330,7 +1359,7 @@ class ConstDefiner(PropertyDefiner):
|
|||||||
' { "%s", %s }',
|
' { "%s", %s }',
|
||||||
' { 0, JSVAL_VOID }',
|
' { 0, JSVAL_VOID }',
|
||||||
'ConstantSpec',
|
'ConstantSpec',
|
||||||
PropertyDefiner.getControllingPref, specData, doIdArrays)
|
PropertyDefiner.getControllingCondition, specData, doIdArrays)
|
||||||
|
|
||||||
class PropertyArrays():
|
class PropertyArrays():
|
||||||
def __init__(self, descriptor):
|
def __init__(self, descriptor):
|
||||||
|
Loading…
Reference in New Issue
Block a user