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

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

Issue 14455007: Refactoring DOM annotations and comment generation, adding DOM API triage list (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 8 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
« no previous file with comments | « tools/dom/scripts/dartdomgenerator.py ('k') | tools/dom/scripts/generator.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tools/dom/scripts/dartmetadata.py
diff --git a/tools/dom/scripts/dartmetadata.py b/tools/dom/scripts/dartmetadata.py
new file mode 100644
index 0000000000000000000000000000000000000000..2479cedca7b5af212c345efc572268cc9d6180a3
--- /dev/null
+++ b/tools/dom/scripts/dartmetadata.py
@@ -0,0 +1,562 @@
+#!/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 provides shared functionality for systems to generate
+Dart APIs from the IDL database."""
+
+import copy
+import json
+import monitored
+import os
+import re
+from generator import ConstantOutputOrder
+from htmlrenamer import renamed_html_members
+
+# Annotations to be placed on native members. The table is indexed by the IDL
+# interface and member name, and by IDL return or field type name. Both are
+# used to assemble the annotations:
+#
+# INTERFACE.MEMBER: annotations for member.
+# +TYPE: add annotations only if there are member annotations.
+# -TYPE: add annotations only if there are no member annotations.
+# TYPE: add regardless of member annotations.
+
+_dart2js_annotations = monitored.Dict('dartmetadata._dart2js_annotations', {
+
+ 'ArrayBufferView': [
+ "@Creates('TypedData')",
+ "@Returns('TypedData|Null')",
+ ],
+
+ 'CanvasRenderingContext2D.createImageData': [
+ "@Creates('ImageData|=Object')",
+ ],
+
+ 'CanvasRenderingContext2D.getImageData': [
+ "@Creates('ImageData|=Object')",
+ ],
+
+ 'CanvasRenderingContext2D.webkitGetImageDataHD': [
+ "@Creates('ImageData|=Object')",
+ ],
+
+ 'CanvasRenderingContext2D.fillStyle': [
+ "@Creates('String|CanvasGradient|CanvasPattern')",
+ "@Returns('String|CanvasGradient|CanvasPattern')",
+ ],
+
+ 'CanvasRenderingContext2D.strokeStyle': [
+ "@Creates('String|CanvasGradient|CanvasPattern')",
+ "@Returns('String|CanvasGradient|CanvasPattern')",
+ ],
+
+ # Methods returning Window can return a local window, or a cross-frame
+ # window (=Object) that needs wrapping.
+ 'DOMWindow': [
+ "@Creates('Window|=Object')",
+ "@Returns('Window|=Object')",
+ ],
+
+ 'DOMWindow.openDatabase': [
+ "@Creates('SqlDatabase')",
+ ],
+
+ # To be in callback with the browser-created Event, we had to have called
+ # addEventListener on the target, so we avoid
+ 'Event.currentTarget': [
+ "@Creates('Null')",
+ "@Returns('EventTarget|=Object')",
+ ],
+
+ # Only nodes in the DOM bubble and have target !== currentTarget.
+ 'Event.target': [
+ "@Creates('Node')",
+ "@Returns('EventTarget|=Object')",
+ ],
+
+ 'MouseEvent.relatedTarget': [
+ "@Creates('Node')",
+ "@Returns('EventTarget|=Object')",
+ ],
+
+ # Touch targets are Elements in a Document, or the Document.
+ 'Touch.target': [
+ "@Creates('Element|Document')",
+ "@Returns('Element|Document')",
+ ],
+
+ 'FileReader.result': ["@Creates('String|ByteBuffer|Null')"],
+
+ # Rather than have the result of an IDBRequest as a union over all possible
+ # results, we mark the result as instantiating any classes, and mark
+ # each operation with the classes that it could cause to be asynchronously
+ # instantiated.
+ 'IDBRequest.result': ["@Creates('Null')"],
+
+ # The source is usually a participant in the operation that generated the
+ # IDBRequest.
+ 'IDBRequest.source': ["@Creates('Null')"],
+
+ 'IDBFactory.open': ["@Creates('Database')"],
+ 'IDBFactory.webkitGetDatabaseNames': ["@Creates('DomStringList')"],
+
+ 'IDBObjectStore.put': ["@_annotation_Creates_IDBKey"],
+ 'IDBObjectStore.add': ["@_annotation_Creates_IDBKey"],
+ 'IDBObjectStore.get': ["@annotation_Creates_SerializedScriptValue"],
+ 'IDBObjectStore.openCursor': ["@Creates('Cursor')"],
+
+ 'IDBIndex.get': ["@annotation_Creates_SerializedScriptValue"],
+ 'IDBIndex.getKey': [
+ "@annotation_Creates_SerializedScriptValue",
+ # The source is the object store behind the index.
+ "@Creates('ObjectStore')",
+ ],
+ 'IDBIndex.openCursor': ["@Creates('Cursor')"],
+ 'IDBIndex.openKeyCursor': ["@Creates('Cursor')"],
+
+ 'IDBCursorWithValue.value': [
+ '@annotation_Creates_SerializedScriptValue',
+ '@annotation_Returns_SerializedScriptValue',
+ ],
+
+ 'IDBCursor.key': [
+ "@_annotation_Creates_IDBKey",
+ "@_annotation_Returns_IDBKey",
+ ],
+
+ '+IDBRequest': [
+ "@Returns('Request')",
+ "@Creates('Request')",
+ ],
+
+ '+IDBOpenDBRequest': [
+ "@Returns('Request')",
+ "@Creates('Request')",
+ ],
+
+ 'MessageEvent.ports': ["@Creates('=List')"],
+
+ 'MessageEvent.data': [
+ "@annotation_Creates_SerializedScriptValue",
+ "@annotation_Returns_SerializedScriptValue",
+ ],
+ 'PopStateEvent.state': [
+ "@annotation_Creates_SerializedScriptValue",
+ "@annotation_Returns_SerializedScriptValue",
+ ],
+ 'SerializedScriptValue': [
+ "@annotation_Creates_SerializedScriptValue",
+ "@annotation_Returns_SerializedScriptValue",
+ ],
+
+ 'SQLResultSetRowList.item': ["@Creates('=Object')"],
+
+ 'WebGLRenderingContext.getParameter': [
+ # Taken from http://www.khronos.org/registry/webgl/specs/latest/
+ # Section 5.14.3 Setting and getting state
+ "@Creates('Null|num|String|bool|=List|Float32List|Int32List|Uint32List"
+ "|Framebuffer|Renderbuffer|Texture')",
+ "@Returns('Null|num|String|bool|=List|Float32List|Int32List|Uint32List"
+ "|Framebuffer|Renderbuffer|Texture')",
+ ],
+
+ 'XMLHttpRequest.response': [
+ "@Creates('ByteBuffer|Blob|Document|=Object|=List|String|num')",
+ ],
+}, dart2jsOnly=True)
+
+_indexed_db_annotations = [
+ "@SupportedBrowser(SupportedBrowser.CHROME)",
+ "@SupportedBrowser(SupportedBrowser.FIREFOX, '15')",
+ "@SupportedBrowser(SupportedBrowser.IE, '10')",
+ "@Experimental",
+]
+
+_file_system_annotations = [
+ "@SupportedBrowser(SupportedBrowser.CHROME)",
+ "@Experimental",
+]
+
+_all_but_ie9_annotations = [
+ "@SupportedBrowser(SupportedBrowser.CHROME)",
+ "@SupportedBrowser(SupportedBrowser.FIREFOX)",
+ "@SupportedBrowser(SupportedBrowser.IE, '10')",
+ "@SupportedBrowser(SupportedBrowser.SAFARI)",
+]
+
+_history_annotations = _all_but_ie9_annotations
+
+_no_ie_annotations = [
+ "@SupportedBrowser(SupportedBrowser.CHROME)",
+ "@SupportedBrowser(SupportedBrowser.FIREFOX)",
+ "@SupportedBrowser(SupportedBrowser.SAFARI)",
+]
+
+_performance_annotations = [
+ "@SupportedBrowser(SupportedBrowser.CHROME)",
+ "@SupportedBrowser(SupportedBrowser.FIREFOX)",
+ "@SupportedBrowser(SupportedBrowser.IE)",
+]
+
+_rtc_annotations = [ # Note: Firefox nightly builds also support this.
+ "@SupportedBrowser(SupportedBrowser.CHROME)",
+ "@Experimental",
+]
+
+_shadow_dom_annotations = [
+ "@SupportedBrowser(SupportedBrowser.CHROME, '26')",
+ "@Experimental",
+]
+
+_speech_recognition_annotations = [
+ "@SupportedBrowser(SupportedBrowser.CHROME, '25')",
+ "@Experimental",
+]
+
+_svg_annotations = _all_but_ie9_annotations;
+
+_web_sql_annotations = [
+ "@SupportedBrowser(SupportedBrowser.CHROME)",
+ "@SupportedBrowser(SupportedBrowser.SAFARI)",
+ "@Experimental",
+]
+
+_webgl_annotations = [
+ "@SupportedBrowser(SupportedBrowser.CHROME)",
+ "@SupportedBrowser(SupportedBrowser.FIREFOX)",
+ "@Experimental",
+]
+
+_webkit_experimental_annotations = [
+ "@SupportedBrowser(SupportedBrowser.CHROME)",
+ "@SupportedBrowser(SupportedBrowser.SAFARI)",
+ "@Experimental",
+]
+
+# Annotations to be placed on generated members.
+# The table is indexed as:
+# INTERFACE: annotations to be added to the interface declaration
+# INTERFACE.MEMBER: annotation to be added to the member declaration
+_annotations = monitored.Dict('dartmetadata._annotations', {
+ 'CSSHostRule': _shadow_dom_annotations,
+ 'Crypto': _webkit_experimental_annotations,
+ 'Database': _web_sql_annotations,
+ 'DatabaseSync': _web_sql_annotations,
+ 'DOMApplicationCache': [
+ "@SupportedBrowser(SupportedBrowser.CHROME)",
+ "@SupportedBrowser(SupportedBrowser.FIREFOX)",
+ "@SupportedBrowser(SupportedBrowser.IE, '10')",
+ "@SupportedBrowser(SupportedBrowser.OPERA)",
+ "@SupportedBrowser(SupportedBrowser.SAFARI)",
+ ],
+ 'DOMFileSystem': _file_system_annotations,
+ 'DOMFileSystemSync': _file_system_annotations,
+ 'DOMWindow.webkitConvertPointFromNodeToPage': _webkit_experimental_annotations,
+ 'DOMWindow.webkitConvertPointFromPageToNode': _webkit_experimental_annotations,
+ 'DOMWindow.indexedDB': _indexed_db_annotations,
+ 'DOMWindow.openDatabase': _web_sql_annotations,
+ 'DOMWindow.performance': _performance_annotations,
+ 'DOMWindow.webkitNotifications': _webkit_experimental_annotations,
+ 'DOMWindow.webkitRequestFileSystem': _file_system_annotations,
+ 'DOMWindow.webkitResolveLocalFileSystemURL': _file_system_annotations,
+ 'Element.onwebkitTransitionEnd': _all_but_ie9_annotations,
+ # Placeholder to add experimental flag, implementation for this is
+ # pending in a separate CL.
+ 'Element.webkitMatchesSelector': ['@Experimental()'],
+ 'Element.webkitCreateShadowRoot': [
+ "@SupportedBrowser(SupportedBrowser.CHROME, '25')",
+ "@Experimental",
+ ],
+ 'Event.clipboardData': _webkit_experimental_annotations,
+ 'FormData': _all_but_ie9_annotations,
+ 'HashChangeEvent': [
+ "@SupportedBrowser(SupportedBrowser.CHROME)",
+ "@SupportedBrowser(SupportedBrowser.FIREFOX)",
+ "@SupportedBrowser(SupportedBrowser.SAFARI)",
+ ],
+ 'History.pushState': _history_annotations,
+ 'History.replaceState': _history_annotations,
+ 'HTMLContentElement': _shadow_dom_annotations,
+ 'HTMLDataListElement': _all_but_ie9_annotations,
+ 'HTMLDetailsElement': _webkit_experimental_annotations,
+ 'HTMLEmbedElement': [
+ "@SupportedBrowser(SupportedBrowser.CHROME)",
+ "@SupportedBrowser(SupportedBrowser.IE)",
+ "@SupportedBrowser(SupportedBrowser.SAFARI)",
+ ],
+ 'HTMLKeygenElement': _webkit_experimental_annotations,
+ 'HTMLMeterElement': _no_ie_annotations,
+ 'HTMLObjectElement': [
+ "@SupportedBrowser(SupportedBrowser.CHROME)",
+ "@SupportedBrowser(SupportedBrowser.IE)",
+ "@SupportedBrowser(SupportedBrowser.SAFARI)",
+ ],
+ 'HTMLOutputElement': _no_ie_annotations,
+ 'HTMLProgressElement': _all_but_ie9_annotations,
+ 'HTMLShadowElement': _shadow_dom_annotations,
+ 'HTMLTrackElement': [
+ "@SupportedBrowser(SupportedBrowser.CHROME)",
+ "@SupportedBrowser(SupportedBrowser.IE, '10')",
+ "@SupportedBrowser(SupportedBrowser.SAFARI)",
+ ],
+ 'IDBFactory': _indexed_db_annotations,
+ 'IDBDatabase': _indexed_db_annotations,
+ 'LocalMediaStream': _rtc_annotations,
+ 'MediaStream': _rtc_annotations,
+ 'MediaStreamEvent': _rtc_annotations,
+ 'MediaStreamTrack': _rtc_annotations,
+ 'MediaStreamTrackEvent': _rtc_annotations,
+ 'MutationObserver': [
+ "@SupportedBrowser(SupportedBrowser.CHROME)",
+ "@SupportedBrowser(SupportedBrowser.FIREFOX)",
+ "@SupportedBrowser(SupportedBrowser.SAFARI)",
+ "@Experimental",
+ ],
+ 'NotificationCenter': _webkit_experimental_annotations,
+ 'Performance': _performance_annotations,
+ 'PopStateEvent': _history_annotations,
+ 'RTCIceCandidate': _rtc_annotations,
+ 'RTCPeerConnection': _rtc_annotations,
+ 'RTCSessionDescription': _rtc_annotations,
+ 'ShadowRoot': _shadow_dom_annotations,
+ 'SpeechRecognition': _speech_recognition_annotations,
+ 'SpeechRecognitionAlternative': _speech_recognition_annotations,
+ 'SpeechRecognitionError': _speech_recognition_annotations,
+ 'SpeechRecognitionEvent': _speech_recognition_annotations,
+ 'SpeechRecognitionResult': _speech_recognition_annotations,
+ 'SVGAltGlyphElement': _no_ie_annotations,
+ 'SVGAnimateElement': _no_ie_annotations,
+ 'SVGAnimateMotionElement': _no_ie_annotations,
+ 'SVGAnimateTransformElement': _no_ie_annotations,
+ 'SVGFEBlendElement': _svg_annotations,
+ 'SVGFEColorMatrixElement': _svg_annotations,
+ 'SVGFEComponentTransferElement': _svg_annotations,
+ 'SVGFEConvolveMatrixElement': _svg_annotations,
+ 'SVGFEDiffuseLightingElement': _svg_annotations,
+ 'SVGFEDisplacementMapElement': _svg_annotations,
+ 'SVGFEDistantLightElement': _svg_annotations,
+ 'SVGFEFloodElement': _svg_annotations,
+ 'SVGFEFuncAElement': _svg_annotations,
+ 'SVGFEFuncBElement': _svg_annotations,
+ 'SVGFEFuncGElement': _svg_annotations,
+ 'SVGFEFuncRElement': _svg_annotations,
+ 'SVGFEGaussianBlurElement': _svg_annotations,
+ 'SVGFEImageElement': _svg_annotations,
+ 'SVGFEMergeElement': _svg_annotations,
+ 'SVGFEMergeNodeElement': _svg_annotations,
+ 'SVGFEMorphologyElement': _svg_annotations,
+ 'SVGFEOffsetElement': _svg_annotations,
+ 'SVGFEPointLightElement': _svg_annotations,
+ 'SVGFESpecularLightingElement': _svg_annotations,
+ 'SVGFESpotLightElement': _svg_annotations,
+ 'SVGFETileElement': _svg_annotations,
+ 'SVGFETurbulenceElement': _svg_annotations,
+ 'SVGFilterElement': _svg_annotations,
+ 'SVGForeignObjectElement': _no_ie_annotations,
+ 'SVGSetElement': _no_ie_annotations,
+ 'SQLTransaction': _web_sql_annotations,
+ 'SQLTransactionSync': _web_sql_annotations,
+ 'WebGLRenderingContext': _webgl_annotations,
+ 'WebKitCSSMatrix': _webkit_experimental_annotations,
+ 'WebKitPoint': _webkit_experimental_annotations,
+ 'WebSocket': _all_but_ie9_annotations,
+ 'Worker': _all_but_ie9_annotations,
+ 'XMLHttpRequest.onloadend': _all_but_ie9_annotations,
+ 'XMLHttpRequest.onprogress': _all_but_ie9_annotations,
+ 'XMLHttpRequest.response': _all_but_ie9_annotations,
+ 'XMLHttpRequestProgressEvent': _webkit_experimental_annotations,
+ 'XSLTProcessor': [
+ "@SupportedBrowser(SupportedBrowser.CHROME)",
+ "@SupportedBrowser(SupportedBrowser.FIREFOX)",
+ "@SupportedBrowser(SupportedBrowser.SAFARI)",
+ ],
+})
+
+
+class DartMetadata(object):
+ def __init__(self, api_status_path, doc_comments_path):
+ self._api_status_path = api_status_path
+ status_file = open(self._api_status_path, 'r+')
+ self._types = json.load(status_file)
+ status_file.close()
+
+ comments_file = open(doc_comments_path, 'r+')
+ self._doc_comments = json.load(comments_file)
+ comments_file.close()
+
+ def GetFormattedMetadata(self, library_name, interface_name, member_id=None,
+ indentation=''):
+ """ Gets all comments and annotations for an interface or member.
+ """
+ return self.FormatMetadata(
+ self.GetMetadata(library_name, interface_name, member_id),
+ indentation)
+
+ def GetMetadata(self, library_name, interface_name,
+ member_name=None, source_member_name=None):
+ """ Gets all comments and annotations for an interface or member.
+
+ Args:
+ source_member_name: If the member is dependent on a different member
+ then this is used to apply the support annotations from the other
+ member.
+ """
+ annotations = self._GetComments(library_name, interface_name, member_name)
+ annotations = annotations + self._GetCommonAnnotations(
+ interface_name, member_name, source_member_name)
+
+ return annotations
+
+ def GetDart2JSMetadata(self, idl_type, library_name,
+ interface_name, member_name,):
+ """ Gets all annotations for Dart2JS members- including annotations for
+ both dart2js and dartium.
+ """
+ annotations = self.GetMetadata(library_name, interface_name, member_name)
+
+ ann2 = self._GetDart2JSSpecificAnnotations(idl_type, interface_name, member_name)
+ if ann2:
+ if annotations:
+ annotations.extend(ann2)
+ else:
+ annotations = ann2
+ return annotations
+
+ def _GetCommonAnnotations(self, interface_name, member_name=None,
+ source_member_name=None):
+ if member_name:
+ key = '%s.%s' % (interface_name, member_name)
+ else:
+ key = interface_name
+
+ annotations = ["@DomName('" + key + "')"]
+
+ # Only add this for members, so we don't add DocsEditable to templated
+ # classes (they get it from the default class template)
+ if member_name:
+ annotations.append('@DocsEditable');
+
+ if key in _annotations:
+ annotations.extend(_annotations[key])
+
+ if (member_name and member_name.startswith('webkit') and
+ key not in renamed_html_members):
+ annotations.extend(_webkit_experimental_annotations)
+
+ if source_member_name:
+ member_name = source_member_name
+
+ # TODO(blois): Emit support level annotations
+ self._GetSupportLevelAnnotation(interface_name, member_name)
+
+ return annotations
+
+ def _GetComments(self, library_name, interface_name, member_name=None):
+ """ Gets all comments for the interface or member and returns a list. """
+
+ # Add documentation from JSON.
+ comments = []
+ library_name = 'dart.dom.%s' % library_name
+ if library_name in self._doc_comments:
+ library_info = self._doc_comments[library_name]
+ if interface_name in library_info:
+ interface_info = library_info[interface_name]
+ if member_name:
+ if 'members' in interface_info and member_name in interface_info['members']:
+ comments = interface_info['members'][member_name]
+ elif 'comment' in interface_info:
+ comments = interface_info['comment']
+
+ if comments:
+ comments = ['\n'.join(comments)]
+
+ return comments
+
+
+ def AnyConversionAnnotations(self, idl_type, interface_name, member_name):
+ if (_annotations.get('%s.%s' % (interface_name, member_name)) or
+ self._GetDart2JSSpecificAnnotations(idl_type, interface_name, member_name)):
+ return True
+ else:
+ return False
+
+ def FormatMetadata(self, metadata, indentation):
+ if metadata:
+ newline = '\n%s' % indentation
+ result = newline.join(metadata) + newline
+ return result
+ return ''
+
+ def _GetDart2JSSpecificAnnotations(self, idl_type, interface_name, member_name):
+ """ Finds dart2js-specific annotations. This does not include ones shared with
+ dartium.
+ """
+ ann1 = _dart2js_annotations.get("%s.%s" % (interface_name, member_name))
+ if ann1:
+ ann2 = _dart2js_annotations.get('+' + idl_type)
+ if ann2:
+ return ann2 + ann1
+ ann2 = _dart2js_annotations.get(idl_type)
+ if ann2:
+ return ann2 + ann1
+ return ann1
+
+ ann2 = _dart2js_annotations.get('-' + idl_type)
+ if ann2:
+ return ann2
+ ann2 = _dart2js_annotations.get(idl_type)
+ return ann2
+
+ def _GetSupportLevel(self, interface_id, member_id=None):
+ """ Looks up the interface or member in the DOM status list and returns the
+ support level for it.
+ """
+ if interface_id in self._types:
+ type_info = self._types[interface_id]
+ else:
+ type_info = {
+ 'members': {},
+ 'support_level': 'untriaged',
+ }
+ self._types[interface_id] = type_info
+
+ if not member_id:
+ return type_info.get('support_level')
+
+ members = type_info['members']
+
+ if member_id in members:
+ member_info = members[member_id]
+ else:
+ if member_id == interface_id:
+ member_info = {}
+ else:
+ member_info = {'support_level': 'untriaged'}
+ members[member_id] = member_info
+
+ support_level = member_info.get('support_level')
+ # If unset then it inherits from the type.
+ if not support_level:
+ support_level = type_info.get('support_level')
+ return support_level
+
+ def _GetSupportLevelAnnotation(self, interface_id, member_id=None):
+ support_level = self._GetSupportLevel(interface_id, member_id)
+
+ if support_level == 'untriaged':
+ return '@Experimental'
+ elif support_level == 'experimental':
+ return '@Experimental'
+ elif support_level == 'nonstandard':
+ return '@Experimental'
+ elif support_level == 'stable':
+ return
+ elif support_level == 'deprecated':
+ return '@Deprecated'
sra1 2013/04/30 01:29:43 else raise error?
+
+ def Flush(self):
+ json_file = open(self._api_status_path, 'w+')
+ json.dump(self._types, json_file, indent=2, separators=(',', ': '), sort_keys=True)
+ json_file.close()
« no previous file with comments | « tools/dom/scripts/dartdomgenerator.py ('k') | tools/dom/scripts/generator.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698