void inferAllScopes ( Node node ) { // Type analysis happens in two major phases. // 1) Finding all the symbols. // 2) Propagating all the inferred types. // // The order of this analysis is non-obvious. In a complete inference // system, we may need to backtrack arbitrarily far. But the compile-time // costs would be unacceptable. // // We do one pass where we do typed scope creation for all scopes // in pre-order. // // Then we do a second pass where we do all type inference // (type propagation) in pre-order. // // We use a memoized scope creator so that we never create a scope // more than once. // // This will allow us to handle cases like: // var ns = {}; // (function() { /** JSDoc */ ns.method = function() {}; })(); // ns.method(); // In this code, we need to build the symbol table for the inner scope in // order to propagate the type of ns.method in the outer scope. ( new NodeTraversal ( compiler , new FirstScopeBuildingCallback ( ) , scopeCreator ) ) . traverseWithScope ( node , topScope ) ; scopeCreator . resolveTypes ( ) ; ( new NodeTraversal ( compiler , new SecondScopeBuildingCallback ( ) , scopeCreator ) ) . traverseWithScope ( node , topScope ) ; // Resolve any new type names found during the inference. // This runs for nested block scopes after infer runs on the CFG root. compiler . getTypeRegistry ( ) . resolveTypes ( ) ; }
Entry point for type inference when running over part of the tree .