Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor generated spec data to facilitate looking up by spec name #3817

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 58 additions & 29 deletions bin/amphtml-update.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,12 @@ def GeneratePHP(out_dir):
"""
logging.info('entering ...')

allowed_tags, attr_lists, descendant_lists, reference_points, versions = ParseRules(out_dir)
allowed_tags, extension_specs, attr_lists, descendant_lists, reference_points, versions = ParseRules(out_dir)

expected_spec_names = (
'style amp-custom',
'style[amp-keyframes]',
'link rel=stylesheet for fonts',
)
for expected_spec_name in expected_spec_names:
if expected_spec_name not in seen_spec_names:
Expand All @@ -115,6 +116,7 @@ def GeneratePHP(out_dir):
GenerateLayoutAttributesPHP(out, attr_lists)
GenerateGlobalAttributesPHP(out, attr_lists)
GenerateReferencePointsPHP(out, reference_points)
GenerateExtensionSpecsPHP(out, extension_specs)
GenerateFooterPHP(out)

# join out array into a single string and remove unneeded whitespace
Expand Down Expand Up @@ -206,6 +208,15 @@ def GenerateReferencePointsPHP(out, reference_points):
out.append('')
logging.info('... done')

def GenerateExtensionSpecsPHP(out, extension_specs):
logging.info('entering ...')

# Output the reference points.
out.append('')
out.append('\tprivate static $extension_specs = %s;' % Phpize( extension_specs, 1 ).lstrip() )
out.append('')
logging.info('... done')

def GenerateFooterPHP(out):
logging.info('entering ...')

Expand All @@ -226,22 +237,27 @@ def GenerateFooterPHP(out):
*
* @since 1.5
* @internal
*
* @return array Extension specs, keyed by extension name.
*/
public static function get_extension_specs() {
static $extension_specs = [];

if ( ! empty( $extension_specs ) ) {
return $extension_specs;
}
return self::$extension_specs;
}

foreach ( self::get_allowed_tag( 'script' ) as $script_spec ) {
if ( isset( $script_spec[ AMP_Rule_Spec::TAG_SPEC ]['extension_spec'] ) ) {
$extension_specs[ $script_spec[ AMP_Rule_Spec::TAG_SPEC ]['extension_spec']['name'] ] = $script_spec[ AMP_Rule_Spec::TAG_SPEC ]['extension_spec'];
}
/**
* Get extension specs.
*
* @since 1.5
* @internal
*
* @param string $name Extension name.
* @return array Extension specs, keyed by extension name.
*/
public static function get_extension_spec( $name ) {
if ( isset( self::$extension_specs[ $name ] ) ) {
return self::$extension_specs[ $name ];
}

return $extension_specs;
return null;
}

/**
Expand All @@ -250,12 +266,26 @@ def GenerateFooterPHP(out):
* Get the rules for a single tag so that the entire data structure needn't be passed around.
*
* @since 0.7
* @param string $node_name Tag name.
* @return array|null Allowed tag, or null if the tag does not exist.
*
* @param string $tag_name Tag name.
* @param string|null $spec_name Spec name.
* @return array[]|array|null Allowed tags, allowed tag spec, or null if the tag does not exist.
*/
public static function get_allowed_tag( $node_name ) {
if ( isset( self::$allowed_tags[ $node_name ] ) ) {
return self::$allowed_tags[ $node_name ];
public static function get_allowed_tag( $tag_name, $spec_name = null ) {
if ( isset( self::$allowed_tags[ $tag_name ] ) ) {
$rule_specs = self::$allowed_tags[ $tag_name ];
if ( empty( $spec_name ) ) {
return $rule_specs;
}
foreach ( $rule_specs as $rule_spec ) {
if (
( ! isset( $rule_spec['tag_spec']['spec_name'] ) && $tag_name === $spec_name )
||
( isset( $rule_spec['tag_spec']['spec_name'] ) && $rule_spec['tag_spec']['spec_name'] === $spec_name )
) {
return array_merge( compact( 'tag_name' ), $rule_spec );
}
}
}
return null;
}
Expand Down Expand Up @@ -339,6 +369,7 @@ def ParseRules(out_dir):
validator_pb2 = imp.load_source('validator_pb2', os.path.join( out_dir, 'validator_pb2.py' ))

allowed_tags = {}
extension_specs = {}
attr_lists = {}
descendant_lists = {}
reference_points = {}
Expand Down Expand Up @@ -398,12 +429,16 @@ def ParseRules(out_dir):
tag_list = []
else:
tag_list = allowed_tags[UnicodeEscape(tag_spec.tag_name).lower()]
# AddTag(allowed_tags, tag_spec, attr_lists)

gotten_tag_spec = GetTagSpec(tag_spec, attr_lists)
if gotten_tag_spec is not None:
tag_list.append(gotten_tag_spec)
allowed_tags[UnicodeEscape(tag_spec.tag_name).lower()] = tag_list
if 'extension_spec' in gotten_tag_spec['tag_spec']:
extension_name = gotten_tag_spec['tag_spec']['extension_spec']['name']
del gotten_tag_spec['tag_spec']['extension_spec']['name']
extension_specs[ extension_name ] = gotten_tag_spec['tag_spec']['extension_spec']
else:
tag_list.append(gotten_tag_spec)
allowed_tags[UnicodeEscape(tag_spec.tag_name).lower()] = tag_list
elif 'descendant_tag_list' == field_desc.name:
for list in field_val:
descendant_lists[list.name] = []
Expand All @@ -416,7 +451,7 @@ def ParseRules(out_dir):
descendant_lists[list.name].append( val.lower() )

logging.info('... done')
return allowed_tags, attr_lists, descendant_lists, reference_points, versions
return allowed_tags, extension_specs, attr_lists, descendant_lists, reference_points, versions


def GetTagSpec(tag_spec, attr_lists):
Expand Down Expand Up @@ -489,14 +524,12 @@ def GetTagSpec(tag_spec, attr_lists):

if 'spec_name' not in tag_spec_dict['tag_spec']:
if 'extension_spec' in tag_spec_dict['tag_spec']:
# CUSTOM_ELEMENT=1 (default), CUSTOM_TEMPLATE=2
extension_type = tag_spec_dict['tag_spec']['extension_spec'].get('extension_type', 1)
spec_name = 'script [%s=%s]' % ( 'custom-element' if 1 == extension_type else 'custom-template', tag_spec_dict['tag_spec']['extension_spec']['name'].lower() )
extension_name = tag_spec_dict['tag_spec']['extension_spec']['name'].lower()
spec_name = 'script %s' % extension_name
else:
spec_name = tag_spec.tag_name.lower()
else:
spec_name = tag_spec_dict['tag_spec']['spec_name']

if '$reference_point' != spec_name:
if spec_name in seen_spec_names:
raise Exception( 'Already seen spec_name: %s' % spec_name )
Expand Down Expand Up @@ -593,10 +626,6 @@ def GetTagRules(tag_spec):
versions.remove( 'latest' )
extension_spec['version'] = sorted( versions, key=lambda version: map(int, version.split('.') ) )

# Unused since amp_filter_script_loader_tag() and \AMP_Tag_And_Attribute_Sanitizer::get_rule_spec_list_to_validate() just hard-codes the check for amp-mustache.
if 'extension_type' in extension_spec:
del extension_spec['extension_type']

if 'deprecated_version' in extension_spec:
del extension_spec['deprecated_version']

Expand Down
Loading