Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(49)

Unified Diff: tools/dom/scripts/htmldartgenerator.py

Issue 12052076: Support overloaded constructors. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tools/dom/scripts/htmldartgenerator.py
diff --git a/tools/dom/scripts/htmldartgenerator.py b/tools/dom/scripts/htmldartgenerator.py
index 6ff883a36ccef94753b5662612295d618e00d012..71ebd2449a5f08f839cea42dcdb96e6a306344ef 100644
--- a/tools/dom/scripts/htmldartgenerator.py
+++ b/tools/dom/scripts/htmldartgenerator.py
@@ -6,6 +6,7 @@
"""This module provides shared functionality for the system to generate
dart:html APIs from the IDL database."""
+import emitter
from generator import AnalyzeOperation, ConstantOutputOrder, \
DartDomNameOfAttribute, FindMatchingAttribute, IsDartCollectionType, \
IsPureInterface, TypeOrNothing, FindCommonAnnotations
@@ -176,8 +177,9 @@ class HtmlDartGenerator(object):
else:
self.EmitOperation(info, method_name)
- def _GenerateDispatcherBody(self,
- operations,
+ def _GenerateOverloadDispatcher(self,
+ signatures,
+ is_void,
parameter_names,
declaration,
generate_call,
@@ -192,7 +194,7 @@ class HtmlDartGenerator(object):
DECLARATION=declaration)
version = [0]
- def GenerateCall(operation, argument_count, checks):
+ def GenerateCall(signature_index, argument_count, checks):
if checks:
(stmts_emitter, call_emitter) = body_emitter.Emit(
' if ($CHECKS) {\n$!STMTS$!CALL }\n',
@@ -203,19 +205,19 @@ class HtmlDartGenerator(object):
'$!STMTS$!CALL',
INDENT=' ');
- if operation.type.id == 'void':
+ if is_void:
call_emitter = call_emitter.Emit('$(INDENT)$!CALL;\n$(INDENT)return;\n')
else:
call_emitter = call_emitter.Emit('$(INDENT)return $!CALL;\n')
version[0] += 1
- generate_call(
- stmts_emitter, call_emitter, version[0], operation, argument_count)
+ generate_call(stmts_emitter, call_emitter,
+ version[0], signature_index, argument_count)
- def GenerateChecksAndCall(operation, argument_count):
+ def GenerateChecksAndCall(signature_index, argument_count):
checks = []
for i in range(0, argument_count):
- argument = operation.arguments[i]
+ argument = signatures[signature_index][i]
parameter_name = parameter_names[i]
test_type = self._DartType(argument.type.id)
if test_type in ['dynamic', 'Object']:
@@ -227,34 +229,60 @@ class HtmlDartGenerator(object):
# optional argument could have been passed by name, leaving 'holes'.
checks.extend(['!?%s' % name for name in parameter_names[argument_count:]])
- GenerateCall(operation, argument_count, checks)
+ GenerateCall(signature_index, argument_count, checks)
# TODO: Optimize the dispatch to avoid repeated checks.
- if len(operations) > 1:
- for operation in operations:
- for position, argument in enumerate(operation.arguments):
- if is_optional(operation, argument):
- GenerateChecksAndCall(operation, position)
- GenerateChecksAndCall(operation, len(operation.arguments))
+ if len(signatures) > 1:
+ for signature_index, signature in enumerate(signatures):
+ for argument_position, argument in enumerate(signature):
+ if is_optional(signature_index, argument):
+ GenerateChecksAndCall(signature_index, argument_position)
+ GenerateChecksAndCall(signature_index, len(signature))
body_emitter.Emit(
' throw new ArgumentError("Incorrect number or type of arguments");'
'\n');
else:
- operation = operations[0]
- argument_count = len(operation.arguments)
- for position, argument in list(enumerate(operation.arguments))[::-1]:
- if is_optional(operation, argument):
- check = '?%s' % parameter_names[position]
- # argument_count instead of position + 1 is used here to cover one
+ signature = signatures[0]
+ argument_count = len(signature)
+ for argument_position, argument in list(enumerate(signature))[::-1]:
+ if is_optional(0, argument):
+ check = '?%s' % parameter_names[argument_position]
+ # argument_count instead of argument_position + 1 is used here to cover one
# complicated case with the effectively optional argument in the middle.
# Consider foo(x, [Optional] y, [Optional=DefaultIsNullString] z)
# (as of now it's modelled after HTMLMediaElement.webkitAddKey).
# y is optional in WebCore, while z is not.
# In this case, if y was actually passed, we'd like to emit foo(x, y, z) invocation,
# not foo(x, y).
- GenerateCall(operation, argument_count, [check])
- argument_count = position
- GenerateCall(operation, argument_count, [])
+ GenerateCall(0, argument_count, [check])
+ argument_count = argument_position
+ GenerateCall(0, argument_count, [])
+
+ def _GenerateDispatcherBody(self,
+ operations,
+ parameter_names,
+ declaration,
+ generate_call,
+ is_optional,
+ can_omit_type_check=lambda type, pos: False):
+
+ def GenerateCall(
+ stmts_emitter, call_emitter, version, signature_index, argument_count):
+ generate_call(
+ stmts_emitter, call_emitter,
+ version, operations[signature_index], argument_count)
+
+ def IsOptional(signature_index, argument):
+ return is_optional(operations[signature_index], argument)
+
+ self._GenerateOverloadDispatcher(
+ [operation.arguments for operation in operations],
+ operations[0].type.id == 'void',
+ parameter_names,
+ declaration,
+ GenerateCall,
+ IsOptional,
+ can_omit_type_check)
def AdditionalImplementedInterfaces(self):
# TODO: Include all implemented interfaces, including other Lists.
@@ -306,6 +334,9 @@ class HtmlDartGenerator(object):
def _AddConstructor(self,
constructor_info, factory_name, factory_constructor_name):
+ if self.HasCustomFactory():
+ return
+
self._members_emitter.Emit('\n @DocsEditable');
if not factory_constructor_name:
@@ -316,61 +347,86 @@ class HtmlDartGenerator(object):
factory_parameters = ', '.join(constructor_info.factory_parameters)
has_factory_provider = False
- has_optional = any(param_info.is_optional
- for param_info in constructor_info.param_infos)
+ if constructor_info.pure_dart_constructor:
+ # TODO: use common dispatcher generation for this case as well.
Emily Fortuna 2013/01/28 23:01:28 nit: TODO should include username.
Anton Muhin 2013/01/29 12:09:28 Done.
+ has_optional = any(param_info.is_optional
+ for param_info in constructor_info.param_infos)
- if not has_optional:
- self._members_emitter.Emit(
- '\n'
- ' factory $CTOR($PARAMS) => '
- '$FACTORY.$CTOR_FACTORY_NAME($FACTORY_PARAMS);\n',
- CTOR=constructor_info._ConstructorFullName(self._DartType),
- PARAMS=constructor_info.ParametersDeclaration(self._DartType),
- FACTORY=factory_name,
- CTOR_FACTORY_NAME=factory_constructor_name,
- FACTORY_PARAMS=factory_parameters)
- else:
- if has_factory_provider:
- dispatcher_emitter = self._members_emitter.Emit(
+ if not has_optional:
+ self._members_emitter.Emit(
'\n'
- ' factory $CTOR($PARAMS) {\n'
- '$!DISPATCHER'
- ' return $FACTORY._create($FACTORY_PARAMS);\n'
- ' }\n',
+ ' factory $CTOR($PARAMS) => '
+ '$FACTORY.$CTOR_FACTORY_NAME($FACTORY_PARAMS);\n',
CTOR=constructor_info._ConstructorFullName(self._DartType),
PARAMS=constructor_info.ParametersDeclaration(self._DartType),
FACTORY=factory_name,
- FACTORY_PARAMS=constructor_info.ParametersAsArgumentList())
-
- for index, param_info in enumerate(constructor_info.param_infos):
- if param_info.is_optional:
- dispatcher_emitter.Emit(
- ' if (!?$OPT_PARAM_NAME) {\n'
- ' return $FACTORY._create($FACTORY_PARAMS);\n'
- ' }\n',
- OPT_PARAM_NAME=param_info.name,
- FACTORY=factory_name,
- FACTORY_PARAMS=constructor_info.ParametersAsArgumentList(index))
- else:
- inits = self._members_emitter.Emit(
- '\n'
- ' factory $CONSTRUCTOR($PARAMS) {\n'
- ' var e = $FACTORY.$CTOR_FACTORY_NAME($FACTORY_PARAMS);\n'
- '$!INITS'
- ' return e;\n'
- ' }\n',
- CONSTRUCTOR=constructor_info._ConstructorFullName(self._DartType),
- FACTORY=factory_name,
CTOR_FACTORY_NAME=factory_constructor_name,
- PARAMS=constructor_info.ParametersDeclaration(self._DartType),
FACTORY_PARAMS=factory_parameters)
+ else:
+ if has_factory_provider:
+ dispatcher_emitter = self._members_emitter.Emit(
+ '\n'
+ ' factory $CTOR($PARAMS) {\n'
+ '$!DISPATCHER'
+ ' return $FACTORY._create($FACTORY_PARAMS);\n'
+ ' }\n',
+ CTOR=constructor_info._ConstructorFullName(self._DartType),
+ PARAMS=constructor_info.ParametersDeclaration(self._DartType),
+ FACTORY=factory_name,
+ FACTORY_PARAMS=constructor_info.ParametersAsArgumentList())
+
+ for index, param_info in enumerate(constructor_info.param_infos):
+ if param_info.is_optional:
+ dispatcher_emitter.Emit(
+ ' if (!?$OPT_PARAM_NAME) {\n'
+ ' return $FACTORY._create($FACTORY_PARAMS);\n'
+ ' }\n',
+ OPT_PARAM_NAME=param_info.name,
+ FACTORY=factory_name,
+ FACTORY_PARAMS=constructor_info.ParametersAsArgumentList(index))
+ else:
+ inits = self._members_emitter.Emit(
+ '\n'
+ ' factory $CONSTRUCTOR($PARAMS) {\n'
+ ' var e = $FACTORY.$CTOR_FACTORY_NAME($FACTORY_PARAMS);\n'
+ '$!INITS'
+ ' return e;\n'
+ ' }\n',
+ CONSTRUCTOR=constructor_info._ConstructorFullName(self._DartType),
+ FACTORY=factory_name,
+ CTOR_FACTORY_NAME=factory_constructor_name,
+ PARAMS=constructor_info.ParametersDeclaration(self._DartType),
+ FACTORY_PARAMS=factory_parameters)
- for index, param_info in enumerate(constructor_info.param_infos):
- if param_info.is_optional:
- inits.Emit(' if ($E != null) e.$E = $E;\n', E=param_info.name)
-
- if not constructor_info.pure_dart_constructor:
- self.EmitStaticFactory(constructor_info)
+ for index, param_info in enumerate(constructor_info.param_infos):
+ if param_info.is_optional:
+ inits.Emit(' if ($E != null) e.$E = $E;\n', E=param_info.name)
+ else:
+ def GenerateCall(
+ stmts_emitter, call_emitter,
+ version, signature_index, argument_count):
+ name = emitter.Format('_create_$VERSION', VERSION=version)
+ call_emitter.Emit('$FACTORY.$NAME($FACTORY_PARAMS)',
+ FACTORY=factory_name,
+ NAME=name,
+ FACTORY_PARAMS= \
+ constructor_info.ParametersAsArgumentList(argument_count))
+ self.EmitStaticFactoryOverload(
+ constructor_info, name,
+ constructor_info.idl_args[signature_index][:argument_count])
+
+ def IsOptional(signature_index, argument):
+ return self.IsConstructorArgumentOptional(argument)
+
+ self._GenerateOverloadDispatcher(
+ constructor_info.idl_args,
+ False,
+ [info.name for info in constructor_info.param_infos],
+ emitter.Format('factory $CTOR($PARAMS)',
+ CTOR=constructor_info._ConstructorFullName(self._DartType),
+ PARAMS=constructor_info.ParametersDeclaration(self._DartType)),
+ GenerateCall,
+ IsOptional)
def EmitHelpers(self, base_class):
pass

Powered by Google App Engine
This is Rietveld 408576698