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 "src/zone/zone.h"
9 :
10 : namespace v8 {
11 : namespace internal {
12 :
13 : class AstConsString;
14 : class AstRawString;
15 : class AstValueFactory;
16 : class FunctionLiteral;
17 :
18 : enum class InferName { kYes, kNo };
19 :
20 : // FuncNameInferrer is a stateful class that is used to perform name
21 : // inference for anonymous functions during static analysis of source code.
22 : // Inference is performed in cases when an anonymous function is assigned
23 : // to a variable or a property (see test-func-name-inference.cc for examples.)
24 : //
25 : // The basic idea is that during parsing of LHSs of certain expressions
26 : // (assignments, declarations, object literals) we collect name strings,
27 : // and during parsing of the RHS, a function literal can be collected. After
28 : // parsing the RHS we can infer a name for function literals that do not have
29 : // a name.
30 : class FuncNameInferrer : public ZoneObject {
31 : public:
32 : FuncNameInferrer(AstValueFactory* ast_value_factory, Zone* zone);
33 :
34 : // To enter function name inference state, put a FuncNameInferrer::State
35 : // on the stack.
36 : class State {
37 : public:
38 118721083 : explicit State(FuncNameInferrer* fni) : fni_(fni) {
39 118721083 : if (fni_ != nullptr) fni_->Enter();
40 118721089 : }
41 : ~State() {
42 118640129 : if (fni_ != nullptr) fni_->Leave();
43 : }
44 :
45 : private:
46 : FuncNameInferrer* fni_;
47 :
48 : DISALLOW_COPY_AND_ASSIGN(State);
49 : };
50 :
51 : // Returns whether we have entered name collection state.
52 83679947 : bool IsOpen() const { return !entries_stack_.is_empty(); }
53 :
54 : // Pushes an enclosing the name of enclosing function onto names stack.
55 : void PushEnclosingName(const AstRawString* name);
56 :
57 : // Pushes an encountered name onto names stack when in collection state.
58 : void PushLiteralName(const AstRawString* name);
59 :
60 : void PushVariableName(const AstRawString* name);
61 :
62 : // Adds a function to infer name for.
63 3410544 : void AddFunction(FunctionLiteral* func_to_infer) {
64 2885794 : if (IsOpen()) {
65 2707942 : funcs_to_infer_.Add(func_to_infer, zone());
66 : }
67 702602 : }
68 :
69 7018366 : void RemoveLastFunction() {
70 7018366 : if (IsOpen() && !funcs_to_infer_.is_empty()) {
71 182637 : funcs_to_infer_.RemoveLast();
72 : }
73 7018366 : }
74 :
75 : void RemoveAsyncKeywordFromEnd();
76 :
77 : // Infers a function name and leaves names collection state.
78 472919 : void Infer() {
79 : DCHECK(IsOpen());
80 16415573 : if (!funcs_to_infer_.is_empty()) {
81 2021055 : InferFunctionsNames();
82 : }
83 472919 : }
84 :
85 : private:
86 : enum NameType {
87 : kEnclosingConstructorName,
88 : kLiteralName,
89 : kVariableName
90 : };
91 : struct Name {
92 72214551 : Name(const AstRawString* name, NameType type) : name(name), type(type) {}
93 : const AstRawString* name;
94 : NameType type;
95 : };
96 :
97 74667546 : void Enter() { entries_stack_.Add(names_stack_.length(), zone()); }
98 :
99 74667549 : void Leave() {
100 : DCHECK(IsOpen());
101 149335101 : names_stack_.Rewind(entries_stack_.RemoveLast());
102 74667552 : if (entries_stack_.is_empty()) funcs_to_infer_.Clear();
103 74667552 : }
104 :
105 : Zone* zone() const { return zone_; }
106 :
107 : // Constructs a full name in dotted notation from gathered names.
108 : const AstConsString* MakeNameFromStack();
109 :
110 : // Performs name inferring for added functions.
111 : void InferFunctionsNames();
112 :
113 : AstValueFactory* ast_value_factory_;
114 : ZoneList<int> entries_stack_;
115 : ZoneList<Name> names_stack_;
116 : ZoneList<FunctionLiteral*> funcs_to_infer_;
117 : Zone* zone_;
118 :
119 : DISALLOW_COPY_AND_ASSIGN(FuncNameInferrer);
120 : };
121 :
122 :
123 : } // namespace internal
124 : } // namespace v8
125 :
126 : #endif // V8_PARSING_FUNC_NAME_INFERRER_H_
|