Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 library fasta.analyzer.ast_builder; | 5 library fasta.analyzer.ast_builder; |
| 6 | 6 |
| 7 import 'package:analyzer/analyzer.dart'; | 7 import 'package:analyzer/analyzer.dart'; |
| 8 import 'package:analyzer/dart/ast/ast_factory.dart' show AstFactory; | 8 import 'package:analyzer/dart/ast/ast_factory.dart' show AstFactory; |
| 9 import 'package:analyzer/dart/ast/standard_ast_factory.dart' as standard; | 9 import 'package:analyzer/dart/ast/standard_ast_factory.dart' as standard; |
| 10 import 'package:analyzer/dart/ast/token.dart' as analyzer show Token; | 10 import 'package:analyzer/dart/ast/token.dart' as analyzer show Token; |
| 11 import 'package:analyzer/dart/element/element.dart' show Element; | 11 import 'package:analyzer/dart/element/element.dart' show Element; |
| 12 import 'package:front_end/src/fasta/parser/parser.dart' | 12 import 'package:front_end/src/fasta/parser/parser.dart' |
| 13 show FormalParameterType; | 13 show FormalParameterType; |
| 14 import 'package:front_end/src/fasta/scanner/precedence.dart'; | |
| 15 import 'package:front_end/src/fasta/scanner/string_scanner.dart'; | |
| 14 import 'package:front_end/src/fasta/scanner/token.dart' | 16 import 'package:front_end/src/fasta/scanner/token.dart' |
| 15 show BeginGroupToken, Token; | 17 show BeginGroupToken, CommentToken, Token; |
| 16 | 18 |
| 17 import 'package:front_end/src/fasta/errors.dart' show internalError; | 19 import 'package:front_end/src/fasta/errors.dart' show internalError; |
| 18 import 'package:front_end/src/fasta/fasta_codes.dart' | 20 import 'package:front_end/src/fasta/fasta_codes.dart' |
| 19 show FastaMessage, codeExpectedExpression; | 21 show FastaMessage, codeExpectedExpression; |
| 20 import 'package:front_end/src/fasta/kernel/kernel_builder.dart' | 22 import 'package:front_end/src/fasta/kernel/kernel_builder.dart' |
| 21 show Builder, KernelLibraryBuilder, ProcedureBuilder, Scope; | 23 show Builder, KernelLibraryBuilder, ProcedureBuilder, Scope; |
| 22 import 'package:front_end/src/fasta/parser/identifier_context.dart' | 24 import 'package:front_end/src/fasta/parser/identifier_context.dart' |
| 23 show IdentifierContext; | 25 show IdentifierContext; |
| 24 import 'package:front_end/src/fasta/quote.dart'; | 26 import 'package:front_end/src/fasta/quote.dart'; |
| 25 import 'package:front_end/src/fasta/source/scope_listener.dart' | 27 import 'package:front_end/src/fasta/source/scope_listener.dart' |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 38 final AstFactory ast = standard.astFactory; | 40 final AstFactory ast = standard.astFactory; |
| 39 | 41 |
| 40 final ErrorReporter errorReporter; | 42 final ErrorReporter errorReporter; |
| 41 final KernelLibraryBuilder library; | 43 final KernelLibraryBuilder library; |
| 42 final Builder member; | 44 final Builder member; |
| 43 final ElementStore elementStore; | 45 final ElementStore elementStore; |
| 44 | 46 |
| 45 @override | 47 @override |
| 46 final Uri uri; | 48 final Uri uri; |
| 47 | 49 |
| 50 bool parseGenericMethodComments = false; | |
| 51 | |
| 48 /// The name of the class currently being parsed, or `null` if no class is | 52 /// The name of the class currently being parsed, or `null` if no class is |
| 49 /// being parsed. | 53 /// being parsed. |
| 50 String className; | 54 String className; |
| 51 | 55 |
| 52 AstBuilder(this.errorReporter, this.library, this.member, this.elementStore, | 56 AstBuilder(this.errorReporter, this.library, this.member, this.elementStore, |
| 53 Scope scope, | 57 Scope scope, |
| 54 [Uri uri]) | 58 [Uri uri]) |
| 55 : uri = uri ?? library.fileUri, | 59 : uri = uri ?? library.fileUri, |
| 56 super(scope); | 60 super(scope); |
| 57 | 61 |
| (...skipping 1803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1861 // See Parser.parseCommentAndMetadata | 1865 // See Parser.parseCommentAndMetadata |
| 1862 var tokens = <analyzer.Token>[toAnalyzerCommentToken(comments)]; | 1866 var tokens = <analyzer.Token>[toAnalyzerCommentToken(comments)]; |
| 1863 var references = <CommentReference>[]; | 1867 var references = <CommentReference>[]; |
| 1864 return ast.documentationComment(tokens, references); | 1868 return ast.documentationComment(tokens, references); |
| 1865 } | 1869 } |
| 1866 | 1870 |
| 1867 @override | 1871 @override |
| 1868 void debugEvent(String name) { | 1872 void debugEvent(String name) { |
| 1869 // printEvent(name); | 1873 // printEvent(name); |
| 1870 } | 1874 } |
| 1875 | |
| 1876 @override | |
| 1877 Token injectGenericCommentTypeAssign(Token token) { | |
|
Paul Berry
2017/04/07 16:03:32
I'm concerned about putting these methods in AstBu
scheglov
2017/04/07 19:58:52
Done.
| |
| 1878 return _injectGenericComment(token, GENERIC_METHOD_TYPE_ASSIGN, 3); | |
| 1879 } | |
| 1880 | |
| 1881 @override | |
| 1882 Token injectGenericCommentTypeList(Token token) { | |
| 1883 return _injectGenericComment(token, GENERIC_METHOD_TYPE_LIST, 2); | |
| 1884 } | |
| 1885 | |
| 1886 @override | |
| 1887 Token replaceTokenWithGenericCommentTypeAssign( | |
| 1888 Token tokenToStartReplacing, Token tokenWithComment) { | |
| 1889 Token injected = injectGenericCommentTypeAssign(tokenWithComment); | |
| 1890 if (!identical(injected, tokenWithComment)) { | |
| 1891 Token prev = tokenToStartReplacing.previous; | |
| 1892 prev.setNextWithoutSettingPrevious(injected); | |
| 1893 tokenToStartReplacing = injected; | |
| 1894 tokenToStartReplacing.previous = prev; | |
| 1895 } | |
| 1896 return tokenToStartReplacing; | |
| 1897 } | |
| 1898 | |
| 1899 /// Check if the given [token] has a comment token with the given [info], | |
| 1900 /// which should be either [GENERIC_METHOD_TYPE_ASSIGN] or | |
| 1901 /// [GENERIC_METHOD_TYPE_LIST]. If found, parse the comment into tokens and | |
| 1902 /// inject into the token stream before the [token]. | |
| 1903 Token _injectGenericComment(Token token, PrecedenceInfo info, int prefixLen) { | |
| 1904 if (parseGenericMethodComments) { | |
| 1905 CommentToken t = token.precedingCommentTokens; | |
| 1906 for (; t != null; t = t.next) { | |
| 1907 if (t.info == info) { | |
| 1908 String code = t.lexeme.substring(prefixLen, t.lexeme.length - 2); | |
| 1909 Token tokens = _scanGenericMethodComment(code, t.offset + prefixLen); | |
| 1910 if (tokens != null) { | |
| 1911 // Remove the token from the comment stream. | |
| 1912 t.remove(); | |
| 1913 // Insert the tokens into the stream. | |
| 1914 _injectTokenList(token, tokens); | |
| 1915 return tokens; | |
| 1916 } | |
| 1917 } | |
| 1918 } | |
| 1919 } | |
| 1920 return token; | |
| 1921 } | |
| 1922 | |
| 1923 void _injectTokenList(Token beforeToken, Token firstToken) { | |
| 1924 // Scanner creates a cyclic EOF token. | |
| 1925 Token lastToken = firstToken; | |
| 1926 while (lastToken.next.info != EOF_INFO) { | |
| 1927 lastToken = lastToken.next; | |
| 1928 } | |
| 1929 // Inject these new tokens into the stream. | |
| 1930 Token previous = beforeToken.previous; | |
| 1931 lastToken.setNext(beforeToken); | |
| 1932 previous.setNext(firstToken); | |
| 1933 beforeToken = firstToken; | |
| 1934 } | |
| 1935 | |
| 1936 /// Scans the given [code], and returns the tokens, otherwise returns `null`. | |
| 1937 Token _scanGenericMethodComment(String code, int offset) { | |
| 1938 var scanner = new SubStringScanner(offset, code); | |
| 1939 Token firstToken = scanner.tokenize(); | |
| 1940 if (scanner.hasErrors) { | |
| 1941 return null; | |
| 1942 } | |
| 1943 return firstToken; | |
| 1944 } | |
| 1871 } | 1945 } |
| 1872 | 1946 |
| 1873 /// Data structure placed on the stack to represent a class body. | 1947 /// Data structure placed on the stack to represent a class body. |
| 1874 /// | 1948 /// |
| 1875 /// This is needed because analyzer has no separate AST representation of a | 1949 /// This is needed because analyzer has no separate AST representation of a |
| 1876 /// class body; it simply stores all of the relevant data in the | 1950 /// class body; it simply stores all of the relevant data in the |
| 1877 /// [ClassDeclaration] object. | 1951 /// [ClassDeclaration] object. |
| 1878 class _ClassBody { | 1952 class _ClassBody { |
| 1879 final Token beginToken; | 1953 final Token beginToken; |
| 1880 | 1954 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1965 } else if (identical('static', s)) { | 2039 } else if (identical('static', s)) { |
| 1966 staticKeyword = token; | 2040 staticKeyword = token; |
| 1967 } else if (identical('var', s)) { | 2041 } else if (identical('var', s)) { |
| 1968 finalConstOrVarKeyword = token; | 2042 finalConstOrVarKeyword = token; |
| 1969 } else { | 2043 } else { |
| 1970 internalError('Unhandled modifier: $s'); | 2044 internalError('Unhandled modifier: $s'); |
| 1971 } | 2045 } |
| 1972 } | 2046 } |
| 1973 } | 2047 } |
| 1974 } | 2048 } |
| OLD | NEW |