880f4d814a
Review URL: https://chromiumcodereview.appspot.com//10913125 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@12082 260f80e4-7a28-3924-810f-c04153c831b5
201 lines
7.1 KiB
Python
201 lines
7.1 KiB
Python
#!/usr/bin/python
|
|
# Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
|
# for details. All rights reserved. Use of this source code is governed by a
|
|
# BSD-style license that can be found in the LICENSE file.
|
|
|
|
"""This module providesfunctionality for systems to generate
|
|
Dart interfaces from the IDL database."""
|
|
|
|
import os
|
|
import systembase
|
|
from generator import *
|
|
|
|
class InterfacesSystem(systembase.System):
|
|
|
|
def __init__(self, options):
|
|
super(InterfacesSystem, self).__init__(options)
|
|
self._dart_interface_file_paths = []
|
|
|
|
|
|
def ProcessInterface(self, interface):
|
|
"""."""
|
|
interface_name = interface.id
|
|
dart_interface_file_path = self._FilePathForDartInterface(interface_name)
|
|
|
|
self._dart_interface_file_paths.append(dart_interface_file_path)
|
|
|
|
dart_interface_code = self._emitters.FileEmitter(dart_interface_file_path)
|
|
|
|
template_file = 'interface_%s.darttemplate' % interface_name
|
|
template = self._templates.TryLoad(template_file)
|
|
if not template:
|
|
template = self._templates.Load('interface.darttemplate')
|
|
|
|
DartInterfaceGenerator(
|
|
self, interface, dart_interface_code, template).Generate()
|
|
|
|
def ProcessCallback(self, interface, info):
|
|
"""Generates a typedef for the callback interface."""
|
|
interface_name = interface.id
|
|
file_path = self._FilePathForDartInterface(interface_name)
|
|
self._ProcessCallback(interface, info, file_path)
|
|
|
|
def GenerateLibraries(self):
|
|
pass
|
|
|
|
|
|
def _FilePathForDartInterface(self, interface_name):
|
|
"""Returns the file path of the Dart interface definition."""
|
|
return os.path.join(self._output_dir, 'src', 'interface',
|
|
'%s.dart' % interface_name)
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
class DartInterfaceGenerator(systembase.BaseGenerator):
|
|
"""Generates Dart Interface definition for one DOM IDL interface."""
|
|
|
|
def __init__(self, system, interface, emitter, template):
|
|
"""Generates Dart code for the given interface.
|
|
|
|
Args:
|
|
interface -- an IDLInterface instance. It is assumed that all types have
|
|
been converted to Dart types (e.g. int, String), unless they are in the
|
|
same package as the interface.
|
|
super_interface -- the name of the common interface that this interface
|
|
implements, if any.
|
|
"""
|
|
super(DartInterfaceGenerator, self).__init__(system._database, interface)
|
|
self._system = system
|
|
self._emitter = emitter
|
|
self._template = template
|
|
self._super_interface = interface.ext_attrs.get(
|
|
'synthesizedSuperInterfaceName', None)
|
|
|
|
def StartInterface(self):
|
|
if self._super_interface:
|
|
typename = self._super_interface
|
|
else:
|
|
typename = self._interface.id
|
|
|
|
|
|
extends = []
|
|
suppressed_extends = []
|
|
|
|
for parent in self._interface.parents:
|
|
# TODO(vsm): Remove source_filter.
|
|
if MatchSourceFilter(parent):
|
|
# Parent is a DOM type.
|
|
extends.append(self._DartType(parent.type.id))
|
|
elif '<' in parent.type.id:
|
|
# Parent is a Dart collection type.
|
|
# TODO(vsm): Make this check more robust.
|
|
extends.append(parent.type.id)
|
|
else:
|
|
suppressed_extends.append('%s.%s' %
|
|
(self._common_prefix, parent.type.id))
|
|
|
|
comment = ' extends'
|
|
extends_str = ''
|
|
if extends:
|
|
extends_str += ' extends ' + ', '.join(extends)
|
|
comment = ','
|
|
if suppressed_extends:
|
|
extends_str += ' /*%s %s */' % (comment, ', '.join(suppressed_extends))
|
|
|
|
factory_provider = None
|
|
constructor_info = AnalyzeConstructor(self._interface)
|
|
if constructor_info:
|
|
factory_provider = '_' + typename + 'FactoryProvider'
|
|
|
|
if typename in interface_factories:
|
|
factory_provider = interface_factories[typename]
|
|
|
|
if factory_provider:
|
|
extends_str += ' default ' + factory_provider
|
|
|
|
# TODO(vsm): Add appropriate package / namespace syntax.
|
|
(self._members_emitter,
|
|
self._top_level_emitter) = self._emitter.Emit(
|
|
self._template + '$!TOP_LEVEL',
|
|
ID=typename,
|
|
EXTENDS=extends_str)
|
|
|
|
if constructor_info:
|
|
self._members_emitter.Emit(
|
|
'\n'
|
|
' $CTOR($PARAMS);\n',
|
|
CTOR=typename,
|
|
PARAMS=constructor_info.ParametersInterfaceDeclaration(self._DartType))
|
|
|
|
element_type = MaybeTypedArrayElementTypeInHierarchy(
|
|
self._interface, self._system._database)
|
|
if element_type:
|
|
self._members_emitter.Emit(
|
|
'\n'
|
|
' $CTOR(int length);\n'
|
|
'\n'
|
|
' $CTOR.fromList(List<$TYPE> list);\n'
|
|
'\n'
|
|
' $CTOR.fromBuffer(ArrayBuffer buffer,'
|
|
' [int byteOffset, int length]);\n',
|
|
CTOR=self._interface.id,
|
|
TYPE=self._DartType(element_type))
|
|
|
|
|
|
def FinishInterface(self):
|
|
# TODO(vsm): Use typedef if / when that is supported in Dart.
|
|
# Define variant as subtype.
|
|
if (self._super_interface and
|
|
self._interface.id is not self._super_interface):
|
|
consts_emitter = self._top_level_emitter.Emit(
|
|
'\n'
|
|
'interface $NAME extends $BASE {\n'
|
|
'$!CONSTS'
|
|
'}\n',
|
|
NAME=self._interface.id,
|
|
BASE=self._super_interface)
|
|
for const in sorted(self._interface.constants, ConstantOutputOrder):
|
|
self._EmitConstant(consts_emitter, const)
|
|
|
|
def AddConstant(self, constant):
|
|
if (not self._super_interface or
|
|
self._interface.id is self._super_interface):
|
|
self._EmitConstant(self._members_emitter, constant)
|
|
|
|
def _EmitConstant(self, emitter, constant):
|
|
emitter.Emit('\n static const $TYPE$NAME = $VALUE;\n',
|
|
NAME=constant.id,
|
|
TYPE=TypeOrNothing(self._DartType(constant.type.id),
|
|
constant.type.id),
|
|
VALUE=constant.value)
|
|
|
|
def AddAttribute(self, attribute):
|
|
getter = attribute
|
|
setter = attribute if not systembase.IsReadOnly(attribute) else None
|
|
if getter and setter and getter.type.id == setter.type.id:
|
|
self._members_emitter.Emit('\n $TYPE $NAME;\n',
|
|
NAME=DartDomNameOfAttribute(getter),
|
|
TYPE=TypeOrVar(self._DartType(getter.type.id),
|
|
getter.type.id))
|
|
return
|
|
if getter and not setter:
|
|
self._members_emitter.Emit('\n final $TYPE$NAME;\n',
|
|
NAME=DartDomNameOfAttribute(getter),
|
|
TYPE=TypeOrNothing(self._DartType(getter.type.id),
|
|
getter.type.id))
|
|
return
|
|
raise Exception('Unexpected getter/setter combination %s %s' %
|
|
(getter, setter))
|
|
|
|
def AddOperation(self, info):
|
|
"""
|
|
Arguments:
|
|
operations - contains the overloads, one or more operations with the same
|
|
name.
|
|
"""
|
|
self._members_emitter.Emit('\n'
|
|
' $TYPE $NAME($PARAMS);\n',
|
|
TYPE=self._DartType(info.type_name),
|
|
NAME=info.name,
|
|
PARAMS=info.ParametersInterfaceDeclaration(self._DartType))
|