зеркало из https://github.com/mozilla/gecko-dev.git
Bug 882541 part 1. Don't require all arguments after an optional argument to be optional. r=khuey
This commit is contained in:
Родитель
11620341e6
Коммит
0b96fd507b
|
@ -3143,15 +3143,12 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
|||
|
||||
def finish(self, scope):
|
||||
for overload in self._overloads:
|
||||
inOptionalArguments = False
|
||||
variadicArgument = None
|
||||
|
||||
arguments = overload.arguments
|
||||
for (idx, argument) in enumerate(arguments):
|
||||
if argument.isComplete():
|
||||
continue
|
||||
|
||||
argument.complete(scope)
|
||||
if not argument.isComplete():
|
||||
argument.complete(scope)
|
||||
assert argument.type.isComplete()
|
||||
|
||||
if (argument.type.isDictionary() or
|
||||
|
@ -3161,7 +3158,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
|||
# end of the list or followed by optional arguments must be
|
||||
# optional.
|
||||
if (not argument.optional and
|
||||
(idx == len(arguments) - 1 or arguments[idx+1].optional)):
|
||||
all(arg.optional for arg in arguments[idx+1:])):
|
||||
raise WebIDLError("Dictionary argument or union "
|
||||
"argument containing a dictionary "
|
||||
"not followed by a required argument "
|
||||
|
@ -3179,13 +3176,6 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
|||
if variadicArgument:
|
||||
raise WebIDLError("Variadic argument is not last argument",
|
||||
[variadicArgument.location])
|
||||
# Once we see an optional argument, there can't be any non-optional
|
||||
# arguments.
|
||||
if inOptionalArguments and not argument.optional:
|
||||
raise WebIDLError("Non-optional argument after optional "
|
||||
"arguments",
|
||||
[argument.location])
|
||||
inOptionalArguments = argument.optional
|
||||
if argument.variadic:
|
||||
variadicArgument = argument
|
||||
|
||||
|
@ -3230,7 +3220,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
|
|||
return [overload for overload in self._overloads if
|
||||
len(overload.arguments) == argc or
|
||||
(len(overload.arguments) > argc and
|
||||
overload.arguments[argc].optional) or
|
||||
all(arg.optional for arg in overload.arguments[argc:])) or
|
||||
(len(overload.arguments) < argc and
|
||||
len(overload.arguments) > 0 and
|
||||
overload.arguments[-1].variadic)]
|
||||
|
@ -4060,21 +4050,6 @@ class Parser(Tokenizer):
|
|||
raise WebIDLError("stringifier must have DOMString return type",
|
||||
[self.getLocation(p, 2)])
|
||||
|
||||
inOptionalArguments = False
|
||||
variadicArgument = False
|
||||
for argument in arguments:
|
||||
# Only the last argument can be variadic
|
||||
if variadicArgument:
|
||||
raise WebIDLError("Only the last argument can be variadic",
|
||||
[variadicArgument.location])
|
||||
# Once we see an optional argument, there can't be any non-optional
|
||||
# arguments.
|
||||
if inOptionalArguments and not argument.optional:
|
||||
raise WebIDLError("Cannot have a non-optional argument following an optional argument",
|
||||
[argument.location])
|
||||
inOptionalArguments = argument.optional
|
||||
variadicArgument = argument if argument.variadic else None
|
||||
|
||||
# identifier might be None. This is only permitted for special methods.
|
||||
if not identifier:
|
||||
if not getter and not setter and not creator and \
|
||||
|
|
|
@ -171,6 +171,23 @@ def WebIDLTest(parser, harness):
|
|||
|
||||
harness.ok(threw, "Dictionary arg followed by optional arg must be optional")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
parser.parse("""
|
||||
dictionary A {
|
||||
};
|
||||
interface X {
|
||||
void doFoo(A arg1, optional long arg2, long arg3);
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(not threw,
|
||||
"Dictionary arg followed by non-optional arg doesn't have to be optional")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
|
|
|
@ -11,9 +11,9 @@ def WebIDLTest(parser, harness):
|
|||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw,
|
||||
"Should have thrown on non-optional argument following optional "
|
||||
"argument.")
|
||||
harness.ok(not threw,
|
||||
"Should not have thrown on non-optional argument following "
|
||||
"optional argument.")
|
||||
|
||||
parser = parser.reset()
|
||||
parser.parse("""
|
||||
|
|
|
@ -11,6 +11,8 @@ def WebIDLTest(parser, harness):
|
|||
void withVariadics(long... numbers);
|
||||
void withVariadics(TestOverloads iface);
|
||||
void withVariadics(long num, TestOverloads iface);
|
||||
void optionalTest();
|
||||
void optionalTest(optional long num1, long num2);
|
||||
};
|
||||
""")
|
||||
|
||||
|
@ -23,7 +25,7 @@ def WebIDLTest(parser, harness):
|
|||
"Should be an IDLInterface")
|
||||
harness.check(iface.identifier.QName(), "::TestOverloads", "Interface has the right QName")
|
||||
harness.check(iface.identifier.name, "TestOverloads", "Interface has the right name")
|
||||
harness.check(len(iface.members), 3, "Expect %s members" % 3)
|
||||
harness.check(len(iface.members), 4, "Expect %s members" % 4)
|
||||
|
||||
member = iface.members[0]
|
||||
harness.check(member.identifier.QName(), "::TestOverloads::basic", "Method has the right QName")
|
||||
|
@ -48,3 +50,11 @@ def WebIDLTest(parser, harness):
|
|||
harness.check(argument.identifier.QName(), "::TestOverloads::basic::arg1", "Argument has the right QName")
|
||||
harness.check(argument.identifier.name, "arg1", "Argument has the right name")
|
||||
harness.check(str(argument.type), "Long", "Argument has the right type")
|
||||
|
||||
member = iface.members[3]
|
||||
harness.check(len(member.overloadsForArgCount(0)), 1,
|
||||
"Only one overload for no args")
|
||||
harness.check(len(member.overloadsForArgCount(1)), 0,
|
||||
"No overloads for one arg")
|
||||
harness.check(len(member.overloadsForArgCount(2)), 1,
|
||||
"Only one overload for two args")
|
||||
|
|
|
@ -1,51 +1,62 @@
|
|||
def WebIDLTest(parser, harness):
|
||||
threw = False
|
||||
try:
|
||||
results = parser.parse("""
|
||||
parser.parse("""
|
||||
interface VariadicConstraints1 {
|
||||
void foo(byte... arg1, byte arg2);
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown.")
|
||||
harness.ok(threw,
|
||||
"Should have thrown on variadic argument followed by required "
|
||||
"argument.")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
results = parser.parse("""
|
||||
parser.parse("""
|
||||
interface VariadicConstraints2 {
|
||||
void foo(byte... arg1, optional byte arg2);
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish();
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown.")
|
||||
harness.ok(threw,
|
||||
"Should have thrown on variadic argument followed by optional "
|
||||
"argument.")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
results = parser.parse("""
|
||||
parser.parse("""
|
||||
interface VariadicConstraints3 {
|
||||
void foo(optional byte... arg1);
|
||||
};
|
||||
""")
|
||||
results = parser.finish()
|
||||
|
||||
except:
|
||||
threw = True
|
||||
|
||||
harness.ok(threw, "Should have thrown.")
|
||||
harness.ok(threw,
|
||||
"Should have thrown on variadic argument explicitly flagged as "
|
||||
"optional.")
|
||||
|
||||
parser = parser.reset()
|
||||
threw = False
|
||||
try:
|
||||
results = parser.parse("""
|
||||
parser.parse("""
|
||||
interface VariadicConstraints4 {
|
||||
void foo(byte... arg1 = 0);
|
||||
};
|
||||
""")
|
||||
|
||||
results = parser.finish()
|
||||
except:
|
||||
threw = True
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче