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

Unified Diff: grit/node/base.py

Issue 156443002: Provide defines as local variables in if-expressions. (Closed) Base URL: http://grit-i18n.googlecode.com/svn/trunk
Patch Set: rebased past is_posix fix, fixed is_posix again and updated unittests Created 6 years, 10 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 | « grit/grd_reader_unittest.py ('k') | grit/node/base_unittest.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: grit/node/base.py
diff --git a/grit/node/base.py b/grit/node/base.py
index 824532c62fe1846d446dd40060a7faa2c2035692..5ce037f3f26c76b795a92e87eb1e6df3f445eb8a 100644
--- a/grit/node/base.py
+++ b/grit/node/base.py
@@ -6,9 +6,8 @@
'''Base types for nodes in a GRIT resource tree.
'''
-import collections
+import ast
import os
-import sys
import types
from xml.sax import saxutils
@@ -28,11 +27,12 @@ class Node(object):
# Default nodes to not whitelist skipped
_whitelist_marked_as_skip = False
- # A class-static cache to memoize EvaluateExpression().
- # It has a 2 level nested dict structure. The outer dict has keys
- # of tuples which define the environment in which the expression
- # will be evaluated. The inner dict is map of expr->result.
- eval_expr_cache = collections.defaultdict(dict)
+ # A class-static cache to speed up EvaluateExpression().
+ # Keys are expressions (e.g. 'is_ios and lang == "fr"'). Values are tuples
+ # (code, variables_in_expr) where code is the compiled expression and can be
+ # directly eval'd, and variables_in_expr is the list of variable and method
+ # names used in the expression (e.g. ['is_ios', 'lang']).
+ eval_expr_cache = {}
def __init__(self):
self.children = [] # A list of child elements
@@ -442,59 +442,62 @@ class Node(object):
return []
@classmethod
- def GetPlatformAssertion(cls, target_platform):
- '''If the platform is a specific well-known platform, this returns
- the is_xyz string representing that platform (e.g. is_linux),
- otherwise the empty string.
- '''
- platform = ''
- if target_platform == 'darwin':
- platform = 'is_macosx'
- elif target_platform.startswith('linux'):
- platform = 'is_linux'
- elif target_platform in ('cygwin', 'win32'):
- platform = 'is_win'
- elif target_platform in ('android', 'ios'):
- platform = 'is_%s' % target_platform
- return platform
-
- @classmethod
- def EvaluateExpression(cls, expr, defs, target_platform, extra_variables=None):
+ def EvaluateExpression(cls, expr, defs, target_platform, extra_variables={}):
'''Worker for EvaluateCondition (below) and conditions in XTB files.'''
- cache_dict = cls.eval_expr_cache[
- (tuple(defs.iteritems()), target_platform, extra_variables)]
- if expr in cache_dict:
- return cache_dict[expr]
- def pp_ifdef(symbol):
- return symbol in defs
- def pp_if(symbol):
- return defs.get(symbol, False)
- variable_map = {
- 'defs' : defs,
- 'os': target_platform,
-
- # One of these is_xyz assertions gets set to True in the line
- # following this initializer block.
- 'is_linux': False,
- 'is_macosx': False,
- 'is_win': False,
- 'is_android': False,
- 'is_ios': False,
-
- # is_posix is not mutually exclusive of the others and gets
- # set here, not below.
- 'is_posix': (target_platform in ('darwin', 'linux2', 'linux3', 'sunos5',
- 'android', 'ios')
- or 'bsd' in target_platform),
-
- 'pp_ifdef' : pp_ifdef,
- 'pp_if' : pp_if,
- }
- variable_map[Node.GetPlatformAssertion(target_platform)] = True
+ if expr in cls.eval_expr_cache:
+ code, variables_in_expr = cls.eval_expr_cache[expr]
+ else:
+ # Get a list of all variable and method names used in the expression.
+ syntax_tree = ast.parse(expr, mode='eval')
+ variables_in_expr = [node.id for node in ast.walk(syntax_tree) if
+ isinstance(node, ast.Name) and node.id not in ('True', 'False')]
+ code = compile(syntax_tree, filename='<string>', mode='eval')
+ cls.eval_expr_cache[expr] = code, variables_in_expr
+
+ # Set values only for variables that are needed to eval the expression.
+ variable_map = {}
+ for name in variables_in_expr:
+ if name == 'os':
+ value = target_platform
+ elif name == 'defs':
+ value = defs
+
+ elif name == 'is_linux':
+ value = target_platform.startswith('linux')
+ elif name == 'is_macosx':
+ value = target_platform == 'darwin'
+ elif name == 'is_win':
+ value = target_platform in ('cygwin', 'win32')
+ elif name == 'is_android':
+ value = target_platform == 'android'
+ elif name == 'is_ios':
+ value = target_platform == 'ios'
+ elif name == 'is_posix':
+ value = (target_platform in ('darwin', 'linux2', 'linux3', 'sunos5',
+ 'android', 'ios')
+ or 'bsd' in target_platform)
+
+ elif name == 'pp_ifdef':
+ def pp_ifdef(symbol):
+ return symbol in defs
+ value = pp_ifdef
+ elif name == 'pp_if':
+ def pp_if(symbol):
+ return defs.get(symbol, False)
+ value = pp_if
+
+ elif name in defs:
+ value = defs[name]
+ elif name in extra_variables:
+ value = extra_variables[name]
+ else:
+ # Undefined variables default to False.
+ value = False
- if extra_variables:
- variable_map.update(extra_variables)
- eval_result = cache_dict[expr] = eval(expr, {}, variable_map)
+ variable_map[name] = value
+
+ eval_result = eval(code, {}, variable_map)
+ assert isinstance(eval_result, bool)
return eval_result
def EvaluateCondition(self, expr):
@@ -518,10 +521,10 @@ class Node(object):
context = getattr(root, 'output_context', '')
defs = getattr(root, 'defines', {})
target_platform = getattr(root, 'target_platform', '')
- extra_variables = (
- ('lang', lang),
- ('context', context),
- )
+ extra_variables = {
+ 'lang': lang,
+ 'context': context,
+ }
return Node.EvaluateExpression(
expr, defs, target_platform, extra_variables)
« no previous file with comments | « grit/grd_reader_unittest.py ('k') | grit/node/base_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698