| // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| /// The models used to represent Dart code. |
| library dartdoc.element_type; |
| |
| import 'package:analyzer/dart/element/element.dart'; |
| import 'package:analyzer/dart/element/type.dart'; |
| |
| import 'model.dart'; |
| |
| class ElementType { |
| final DartType _type; |
| final ModelElement element; |
| String _linkedName; |
| |
| ElementType(this._type, this.element); |
| |
| bool get isDynamic => _type.isDynamic; |
| |
| bool get isFunctionType => (_type is FunctionType); |
| |
| bool get isParameterizedType { |
| if (_type is FunctionType) { |
| return typeArguments.isNotEmpty; |
| } else if (_type is ParameterizedType) { |
| return (_type as ParameterizedType).typeArguments.isNotEmpty; |
| } |
| return false; |
| } |
| |
| bool get isParameterType => (_type is TypeParameterType); |
| |
| String get linkedName { |
| if (_linkedName != null) return _linkedName; |
| |
| StringBuffer buf = new StringBuffer(); |
| |
| if (isParameterType) { |
| buf.write(name); |
| } else { |
| buf.write(element.linkedName); |
| } |
| |
| // not TypeParameterType or Void or Union type |
| if (isParameterizedType) { |
| if (typeArguments.every((t) => t.linkedName == 'dynamic')) { |
| _linkedName = buf.toString(); |
| return _linkedName; |
| } |
| if (typeArguments.isNotEmpty) { |
| buf.write('<'); |
| buf.writeAll(typeArguments.map((t) => t.linkedName), ', '); |
| buf.write('>'); |
| } |
| } |
| _linkedName = buf.toString(); |
| |
| return _linkedName; |
| } |
| |
| String get name => _type.name; |
| |
| ModelElement get returnElement { |
| Element e = _returnTypeCore.element; |
| if (e == null || e.library == null) { |
| return null; |
| } |
| Library lib = element.package.findLibraryFor(e); |
| if (lib == null) { |
| lib = new Library(e.library, element.package); |
| } |
| return (new ModelElement.from(e, lib)); |
| } |
| |
| List<ElementType> get typeArguments { |
| var type = _type; |
| if (type is FunctionType) { |
| Iterable<DartType> typeArguments; |
| if (type.element is FunctionTypeAliasElement && |
| type.typeFormals.isEmpty) { |
| // TODO(jmesserly): simplify check above; we should have a way |
| // to find instantiated typedefs without consulting the element. |
| // Also, it will not work if we support typedefs declared inside classes. |
| typeArguments = type.typeArguments; |
| } else { |
| typeArguments = type.typeFormals.map((f) => f.type); |
| } |
| return typeArguments.map(_getElementTypeFrom).toList(); |
| } else { |
| return (_type as ParameterizedType) |
| .typeArguments |
| .map((f) => _getElementTypeFrom(f)) |
| .toList(); |
| } |
| } |
| |
| ElementType get _returnType { |
| var rt = _returnTypeCore; |
| Library lib = element.package.findLibraryFor(rt.element); |
| if (lib == null) { |
| lib = new Library(rt.element.library, element.package); |
| } |
| return new ElementType(rt, new ModelElement.from(rt.element, lib)); |
| } |
| |
| DartType get _returnTypeCore => (_type as FunctionType).returnType; |
| |
| String get _returnTypeName => _returnTypeCore.name; |
| |
| String createLinkedReturnTypeName() { |
| if (_returnTypeCore.element == null || |
| _returnTypeCore.element.library == null) { |
| if (_returnTypeName != null) { |
| if (_returnTypeName == 'dynamic' && element.isAsynchronous) { |
| // TODO(keertip): for SDK docs it should be a link |
| return 'Future'; |
| } |
| return _returnTypeName; |
| } else { |
| return ''; |
| } |
| } else { |
| return _returnType.linkedName; |
| } |
| } |
| |
| @override |
| String toString() => "$_type"; |
| |
| ElementType _getElementTypeFrom(DartType f) { |
| Library lib; |
| // can happen if element is dynamic |
| lib = element.package.findLibraryFor(f.element); |
| if (lib == null && f.element.library != null) { |
| lib = new Library(f.element.library, element.package); |
| } |
| return new ElementType(f, new ModelElement.from(f.element, lib)); |
| } |
| } |