| 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 |