| 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 protocol.server; | 5 library protocol.server; |
| 6 | 6 |
| 7 import 'package:analysis_server/plugin/protocol/protocol.dart'; | 7 import 'package:analysis_server/plugin/protocol/protocol.dart'; |
| 8 import 'package:analysis_server/plugin/protocol/protocol_dart.dart'; |
| 8 import 'package:analysis_server/src/services/correction/fix.dart'; | 9 import 'package:analysis_server/src/services/correction/fix.dart'; |
| 9 import 'package:analysis_server/src/services/search/search_engine.dart' | 10 import 'package:analysis_server/src/services/search/search_engine.dart' |
| 10 as engine; | 11 as engine; |
| 11 import 'package:analyzer/src/generated/ast.dart' as engine; | 12 import 'package:analyzer/src/generated/ast.dart' as engine; |
| 12 import 'package:analyzer/src/generated/element.dart' as engine; | 13 import 'package:analyzer/src/generated/element.dart' as engine; |
| 13 import 'package:analyzer/src/generated/engine.dart' as engine; | 14 import 'package:analyzer/src/generated/engine.dart' as engine; |
| 14 import 'package:analyzer/src/generated/error.dart' as engine; | 15 import 'package:analyzer/src/generated/error.dart' as engine; |
| 15 import 'package:analyzer/src/generated/source.dart' as engine; | 16 import 'package:analyzer/src/generated/source.dart' as engine; |
| 16 import 'package:analyzer/src/generated/utilities_dart.dart' as engine; | 17 import 'package:analyzer/src/generated/utilities_dart.dart' as engine; |
| 17 | 18 |
| 18 export 'package:analysis_server/plugin/protocol/protocol.dart'; | 19 export 'package:analysis_server/plugin/protocol/protocol.dart'; |
| 20 export 'package:analysis_server/plugin/protocol/protocol_dart.dart'; |
| 19 | 21 |
| 20 /** | 22 /** |
| 21 * Returns a list of AnalysisErrors correponding to the given list of Engine | 23 * Returns a list of AnalysisErrors correponding to the given list of Engine |
| 22 * errors. | 24 * errors. |
| 23 */ | 25 */ |
| 24 List<AnalysisError> doAnalysisError_listFromEngine( | 26 List<AnalysisError> doAnalysisError_listFromEngine( |
| 25 engine.LineInfo lineInfo, List<engine.AnalysisError> errors) { | 27 engine.LineInfo lineInfo, List<engine.AnalysisError> errors) { |
| 26 return errors.map((engine.AnalysisError error) { | 28 return errors.map((engine.AnalysisError error) { |
| 27 return newAnalysisError_fromEngine(lineInfo, error); | 29 return newAnalysisError_fromEngine(lineInfo, error); |
| 28 }).toList(); | 30 }).toList(); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 var severity = new AnalysisErrorSeverity(errorCode.errorSeverity.name); | 94 var severity = new AnalysisErrorSeverity(errorCode.errorSeverity.name); |
| 93 var type = new AnalysisErrorType(errorCode.type.name); | 95 var type = new AnalysisErrorType(errorCode.type.name); |
| 94 String message = error.message; | 96 String message = error.message; |
| 95 String correction = error.correction; | 97 String correction = error.correction; |
| 96 bool fix = hasFix(error.errorCode); | 98 bool fix = hasFix(error.errorCode); |
| 97 return new AnalysisError(severity, type, location, message, | 99 return new AnalysisError(severity, type, location, message, |
| 98 correction: correction, hasFix: fix); | 100 correction: correction, hasFix: fix); |
| 99 } | 101 } |
| 100 | 102 |
| 101 /** | 103 /** |
| 102 * Construct based on a value from the analyzer engine. | |
| 103 */ | |
| 104 Element newElement_fromEngine(engine.Element element) { | |
| 105 String name = element.displayName; | |
| 106 String elementTypeParameters = _getTypeParametersString(element); | |
| 107 String elementParameters = _getParametersString(element); | |
| 108 String elementReturnType = getReturnTypeString(element); | |
| 109 ElementKind kind = newElementKind_fromEngineElement(element); | |
| 110 return new Element( | |
| 111 kind, | |
| 112 name, | |
| 113 Element.makeFlags( | |
| 114 isPrivate: element.isPrivate, | |
| 115 isDeprecated: element.isDeprecated, | |
| 116 isAbstract: _isAbstract(element), | |
| 117 isConst: _isConst(element), | |
| 118 isFinal: _isFinal(element), | |
| 119 isStatic: _isStatic(element)), | |
| 120 location: newLocation_fromElement(element), | |
| 121 typeParameters: elementTypeParameters, | |
| 122 parameters: elementParameters, | |
| 123 returnType: elementReturnType); | |
| 124 } | |
| 125 | |
| 126 /** | |
| 127 * Construct based on a value from the analyzer engine. | |
| 128 * This does not take into account that | |
| 129 * instances of ClassElement can be an enum and | |
| 130 * instances of FieldElement can be an enum constant. | |
| 131 * Use [newElementKind_fromEngineElement] where possible. | |
| 132 */ | |
| 133 ElementKind newElementKind_fromEngine(engine.ElementKind kind) { | |
| 134 if (kind == engine.ElementKind.CLASS) { | |
| 135 return ElementKind.CLASS; | |
| 136 } | |
| 137 if (kind == engine.ElementKind.COMPILATION_UNIT) { | |
| 138 return ElementKind.COMPILATION_UNIT; | |
| 139 } | |
| 140 if (kind == engine.ElementKind.CONSTRUCTOR) { | |
| 141 return ElementKind.CONSTRUCTOR; | |
| 142 } | |
| 143 if (kind == engine.ElementKind.FIELD) { | |
| 144 return ElementKind.FIELD; | |
| 145 } | |
| 146 if (kind == engine.ElementKind.FUNCTION) { | |
| 147 return ElementKind.FUNCTION; | |
| 148 } | |
| 149 if (kind == engine.ElementKind.FUNCTION_TYPE_ALIAS) { | |
| 150 return ElementKind.FUNCTION_TYPE_ALIAS; | |
| 151 } | |
| 152 if (kind == engine.ElementKind.GETTER) { | |
| 153 return ElementKind.GETTER; | |
| 154 } | |
| 155 if (kind == engine.ElementKind.LABEL) { | |
| 156 return ElementKind.LABEL; | |
| 157 } | |
| 158 if (kind == engine.ElementKind.LIBRARY) { | |
| 159 return ElementKind.LIBRARY; | |
| 160 } | |
| 161 if (kind == engine.ElementKind.LOCAL_VARIABLE) { | |
| 162 return ElementKind.LOCAL_VARIABLE; | |
| 163 } | |
| 164 if (kind == engine.ElementKind.METHOD) { | |
| 165 return ElementKind.METHOD; | |
| 166 } | |
| 167 if (kind == engine.ElementKind.PARAMETER) { | |
| 168 return ElementKind.PARAMETER; | |
| 169 } | |
| 170 if (kind == engine.ElementKind.PREFIX) { | |
| 171 return ElementKind.PREFIX; | |
| 172 } | |
| 173 if (kind == engine.ElementKind.SETTER) { | |
| 174 return ElementKind.SETTER; | |
| 175 } | |
| 176 if (kind == engine.ElementKind.TOP_LEVEL_VARIABLE) { | |
| 177 return ElementKind.TOP_LEVEL_VARIABLE; | |
| 178 } | |
| 179 if (kind == engine.ElementKind.TYPE_PARAMETER) { | |
| 180 return ElementKind.TYPE_PARAMETER; | |
| 181 } | |
| 182 return ElementKind.UNKNOWN; | |
| 183 } | |
| 184 | |
| 185 /** | |
| 186 * Construct based on a value from the analyzer engine. | |
| 187 */ | |
| 188 ElementKind newElementKind_fromEngineElement(engine.Element element) { | |
| 189 if (element is engine.ClassElement && element.isEnum) { | |
| 190 return ElementKind.ENUM; | |
| 191 } | |
| 192 if (element is engine.FieldElement && | |
| 193 element.isEnumConstant && | |
| 194 // MyEnum.values and MyEnum.one.index return isEnumConstant = true | |
| 195 // so these additional checks are necessary. | |
| 196 // TODO(danrubel) MyEnum.values is constant, but is a list | |
| 197 // so should it return isEnumConstant = true? | |
| 198 // MyEnum.one.index is final but *not* constant | |
| 199 // so should it return isEnumConstant = true? | |
| 200 // Or should we return ElementKind.ENUM_CONSTANT here | |
| 201 // in either or both of these cases? | |
| 202 element.type != null && | |
| 203 element.type.element == element.enclosingElement) { | |
| 204 return ElementKind.ENUM_CONSTANT; | |
| 205 } | |
| 206 return newElementKind_fromEngine(element.kind); | |
| 207 } | |
| 208 | |
| 209 /** | |
| 210 * Create a Location based on an [engine.Element]. | 104 * Create a Location based on an [engine.Element]. |
| 211 */ | 105 */ |
| 212 Location newLocation_fromElement(engine.Element element) { | 106 Location newLocation_fromElement(engine.Element element) { |
| 213 engine.AnalysisContext context = element.context; | 107 engine.AnalysisContext context = element.context; |
| 214 engine.Source source = element.source; | 108 engine.Source source = element.source; |
| 215 if (context == null || source == null) { | 109 if (context == null || source == null) { |
| 216 return null; | 110 return null; |
| 217 } | 111 } |
| 218 int offset = element.nameOffset; | 112 int offset = element.nameOffset; |
| 219 int length = element.nameLength; | 113 int length = element.nameLength; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 engine.CompilationUnitElement unitElement = unit.element; | 149 engine.CompilationUnitElement unitElement = unit.element; |
| 256 engine.AnalysisContext context = unitElement.context; | 150 engine.AnalysisContext context = unitElement.context; |
| 257 engine.Source source = unitElement.source; | 151 engine.Source source = unitElement.source; |
| 258 return _locationForArgs(context, source, range); | 152 return _locationForArgs(context, source, range); |
| 259 } | 153 } |
| 260 | 154 |
| 261 /** | 155 /** |
| 262 * Construct based on an element from the analyzer engine. | 156 * Construct based on an element from the analyzer engine. |
| 263 */ | 157 */ |
| 264 OverriddenMember newOverriddenMember_fromEngine(engine.Element member) { | 158 OverriddenMember newOverriddenMember_fromEngine(engine.Element member) { |
| 265 Element element = newElement_fromEngine(member); | 159 Element element = convertElement(member); |
| 266 String className = member.enclosingElement.displayName; | 160 String className = member.enclosingElement.displayName; |
| 267 return new OverriddenMember(element, className); | 161 return new OverriddenMember(element, className); |
| 268 } | 162 } |
| 269 | 163 |
| 270 /** | 164 /** |
| 271 * Construct based on a value from the search engine. | 165 * Construct based on a value from the search engine. |
| 272 */ | 166 */ |
| 273 SearchResult newSearchResult_fromMatch(engine.SearchMatch match) { | 167 SearchResult newSearchResult_fromMatch(engine.SearchMatch match) { |
| 274 SearchResultKind kind = newSearchResultKind_fromEngine(match.kind); | 168 SearchResultKind kind = newSearchResultKind_fromEngine(match.kind); |
| 275 Location location = newLocation_fromMatch(match); | 169 Location location = newLocation_fromMatch(match); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 306 * Construct based on a SourceRange. | 200 * Construct based on a SourceRange. |
| 307 */ | 201 */ |
| 308 SourceEdit newSourceEdit_range(engine.SourceRange range, String replacement, | 202 SourceEdit newSourceEdit_range(engine.SourceRange range, String replacement, |
| 309 {String id}) { | 203 {String id}) { |
| 310 return new SourceEdit(range.offset, range.length, replacement, id: id); | 204 return new SourceEdit(range.offset, range.length, replacement, id: id); |
| 311 } | 205 } |
| 312 | 206 |
| 313 List<Element> _computePath(engine.Element element) { | 207 List<Element> _computePath(engine.Element element) { |
| 314 List<Element> path = <Element>[]; | 208 List<Element> path = <Element>[]; |
| 315 while (element != null) { | 209 while (element != null) { |
| 316 path.add(newElement_fromEngine(element)); | 210 path.add(convertElement(element)); |
| 317 // go up | 211 // go up |
| 318 if (element is engine.PrefixElement) { | 212 if (element is engine.PrefixElement) { |
| 319 // imports are library children, but they are physically in the unit | 213 // imports are library children, but they are physically in the unit |
| 320 engine.LibraryElement library = element.enclosingElement; | 214 engine.LibraryElement library = element.enclosingElement; |
| 321 element = library.definingCompilationUnit; | 215 element = library.definingCompilationUnit; |
| 322 } else { | 216 } else { |
| 323 element = element.enclosingElement; | 217 element = element.enclosingElement; |
| 324 } | 218 } |
| 325 } | 219 } |
| 326 return path; | 220 return path; |
| 327 } | 221 } |
| 328 | 222 |
| 329 String _getParametersString(engine.Element element) { | |
| 330 // TODO(scheglov) expose the corresponding feature from ExecutableElement | |
| 331 List<engine.ParameterElement> parameters; | |
| 332 if (element is engine.ExecutableElement) { | |
| 333 // valid getters don't have parameters | |
| 334 if (element.kind == engine.ElementKind.GETTER && | |
| 335 element.parameters.isEmpty) { | |
| 336 return null; | |
| 337 } | |
| 338 parameters = element.parameters; | |
| 339 } else if (element is engine.FunctionTypeAliasElement) { | |
| 340 parameters = element.parameters; | |
| 341 } else { | |
| 342 return null; | |
| 343 } | |
| 344 StringBuffer sb = new StringBuffer(); | |
| 345 String closeOptionalString = ''; | |
| 346 for (engine.ParameterElement parameter in parameters) { | |
| 347 if (sb.isNotEmpty) { | |
| 348 sb.write(', '); | |
| 349 } | |
| 350 if (closeOptionalString.isEmpty) { | |
| 351 engine.ParameterKind kind = parameter.parameterKind; | |
| 352 if (kind == engine.ParameterKind.NAMED) { | |
| 353 sb.write('{'); | |
| 354 closeOptionalString = '}'; | |
| 355 } | |
| 356 if (kind == engine.ParameterKind.POSITIONAL) { | |
| 357 sb.write('['); | |
| 358 closeOptionalString = ']'; | |
| 359 } | |
| 360 } | |
| 361 parameter.appendToWithoutDelimiters(sb); | |
| 362 } | |
| 363 sb.write(closeOptionalString); | |
| 364 return '(' + sb.toString() + ')'; | |
| 365 } | |
| 366 | |
| 367 String _getTypeParametersString(engine.Element element) { | |
| 368 List<engine.TypeParameterElement> typeParameters; | |
| 369 if (element is engine.ClassElement) { | |
| 370 typeParameters = element.typeParameters; | |
| 371 } else if (element is engine.FunctionTypeAliasElement) { | |
| 372 typeParameters = element.typeParameters; | |
| 373 } | |
| 374 if (typeParameters == null || typeParameters.isEmpty) { | |
| 375 return null; | |
| 376 } | |
| 377 return '<${typeParameters.join(', ')}>'; | |
| 378 } | |
| 379 | |
| 380 bool _isAbstract(engine.Element element) { | |
| 381 // TODO(scheglov) add isAbstract to Element API | |
| 382 if (element is engine.ClassElement) { | |
| 383 return element.isAbstract; | |
| 384 } | |
| 385 if (element is engine.MethodElement) { | |
| 386 return element.isAbstract; | |
| 387 } | |
| 388 if (element is engine.PropertyAccessorElement) { | |
| 389 return element.isAbstract; | |
| 390 } | |
| 391 return false; | |
| 392 } | |
| 393 | |
| 394 bool _isConst(engine.Element element) { | |
| 395 // TODO(scheglov) add isConst to Element API | |
| 396 if (element is engine.ConstructorElement) { | |
| 397 return element.isConst; | |
| 398 } | |
| 399 if (element is engine.VariableElement) { | |
| 400 return element.isConst; | |
| 401 } | |
| 402 return false; | |
| 403 } | |
| 404 | |
| 405 bool _isFinal(engine.Element element) { | |
| 406 // TODO(scheglov) add isFinal to Element API | |
| 407 if (element is engine.VariableElement) { | |
| 408 return element.isFinal; | |
| 409 } | |
| 410 return false; | |
| 411 } | |
| 412 | |
| 413 bool _isStatic(engine.Element element) { | |
| 414 // TODO(scheglov) add isStatic to Element API | |
| 415 if (element is engine.ExecutableElement) { | |
| 416 return element.isStatic; | |
| 417 } | |
| 418 if (element is engine.PropertyInducingElement) { | |
| 419 return element.isStatic; | |
| 420 } | |
| 421 return false; | |
| 422 } | |
| 423 | |
| 424 /** | 223 /** |
| 425 * Creates a new [Location]. | 224 * Creates a new [Location]. |
| 426 */ | 225 */ |
| 427 Location _locationForArgs(engine.AnalysisContext context, engine.Source source, | 226 Location _locationForArgs(engine.AnalysisContext context, engine.Source source, |
| 428 engine.SourceRange range) { | 227 engine.SourceRange range) { |
| 429 int startLine = 0; | 228 int startLine = 0; |
| 430 int startColumn = 0; | 229 int startColumn = 0; |
| 431 { | 230 { |
| 432 engine.LineInfo lineInfo = context.getLineInfo(source); | 231 engine.LineInfo lineInfo = context.getLineInfo(source); |
| 433 if (lineInfo != null) { | 232 if (lineInfo != null) { |
| 434 engine.LineInfo_Location offsetLocation = | 233 engine.LineInfo_Location offsetLocation = |
| 435 lineInfo.getLocation(range.offset); | 234 lineInfo.getLocation(range.offset); |
| 436 startLine = offsetLocation.lineNumber; | 235 startLine = offsetLocation.lineNumber; |
| 437 startColumn = offsetLocation.columnNumber; | 236 startColumn = offsetLocation.columnNumber; |
| 438 } | 237 } |
| 439 } | 238 } |
| 440 return new Location( | 239 return new Location( |
| 441 source.fullName, range.offset, range.length, startLine, startColumn); | 240 source.fullName, range.offset, range.length, startLine, startColumn); |
| 442 } | 241 } |
| OLD | NEW |