| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
| 8 #include "vm/bigint_operations.h" | 8 #include "vm/bigint_operations.h" |
| 9 #include "vm/bootstrap.h" | 9 #include "vm/bootstrap.h" |
| 10 #include "vm/class_finalizer.h" | 10 #include "vm/class_finalizer.h" |
| (...skipping 8858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8869 if (obj.IsClass()) { | 8869 if (obj.IsClass()) { |
| 8870 return Class::Cast(obj).raw(); | 8870 return Class::Cast(obj).raw(); |
| 8871 } | 8871 } |
| 8872 return Class::null(); | 8872 return Class::null(); |
| 8873 } | 8873 } |
| 8874 | 8874 |
| 8875 | 8875 |
| 8876 // Resolve an identifier by checking the global scope of the current | 8876 // Resolve an identifier by checking the global scope of the current |
| 8877 // library. If not found in the current library, then look in the scopes | 8877 // library. If not found in the current library, then look in the scopes |
| 8878 // of all libraries that are imported without a library prefix. | 8878 // of all libraries that are imported without a library prefix. |
| 8879 // Issue an error if the identifier is not found in the global scope | |
| 8880 // of the current library, but is defined in more than one imported | |
| 8881 // library, i.e. if the identifier cannot be resolved unambiguously. | |
| 8882 AstNode* Parser::ResolveIdentInCurrentLibraryScope(intptr_t ident_pos, | 8879 AstNode* Parser::ResolveIdentInCurrentLibraryScope(intptr_t ident_pos, |
| 8883 const String& ident) { | 8880 const String& ident) { |
| 8884 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); | 8881 TRACE_PARSER("ResolveIdentInCurrentLibraryScope"); |
| 8885 const Object& obj = | 8882 const Object& obj = |
| 8886 Object::Handle(ResolveNameInCurrentLibraryScope(ident)); | 8883 Object::Handle(ResolveNameInCurrentLibraryScope(ident)); |
| 8887 if (obj.IsClass()) { | 8884 if (obj.IsClass()) { |
| 8888 const Class& cls = Class::Cast(obj); | 8885 const Class& cls = Class::Cast(obj); |
| 8889 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw())); | 8886 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw())); |
| 8890 } else if (obj.IsField()) { | 8887 } else if (obj.IsField()) { |
| 8891 const Field& field = Field::Cast(obj); | 8888 const Field& field = Field::Cast(obj); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8925 Object::Handle(ResolveNameInPrefixScope(prefix, name)); | 8922 Object::Handle(ResolveNameInPrefixScope(prefix, name)); |
| 8926 if (obj.IsClass()) { | 8923 if (obj.IsClass()) { |
| 8927 return Class::Cast(obj).raw(); | 8924 return Class::Cast(obj).raw(); |
| 8928 } | 8925 } |
| 8929 return Class::null(); | 8926 return Class::null(); |
| 8930 } | 8927 } |
| 8931 | 8928 |
| 8932 | 8929 |
| 8933 // Do a lookup for the identifier in the scope of the specified | 8930 // Do a lookup for the identifier in the scope of the specified |
| 8934 // library prefix. This means trying to resolve it locally in all of the | 8931 // library prefix. This means trying to resolve it locally in all of the |
| 8935 // libraries present in the library prefix. If there are multiple libraries | 8932 // libraries present in the library prefix. |
| 8936 // with the name, issue an ambiguous reference error. | |
| 8937 AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos, | 8933 AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos, |
| 8938 const LibraryPrefix& prefix, | 8934 const LibraryPrefix& prefix, |
| 8939 const String& ident) { | 8935 const String& ident) { |
| 8940 TRACE_PARSER("ResolveIdentInPrefixScope"); | 8936 TRACE_PARSER("ResolveIdentInPrefixScope"); |
| 8941 Object& obj = Object::Handle(ResolveNameInPrefixScope(prefix, ident)); | 8937 Object& obj = Object::Handle(ResolveNameInPrefixScope(prefix, ident)); |
| 8942 if (obj.IsNull()) { | 8938 if (obj.IsNull()) { |
| 8943 // Unresolved prefixed primary identifier. | 8939 // Unresolved prefixed primary identifier. |
| 8944 ErrorMsg(ident_pos, "identifier '%s.%s' cannot be resolved", | 8940 String& qualified_name = String::ZoneHandle(prefix.name()); |
| 8945 String::Handle(prefix.name()).ToCString(), | 8941 qualified_name = String::Concat(qualified_name, Symbols::Dot()); |
| 8946 ident.ToCString()); | 8942 qualified_name = String::Concat(qualified_name, ident); |
| 8947 } | 8943 qualified_name = Symbols::New(qualified_name); |
| 8948 if (obj.IsClass()) { | 8944 return new PrimaryNode(ident_pos, qualified_name); |
| 8945 } else if (obj.IsClass()) { |
| 8949 const Class& cls = Class::Cast(obj); | 8946 const Class& cls = Class::Cast(obj); |
| 8950 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw())); | 8947 return new PrimaryNode(ident_pos, Class::ZoneHandle(cls.raw())); |
| 8951 } else if (obj.IsField()) { | 8948 } else if (obj.IsField()) { |
| 8952 const Field& field = Field::Cast(obj); | 8949 const Field& field = Field::Cast(obj); |
| 8953 ASSERT(field.is_static()); | 8950 ASSERT(field.is_static()); |
| 8954 return GenerateStaticFieldLookup(field, ident_pos); | 8951 return GenerateStaticFieldLookup(field, ident_pos); |
| 8955 } else if (obj.IsFunction()) { | 8952 } else if (obj.IsFunction()) { |
| 8956 const Function& func = Function::Cast(obj); | 8953 const Function& func = Function::Cast(obj); |
| 8957 ASSERT(func.is_static()); | 8954 ASSERT(func.is_static()); |
| 8958 if (func.IsGetterFunction() || func.IsSetterFunction()) { | 8955 if (func.IsGetterFunction() || func.IsSetterFunction()) { |
| 8959 return new StaticGetterNode(ident_pos, | 8956 return new StaticGetterNode(ident_pos, |
| 8960 /* receiver */ NULL, | 8957 /* receiver */ NULL, |
| 8961 /* is_super_getter */ false, | 8958 /* is_super_getter */ false, |
| 8962 Class::ZoneHandle(func.Owner()), | 8959 Class::ZoneHandle(func.Owner()), |
| 8963 ident); | 8960 ident); |
| 8964 | 8961 |
| 8965 } else { | 8962 } else { |
| 8966 return new PrimaryNode(ident_pos, Function::ZoneHandle(func.raw())); | 8963 return new PrimaryNode(ident_pos, Function::ZoneHandle(func.raw())); |
| 8967 } | 8964 } |
| 8968 } else { | |
| 8969 // TODO(hausner): Should this be an error? It is not meaningful to | |
| 8970 // reference a library prefix defined in an imported library. | |
| 8971 ASSERT(obj.IsLibraryPrefix()); | |
| 8972 } | 8965 } |
| 8973 // Lexically unresolved primary identifiers are referenced by their name. | 8966 // All possible object types are handled above. |
| 8974 return new PrimaryNode(ident_pos, ident); | 8967 UNREACHABLE(); |
| 8968 return NULL; |
| 8975 } | 8969 } |
| 8976 | 8970 |
| 8977 | 8971 |
| 8978 // Resolve identifier. Issue an error message if | 8972 // Resolve identifier. Issue an error message if |
| 8979 // the ident refers to a method and allow_closure_names is false. | 8973 // the ident refers to a method and allow_closure_names is false. |
| 8980 // If the name cannot be resolved, turn it into an instance field access | 8974 // If the name cannot be resolved, turn it into an instance field access |
| 8981 // if we're compiling an instance method, or issue an error message | 8975 // if we're compiling an instance method, or generate |
| 8982 // if we're compiling a static method. | 8976 // throw NoSuchMethodError if we're compiling a static method. |
| 8983 AstNode* Parser::ResolveIdent(intptr_t ident_pos, | 8977 AstNode* Parser::ResolveIdent(intptr_t ident_pos, |
| 8984 const String& ident, | 8978 const String& ident, |
| 8985 bool allow_closure_names) { | 8979 bool allow_closure_names) { |
| 8986 TRACE_PARSER("ResolveIdent"); | 8980 TRACE_PARSER("ResolveIdent"); |
| 8987 // First try to find the variable in the local scope (block scope or | 8981 // First try to find the variable in the local scope (block scope or |
| 8988 // class scope). | 8982 // class scope). |
| 8989 AstNode* resolved = NULL; | 8983 AstNode* resolved = NULL; |
| 8990 ResolveIdentInLocalScope(ident_pos, ident, &resolved); | 8984 ResolveIdentInLocalScope(ident_pos, ident, &resolved); |
| 8991 if (resolved == NULL) { | 8985 if (resolved == NULL) { |
| 8992 // Check whether the identifier is a type parameter. | 8986 // Check whether the identifier is a type parameter. |
| (...skipping 965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9958 primary = ResolveIdentInCurrentLibraryScope(qual_ident.ident_pos, | 9952 primary = ResolveIdentInCurrentLibraryScope(qual_ident.ident_pos, |
| 9959 *qual_ident.ident); | 9953 *qual_ident.ident); |
| 9960 } | 9954 } |
| 9961 } else { | 9955 } else { |
| 9962 // This is a qualified identifier with a library prefix so resolve | 9956 // This is a qualified identifier with a library prefix so resolve |
| 9963 // the identifier locally in that library (we do not include the | 9957 // the identifier locally in that library (we do not include the |
| 9964 // libraries imported by that library). | 9958 // libraries imported by that library). |
| 9965 primary = ResolveIdentInPrefixScope(qual_ident.ident_pos, | 9959 primary = ResolveIdentInPrefixScope(qual_ident.ident_pos, |
| 9966 *qual_ident.lib_prefix, | 9960 *qual_ident.lib_prefix, |
| 9967 *qual_ident.ident); | 9961 *qual_ident.ident); |
| 9962 // If the identifier could not be resolved, throw a NoSuchMethodError. |
| 9963 // Note: unlike in the case of an unqualified identifier, do not |
| 9964 // interpret the unresolved identifier as an instance method or |
| 9965 // instance getter call when compiling an instance method. |
| 9966 // TODO(hausner): Ideally we should generate the NoSuchMethodError |
| 9967 // later, when we know more about how the unresolved name is used. |
| 9968 // For example, we don't know yet whether the unresolved name |
| 9969 // refers to a getter or a setter. However, it is more awkward |
| 9970 // to distinuish four NoSuchMethodError cases all over the place |
| 9971 // in the parser. The four cases are: prefixed vs non-prefixed |
| 9972 // name, static vs dynamic context in which the unresolved name |
| 9973 // is used. We cheat a little here by looking at the next token |
| 9974 // to determine whether we have an unresolved method call or |
| 9975 // field access. |
| 9976 if (primary->IsPrimaryNode() && |
| 9977 primary->AsPrimaryNode()->primary().IsString()) { |
| 9978 InvocationMirror::Type call_type = |
| 9979 CurrentToken() == Token::kLPAREN ? |
| 9980 InvocationMirror::kMethod : InvocationMirror::kGetter; |
| 9981 const String& unresolved_name = |
| 9982 String::Cast(primary->AsPrimaryNode()->primary()); |
| 9983 primary = ThrowNoSuchMethodError(primary->token_pos(), |
| 9984 current_class(), |
| 9985 unresolved_name, |
| 9986 NULL, // No arguments. |
| 9987 InvocationMirror::kTopLevel, |
| 9988 call_type); |
| 9989 } |
| 9968 } | 9990 } |
| 9969 ASSERT(primary != NULL); | 9991 ASSERT(primary != NULL); |
| 9970 } else if (CurrentToken() == Token::kTHIS) { | 9992 } else if (CurrentToken() == Token::kTHIS) { |
| 9971 LocalVariable* local = LookupLocalScope(Symbols::This()); | 9993 LocalVariable* local = LookupLocalScope(Symbols::This()); |
| 9972 if (local == NULL) { | 9994 if (local == NULL) { |
| 9973 ErrorMsg("receiver 'this' is not in scope"); | 9995 ErrorMsg("receiver 'this' is not in scope"); |
| 9974 } | 9996 } |
| 9975 primary = new LoadLocalNode(TokenPos(), local); | 9997 primary = new LoadLocalNode(TokenPos(), local); |
| 9976 ConsumeToken(); | 9998 ConsumeToken(); |
| 9977 } else if (CurrentToken() == Token::kINTEGER) { | 9999 } else if (CurrentToken() == Token::kINTEGER) { |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10394 void Parser::SkipQualIdent() { | 10416 void Parser::SkipQualIdent() { |
| 10395 ASSERT(IsIdentifier()); | 10417 ASSERT(IsIdentifier()); |
| 10396 ConsumeToken(); | 10418 ConsumeToken(); |
| 10397 if (CurrentToken() == Token::kPERIOD) { | 10419 if (CurrentToken() == Token::kPERIOD) { |
| 10398 ConsumeToken(); // Consume the kPERIOD token. | 10420 ConsumeToken(); // Consume the kPERIOD token. |
| 10399 ExpectIdentifier("identifier expected after '.'"); | 10421 ExpectIdentifier("identifier expected after '.'"); |
| 10400 } | 10422 } |
| 10401 } | 10423 } |
| 10402 | 10424 |
| 10403 } // namespace dart | 10425 } // namespace dart |
| OLD | NEW |