OLD | NEW |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 import 'dart:async'; | 5 import 'dart:async'; |
6 import 'dart:math'; | 6 import 'dart:math'; |
7 | 7 |
8 import 'package:analysis_server/src/protocol_server.dart' hide Element; | 8 import 'package:analysis_server/src/protocol_server.dart' hide Element; |
9 import 'package:analysis_server/src/services/correction/source_buffer.dart'; | 9 import 'package:analysis_server/src/services/correction/source_buffer.dart'; |
10 import 'package:analysis_server/src/services/correction/util.dart'; | 10 import 'package:analysis_server/src/services/correction/util.dart'; |
11 import 'package:analyzer/dart/ast/ast.dart'; | 11 import 'package:analyzer/dart/ast/ast.dart'; |
12 import 'package:analyzer/dart/ast/token.dart'; | 12 import 'package:analyzer/dart/ast/token.dart'; |
13 import 'package:analyzer/dart/element/element.dart'; | 13 import 'package:analyzer/dart/element/element.dart'; |
14 import 'package:analyzer/error/error.dart'; | 14 import 'package:analyzer/error/error.dart'; |
15 import 'package:analyzer/error/error.dart' as engine; | 15 import 'package:analyzer/error/error.dart' as engine; |
16 import 'package:analyzer/src/dart/ast/utilities.dart'; | 16 import 'package:analyzer/src/dart/ast/utilities.dart'; |
17 import 'package:analyzer/src/dart/error/hint_codes.dart'; | 17 import 'package:analyzer/src/dart/error/hint_codes.dart'; |
18 import 'package:analyzer/src/dart/error/syntactic_errors.dart'; | 18 import 'package:analyzer/src/dart/error/syntactic_errors.dart'; |
19 import 'package:analyzer/src/error/codes.dart'; | 19 import 'package:analyzer/src/error/codes.dart'; |
20 import 'package:analyzer/src/generated/engine.dart'; | |
21 import 'package:analyzer/src/generated/java_core.dart'; | 20 import 'package:analyzer/src/generated/java_core.dart'; |
22 import 'package:analyzer/src/generated/source.dart'; | 21 import 'package:analyzer/src/generated/source.dart'; |
23 import 'package:analyzer_plugin/utilities/range_factory.dart'; | 22 import 'package:analyzer_plugin/utilities/range_factory.dart'; |
24 | 23 |
25 /** | 24 /** |
26 * An enumeration of possible statement completion kinds. | 25 * An enumeration of possible statement completion kinds. |
27 */ | 26 */ |
28 class DartStatementCompletion { | 27 class DartStatementCompletion { |
29 static const NO_COMPLETION = | 28 static const NO_COMPLETION = |
30 const StatementCompletionKind('No_COMPLETION', 'No completion available'); | 29 const StatementCompletionKind('No_COMPLETION', 'No completion available'); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 } | 126 } |
128 | 127 |
129 /** | 128 /** |
130 * The computer for Dart statement completions. | 129 * The computer for Dart statement completions. |
131 */ | 130 */ |
132 class StatementCompletionProcessor { | 131 class StatementCompletionProcessor { |
133 static final NO_COMPLETION = new StatementCompletion( | 132 static final NO_COMPLETION = new StatementCompletion( |
134 DartStatementCompletion.NO_COMPLETION, new SourceChange("", edits: [])); | 133 DartStatementCompletion.NO_COMPLETION, new SourceChange("", edits: [])); |
135 | 134 |
136 final StatementCompletionContext statementContext; | 135 final StatementCompletionContext statementContext; |
137 final AnalysisContext analysisContext; | |
138 final CorrectionUtils utils; | 136 final CorrectionUtils utils; |
139 int fileStamp; | |
140 AstNode node; | 137 AstNode node; |
141 StatementCompletion completion; | 138 StatementCompletion completion; |
142 SourceChange change = new SourceChange('statement-completion'); | 139 SourceChange change = new SourceChange('statement-completion'); |
143 List errors = <engine.AnalysisError>[]; | 140 List errors = <engine.AnalysisError>[]; |
144 final Map<String, LinkedEditGroup> linkedPositionGroups = | 141 final Map<String, LinkedEditGroup> linkedPositionGroups = |
145 <String, LinkedEditGroup>{}; | 142 <String, LinkedEditGroup>{}; |
146 Position exitPosition = null; | 143 Position exitPosition = null; |
147 | 144 |
148 StatementCompletionProcessor(this.statementContext) | 145 StatementCompletionProcessor(this.statementContext) |
149 : analysisContext = statementContext.unitElement.context, | 146 : utils = new CorrectionUtils(statementContext.unit); |
150 utils = new CorrectionUtils(statementContext.unit) { | |
151 fileStamp = analysisContext.getModificationStamp(source); | |
152 } | |
153 | 147 |
154 String get eol => utils.endOfLine; | 148 String get eol => utils.endOfLine; |
155 | 149 |
156 String get file => statementContext.file; | 150 String get file => statementContext.file; |
157 | 151 |
158 LineInfo get lineInfo => statementContext.lineInfo; | 152 LineInfo get lineInfo => statementContext.lineInfo; |
159 | 153 |
160 int get requestLine => lineInfo.getLocation(selectionOffset).lineNumber; | 154 int get requestLine => lineInfo.getLocation(selectionOffset).lineNumber; |
161 | 155 |
162 int get selectionOffset => statementContext.selectionOffset; | 156 int get selectionOffset => statementContext.selectionOffset; |
163 | 157 |
164 Source get source => statementContext.unitElement.source; | 158 Source get source => statementContext.unitElement.source; |
165 | 159 |
166 CompilationUnit get unit => statementContext.unit; | 160 CompilationUnit get unit => statementContext.unit; |
167 | 161 |
168 CompilationUnitElement get unitElement => statementContext.unitElement; | 162 CompilationUnitElement get unitElement => statementContext.unitElement; |
169 | 163 |
170 Future<StatementCompletion> compute() async { | 164 Future<StatementCompletion> compute() async { |
171 // If the source was changed between the constructor and running | |
172 // this asynchronous method, it is not safe to use the unit. | |
173 if (analysisContext.getModificationStamp(source) != fileStamp) { | |
174 return NO_COMPLETION; | |
175 } | |
176 node = _selectedNode(); | 165 node = _selectedNode(); |
177 if (node == null) { | 166 if (node == null) { |
178 return NO_COMPLETION; | 167 return NO_COMPLETION; |
179 } | 168 } |
180 node = node | 169 node = node |
181 .getAncestor((n) => n is Statement || _isNonStatementDeclaration(n)); | 170 .getAncestor((n) => n is Statement || _isNonStatementDeclaration(n)); |
182 if (node == null) { | 171 if (node == null) { |
183 return _complete_simpleEnter() ? completion : NO_COMPLETION; | 172 return _complete_simpleEnter() ? completion : NO_COMPLETION; |
184 } | 173 } |
185 if (node is Block) { | 174 if (node is Block) { |
(...skipping 1053 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1239 final Token keyword; | 1228 final Token keyword; |
1240 final Token leftParenthesis, rightParenthesis; | 1229 final Token leftParenthesis, rightParenthesis; |
1241 final Expression condition; | 1230 final Expression condition; |
1242 final Statement block; | 1231 final Statement block; |
1243 | 1232 |
1244 _KeywordConditionBlockStructure(this.keyword, this.leftParenthesis, | 1233 _KeywordConditionBlockStructure(this.keyword, this.leftParenthesis, |
1245 this.condition, this.rightParenthesis, this.block); | 1234 this.condition, this.rightParenthesis, this.block); |
1246 | 1235 |
1247 int get offset => keyword.offset; | 1236 int get offset => keyword.offset; |
1248 } | 1237 } |
OLD | NEW |