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 |