| 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 "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 3942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3953 | 3953 |
| 3954 void Parser::ParseLibraryImport() { | 3954 void Parser::ParseLibraryImport() { |
| 3955 TRACE_PARSER("ParseLibraryImport"); | 3955 TRACE_PARSER("ParseLibraryImport"); |
| 3956 while (CurrentToken() == Token::kIMPORT) { | 3956 while (CurrentToken() == Token::kIMPORT) { |
| 3957 const intptr_t import_pos = TokenPos(); | 3957 const intptr_t import_pos = TokenPos(); |
| 3958 ConsumeToken(); | 3958 ConsumeToken(); |
| 3959 ExpectToken(Token::kLPAREN); | 3959 ExpectToken(Token::kLPAREN); |
| 3960 if (CurrentToken() != Token::kSTRING) { | 3960 if (CurrentToken() != Token::kSTRING) { |
| 3961 ErrorMsg("library url expected"); | 3961 ErrorMsg("library url expected"); |
| 3962 } | 3962 } |
| 3963 const String& url = *ParseImportStringLiteral(); | 3963 const String& url = *CurrentLiteral(); |
| 3964 ConsumeToken(); |
| 3964 String& prefix = String::Handle(); | 3965 String& prefix = String::Handle(); |
| 3965 if (CurrentToken() == Token::kCOMMA) { | 3966 if (CurrentToken() == Token::kCOMMA) { |
| 3966 ConsumeToken(); | 3967 ConsumeToken(); |
| 3967 if (!IsLiteral("prefix")) { | 3968 if (!IsLiteral("prefix")) { |
| 3968 ErrorMsg("prefix: expected"); | 3969 ErrorMsg("prefix: expected"); |
| 3969 } | 3970 } |
| 3970 ConsumeToken(); | 3971 ConsumeToken(); |
| 3971 ExpectToken(Token::kCOLON); | 3972 ExpectToken(Token::kCOLON); |
| 3972 if (CurrentToken() != Token::kSTRING) { | 3973 if (CurrentToken() != Token::kSTRING) { |
| 3973 ErrorMsg("prefix expected"); | 3974 ErrorMsg("prefix expected"); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4017 | 4018 |
| 4018 void Parser::ParseLibraryInclude() { | 4019 void Parser::ParseLibraryInclude() { |
| 4019 TRACE_PARSER("ParseLibraryInclude"); | 4020 TRACE_PARSER("ParseLibraryInclude"); |
| 4020 while (CurrentToken() == Token::kSOURCE) { | 4021 while (CurrentToken() == Token::kSOURCE) { |
| 4021 const intptr_t source_pos = TokenPos(); | 4022 const intptr_t source_pos = TokenPos(); |
| 4022 ConsumeToken(); | 4023 ConsumeToken(); |
| 4023 ExpectToken(Token::kLPAREN); | 4024 ExpectToken(Token::kLPAREN); |
| 4024 if (CurrentToken() != Token::kSTRING) { | 4025 if (CurrentToken() != Token::kSTRING) { |
| 4025 ErrorMsg("source url expected"); | 4026 ErrorMsg("source url expected"); |
| 4026 } | 4027 } |
| 4027 const String& url = *ParseImportStringLiteral(); | 4028 const String& url = *CurrentLiteral(); |
| 4029 ConsumeToken(); |
| 4028 ExpectToken(Token::kRPAREN); | 4030 ExpectToken(Token::kRPAREN); |
| 4029 ExpectToken(Token::kSEMICOLON); | 4031 ExpectToken(Token::kSEMICOLON); |
| 4030 Dart_Handle handle = CallLibraryTagHandler(kCanonicalizeUrl, | 4032 Dart_Handle handle = CallLibraryTagHandler(kCanonicalizeUrl, |
| 4031 source_pos, | 4033 source_pos, |
| 4032 url); | 4034 url); |
| 4033 const String& canon_url = String::CheckedHandle(Api::UnwrapHandle(handle)); | 4035 const String& canon_url = String::CheckedHandle(Api::UnwrapHandle(handle)); |
| 4034 CallLibraryTagHandler(kSourceTag, source_pos, canon_url); | 4036 CallLibraryTagHandler(kSourceTag, source_pos, canon_url); |
| 4035 } | 4037 } |
| 4036 } | 4038 } |
| 4037 | 4039 |
| (...skipping 3998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8036 } else { | 8038 } else { |
| 8037 ASSERT(primary->primary().IsClass()); | 8039 ASSERT(primary->primary().IsClass()); |
| 8038 ErrorMsg(ident_pos, "illegal reference to class or interface '%s'", | 8040 ErrorMsg(ident_pos, "illegal reference to class or interface '%s'", |
| 8039 ident.ToCString()); | 8041 ident.ToCString()); |
| 8040 } | 8042 } |
| 8041 } | 8043 } |
| 8042 return resolved; | 8044 return resolved; |
| 8043 } | 8045 } |
| 8044 | 8046 |
| 8045 | 8047 |
| 8046 // Resolve variables used in an import string literal. | |
| 8047 // If the variable name cannot be resolved issue an error message. | |
| 8048 // Currently we only resolve against the global map which is passed in | |
| 8049 // when the script is loaded. | |
| 8050 RawString* Parser::ResolveImportVar(intptr_t ident_pos, const String& ident) { | |
| 8051 TRACE_PARSER("ResolveImportVar"); | |
| 8052 const Array& import_map = | |
| 8053 Array::Handle(Isolate::Current()->object_store()->import_map()); | |
| 8054 if (!import_map.IsNull()) { | |
| 8055 intptr_t length = import_map.Length(); | |
| 8056 intptr_t index = 0; | |
| 8057 String& name = String::Handle(); | |
| 8058 while (index < (length - 1)) { | |
| 8059 name ^= import_map.At(index); | |
| 8060 if (name.Equals(ident)) { | |
| 8061 name ^= import_map.At(index + 1); | |
| 8062 return name.raw(); | |
| 8063 } | |
| 8064 index += 2; | |
| 8065 } | |
| 8066 } | |
| 8067 ErrorMsg(ident_pos, "import variable '%s' has not been defined", | |
| 8068 ident.ToCString()); | |
| 8069 return String::null(); | |
| 8070 } | |
| 8071 | |
| 8072 | |
| 8073 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and | 8048 // Parses type = [ident "."] ident ["<" type { "," type } ">"], then resolve and |
| 8074 // finalize it according to the given type finalization mode. | 8049 // finalize it according to the given type finalization mode. |
| 8075 RawAbstractType* Parser::ParseType( | 8050 RawAbstractType* Parser::ParseType( |
| 8076 ClassFinalizer::FinalizationKind finalization) { | 8051 ClassFinalizer::FinalizationKind finalization) { |
| 8077 TRACE_PARSER("ParseType"); | 8052 TRACE_PARSER("ParseType"); |
| 8078 if (CurrentToken() != Token::kIDENT) { | 8053 if (CurrentToken() != Token::kIDENT) { |
| 8079 ErrorMsg("type name expected"); | 8054 ErrorMsg("type name expected"); |
| 8080 } | 8055 } |
| 8081 QualIdent type_name; | 8056 QualIdent type_name; |
| 8082 if (finalization == ClassFinalizer::kIgnore) { | 8057 if (finalization == ClassFinalizer::kIgnore) { |
| (...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8879 new ArgumentListNode(values->token_pos()); | 8854 new ArgumentListNode(values->token_pos()); |
| 8880 interpolate_arg->Add(values); | 8855 interpolate_arg->Add(values); |
| 8881 const String& cls_name = String::Handle(Symbols::StringBase()); | 8856 const String& cls_name = String::Handle(Symbols::StringBase()); |
| 8882 const String& func_name = String::Handle(Symbols::Interpolate()); | 8857 const String& func_name = String::Handle(Symbols::Interpolate()); |
| 8883 primary = MakeStaticCall(cls_name, func_name, interpolate_arg); | 8858 primary = MakeStaticCall(cls_name, func_name, interpolate_arg); |
| 8884 } | 8859 } |
| 8885 return primary; | 8860 return primary; |
| 8886 } | 8861 } |
| 8887 | 8862 |
| 8888 | 8863 |
| 8889 // An import string literal consists of the concatenation of the next n tokens | |
| 8890 // that satisfy the EBNF grammar: | |
| 8891 // literal = kSTRING {{ interpol }+ kSTRING } | |
| 8892 // interpol = kINTERPOL_VAR | |
| 8893 // In other words, the scanner breaks down interpolated strings so that | |
| 8894 // a string literal always begins and ends with a kSTRING token, and | |
| 8895 // there are never two kSTRING tokens next to each other. | |
| 8896 String* Parser::ParseImportStringLiteral() { | |
| 8897 TRACE_PARSER("ParseImportStringLiteral"); | |
| 8898 if ((CurrentToken() == Token::kSTRING) && | |
| 8899 (LookaheadToken(1) != Token::kINTERPOL_VAR) && | |
| 8900 (LookaheadToken(1) != Token::kINTERPOL_START)) { | |
| 8901 // Common case: no interpolation. | |
| 8902 String* result = CurrentLiteral(); | |
| 8903 ConsumeToken(); | |
| 8904 return result; | |
| 8905 } | |
| 8906 // String interpolation needed. | |
| 8907 String& result = String::ZoneHandle(Symbols::Empty()); | |
| 8908 String& resolved_name = String::Handle(); | |
| 8909 while (CurrentToken() == Token::kSTRING) { | |
| 8910 result = String::Concat(result, *CurrentLiteral()); | |
| 8911 ConsumeToken(); | |
| 8912 if ((CurrentToken() != Token::kINTERPOL_VAR) && | |
| 8913 (CurrentToken() != Token::kINTERPOL_START)) { | |
| 8914 break; | |
| 8915 } | |
| 8916 while ((CurrentToken() == Token::kINTERPOL_VAR) || | |
| 8917 (CurrentToken() == Token::kINTERPOL_START)) { | |
| 8918 if (CurrentToken() == Token::kINTERPOL_START) { | |
| 8919 ConsumeToken(); | |
| 8920 if (IsIdentifier()) { | |
| 8921 resolved_name = ResolveImportVar(TokenPos(), *CurrentLiteral()); | |
| 8922 result = String::Concat(result, resolved_name); | |
| 8923 ConsumeToken(); | |
| 8924 if (CurrentToken() != Token::kINTERPOL_END) { | |
| 8925 ErrorMsg("'}' expected"); | |
| 8926 } | |
| 8927 ConsumeToken(); | |
| 8928 } else { | |
| 8929 ErrorMsg("identifier expected"); | |
| 8930 } | |
| 8931 } else { | |
| 8932 ASSERT(CurrentToken() == Token::kINTERPOL_VAR); | |
| 8933 resolved_name = ResolveImportVar(TokenPos(), *CurrentLiteral()); | |
| 8934 result = String::Concat(result, resolved_name); | |
| 8935 ConsumeToken(); | |
| 8936 } | |
| 8937 } | |
| 8938 // A string literal always ends with a kSTRING token. | |
| 8939 ASSERT(CurrentToken() == Token::kSTRING); | |
| 8940 } | |
| 8941 return &result; | |
| 8942 } | |
| 8943 | |
| 8944 | |
| 8945 AstNode* Parser::ParseArgumentDefinitionTest() { | 8864 AstNode* Parser::ParseArgumentDefinitionTest() { |
| 8946 const intptr_t test_pos = TokenPos(); | 8865 const intptr_t test_pos = TokenPos(); |
| 8947 ConsumeToken(); | 8866 ConsumeToken(); |
| 8948 const intptr_t ident_pos = TokenPos(); | 8867 const intptr_t ident_pos = TokenPos(); |
| 8949 String* ident = ExpectIdentifier("parameter name expected"); | 8868 String* ident = ExpectIdentifier("parameter name expected"); |
| 8950 Function& owner_function = Function::Handle(); | 8869 Function& owner_function = Function::Handle(); |
| 8951 LocalScope* owner_scope; | 8870 LocalScope* owner_scope; |
| 8952 intptr_t param_index; | 8871 intptr_t param_index; |
| 8953 if (!IsFormalParameter(*ident, &owner_function, &owner_scope, ¶m_index)) { | 8872 if (!IsFormalParameter(*ident, &owner_function, &owner_scope, ¶m_index)) { |
| 8954 ErrorMsg(ident_pos, "formal parameter name expected"); | 8873 ErrorMsg(ident_pos, "formal parameter name expected"); |
| (...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9415 void Parser::SkipQualIdent() { | 9334 void Parser::SkipQualIdent() { |
| 9416 ASSERT(IsIdentifier()); | 9335 ASSERT(IsIdentifier()); |
| 9417 ConsumeToken(); | 9336 ConsumeToken(); |
| 9418 if (CurrentToken() == Token::kPERIOD) { | 9337 if (CurrentToken() == Token::kPERIOD) { |
| 9419 ConsumeToken(); // Consume the kPERIOD token. | 9338 ConsumeToken(); // Consume the kPERIOD token. |
| 9420 ExpectIdentifier("identifier expected after '.'"); | 9339 ExpectIdentifier("identifier expected after '.'"); |
| 9421 } | 9340 } |
| 9422 } | 9341 } |
| 9423 | 9342 |
| 9424 } // namespace dart | 9343 } // namespace dart |
| OLD | NEW |