Skip to content

Commit

Permalink
Pepper: Add IDL support for "channel=dev".
Browse files Browse the repository at this point in the history
This adds some basic support for the "channel=dev" label annotation for pepper
IDL files.

Design doc is at:
  https://docs.google.com/a/chromium.org/document/d/1Q660kK72_230gxnqtgQavMcDT5_gLgPVh_W51MXT6nk/edit

TESTED=idl_tests.py, generator.py
BUG=325403

Review URL: https://codereview.chromium.org/105313002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@241305 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
teravest@chromium.org committed Dec 17, 2013
1 parent 6c62020 commit 67676f2
Show file tree
Hide file tree
Showing 8 changed files with 275 additions and 20 deletions.
9 changes: 7 additions & 2 deletions ppapi/generators/idl_ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ class IDLLabelResolver(IDLVisitor):
def Depart(self, node, ignore, childdata):
# Build list of Release=Version
if node.IsA('LabelItem'):
return (node.GetName(), node.GetProperty('VALUE'))
channel = node.GetProperty('channel')
if not channel:
channel = 'stable'
return (node.GetName(), node.GetProperty('VALUE'), channel)

# On completion of the Label, apply to the parent File if the
# name of the label matches the generation label.
Expand Down Expand Up @@ -75,7 +78,9 @@ def Arrive(self, node, parent_namespace):
if parent_namespace and node.cls in IDLNode.NamedSet:
# Set version min and max based on properties
if self.release_map:
vmin = node.GetProperty('version')
vmin = node.GetProperty('dev_version')
if vmin == None:
vmin = node.GetProperty('version')
vmax = node.GetProperty('deprecate')
# If no min is available, the use the parent File's min
if vmin == None:
Expand Down
31 changes: 26 additions & 5 deletions ppapi/generators/idl_c_header.py
Original file line number Diff line number Diff line change
Expand Up @@ -288,12 +288,33 @@ def GenerateHead(self, out, filenode, releases, options):
# Skip this interface if there are no matching versions
if not unique: continue

last_stable_ver = None
last_dev_rel = None
for rel in unique:
channel = node.GetProperty('FILE').release_map.GetChannel(rel)
if channel == 'dev':
last_dev_rel = rel

for rel in unique:
version = node.GetVersion(rel)
name = cgen.GetInterfaceString(node, version)
strver = str(version).replace('.', '_')
idefs += cgen.GetDefine('%s_%s' % (macro, strver), '"%s"' % name)
idefs += cgen.GetDefine(macro, '%s_%s' % (macro, strver)) + '\n'
channel = node.GetProperty('FILE').release_map.GetChannel(rel)
if channel == 'dev':
# Skip dev channel interface versions that are
# Not the newest version, and
# Don't have an equivalent stable version.
if rel != last_dev_rel and not node.DevInterfaceMatchesStable(rel):
continue
value_string = '"%s" /* dev */' % name
else:
value_string = '"%s"' % name
last_stable_ver = strver
idefs += cgen.GetDefine('%s_%s' % (macro, strver), value_string)
if last_stable_ver:
idefs += cgen.GetDefine(macro, '%s_%s' % (macro, last_stable_ver))
idefs += '\n'

out.Write(idefs)

# Generate the @file comment
Expand Down Expand Up @@ -337,11 +358,11 @@ def main(args):
filenames = glob.glob(idldir)

ast = ParseFiles(filenames)
if hgen.GenerateRange(ast, ['M13', 'M14', 'M15'], {}):
print "Golden file for M13-M15 failed."
if hgen.GenerateRange(ast, ['M13', 'M14', 'M15', 'M16', 'M17'], {}):
print "Golden file for M13-M17 failed."
failed =1
else:
print "Golden file for M13-M15 passed."
print "Golden file for M13-M17 passed."

return failed

Expand Down
53 changes: 43 additions & 10 deletions ppapi/generators/idl_c_proto.py
Original file line number Diff line number Diff line change
Expand Up @@ -538,17 +538,25 @@ def GetStructName(self, node, release, include_version=False):

def DefineStructInternals(self, node, release,
include_version=False, comment=True):
channel = node.GetProperty('FILE').release_map.GetChannel(release)
if channel == 'dev':
channel_comment = ' /* dev */'
else:
channel_comment = ''
out = ''
if node.GetProperty('union'):
out += 'union %s {\n' % (
self.GetStructName(node, release, include_version))
out += 'union %s {%s\n' % (
self.GetStructName(node, release, include_version), channel_comment)
else:
out += 'struct %s {\n' % (
self.GetStructName(node, release, include_version))
out += 'struct %s {%s\n' % (
self.GetStructName(node, release, include_version), channel_comment)

