Reviewers: ihab.awad,
Description: This is part 5 of https://groups.google.com/group/google-caja-discuss/browse_thread/thread/50db6111ae71c2c9 We currently have a Scope class which was defined for the Rewriter scheme. For each optimization pass I've done, I've ended up writing my own scope scheme, often on top of Scope. E.g. the AlphaRenaming uses an identity map to associate extra info with scopes, and the array index optimization builds it's own scope tree, so that it can easily walk from a scope to its children. The linter uses a scoping scheme that abstracts away the decision of where declarations are introduced into scopes and which scopes they are hoisted to, so that it can make sure that scoping is consistent between JScript and other interpreters. Further changelists will unify these scoping schemes and support the following use cases: # In a rewriter to scope lazily # On an entire tree to attach a scope to each node # To generate masking errors about violations of Cajita specific invariants (such as forbidding declaration of the name "cajita") # To identify the kind of symbol -- function declaration, local function name, exception, data, globals # To collect information about declarations # To resolve references to declaration points or to scopes # To detect redelcaration # To emulate ES5 scoping rules # To emulate broken IE scoping # To collect uses of a variable # To determine whether/where a symbol is used as a LeftHandSideExpression # To collect uses in narrower scopes. # To collect the set of symbols from wider scopes. There are a few separable concerns here: # Applying scoping rules of a given variant of JS -- exception hoisting, whether function constructors' names intrude on the containing scope to introduce scopes, and collect declarations # Associating scopes with parse tree nodes Collecting usage information Please see ScopeListener for a general interface to collecting and collating Scope information. See ScopeAnalyzer for a general implementation that implements a scoping scheme, and its concrete implementations: ES5ScopeAnalyzer, JScriptScopeAnalyzer, WorstCaseScopeAnalyzer. The ScopeAnalyzerTests give an idea of how ScopeAnalyzer works. In later CLS, Scope has been rewritten to use ES5ScopeAnalyzer under the hood, and Rewriter will change to create the scopes so that it is no longer the responsibility of Rules to create and pass around scopes. Please review this at http://codereview.appspot.com/148045 Affected files: M build.xml M src/com/google/caja/ancillary/opt/LocalVarRenamer.java M src/com/google/caja/parser/js/Operation.java A src/com/google/caja/parser/js/scope/AbstractScope.java A src/com/google/caja/parser/js/scope/ES5ScopeAnalyzer.java A src/com/google/caja/parser/js/scope/JScriptScopeAnalyzer.java A src/com/google/caja/parser/js/scope/ScopeAnalyzer.java A src/com/google/caja/parser/js/scope/ScopeListener.java A src/com/google/caja/parser/js/scope/ScopeType.java A src/com/google/caja/parser/js/scope/WorstCaseScopeAnalyzer.java M src/com/google/caja/parser/quasiliteral/Scope.java M src/com/google/caja/parser/quasiliteral/SyntheticRuleSet.java A tests/com/google/caja/parser/js/scope/ScopeAnalyzerTest.java
