| 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.local; | 5 library services.completion.computer.dart.local; |
| 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' as protocol show Element, Ele
mentKind; |
| 10 import 'package:analysis_server/src/protocol.dart' hide Element, ElementKind; |
| 10 import 'package:analysis_server/src/services/completion/dart_completion_manager.
dart'; | 11 import 'package:analysis_server/src/services/completion/dart_completion_manager.
dart'; |
| 11 import 'package:analyzer/src/generated/ast.dart'; | 12 import 'package:analyzer/src/generated/ast.dart'; |
| 13 import 'package:analyzer/src/generated/scanner.dart'; |
| 12 | 14 |
| 13 /** | 15 /** |
| 14 * A computer for calculating `completion.getSuggestions` request results | 16 * A computer for calculating `completion.getSuggestions` request results |
| 15 * for the local library in which the completion is requested. | 17 * for the local library in which the completion is requested. |
| 16 */ | 18 */ |
| 17 class LocalComputer extends DartCompletionComputer { | 19 class LocalComputer extends DartCompletionComputer { |
| 18 | 20 |
| 19 @override | 21 @override |
| 20 bool computeFast(DartCompletionRequest request) { | 22 bool computeFast(DartCompletionRequest request) { |
| 21 | 23 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 36 // include results from part files that are included in the library | 38 // include results from part files that are included in the library |
| 37 return new Future.value(false); | 39 return new Future.value(false); |
| 38 } | 40 } |
| 39 } | 41 } |
| 40 | 42 |
| 41 /** | 43 /** |
| 42 * A visitor for collecting suggestions from the most specific child [AstNode] | 44 * A visitor for collecting suggestions from the most specific child [AstNode] |
| 43 * that contains the completion offset to the [CompilationUnit]. | 45 * that contains the completion offset to the [CompilationUnit]. |
| 44 */ | 46 */ |
| 45 class _LocalVisitor extends GeneralizingAstVisitor<dynamic> { | 47 class _LocalVisitor extends GeneralizingAstVisitor<dynamic> { |
| 48 static const DYNAMIC = 'dynamic'; |
| 49 |
| 50 static final TypeName NO_RETURN_TYPE = new TypeName( |
| 51 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, '', 0)), |
| 52 null); |
| 53 |
| 54 static final TypeName STACKTRACE_TYPE = new TypeName( |
| 55 new SimpleIdentifier(new StringToken(TokenType.IDENTIFIER, 'StackTrace', 0
)), |
| 56 null); |
| 57 |
| 46 final DartCompletionRequest request; | 58 final DartCompletionRequest request; |
| 47 | 59 |
| 48 _LocalVisitor(this.request); | 60 _LocalVisitor(this.request); |
| 49 | 61 |
| 50 @override | 62 @override |
| 51 visitBlock(Block node) { | 63 visitBlock(Block node) { |
| 52 node.statements.forEach((Statement stmt) { | 64 node.statements.forEach((Statement stmt) { |
| 53 if (stmt.offset < request.offset) { | 65 if (stmt.offset < request.offset) { |
| 54 if (stmt is LabeledStatement) { | 66 if (stmt is LabeledStatement) { |
| 55 stmt.labels.forEach((Label label) { | 67 stmt.labels.forEach((Label label) { |
| 56 // _addSuggestion(label.label, CompletionSuggestionKind.LABEL); | 68 // _addSuggestion(label.label, CompletionSuggestionKind.LABEL); |
| 57 }); | 69 }); |
| 58 } else if (stmt is VariableDeclarationStatement) { | 70 } else if (stmt is VariableDeclarationStatement) { |
| 59 VariableDeclarationList varList = stmt.variables; | 71 var varList = stmt.variables; |
| 60 if (varList != null) { | 72 if (varList != null) { |
| 61 varList.variables.forEach((VariableDeclaration varDecl) { | 73 varList.variables.forEach((VariableDeclaration varDecl) { |
| 62 if (varDecl.end < request.offset) { | 74 if (varDecl.end < request.offset) { |
| 63 _addSuggestion( | 75 _addLocalVarSuggestion(varDecl.name, varList.type); |
| 64 varDecl.name, | |
| 65 CompletionSuggestionKind.LOCAL_VARIABLE, | |
| 66 varList.type, | |
| 67 null); | |
| 68 } | 76 } |
| 69 }); | 77 }); |
| 70 } | 78 } |
| 71 } | 79 } |
| 72 } | 80 } |
| 73 }); | 81 }); |
| 74 visitNode(node); | 82 visitNode(node); |
| 75 } | 83 } |
| 76 | 84 |
| 77 @override | 85 @override |
| 78 visitCatchClause(CatchClause node) { | 86 visitCatchClause(CatchClause node) { |
| 79 _addSuggestion( | 87 _addParamSuggestion(node.exceptionParameter, node.exceptionType); |
| 80 node.exceptionParameter, | 88 CompletionSuggestion suggestion = |
| 81 CompletionSuggestionKind.PARAMETER, | 89 _addParamSuggestion(node.stackTraceParameter, STACKTRACE_TYPE); |
| 82 node.exceptionType, | |
| 83 null); | |
| 84 // TODO (danrubel) add stack trace types | |
| 85 _addSuggestion( | |
| 86 node.stackTraceParameter, | |
| 87 CompletionSuggestionKind.PARAMETER, | |
| 88 null, | |
| 89 null); | |
| 90 visitNode(node); | 90 visitNode(node); |
| 91 } | 91 } |
| 92 | 92 |
| 93 @override | 93 @override |
| 94 visitClassDeclaration(ClassDeclaration node) { | 94 visitClassDeclaration(ClassDeclaration node) { |
| 95 node.members.forEach((ClassMember classMbr) { | 95 node.members.forEach((ClassMember classMbr) { |
| 96 if (classMbr is FieldDeclaration) { | 96 if (classMbr is FieldDeclaration) { |
| 97 _addVarListSuggestions( | 97 _addFieldSuggestions(node, classMbr); |
| 98 classMbr.fields, | |
| 99 CompletionSuggestionKind.FIELD, | |
| 100 node); | |
| 101 } else if (classMbr is MethodDeclaration) { | 98 } else if (classMbr is MethodDeclaration) { |
| 102 _addSuggestion( | 99 _addMethodSuggestion(node, classMbr); |
| 103 classMbr.name, | |
| 104 CompletionSuggestionKind.METHOD_NAME, | |
| 105 classMbr.returnType, | |
| 106 node); | |
| 107 } | 100 } |
| 108 }); | 101 }); |
| 109 visitNode(node); | 102 visitNode(node); |
| 110 } | 103 } |
| 111 | 104 |
| 112 @override | 105 @override |
| 113 visitCompilationUnit(CompilationUnit node) { | 106 visitCompilationUnit(CompilationUnit node) { |
| 114 node.directives.forEach((Directive directive) { | 107 node.directives.forEach((Directive directive) { |
| 115 if (directive is ImportDirective) { | 108 if (directive is ImportDirective) { |
| 116 _addSuggestion( | 109 _addLibraryPrefixSuggestion(directive); |
| 117 directive.prefix, | |
| 118 CompletionSuggestionKind.LIBRARY_PREFIX, | |
| 119 null, | |
| 120 null); | |
| 121 } | 110 } |
| 122 }); | 111 }); |
| 123 node.declarations.forEach((Declaration declaration) { | 112 node.declarations.forEach((Declaration declaration) { |
| 124 if (declaration is ClassDeclaration) { | 113 if (declaration is ClassDeclaration) { |
| 125 _addSuggestion( | 114 _addClassSuggestion(declaration); |
| 126 declaration.name, | |
| 127 CompletionSuggestionKind.CLASS, | |
| 128 null, | |
| 129 null); | |
| 130 } else if (declaration is EnumDeclaration) { | 115 } else if (declaration is EnumDeclaration) { |
| 131 // _addSuggestion(d.name, CompletionSuggestionKind.ENUM); | 116 // _addSuggestion(d.name, CompletionSuggestionKind.ENUM); |
| 132 } else if (declaration is FunctionDeclaration) { | 117 } else if (declaration is FunctionDeclaration) { |
| 133 _addSuggestion( | 118 _addFunctionSuggestion(declaration); |
| 134 declaration.name, | |
| 135 CompletionSuggestionKind.FUNCTION, | |
| 136 declaration.returnType, | |
| 137 null); | |
| 138 } else if (declaration is TopLevelVariableDeclaration) { | 119 } else if (declaration is TopLevelVariableDeclaration) { |
| 139 _addVarListSuggestions( | 120 _addTopLevelVarSuggestions(declaration.variables); |
| 140 declaration.variables, | |
| 141 CompletionSuggestionKind.TOP_LEVEL_VARIABLE, | |
| 142 null); | |
| 143 } else if (declaration is ClassTypeAlias) { | 121 } else if (declaration is ClassTypeAlias) { |
| 144 _addSuggestion( | 122 _addSuggestion( |
| 145 declaration.name, | 123 declaration.name, |
| 146 CompletionSuggestionKind.CLASS_ALIAS, | 124 CompletionSuggestionKind.CLASS_ALIAS, |
| 147 null, | 125 null, |
| 148 null); | 126 null); |
| 149 } else if (declaration is FunctionTypeAlias) { | 127 } else if (declaration is FunctionTypeAlias) { |
| 150 _addSuggestion( | 128 _addSuggestion( |
| 151 declaration.name, | 129 declaration.name, |
| 152 CompletionSuggestionKind.FUNCTION_TYPE_ALIAS, | 130 CompletionSuggestionKind.FUNCTION_TYPE_ALIAS, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 164 // TODO (danrubel) suggest possible names for variable declaration | 142 // TODO (danrubel) suggest possible names for variable declaration |
| 165 // based upon variable type | 143 // based upon variable type |
| 166 return; | 144 return; |
| 167 } | 145 } |
| 168 } | 146 } |
| 169 visitNode(node); | 147 visitNode(node); |
| 170 } | 148 } |
| 171 | 149 |
| 172 @override | 150 @override |
| 173 visitForEachStatement(ForEachStatement node) { | 151 visitForEachStatement(ForEachStatement node) { |
| 174 // TODO (danrubel) supply type of local variable | 152 SimpleIdentifier id; |
| 175 _addSuggestion( | 153 TypeName type; |
| 176 node.identifier, | 154 DeclaredIdentifier loopVar = node.loopVariable; |
| 177 CompletionSuggestionKind.LOCAL_VARIABLE, | 155 if (loopVar != null) { |
| 178 null, | 156 id = loopVar.identifier; |
| 179 null); | 157 type = loopVar.type; |
| 158 } else { |
| 159 id = node.identifier; |
| 160 type = null; |
| 161 } |
| 162 _addLocalVarSuggestion(id, type); |
| 180 visitNode(node); | 163 visitNode(node); |
| 181 } | 164 } |
| 182 | 165 |
| 183 @override | 166 @override |
| 184 visitForStatement(ForStatement node) { | 167 visitForStatement(ForStatement node) { |
| 185 _addVarListSuggestions( | 168 var varList = node.variables; |
| 186 node.variables, | 169 if (varList != null) { |
| 187 CompletionSuggestionKind.LOCAL_VARIABLE, | 170 varList.variables.forEach((VariableDeclaration varDecl) { |
| 188 null); | 171 _addLocalVarSuggestion(varDecl.name, varList.type); |
| 172 }); |
| 173 } |
| 189 visitNode(node); | 174 visitNode(node); |
| 190 } | 175 } |
| 191 | 176 |
| 192 @override | 177 @override |
| 193 visitFunctionDeclaration(FunctionDeclaration node) { | 178 visitFunctionDeclaration(FunctionDeclaration node) { |
| 194 // This is added by the compilation unit containing it | 179 // This is added by the compilation unit containing it |
| 195 //_addSuggestion(node.name, CompletionSuggestionKind.FUNCTION); | 180 //_addSuggestion(node.name, CompletionSuggestionKind.FUNCTION); |
| 196 visitNode(node); | 181 visitNode(node); |
| 197 } | 182 } |
| 198 | 183 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 217 visitVariableDeclaration(VariableDeclaration node) { | 202 visitVariableDeclaration(VariableDeclaration node) { |
| 218 // Do not add suggestions if editing the name in a var declaration | 203 // Do not add suggestions if editing the name in a var declaration |
| 219 SimpleIdentifier name = node.name; | 204 SimpleIdentifier name = node.name; |
| 220 if (name == null || | 205 if (name == null || |
| 221 name.offset < request.offset || | 206 name.offset < request.offset || |
| 222 request.offset > name.end) { | 207 request.offset > name.end) { |
| 223 visitNode(node); | 208 visitNode(node); |
| 224 } | 209 } |
| 225 } | 210 } |
| 226 | 211 |
| 212 void _addClassSuggestion(ClassDeclaration declaration) { |
| 213 CompletionSuggestion suggestion = |
| 214 _addSuggestion(declaration.name, CompletionSuggestionKind.CLASS, null, n
ull); |
| 215 if (suggestion != null) { |
| 216 suggestion.element = _createElement( |
| 217 protocol.ElementKind.CLASS, |
| 218 declaration.name, |
| 219 NO_RETURN_TYPE, |
| 220 declaration.isAbstract, |
| 221 _isDeprecated(declaration.metadata)); |
| 222 } |
| 223 } |
| 224 |
| 225 void _addFieldSuggestions(ClassDeclaration node, FieldDeclaration fieldDecl) { |
| 226 bool isDeprecated = _isDeprecated(fieldDecl.metadata); |
| 227 fieldDecl.fields.variables.forEach((VariableDeclaration varDecl) { |
| 228 CompletionSuggestion suggestion = _addSuggestion( |
| 229 varDecl.name, |
| 230 CompletionSuggestionKind.GETTER, |
| 231 fieldDecl.fields.type, |
| 232 node); |
| 233 if (suggestion != null) { |
| 234 suggestion.element = _createElement( |
| 235 protocol.ElementKind.GETTER, |
| 236 varDecl.name, |
| 237 fieldDecl.fields.type, |
| 238 false, |
| 239 isDeprecated || _isDeprecated(varDecl.metadata)); |
| 240 } |
| 241 }); |
| 242 } |
| 243 |
| 244 void _addFunctionSuggestion(FunctionDeclaration declaration) { |
| 245 CompletionSuggestion suggestion = _addSuggestion( |
| 246 declaration.name, |
| 247 CompletionSuggestionKind.FUNCTION, |
| 248 declaration.returnType, |
| 249 null); |
| 250 if (suggestion != null) { |
| 251 suggestion.element = _createElement( |
| 252 protocol.ElementKind.FUNCTION, |
| 253 declaration.name, |
| 254 declaration.returnType, |
| 255 false, |
| 256 _isDeprecated(declaration.metadata)); |
| 257 } |
| 258 } |
| 259 |
| 260 void _addLibraryPrefixSuggestion(ImportDirective directive) { |
| 261 CompletionSuggestion suggestion = _addSuggestion( |
| 262 directive.prefix, |
| 263 CompletionSuggestionKind.LIBRARY_PREFIX, |
| 264 null, |
| 265 null); |
| 266 if (suggestion != null) { |
| 267 suggestion.element = _createElement( |
| 268 protocol.ElementKind.LIBRARY, |
| 269 directive.prefix, |
| 270 NO_RETURN_TYPE, |
| 271 false, |
| 272 false); |
| 273 } |
| 274 } |
| 275 |
| 276 void _addLocalVarSuggestion(SimpleIdentifier id, TypeName returnType) { |
| 277 CompletionSuggestion suggestion = |
| 278 _addSuggestion(id, CompletionSuggestionKind.LOCAL_VARIABLE, returnType,
null); |
| 279 if (suggestion != null) { |
| 280 suggestion.element = _createElement( |
| 281 protocol.ElementKind.LOCAL_VARIABLE, |
| 282 id, |
| 283 returnType, |
| 284 false, |
| 285 false); |
| 286 } |
| 287 } |
| 288 |
| 289 void _addMethodSuggestion(ClassDeclaration node, MethodDeclaration classMbr) { |
| 290 protocol.ElementKind kind; |
| 291 CompletionSuggestionKind csKind; |
| 292 if (classMbr.isGetter) { |
| 293 kind = protocol.ElementKind.GETTER; |
| 294 csKind = CompletionSuggestionKind.GETTER; |
| 295 } else if (classMbr.isSetter) { |
| 296 kind = protocol.ElementKind.SETTER; |
| 297 csKind = CompletionSuggestionKind.SETTER; |
| 298 } else { |
| 299 kind = protocol.ElementKind.METHOD; |
| 300 csKind = CompletionSuggestionKind.METHOD; |
| 301 } |
| 302 CompletionSuggestion suggestion = |
| 303 _addSuggestion(classMbr.name, csKind, classMbr.returnType, node); |
| 304 suggestion.element = _createElement( |
| 305 kind, |
| 306 classMbr.name, |
| 307 classMbr.returnType, |
| 308 classMbr.isAbstract, |
| 309 _isDeprecated(classMbr.metadata)); |
| 310 } |
| 311 |
| 227 void _addParamListSuggestions(FormalParameterList paramList) { | 312 void _addParamListSuggestions(FormalParameterList paramList) { |
| 228 if (paramList != null) { | 313 if (paramList != null) { |
| 229 paramList.parameters.forEach((FormalParameter param) { | 314 paramList.parameters.forEach((FormalParameter param) { |
| 230 NormalFormalParameter normalParam; | 315 NormalFormalParameter normalParam; |
| 231 if (param is DefaultFormalParameter) { | 316 if (param is DefaultFormalParameter) { |
| 232 normalParam = param.parameter; | 317 normalParam = param.parameter; |
| 233 } else if (param is NormalFormalParameter) { | 318 } else if (param is NormalFormalParameter) { |
| 234 normalParam = param; | 319 normalParam = param; |
| 235 } | 320 } |
| 236 TypeName type = null; | 321 TypeName type = null; |
| 237 if (normalParam is FieldFormalParameter) { | 322 if (normalParam is FieldFormalParameter) { |
| 238 type = normalParam.type; | 323 type = normalParam.type; |
| 239 } else if (normalParam is FunctionTypedFormalParameter) { | 324 } else if (normalParam is FunctionTypedFormalParameter) { |
| 240 type = normalParam.returnType; | 325 type = normalParam.returnType; |
| 241 } else if (normalParam is SimpleFormalParameter) { | 326 } else if (normalParam is SimpleFormalParameter) { |
| 242 type = normalParam.type; | 327 type = normalParam.type; |
| 243 } | 328 } |
| 244 _addSuggestion( | 329 _addParamSuggestion(param.identifier, type); |
| 245 param.identifier, | |
| 246 CompletionSuggestionKind.PARAMETER, | |
| 247 type, | |
| 248 null); | |
| 249 }); | 330 }); |
| 250 } | 331 } |
| 251 } | 332 } |
| 252 | 333 |
| 253 void _addSuggestion(SimpleIdentifier id, CompletionSuggestionKind kind, | 334 CompletionSuggestion _addParamSuggestion(SimpleIdentifier identifier, |
| 254 TypeName typeName, ClassDeclaration classDecl) { | 335 TypeName type) { |
| 336 CompletionSuggestion suggestion = |
| 337 _addSuggestion(identifier, CompletionSuggestionKind.PARAMETER, type, nul
l); |
| 338 if (suggestion != null) { |
| 339 suggestion.element = |
| 340 _createElement(protocol.ElementKind.PARAMETER, identifier, type, false
, false); |
| 341 } |
| 342 return suggestion; |
| 343 } |
| 344 |
| 345 CompletionSuggestion _addSuggestion(SimpleIdentifier id, |
| 346 CompletionSuggestionKind kind, TypeName typeName, ClassDeclaration classDe
cl) { |
| 255 if (id != null) { | 347 if (id != null) { |
| 256 String completion = id.name; | 348 String completion = id.name; |
| 257 if (completion != null && completion.length > 0) { | 349 if (completion != null && completion.length > 0) { |
| 258 CompletionSuggestion suggestion = new CompletionSuggestion( | 350 CompletionSuggestion suggestion = new CompletionSuggestion( |
| 259 kind, | 351 kind, |
| 260 CompletionRelevance.DEFAULT, | 352 CompletionRelevance.DEFAULT, |
| 261 completion, | 353 completion, |
| 262 completion.length, | 354 completion.length, |
| 263 0, | 355 0, |
| 264 false, | 356 false, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 275 if (typeName != null) { | 367 if (typeName != null) { |
| 276 Identifier identifier = typeName.name; | 368 Identifier identifier = typeName.name; |
| 277 if (identifier != null) { | 369 if (identifier != null) { |
| 278 String name = identifier.name; | 370 String name = identifier.name; |
| 279 if (name != null && name.length > 0) { | 371 if (name != null && name.length > 0) { |
| 280 suggestion.returnType = name; | 372 suggestion.returnType = name; |
| 281 } | 373 } |
| 282 } | 374 } |
| 283 } | 375 } |
| 284 request.suggestions.add(suggestion); | 376 request.suggestions.add(suggestion); |
| 377 return suggestion; |
| 285 } | 378 } |
| 286 } | 379 } |
| 380 return null; |
| 381 } |
| 382 |
| 383 void _addTopLevelVarSuggestions(VariableDeclarationList varList) { |
| 384 if (varList != null) { |
| 385 bool isDeprecated = _isDeprecated(varList.metadata); |
| 386 varList.variables.forEach((VariableDeclaration varDecl) { |
| 387 CompletionSuggestion suggestion = _addSuggestion( |
| 388 varDecl.name, |
| 389 CompletionSuggestionKind.TOP_LEVEL_VARIABLE, |
| 390 varList.type, |
| 391 null); |
| 392 if (suggestion != null) { |
| 393 suggestion.element = _createElement( |
| 394 protocol.ElementKind.TOP_LEVEL_VARIABLE, |
| 395 varDecl.name, |
| 396 varList.type, |
| 397 false, |
| 398 isDeprecated || _isDeprecated(varDecl.metadata)); |
| 399 } |
| 400 }); |
| 401 } |
| 287 } | 402 } |
| 288 | 403 |
| 289 void _addVarListSuggestions(VariableDeclarationList variables, | 404 /** |
| 290 CompletionSuggestionKind kind, ClassDeclaration classDecl) { | 405 * Create a new protocol Element for inclusion in a completion suggestion. |
| 291 variables.variables.forEach((VariableDeclaration varDecl) { | 406 */ |
| 292 _addSuggestion(varDecl.name, kind, variables.type, classDecl); | 407 protocol.Element _createElement(protocol.ElementKind kind, |
| 293 }); | 408 SimpleIdentifier id, TypeName returnType, bool isAbstract, bool isDeprecat
ed) { |
| 409 String name = id.name; |
| 410 int flags = protocol.Element.makeFlags( |
| 411 isAbstract: isAbstract, |
| 412 isDeprecated: isDeprecated, |
| 413 isPrivate: Identifier.isPrivateName(name)); |
| 414 return new protocol.Element( |
| 415 kind, |
| 416 name, |
| 417 flags, |
| 418 returnType: _nameForType(returnType)); |
| 419 } |
| 420 |
| 421 /** |
| 422 * Return `true` if the @deprecated annotation is present |
| 423 */ |
| 424 bool _isDeprecated(NodeList<Annotation> metadata) => |
| 425 metadata != null && |
| 426 metadata.any( |
| 427 (Annotation a) => a.name is SimpleIdentifier && a.name.name == 'de
precated'); |
| 428 |
| 429 /** |
| 430 * Return the name for the given type. |
| 431 */ |
| 432 String _nameForType(TypeName type) { |
| 433 if (type == NO_RETURN_TYPE) { |
| 434 return null; |
| 435 } |
| 436 if (type == null) { |
| 437 return DYNAMIC; |
| 438 } |
| 439 Identifier id = type.name; |
| 440 if (id == null) { |
| 441 return DYNAMIC; |
| 442 } |
| 443 String name = id.name; |
| 444 if (name == null || name.length <= 0) { |
| 445 return DYNAMIC; |
| 446 } |
| 447 TypeArgumentList typeArgs = type.typeArguments; |
| 448 if (typeArgs != null) { |
| 449 //TODO (danrubel) include type arguments |
| 450 } |
| 451 return name; |
| 294 } | 452 } |
| 295 } | 453 } |
| OLD | NEW |