| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 /** |
| 6 * Utilities for converting Dart entities into analysis server's protocol |
| 7 * entities. |
| 8 */ |
| 9 library analysis_server.plugin.protocol.protocol_dart; |
| 10 |
| 11 import 'package:analysis_server/plugin/protocol/protocol.dart'; |
| 12 import 'package:analysis_server/src/protocol_server.dart'; |
| 13 import 'package:analyzer/src/generated/element.dart' as engine; |
| 14 import 'package:analyzer/src/generated/utilities_dart.dart' as engine; |
| 15 |
| 16 /** |
| 17 * Return a protocol [Element] corresponding to the given [engine.Element]. |
| 18 */ |
| 19 Element convertElement(engine.Element element) { |
| 20 String name = element.displayName; |
| 21 String elementTypeParameters = _getTypeParametersString(element); |
| 22 String elementParameters = _getParametersString(element); |
| 23 String elementReturnType = getReturnTypeString(element); |
| 24 ElementKind kind = convertElementToElementKind(element); |
| 25 return new Element( |
| 26 kind, |
| 27 name, |
| 28 Element.makeFlags( |
| 29 isPrivate: element.isPrivate, |
| 30 isDeprecated: element.isDeprecated, |
| 31 isAbstract: _isAbstract(element), |
| 32 isConst: _isConst(element), |
| 33 isFinal: _isFinal(element), |
| 34 isStatic: _isStatic(element)), |
| 35 location: newLocation_fromElement(element), |
| 36 typeParameters: elementTypeParameters, |
| 37 parameters: elementParameters, |
| 38 returnType: elementReturnType); |
| 39 } |
| 40 |
| 41 /** |
| 42 * Return a protocol [ElementKind] corresponding to the given |
| 43 * [engine.ElementKind]. |
| 44 * |
| 45 * This does not take into account that an instance of [ClassElement] can be an |
| 46 * enum and an instance of [FieldElement] can be an enum constant. |
| 47 * Use [convertElementToElementKind] where possible. |
| 48 */ |
| 49 ElementKind convertElementKind(engine.ElementKind kind) { |
| 50 if (kind == engine.ElementKind.CLASS) { |
| 51 return ElementKind.CLASS; |
| 52 } |
| 53 if (kind == engine.ElementKind.COMPILATION_UNIT) { |
| 54 return ElementKind.COMPILATION_UNIT; |
| 55 } |
| 56 if (kind == engine.ElementKind.CONSTRUCTOR) { |
| 57 return ElementKind.CONSTRUCTOR; |
| 58 } |
| 59 if (kind == engine.ElementKind.FIELD) { |
| 60 return ElementKind.FIELD; |
| 61 } |
| 62 if (kind == engine.ElementKind.FUNCTION) { |
| 63 return ElementKind.FUNCTION; |
| 64 } |
| 65 if (kind == engine.ElementKind.FUNCTION_TYPE_ALIAS) { |
| 66 return ElementKind.FUNCTION_TYPE_ALIAS; |
| 67 } |
| 68 if (kind == engine.ElementKind.GETTER) { |
| 69 return ElementKind.GETTER; |
| 70 } |
| 71 if (kind == engine.ElementKind.LABEL) { |
| 72 return ElementKind.LABEL; |
| 73 } |
| 74 if (kind == engine.ElementKind.LIBRARY) { |
| 75 return ElementKind.LIBRARY; |
| 76 } |
| 77 if (kind == engine.ElementKind.LOCAL_VARIABLE) { |
| 78 return ElementKind.LOCAL_VARIABLE; |
| 79 } |
| 80 if (kind == engine.ElementKind.METHOD) { |
| 81 return ElementKind.METHOD; |
| 82 } |
| 83 if (kind == engine.ElementKind.PARAMETER) { |
| 84 return ElementKind.PARAMETER; |
| 85 } |
| 86 if (kind == engine.ElementKind.PREFIX) { |
| 87 return ElementKind.PREFIX; |
| 88 } |
| 89 if (kind == engine.ElementKind.SETTER) { |
| 90 return ElementKind.SETTER; |
| 91 } |
| 92 if (kind == engine.ElementKind.TOP_LEVEL_VARIABLE) { |
| 93 return ElementKind.TOP_LEVEL_VARIABLE; |
| 94 } |
| 95 if (kind == engine.ElementKind.TYPE_PARAMETER) { |
| 96 return ElementKind.TYPE_PARAMETER; |
| 97 } |
| 98 return ElementKind.UNKNOWN; |
| 99 } |
| 100 |
| 101 /** |
| 102 * Return an [ElementKind] corresponding to the given [engine.Element]. |
| 103 */ |
| 104 ElementKind convertElementToElementKind(engine.Element element) { |
| 105 if (element is engine.ClassElement && element.isEnum) { |
| 106 return ElementKind.ENUM; |
| 107 } |
| 108 if (element is engine.FieldElement && |
| 109 element.isEnumConstant && |
| 110 // MyEnum.values and MyEnum.one.index return isEnumConstant = true |
| 111 // so these additional checks are necessary. |
| 112 // TODO(danrubel) MyEnum.values is constant, but is a list |
| 113 // so should it return isEnumConstant = true? |
| 114 // MyEnum.one.index is final but *not* constant |
| 115 // so should it return isEnumConstant = true? |
| 116 // Or should we return ElementKind.ENUM_CONSTANT here |
| 117 // in either or both of these cases? |
| 118 element.type != null && |
| 119 element.type.element == element.enclosingElement) { |
| 120 return ElementKind.ENUM_CONSTANT; |
| 121 } |
| 122 return convertElementKind(element.kind); |
| 123 } |
| 124 |
| 125 String _getParametersString(engine.Element element) { |
| 126 // TODO(scheglov) expose the corresponding feature from ExecutableElement |
| 127 List<engine.ParameterElement> parameters; |
| 128 if (element is engine.ExecutableElement) { |
| 129 // valid getters don't have parameters |
| 130 if (element.kind == engine.ElementKind.GETTER && |
| 131 element.parameters.isEmpty) { |
| 132 return null; |
| 133 } |
| 134 parameters = element.parameters; |
| 135 } else if (element is engine.FunctionTypeAliasElement) { |
| 136 parameters = element.parameters; |
| 137 } else { |
| 138 return null; |
| 139 } |
| 140 StringBuffer sb = new StringBuffer(); |
| 141 String closeOptionalString = ''; |
| 142 for (engine.ParameterElement parameter in parameters) { |
| 143 if (sb.isNotEmpty) { |
| 144 sb.write(', '); |
| 145 } |
| 146 if (closeOptionalString.isEmpty) { |
| 147 engine.ParameterKind kind = parameter.parameterKind; |
| 148 if (kind == engine.ParameterKind.NAMED) { |
| 149 sb.write('{'); |
| 150 closeOptionalString = '}'; |
| 151 } |
| 152 if (kind == engine.ParameterKind.POSITIONAL) { |
| 153 sb.write('['); |
| 154 closeOptionalString = ']'; |
| 155 } |
| 156 } |
| 157 parameter.appendToWithoutDelimiters(sb); |
| 158 } |
| 159 sb.write(closeOptionalString); |
| 160 return '(' + sb.toString() + ')'; |
| 161 } |
| 162 |
| 163 String _getTypeParametersString(engine.Element element) { |
| 164 List<engine.TypeParameterElement> typeParameters; |
| 165 if (element is engine.ClassElement) { |
| 166 typeParameters = element.typeParameters; |
| 167 } else if (element is engine.FunctionTypeAliasElement) { |
| 168 typeParameters = element.typeParameters; |
| 169 } |
| 170 if (typeParameters == null || typeParameters.isEmpty) { |
| 171 return null; |
| 172 } |
| 173 return '<${typeParameters.join(', ')}>'; |
| 174 } |
| 175 |
| 176 bool _isAbstract(engine.Element element) { |
| 177 // TODO(scheglov) add isAbstract to Element API |
| 178 if (element is engine.ClassElement) { |
| 179 return element.isAbstract; |
| 180 } |
| 181 if (element is engine.MethodElement) { |
| 182 return element.isAbstract; |
| 183 } |
| 184 if (element is engine.PropertyAccessorElement) { |
| 185 return element.isAbstract; |
| 186 } |
| 187 return false; |
| 188 } |
| 189 |
| 190 bool _isConst(engine.Element element) { |
| 191 // TODO(scheglov) add isConst to Element API |
| 192 if (element is engine.ConstructorElement) { |
| 193 return element.isConst; |
| 194 } |
| 195 if (element is engine.VariableElement) { |
| 196 return element.isConst; |
| 197 } |
| 198 return false; |
| 199 } |
| 200 |
| 201 bool _isFinal(engine.Element element) { |
| 202 // TODO(scheglov) add isFinal to Element API |
| 203 if (element is engine.VariableElement) { |
| 204 return element.isFinal; |
| 205 } |
| 206 return false; |
| 207 } |
| 208 |
| 209 bool _isStatic(engine.Element element) { |
| 210 // TODO(scheglov) add isStatic to Element API |
| 211 if (element is engine.ExecutableElement) { |
| 212 return element.isStatic; |
| 213 } |
| 214 if (element is engine.PropertyInducingElement) { |
| 215 return element.isStatic; |
| 216 } |
| 217 return false; |
| 218 } |
| OLD | NEW |