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/object.h" | 5 #include "vm/object.h" |
6 | 6 |
7 #include "include/dart_api.h" | 7 #include "include/dart_api.h" |
8 #include "platform/assert.h" | 8 #include "platform/assert.h" |
9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 7555 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7566 return raw_ptr()->source_; | 7566 return raw_ptr()->source_; |
7567 } | 7567 } |
7568 | 7568 |
7569 | 7569 |
7570 RawString* Script::GenerateSource() const { | 7570 RawString* Script::GenerateSource() const { |
7571 const TokenStream& token_stream = TokenStream::Handle(tokens()); | 7571 const TokenStream& token_stream = TokenStream::Handle(tokens()); |
7572 return token_stream.GenerateSource(); | 7572 return token_stream.GenerateSource(); |
7573 } | 7573 } |
7574 | 7574 |
7575 | 7575 |
7576 RawGrowableObjectArray* Script::GenerateLineNumberArray() const { | |
7577 const GrowableObjectArray& info = | |
7578 GrowableObjectArray::Handle(GrowableObjectArray::New()); | |
7579 const String& source = String::Handle(Source()); | |
7580 const String& key = Symbols::Empty(); | |
7581 const Object& line_separator = Object::Handle(); | |
7582 const TokenStream& tkns = TokenStream::Handle(tokens()); | |
7583 ASSERT(!tkns.IsNull()); | |
7584 TokenStream::Iterator tkit(tkns, 0, TokenStream::Iterator::kAllTokens); | |
7585 int current_line = -1; | |
7586 Scanner s(source, key); | |
7587 s.Scan(); | |
7588 bool skippedNewline = false; | |
7589 while (tkit.CurrentTokenKind() != Token::kEOS) { | |
7590 if (tkit.CurrentTokenKind() == Token::kNEWLINE) { | |
7591 // Skip newlines from the token stream. | |
7592 skippedNewline = true; | |
7593 tkit.Advance(); | |
7594 continue; | |
7595 } | |
7596 if (s.current_token().kind != tkit.CurrentTokenKind()) { | |
7597 // Suppose we have a multiline string with interpolation: | |
7598 // | |
7599 // 10 ''' | |
7600 // 11 bar | |
7601 // 12 baz | |
7602 // 13 foo is $foo | |
7603 // 14 ''' | |
7604 // | |
7605 // In the token stream, this becomes something like: | |
7606 // | |
7607 // 10 string('bar\nbaz\nfoo is\n') | |
7608 // 11 newline | |
7609 // 12 newline | |
7610 // 13 string('') interpol_var(foo) | |
hausner
2014/03/31 23:11:32
interpol_var is followed at the end by a string co
turnidge
2014/04/01 18:06:05
Done.
| |
7611 // 14 | |
7612 // | |
7613 // In order to keep the token iterator and the scanner in sync, | |
7614 // we need to skip the extra empty string before the | |
7615 // interpolation. | |
7616 if (skippedNewline && | |
7617 (s.current_token().kind == Token::kINTERPOL_VAR || | |
7618 s.current_token().kind == Token::kINTERPOL_START) && | |
7619 tkit.CurrentTokenKind() == Token::kSTRING) { | |
7620 const String& tokenValue = String::Handle(tkit.CurrentLiteral()); | |
7621 if (tokenValue.Length() == 0) { | |
7622 tkit.Advance(); | |
7623 } | |
7624 } | |
7625 } | |
7626 skippedNewline = false; | |
7627 ASSERT(s.current_token().kind == tkit.CurrentTokenKind()); | |
7628 int token_line = s.current_token().position.line; | |
7629 if (token_line != current_line) { | |
7630 // emit line | |
7631 info.Add(line_separator); | |
7632 info.Add(Smi::Handle(Smi::New(token_line + line_offset()))); | |
7633 current_line = token_line; | |
7634 } | |
7635 // TODO(hausner): Could optimize here by not reporting tokens | |
7636 // that will never be a location used by the debugger, e.g. | |
7637 // braces, semicolons, most keywords etc. | |
7638 info.Add(Smi::Handle(Smi::New(tkit.CurrentPosition()))); | |
7639 int column = s.current_token().position.column; | |
7640 // On the first line of the script we must add the column offset. | |
7641 if (token_line == 1) { | |
7642 column += col_offset(); | |
7643 } | |
7644 info.Add(Smi::Handle(Smi::New(column))); | |
7645 tkit.Advance(); | |
7646 s.Scan(); | |
7647 } | |
7648 return info.raw(); | |
7649 } | |
7650 | |
7651 | |
7576 const char* Script::GetKindAsCString() const { | 7652 const char* Script::GetKindAsCString() const { |
7577 switch (kind()) { | 7653 switch (kind()) { |
7578 case RawScript::kScriptTag: | 7654 case RawScript::kScriptTag: |
7579 return "script"; | 7655 return "script"; |
7580 case RawScript::kLibraryTag: | 7656 case RawScript::kLibraryTag: |
7581 return "library"; | 7657 return "library"; |
7582 case RawScript::kSourceTag: | 7658 case RawScript::kSourceTag: |
7583 return "source"; | 7659 return "source"; |
7584 case RawScript::kPatchTag: | 7660 case RawScript::kPatchTag: |
7585 return "patch"; | 7661 return "patch"; |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7855 if (ref) { | 7931 if (ref) { |
7856 return; | 7932 return; |
7857 } | 7933 } |
7858 const String& source = String::Handle(Source()); | 7934 const String& source = String::Handle(Source()); |
7859 jsobj.AddProperty("source", source.ToCString()); | 7935 jsobj.AddProperty("source", source.ToCString()); |
7860 | 7936 |
7861 // Print the line number table | 7937 // Print the line number table |
7862 { | 7938 { |
7863 JSONArray tokenPosTable(&jsobj, "tokenPosTable"); | 7939 JSONArray tokenPosTable(&jsobj, "tokenPosTable"); |
7864 | 7940 |
7865 const TokenStream& tokenStream = TokenStream::Handle(tokens()); | 7941 const GrowableObjectArray& lineNumberArray = |
7866 ASSERT(!tokenStream.IsNull()); | 7942 GrowableObjectArray::Handle(GenerateLineNumberArray()); |
7867 TokenStream::Iterator tokens(tokenStream, 0); | 7943 Object& value = Object::Handle(); |
7944 intptr_t pos = 0; | |
7868 | 7945 |
7869 const String& key = Symbols::Empty(); | 7946 // Skip leading null. |
7870 Scanner scanner(source, key); | 7947 ASSERT(lineNumberArray.Length() > 0); |
7871 scanner.Scan(); | 7948 value = lineNumberArray.At(pos); |
7872 while (scanner.current_token().kind != Token::kEOS) { | 7949 ASSERT(value.IsNull()); |
7873 ASSERT(tokens.IsValid()); | 7950 pos++; |
7874 ASSERT(scanner.current_token().kind == tokens.CurrentTokenKind()); | |
7875 int current_line = scanner.current_token().position.line; | |
7876 | 7951 |
7877 // Each entry begins with a line number... | 7952 while (pos < lineNumberArray.Length()) { |
7878 JSONArray lineInfo(&tokenPosTable); | 7953 JSONArray lineInfo(&tokenPosTable); |
7879 lineInfo.AddValue(current_line + line_offset()); | 7954 while (pos < lineNumberArray.Length()) { |
7880 | 7955 value = lineNumberArray.At(pos); |
7881 // ...and is followed by (token offset, col number) pairs. | 7956 pos++; |
7882 // | 7957 if (value.IsNull()) { |
7883 // TODO(hausner): Could optimize here by not reporting tokens | |
7884 // that will never be a location used by the debugger, e.g. | |
7885 // braces, semicolons, most keywords etc. | |
7886 while (scanner.current_token().kind != Token::kEOS) { | |
7887 ASSERT(tokens.IsValid()); | |
7888 ASSERT(scanner.current_token().kind == tokens.CurrentTokenKind()); | |
7889 | |
7890 int token_line = scanner.current_token().position.line; | |
7891 if (token_line != current_line) { | |
7892 // We have hit a new line. Break to the outer loop. | |
7893 break; | 7958 break; |
7894 } | 7959 } |
7895 lineInfo.AddValue(tokens.CurrentPosition()); | 7960 const Smi& smi = Smi::Cast(value); |
7896 | 7961 lineInfo.AddValue(smi.Value()); |
7897 intptr_t column = scanner.current_token().position.column; | |
7898 if (token_line == 1) { | |
7899 // On the first line of the script we must add the column offset. | |
7900 column += col_offset(); | |
7901 } | |
7902 lineInfo.AddValue(column); | |
7903 scanner.Scan(); | |
7904 tokens.Advance(); | |
7905 } | 7962 } |
7906 } | 7963 } |
7907 } | 7964 } |
7908 } | 7965 } |
7909 | 7966 |
7910 | 7967 |
7911 DictionaryIterator::DictionaryIterator(const Library& library) | 7968 DictionaryIterator::DictionaryIterator(const Library& library) |
7912 : array_(Array::Handle(library.dictionary())), | 7969 : array_(Array::Handle(library.dictionary())), |
7913 // Last element in array is a Smi indicating the number of entries used. | 7970 // Last element in array is a Smi indicating the number of entries used. |
7914 size_(Array::Handle(library.dictionary()).Length() - 1), | 7971 size_(Array::Handle(library.dictionary()).Length() - 1), |
(...skipping 10347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
18262 return "_MirrorReference"; | 18319 return "_MirrorReference"; |
18263 } | 18320 } |
18264 | 18321 |
18265 | 18322 |
18266 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { | 18323 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { |
18267 Instance::PrintToJSONStream(stream, ref); | 18324 Instance::PrintToJSONStream(stream, ref); |
18268 } | 18325 } |
18269 | 18326 |
18270 | 18327 |
18271 } // namespace dart | 18328 } // namespace dart |
OLD | NEW |