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

Unified Diff: Source/bindings/scripts/code_generator_web_modules.py

Issue 1248043003: Initial patch for the web modules layered platform proposal. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 5 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: Source/bindings/scripts/code_generator_web_modules.py
diff --git a/Source/bindings/scripts/code_generator_web_modules.py b/Source/bindings/scripts/code_generator_web_modules.py
new file mode 100644
index 0000000000000000000000000000000000000000..ffad01ab66506ff422cdd8521d9cae92179a7e24
--- /dev/null
+++ b/Source/bindings/scripts/code_generator_web_modules.py
@@ -0,0 +1,134 @@
+# Copyright 2015 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Generate Blink WebModules bindings (.h and .cpp files).
+
+These are used to expose C++ bindings to the rest of Blink for building
+features on top of web APIs instead of baking them into the core code.
+The way these APIs work is to wrap a pointer to the underlying type and
+then pass the wrapped thing by value. Compilers will optimize the
+wrapper out entirely, so there is no performance overhead, but lets
+us enforce that a strictly controlled API surface is exposed to the calling
+code.
+
+We don't want to expose the bad parts of the platform, so we only expose
+APIs that have the WebModulesExposed annotation.
+
+Input: An object of class IdlDefinitions, containing an IDL interface X
+Output: WebModuleX.h and WebModuleX.cpp
+
+Design doc: http://www.chromium.org/developers/design-documents/idl-compiler
+"""
+
+import os
+import posixpath
+import sys
+
+# TODO(ojan): Share this path handling code with code_generator_v8.py..
+
+# Path handling for libraries and templates
+# Paths have to be normalized because Jinja uses the exact template path to
+# determine the hash used in the cache filename, and we need a pre-caching step
+# to be concurrency-safe. Use absolute path because __file__ is absolute if
+# module is imported, and relative if executed directly.
+# If paths differ between pre-caching and individual file compilation, the cache
+# is regenerated, which causes a race condition and breaks concurrent build,
+# since some compile processes will try to read the partially written cache.
+module_path, module_filename = os.path.split(os.path.realpath(__file__))
+third_party_dir = os.path.normpath(os.path.join(
+ module_path, os.pardir, os.pardir, os.pardir, os.pardir))
+templates_dir = os.path.normpath(os.path.join(
+ module_path, os.pardir, 'templates'))
+# Make sure extension is .py, not .pyc or .pyo, so doesn't depend on caching
+module_pyname = os.path.splitext(module_filename)[0] + '.py'
+
+# jinja2 is in chromium's third_party directory.
+# Insert at 1 so at front to override system libraries, and
+# after path[0] == invoking script dir
+sys.path.insert(1, third_party_dir)
+import jinja2
+
+from v8_utilities import cpp_name
+from utilities import idl_filename_to_component
+
+
+def initialize_jinja_env(cache_dir):
+ return jinja2.Environment(
+ loader=jinja2.FileSystemLoader(templates_dir),
+ # Bytecode cache is not concurrency-safe unless pre-cached:
+ # if pre-cached this is read-only, but writing creates a race condition.
+ bytecode_cache=jinja2.FileSystemBytecodeCache(cache_dir),
+ keep_trailing_newline=True, # newline-terminate generated files
+ lstrip_blocks=True, # so can indent control flow tags
+ trim_blocks=True)
+
+
+def web_modules_class_name(interface_name):
+ return "WebModule" + interface_name
+
+
+def includes_for_type(component, idl_type):
+ base_idl_type = idl_type.preprocessed_type.base_type
+
+ # TODO(ojan): Make this work for things that have more dependencies (e.g. NodeLists).
+ # e.g. see v8_types.includes_for_type.
+ return set(['bindings/%s/webmodules/WebModule%s.h' % (component, base_idl_type)])
+
+
+class Attribute(object):
+ def __init__(self, name, idl_type):
+ self.name = name
+ self.idl_type = idl_type
+
+
+class CodeGeneratorWebModules(object):
+ def __init__(self, info_provider, cache_dir, output_dir):
+ self.info_provider = info_provider
+ self.jinja_env = initialize_jinja_env(cache_dir)
+ self.output_dir = output_dir
+
+ def generate_code(self, definitions, definition_name):
+ """Returns .h/.cpp code as ((path, content)...)."""
+ # TODO(ojan): Make this work for dictionaries as well.
+ assert(definition_name in definitions.interfaces)
+ return self.generate_interface_code(
+ definitions, definition_name,
+ definitions.interfaces[definition_name])
+
+ def generate_interface_code(self, definitions, interface_name, interface):
+ interface_info = self.info_provider.interfaces_info[interface_name]
+ full_path = interface_info.get('full_path')
+ component = idl_filename_to_component(full_path)
+
+ attributes = []
+ type_includes = set()
+ for attribute in interface.attributes:
+ if 'WebModulesExposed' in attribute.extended_attributes:
+ type_includes = type_includes.union(
+ includes_for_type(component, attribute.idl_type))
+
+ # TODO(ojan): handle void return types
+ return_type = 'WebModule%s' % attribute.idl_type.preprocessed_type.base_type
+ attribute = Attribute(cpp_name(attribute), return_type)
+ attributes.append(attribute)
+
+ template_context = {
+ 'class_name': web_modules_class_name(interface_name),
+ 'header_includes': sorted([
+ interface_info['include_path'],
+ ] + list(type_includes)),
+ 'attributes': attributes,
+ 'interface_name': interface_name
+ }
+
+ header_path = posixpath.join(self.output_dir, 'WebModule%s.h' % interface_name)
+ cpp_path = posixpath.join(self.output_dir, 'WebModule%s.cpp' % interface_name)
+
+ header_template = self.jinja_env.get_template('web_modules_interface.h')
+ cpp_template = self.jinja_env.get_template('web_modules_interface.cpp')
+
+ return (
+ (header_path, header_template.render(template_context)),
+ (cpp_path, cpp_template.render(template_context)),
+ )

Powered by Google App Engine
This is Rietveld 408576698