Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 1 | // Copyright 2006-2009 the V8 project authors. All rights reserved. |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame^] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 4 | |
| 5 | #ifndef V8_FUNC_NAME_INFERRER_H_ |
| 6 | #define V8_FUNC_NAME_INFERRER_H_ |
| 7 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame^] | 8 | #include "src/handles.h" |
| 9 | #include "src/zone.h" |
| 10 | |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 11 | namespace v8 { |
| 12 | namespace internal { |
| 13 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame^] | 14 | class AstRawString; |
| 15 | class AstString; |
| 16 | class AstValueFactory; |
| 17 | class FunctionLiteral; |
Ben Murdoch | 3fb3ca8 | 2011-12-02 17:19:32 +0000 | [diff] [blame] | 18 | |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 19 | // FuncNameInferrer is a stateful class that is used to perform name |
| 20 | // inference for anonymous functions during static analysis of source code. |
| 21 | // Inference is performed in cases when an anonymous function is assigned |
| 22 | // to a variable or a property (see test-func-name-inference.cc for examples.) |
| 23 | // |
Kristian Monsen | 80d68ea | 2010-09-08 11:05:35 +0100 | [diff] [blame] | 24 | // The basic idea is that during parsing of LHSs of certain expressions |
| 25 | // (assignments, declarations, object literals) we collect name strings, |
| 26 | // and during parsing of the RHS, a function literal can be collected. After |
| 27 | // parsing the RHS we can infer a name for function literals that do not have |
| 28 | // a name. |
| 29 | class FuncNameInferrer : public ZoneObject { |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 30 | public: |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame^] | 31 | FuncNameInferrer(AstValueFactory* ast_value_factory, Zone* zone); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 32 | |
| 33 | // Returns whether we have entered name collection state. |
| 34 | bool IsOpen() const { return !entries_stack_.is_empty(); } |
| 35 | |
| 36 | // Pushes an enclosing the name of enclosing function onto names stack. |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame^] | 37 | void PushEnclosingName(const AstRawString* name); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 38 | |
| 39 | // Enters name collection state. |
| 40 | void Enter() { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame^] | 41 | entries_stack_.Add(names_stack_.length(), zone()); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 42 | } |
| 43 | |
| 44 | // Pushes an encountered name onto names stack when in collection state. |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame^] | 45 | void PushLiteralName(const AstRawString* name); |
Kristian Monsen | 80d68ea | 2010-09-08 11:05:35 +0100 | [diff] [blame] | 46 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame^] | 47 | void PushVariableName(const AstRawString* name); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 48 | |
| 49 | // Adds a function to infer name for. |
| 50 | void AddFunction(FunctionLiteral* func_to_infer) { |
| 51 | if (IsOpen()) { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame^] | 52 | funcs_to_infer_.Add(func_to_infer, zone()); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 53 | } |
| 54 | } |
| 55 | |
Ben Murdoch | 69a99ed | 2011-11-30 16:03:39 +0000 | [diff] [blame] | 56 | void RemoveLastFunction() { |
| 57 | if (IsOpen() && !funcs_to_infer_.is_empty()) { |
| 58 | funcs_to_infer_.RemoveLast(); |
| 59 | } |
| 60 | } |
| 61 | |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 62 | // Infers a function name and leaves names collection state. |
Kristian Monsen | 80d68ea | 2010-09-08 11:05:35 +0100 | [diff] [blame] | 63 | void Infer() { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame^] | 64 | DCHECK(IsOpen()); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 65 | if (!funcs_to_infer_.is_empty()) { |
| 66 | InferFunctionsNames(); |
| 67 | } |
Kristian Monsen | 80d68ea | 2010-09-08 11:05:35 +0100 | [diff] [blame] | 68 | } |
| 69 | |
Ben Murdoch | 3fb3ca8 | 2011-12-02 17:19:32 +0000 | [diff] [blame] | 70 | // Leaves names collection state. |
Kristian Monsen | 80d68ea | 2010-09-08 11:05:35 +0100 | [diff] [blame] | 71 | void Leave() { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame^] | 72 | DCHECK(IsOpen()); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 73 | names_stack_.Rewind(entries_stack_.RemoveLast()); |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame^] | 74 | if (entries_stack_.is_empty()) |
| 75 | funcs_to_infer_.Clear(); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 76 | } |
| 77 | |
| 78 | private: |
Ben Murdoch | 3fb3ca8 | 2011-12-02 17:19:32 +0000 | [diff] [blame] | 79 | enum NameType { |
| 80 | kEnclosingConstructorName, |
| 81 | kLiteralName, |
| 82 | kVariableName |
| 83 | }; |
| 84 | struct Name { |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame^] | 85 | Name(const AstRawString* name, NameType type) : name(name), type(type) {} |
| 86 | const AstRawString* name; |
Ben Murdoch | 3fb3ca8 | 2011-12-02 17:19:32 +0000 | [diff] [blame] | 87 | NameType type; |
| 88 | }; |
| 89 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame^] | 90 | Zone* zone() const { return zone_; } |
Ben Murdoch | 3fb3ca8 | 2011-12-02 17:19:32 +0000 | [diff] [blame] | 91 | |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 92 | // Constructs a full name in dotted notation from gathered names. |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame^] | 93 | const AstString* MakeNameFromStack(); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 94 | |
| 95 | // A helper function for MakeNameFromStack. |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame^] | 96 | const AstString* MakeNameFromStackHelper(int pos, |
| 97 | const AstString* prev); |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 98 | |
| 99 | // Performs name inferring for added functions. |
| 100 | void InferFunctionsNames(); |
| 101 | |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame^] | 102 | AstValueFactory* ast_value_factory_; |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 103 | ZoneList<int> entries_stack_; |
Ben Murdoch | 3fb3ca8 | 2011-12-02 17:19:32 +0000 | [diff] [blame] | 104 | ZoneList<Name> names_stack_; |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 105 | ZoneList<FunctionLiteral*> funcs_to_infer_; |
Ben Murdoch | b8a8cc1 | 2014-11-26 15:28:44 +0000 | [diff] [blame^] | 106 | Zone* zone_; |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 107 | |
| 108 | DISALLOW_COPY_AND_ASSIGN(FuncNameInferrer); |
| 109 | }; |
| 110 | |
| 111 | |
Steve Block | a7e24c1 | 2009-10-30 11:49:00 +0000 | [diff] [blame] | 112 | } } // namespace v8::internal |
| 113 | |
| 114 | #endif // V8_FUNC_NAME_INFERRER_H_ |