channel = node.GetProperty('FILE').release_map.GetChannel(release)
# Generate Member Functions
members = []
for child in node.GetListOf('Member'):
if channel == 'stable' and child.NodeIsDevOnly():
continue
member = self.Define(child, [release], tabs=1, comment=comment)
if not member:
continue
Expand All @@ -563,27 +571,52 @@ def DefineStruct(self, node, releases, prefix='', comment=False):
out = ''
build_list = node.GetUniqueReleases(releases)

newest_stable = None
newest_dev = None
for rel in build_list:
channel = node.GetProperty('FILE').release_map.GetChannel(rel)
if channel == 'stable':
newest_stable = rel
if channel == 'dev':
newest_dev = rel
last_rel = build_list[-1]

# TODO(noelallen) : Bug 157017 finish multiversion support
if node.IsA('Struct'):
if len(build_list) != 1:
node.Error('Can not support multiple versions of node.')
assert len(build_list) == 1
out = self.DefineStructInternals(node, build_list[-1],
# Build the most recent one versioned, with comments
out = self.DefineStructInternals(node, last_rel,
include_version=False, comment=True)

if node.IsA('Interface'):
# Build the most recent one versioned, with comments
out = self.DefineStructInternals(node, build_list[-1],
out = self.DefineStructInternals(node, last_rel,
include_version=True, comment=True)
# Define an unversioned typedef for the most recent version
out += '\ntypedef struct %s %s;\n' % (
self.GetStructName(node, build_list[-1], include_version=True),
self.GetStructName(node, build_list[-1], include_version=False))
if last_rel == newest_stable:
# Define an unversioned typedef for the most recent version
out += '\ntypedef struct %s %s;\n' % (
self.GetStructName(node, last_rel, include_version=True),
self.GetStructName(node, last_rel, include_version=False))

# Build the rest without comments and with the version number appended
for rel in build_list[0:-1]:
channel = node.GetProperty('FILE').release_map.GetChannel(rel)
# Skip dev channel interface versions that are
# Not the newest version, and
# Don't have an equivalent stable version.
if channel == 'dev' and rel != newest_dev:
if not node.DevInterfaceMatchesStable(rel):
continue
out += '\n' + self.DefineStructInternals(node, rel,
include_version=True,
comment=False)
if rel == newest_stable:
# Define an unversioned typedef for the most recent version
out += '\ntypedef struct %s %s;\n' % (
self.GetStructName(node, rel, include_version=True),
self.GetStructName(node, rel, include_version=False))

self.LogExit('Exit DefineStruct')
return out
Expand Down
22 changes: 21 additions & 1 deletion ppapi/generators/idl_node.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,10 @@ def _GetReleaseList(self, releases, visited=None):
else:
my_releases = set([my_min])

r = self.GetRelease(self.GetProperty('version'))
if not r in my_releases:
my_releases |= set([r])

# Break cycle if we reference ourselves
if self in visited:
return [my_min]
Expand Down Expand Up @@ -338,6 +342,22 @@ def GetProperty(self, name):
def GetPropertyLocal(self, name):
return self._property_node.GetPropertyLocal(name)

def NodeIsDevOnly(self):
"""Returns true iff a node is only in dev channel."""
return self.GetProperty('dev_version') and not self.GetProperty('version')

def DevInterfaceMatchesStable(self, release):
"""Returns true if an interface has an equivalent stable version."""
assert(self.IsA('Interface'))
for child in self.GetListOf('Member'):
unique = child.GetUniqueReleases([release])
if not unique or not child.InReleases([release]):
continue
if child.NodeIsDevOnly():
return False
return True


#
# IDLFile
#
Expand All @@ -352,7 +372,7 @@ def __init__(self, name, children, errors=0):
IDLNode.__init__(self, 'File', name, 1, 0, attrs + children)
# TODO(teravest): Why do we set release map like this here? This looks
# suspicious...
self.release_map = IDLReleaseMap([('M13', 1.0)])
self.release_map = IDLReleaseMap([('M13', 1.0, 'stable')])


#
Expand Down
7 changes: 6 additions & 1 deletion ppapi/generators/idl_release.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,11 @@ class IDLReleaseMap(object):
def __init__(self, release_info):
self.version_to_release = {}
self.release_to_version = {}
for release, version in release_info:
self.release_to_channel = {}
for release, version, channel in release_info:
self.version_to_release[version] = release
self.release_to_version[release] = version
self.release_to_channel[release] = channel
self.releases = sorted(self.release_to_version.keys())
self.versions = sorted(self.version_to_release.keys())

Expand All @@ -238,6 +240,9 @@ def GetReleaseRange(self):
def GetVersionRange(self):
return (self.versions[0], self.version[-1])

def GetChannel(self, release):
return self.release_to_channel.get(release, None)

#
# Test Code
#
Expand Down
102 changes: 102 additions & 0 deletions ppapi/generators/test_cgen_range/dev_channel_interface.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/* Copyright 2013 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.
*/

/* From test_cgen_range/dev_channel_interface.idl,
* modified Tue Dec 3 14:58:15 2013.
*/

#ifndef PPAPI_C_TEST_CGEN_RANGE_DEV_CHANNEL_INTERFACE_H_
#define PPAPI_C_TEST_CGEN_RANGE_DEV_CHANNEL_INTERFACE_H_

#include "ppapi/c/pp_macros.h"
#include "ppapi/c/test_cgen_range/versions.h"

#define TESTDEV_INTERFACE_1_0 "TestDev;1.0"
#define TESTDEV_INTERFACE_1_2 "TestDev;1.2"
#define TESTDEV_INTERFACE_1_3 "TestDev;1.3" /* dev */
#define TESTDEV_INTERFACE TESTDEV_INTERFACE_1_2

#define TESTDEVTOSTABLE_INTERFACE_1_0 "TestDevToStable;1.0"
#define TESTDEVTOSTABLE_INTERFACE_1_1 "TestDevToStable;1.1" /* dev */
#define TESTDEVTOSTABLE_INTERFACE_1_2 "TestDevToStable;1.2"
#define TESTDEVTOSTABLE_INTERFACE TESTDEVTOSTABLE_INTERFACE_1_2

/**
* @file
*/


/**
* @addtogroup Interfaces
* @{
*/
/**
* TestDev
*/
struct TestDev_1_3 { /* dev */
/**
* TestDev1()
*/
void (*TestDev1)(void);
/**
* TestDev2()
*/
void (*TestDev2)(void);
/**
* TestDev3()
*/
void (*TestDev3)(void);
/**
* TestDev4()
*/
void (*TestDev4)(void);
};

struct TestDev_1_0 {
void (*TestDev1)(void);
};

struct TestDev_1_2 {
void (*TestDev1)(void);
void (*TestDev3)(void);
};

typedef struct TestDev_1_2 TestDev;

/**
* TestDevToStable
*/
struct TestDevToStable_1_2 {
/**
* Foo() comment.
*/
void (*Foo)(int32_t x);
/**
* Bar() comment.
*/
void (*Bar)(int32_t x);
/**
* Baz() comment.
*/
void (*Baz)(int32_t x);
};

typedef struct TestDevToStable_1_2 TestDevToStable;

struct TestDevToStable_1_0 {
void (*Foo)(int32_t x);
};

struct TestDevToStable_1_1 { /* dev */
void (*Foo)(int32_t x);
void (*Bar)(int32_t x);
void (*Baz)(int32_t x);
};
/**
* @}
*/

#endif /* PPAPI_C_TEST_CGEN_RANGE_DEV_CHANNEL_INTERFACE_H_ */

67 changes: 67 additions & 0 deletions ppapi/generators/test_cgen_range/dev_channel_interface.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/* Copyright 2013 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.
*/

label Chrome {
M13 = 1.0,
[channel=dev] M14 = 1.1,
M15 = 1.2,
[channel=dev] M16 = 1.3,
M17 = 1.4
};

describe {
int32_t;
void;
};

/**
* TestDev
*/
interface TestDev {
/**
* TestDev1()
*/
void TestDev1();

/**
* TestDev2()
*/
[dev_version=1.1]
void TestDev2();

/**
* TestDev3()
*/
[version=1.2]
void TestDev3();

/**
* TestDev4()
*/
[dev_version=1.3]
void TestDev4();
};

/**
* TestDevToStable
*/
interface TestDevToStable {
/**
* Foo() comment.
*/
void Foo([in] int32_t x);

/**
* Bar() comment.
*/
[dev_version=1.1, version=1.2]
void Bar([in] int32_t x);

/**
* Baz() comment.
*/
[dev_version=1.1, version=1.2]
void Baz([in] int32_t x);
};
Loading

0 comments on commit 67676f2

Please sign in to comment.