| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 services.completion.computer.dart.keyword; | 5 library services.completion.computer.dart.keyword; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 | 8 |
| 9 import 'package:analysis_server/src/protocol.dart'; | 9 import 'package:analysis_server/src/protocol.dart'; |
| 10 import 'package:analysis_server/src/services/completion/dart_completion_manager.
dart'; | 10 import 'package:analysis_server/src/services/completion/dart_completion_manager.
dart'; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 Keyword.OPERATOR, | 80 Keyword.OPERATOR, |
| 81 Keyword.SET, | 81 Keyword.SET, |
| 82 Keyword.STATIC, | 82 Keyword.STATIC, |
| 83 Keyword.VAR, | 83 Keyword.VAR, |
| 84 Keyword.VOID]); | 84 Keyword.VOID]); |
| 85 return; | 85 return; |
| 86 } | 86 } |
| 87 // Very simplistic suggestion because analyzer will warn if | 87 // Very simplistic suggestion because analyzer will warn if |
| 88 // the extends / with / implements keywords are out of order | 88 // the extends / with / implements keywords are out of order |
| 89 if (node.extendsClause == null) { | 89 if (node.extendsClause == null) { |
| 90 _addSuggestion(Keyword.EXTENDS); | 90 _addSuggestion(Keyword.EXTENDS, CompletionRelevance.HIGH); |
| 91 } else if (node.withClause == null) { | 91 } else if (node.withClause == null) { |
| 92 _addSuggestion(Keyword.WITH); | 92 _addSuggestion(Keyword.WITH, CompletionRelevance.HIGH); |
| 93 } | 93 } |
| 94 if (node.implementsClause == null) { | 94 if (node.implementsClause == null) { |
| 95 _addSuggestion(Keyword.IMPLEMENTS); | 95 _addSuggestion(Keyword.IMPLEMENTS, CompletionRelevance.HIGH); |
| 96 } | 96 } |
| 97 } | 97 } |
| 98 | 98 |
| 99 @override | 99 @override |
| 100 visitCompilationUnit(CompilationUnit node) { | 100 visitCompilationUnit(CompilationUnit node) { |
| 101 Directive firstDirective; | 101 Directive firstDirective; |
| 102 int endOfDirectives = 0; | 102 int endOfDirectives = 0; |
| 103 if (node.directives.length > 0) { | 103 if (node.directives.length > 0) { |
| 104 firstDirective = node.directives[0]; | 104 firstDirective = node.directives[0]; |
| 105 endOfDirectives = node.directives.last.end - 1; | 105 endOfDirectives = node.directives.last.end - 1; |
| 106 } | 106 } |
| 107 int startOfDeclarations = node.end; | 107 int startOfDeclarations = node.end; |
| 108 if (node.declarations.length > 0) { | 108 if (node.declarations.length > 0) { |
| 109 startOfDeclarations = node.declarations[0].offset; | 109 startOfDeclarations = node.declarations[0].offset; |
| 110 // If the first token is a simple identifier | 110 // If the first token is a simple identifier |
| 111 // and cursor position in within that first token | 111 // and cursor position in within that first token |
| 112 // then consider cursor to be before the first declaration | 112 // then consider cursor to be before the first declaration |
| 113 Token token = node.declarations[0].firstTokenAfterCommentAndMetadata; | 113 Token token = node.declarations[0].firstTokenAfterCommentAndMetadata; |
| 114 if (token.offset <= request.offset && request.offset <= token.end) { | 114 if (token.offset <= request.offset && request.offset <= token.end) { |
| 115 startOfDeclarations = token.end; | 115 startOfDeclarations = token.end; |
| 116 } | 116 } |
| 117 } | 117 } |
| 118 | 118 |
| 119 // Simplistic check for library as first directive | 119 // Simplistic check for library as first directive |
| 120 if (firstDirective is! LibraryDirective) { | 120 if (firstDirective is! LibraryDirective) { |
| 121 if (firstDirective != null) { | 121 if (firstDirective != null) { |
| 122 if (request.offset <= firstDirective.offset) { | 122 if (request.offset <= firstDirective.offset) { |
| 123 _addSuggestions([Keyword.LIBRARY]); | 123 _addSuggestions([Keyword.LIBRARY], CompletionRelevance.HIGH); |
| 124 } | 124 } |
| 125 } else { | 125 } else { |
| 126 if (request.offset <= startOfDeclarations) { | 126 if (request.offset <= startOfDeclarations) { |
| 127 _addSuggestions([Keyword.LIBRARY]); | 127 _addSuggestions([Keyword.LIBRARY], CompletionRelevance.HIGH); |
| 128 } | 128 } |
| 129 } | 129 } |
| 130 } | 130 } |
| 131 if (request.offset <= startOfDeclarations) { | 131 if (request.offset <= startOfDeclarations) { |
| 132 _addSuggestions([Keyword.EXPORT, Keyword.IMPORT, Keyword.PART]); | 132 _addSuggestions( |
| 133 [Keyword.EXPORT, Keyword.IMPORT, Keyword.PART], |
| 134 CompletionRelevance.HIGH); |
| 133 } | 135 } |
| 134 if (request.offset >= endOfDirectives) { | 136 if (request.offset >= endOfDirectives) { |
| 135 _addSuggestions( | 137 _addSuggestions( |
| 136 [ | 138 [ |
| 137 Keyword.ABSTRACT, | 139 Keyword.ABSTRACT, |
| 138 Keyword.CLASS, | 140 Keyword.CLASS, |
| 139 Keyword.CONST, | 141 Keyword.CONST, |
| 140 Keyword.FINAL, | 142 Keyword.FINAL, |
| 141 Keyword.TYPEDEF, | 143 Keyword.TYPEDEF, |
| 142 Keyword.VAR]); | 144 Keyword.VAR], |
| 145 CompletionRelevance.HIGH); |
| 143 } | 146 } |
| 144 } | 147 } |
| 145 | 148 |
| 146 @override | 149 @override |
| 147 visitNode(AstNode node) { | 150 visitNode(AstNode node) { |
| 148 if (_isOffsetAfterNode(node)) { | 151 if (_isOffsetAfterNode(node)) { |
| 149 node.parent.accept(this); | 152 node.parent.accept(this); |
| 150 } | 153 } |
| 151 } | 154 } |
| 152 | 155 |
| 153 visitSimpleIdentifier(SimpleIdentifier node) { | 156 visitSimpleIdentifier(SimpleIdentifier node) { |
| 154 AstNode parent = node.getAncestor((n) => n is TopLevelVariableDeclaration); | 157 AstNode parent = node.getAncestor((n) => n is TopLevelVariableDeclaration); |
| 155 if (parent is TopLevelVariableDeclaration) { | 158 if (parent is TopLevelVariableDeclaration) { |
| 156 if (parent.variables != null && | 159 if (parent.variables != null && |
| 157 parent.variables.type != null && | 160 parent.variables.type != null && |
| 158 parent.variables.type.name == node) { | 161 parent.variables.type.name == node) { |
| 159 AstNode unit = node.getAncestor((n) => n is CompilationUnit); | 162 AstNode unit = node.getAncestor((n) => n is CompilationUnit); |
| 160 if (unit is CompilationUnit) { | 163 if (unit is CompilationUnit) { |
| 161 visitCompilationUnit(unit); | 164 visitCompilationUnit(unit); |
| 162 } | 165 } |
| 163 } | 166 } |
| 164 } | 167 } |
| 165 } | 168 } |
| 166 | 169 |
| 167 void _addSuggestion(Keyword keyword) { | 170 void _addSuggestion(Keyword keyword, [CompletionRelevance relevance = |
| 171 CompletionRelevance.DEFAULT]) { |
| 168 String completion = keyword.syntax; | 172 String completion = keyword.syntax; |
| 169 request.suggestions.add( | 173 request.suggestions.add( |
| 170 new CompletionSuggestion( | 174 new CompletionSuggestion( |
| 171 CompletionSuggestionKind.KEYWORD, | 175 CompletionSuggestionKind.KEYWORD, |
| 172 CompletionRelevance.DEFAULT, | 176 relevance, |
| 173 completion, | 177 completion, |
| 174 completion.length, | 178 completion.length, |
| 175 0, | 179 0, |
| 176 false, | 180 false, |
| 177 false)); | 181 false)); |
| 178 } | 182 } |
| 179 | 183 |
| 180 void _addSuggestions(List<Keyword> keywords) { | 184 void _addSuggestions(List<Keyword> keywords, [CompletionRelevance relevance = |
| 185 CompletionRelevance.DEFAULT]) { |
| 181 keywords.forEach((Keyword keyword) { | 186 keywords.forEach((Keyword keyword) { |
| 182 _addSuggestion(keyword); | 187 _addSuggestion(keyword, relevance); |
| 183 }); | 188 }); |
| 184 } | 189 } |
| 185 | 190 |
| 186 bool _isOffsetAfterNode(AstNode node) { | 191 bool _isOffsetAfterNode(AstNode node) { |
| 187 if (request.offset == node.end) { | 192 if (request.offset == node.end) { |
| 188 Token token = node.endToken; | 193 Token token = node.endToken; |
| 189 if (token != null && !token.isSynthetic) { | 194 if (token != null && !token.isSynthetic) { |
| 190 if (token.lexeme == ';' || token.lexeme == '}') { | 195 if (token.lexeme == ';' || token.lexeme == '}') { |
| 191 return true; | 196 return true; |
| 192 } | 197 } |
| 193 } | 198 } |
| 194 } | 199 } |
| 195 return false; | 200 return false; |
| 196 } | 201 } |
| 197 } | 202 } |
| OLD | NEW |