Bug 882541 part 1. Don't require all arguments after an optional argument to be optional. r=khuey

This commit is contained in:
Boris Zbarsky 2013-10-11 12:28:23 -04:00
Родитель 11620341e6
Коммит 0b96fd507b
5 изменённых файлов: 55 добавлений и 42 удалений

Просмотреть файл

@ -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