LCOV - code coverage report
Current view: top level - src/parsing - func-name-inferrer.h (source / functions) Hit Total Coverage
Test: app.info Lines: 13 14 92.9 %
Date: 2019-04-17 Functions: 3 3 100.0 %

          Line data    Source code
       1             : // Copyright 2006-2009 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_PARSING_FUNC_NAME_INFERRER_H_
       6             : #define V8_PARSING_FUNC_NAME_INFERRER_H_
       7             : 
       8             : #include <vector>
       9             : 
      10             : #include "src/base/macros.h"
      11             : #include "src/pointer-with-payload.h"
      12             : 
      13             : namespace v8 {
      14             : namespace internal {
      15             : 
      16             : class AstConsString;
      17             : class AstRawString;
      18             : class AstValueFactory;
      19             : class FunctionLiteral;
      20             : 
      21             : enum class InferName { kYes, kNo };
      22             : 
      23             : template <>
      24             : struct PointerWithPayloadTraits<AstRawString> {
      25             :   static constexpr int value = 2;
      26             : };
      27             : 
      28             : // FuncNameInferrer is a stateful class that is used to perform name
      29             : // inference for anonymous functions during static analysis of source code.
      30             : // Inference is performed in cases when an anonymous function is assigned
      31             : // to a variable or a property (see test-func-name-inference.cc for examples.)
      32             : //
      33             : // The basic idea is that during parsing of LHSs of certain expressions
      34             : // (assignments, declarations, object literals) we collect name strings,
      35             : // and during parsing of the RHS, a function literal can be collected. After
      36             : // parsing the RHS we can infer a name for function literals that do not have
      37             : // a name.
      38     4931689 : class FuncNameInferrer {
      39             :  public:
      40             :   explicit FuncNameInferrer(AstValueFactory* ast_value_factory);
      41             : 
      42             :   // To enter function name inference state, put a FuncNameInferrer::State
      43             :   // on the stack.
      44             :   class State {
      45             :    public:
      46             :     explicit State(FuncNameInferrer* fni)
      47     7815944 :         : fni_(fni), top_(fni->names_stack_.size()) {
      48    67880160 :       ++fni_->scope_depth_;
      49             :     }
      50     7815943 :     ~State() {
      51             :       DCHECK(fni_->IsOpen());
      52    67879677 :       fni_->names_stack_.resize(top_);
      53    67878961 :       --fni_->scope_depth_;
      54     3907972 :     }
      55             : 
      56             :    private:
      57             :     FuncNameInferrer* fni_;
      58             :     size_t top_;
      59             : 
      60             :     DISALLOW_COPY_AND_ASSIGN(State);
      61             :   };
      62             : 
      63             :   // Returns whether we have entered name collection state.
      64             :   bool IsOpen() const { return scope_depth_ > 0; }
      65             : 
      66             :   // Pushes an enclosing the name of enclosing function onto names stack.
      67             :   void PushEnclosingName(const AstRawString* name);
      68             : 
      69             :   // Pushes an encountered name onto names stack when in collection state.
      70             :   void PushLiteralName(const AstRawString* name);
      71             : 
      72             :   void PushVariableName(const AstRawString* name);
      73             : 
      74             :   // Adds a function to infer name for.
      75      641922 :   void AddFunction(FunctionLiteral* func_to_infer) {
      76     1615805 :     if (IsOpen()) {
      77     1381713 :       funcs_to_infer_.push_back(func_to_infer);
      78             :     }
      79      641922 :   }
      80             : 
      81             :   void RemoveLastFunction() {
      82     6909704 :     if (IsOpen() && !funcs_to_infer_.empty()) funcs_to_infer_.pop_back();
      83             :   }
      84             : 
      85             :   void RemoveAsyncKeywordFromEnd();
      86             : 
      87             :   // Infers a function name and leaves names collection state.
      88             :   void Infer() {
      89             :     DCHECK(IsOpen());
      90    15701471 :     if (!funcs_to_infer_.empty()) InferFunctionsNames();
      91             :   }
      92             : 
      93             :  private:
      94             :   enum NameType : uint8_t {
      95             :     kEnclosingConstructorName,
      96             :     kLiteralName,
      97             :     kVariableName
      98             :   };
      99             :   struct Name {
     100             :     // Needed for names_stack_.resize()
     101           0 :     Name() { UNREACHABLE(); }
     102             :     Name(const AstRawString* name, NameType type)
     103             :         : name_and_type_(name, type) {}
     104             : 
     105             :     PointerWithPayload<const AstRawString, NameType, 2> name_and_type_;
     106             :     inline const AstRawString* name() const {
     107             :       return name_and_type_.GetPointer();
     108             :     }
     109             :     inline NameType type() const { return name_and_type_.GetPayload(); }
     110             :   };
     111             : 
     112             :   // Constructs a full name in dotted notation from gathered names.
     113             :   const AstConsString* MakeNameFromStack();
     114             : 
     115             :   // Performs name inferring for added functions.
     116             :   void InferFunctionsNames();
     117             : 
     118             :   AstValueFactory* ast_value_factory_;
     119             :   std::vector<Name> names_stack_;
     120             :   std::vector<FunctionLiteral*> funcs_to_infer_;
     121             :   size_t scope_depth_ = 0;
     122             : 
     123             :   DISALLOW_COPY_AND_ASSIGN(FuncNameInferrer);
     124             : };
     125             : 
     126             : 
     127             : }  // namespace internal
     128             : }  // namespace v8
     129             : 
     130             : #endif  // V8_PARSING_FUNC_NAME_INFERRER_H_

Generated by: LCOV version 1.10