| // Copyright (c) 2015, 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. |
| |
| import 'dart:convert'; |
| |
| import 'package:analyzer/exception/exception.dart'; |
| import 'package:analyzer/src/dart/element/element.dart'; |
| import 'package:analyzer/src/generated/source.dart'; |
| |
| /// Utility methods that can be mixed in to classes that produce an HTML |
| /// representation of a tree structure. |
| mixin TreeWriter { |
| /// The buffer on which the HTML is to be written. |
| StringBuffer buffer; |
| |
| /// The current level of indentation. |
| int indentLevel = 0; |
| |
| /// A list containing the exceptions that were caught while attempting to |
| /// write out the tree structure. |
| List<CaughtException> exceptions = <CaughtException>[]; |
| |
| void indent([int extra = 0]) { |
| for (var i = 0; i < indentLevel; i++) { |
| buffer.write('┊ '); |
| } |
| if (extra > 0) { |
| buffer.write('┊ '); |
| for (var i = 1; i < extra; i++) { |
| buffer.write(' '); |
| } |
| } |
| } |
| |
| /// Write a representation of the given [properties] to the buffer. |
| void writeProperties(Map<String, Object> properties) { |
| var propertyNames = properties.keys.toList(); |
| propertyNames.sort(); |
| for (var propertyName in propertyNames) { |
| writeProperty(propertyName, properties[propertyName]); |
| } |
| } |
| |
| /// Write the [value] of the property with the given [name]. |
| void writeProperty(String name, Object value) { |
| if (value != null) { |
| indent(2); |
| buffer.write('$name = '); |
| _writePropertyValue(value, indentLevel); |
| buffer.write('<br>'); |
| } |
| } |
| |
| String _toString(Object value) { |
| try { |
| if (value is Source) { |
| return 'Source (uri="${value.uri}", path="${value.fullName}")'; |
| } else if (value is ElementAnnotationImpl) { |
| var buffer = StringBuffer(); |
| buffer.write(_toString(value.element)); |
| var result = value.evaluationResult; |
| if (result == null) { |
| buffer.write(': no result'); |
| } else { |
| buffer.write(': value = '); |
| buffer.write(result.value); |
| buffer.write('; errors = '); |
| buffer.write(result.errors); |
| } |
| return buffer.toString(); |
| } else { |
| return value.toString(); |
| } |
| } catch (exception, stackTrace) { |
| exceptions.add(CaughtException(exception, stackTrace)); |
| } |
| return null; |
| } |
| |
| /// Write the [value] of the property with the given [name]. |
| void _writePropertyValue(Object value, int baseIndent) { |
| if (value is List) { |
| if (value.isEmpty) { |
| buffer.write('[]'); |
| } else { |
| var elementIndent = baseIndent + 2; |
| buffer.write('[<br>'); |
| for (Object element in value) { |
| indent(elementIndent); |
| _writePropertyValue(element, elementIndent); |
| buffer.write('<br>'); |
| } |
| indent(baseIndent); |
| buffer.write(']'); |
| } |
| } else { |
| var valueString = _toString(value); |
| if (valueString == null) { |
| buffer.write('<span style="color: #FF0000">'); |
| buffer.write(htmlEscape.convert(value.runtimeType.toString())); |
| buffer.write('</span>'); |
| } else { |
| buffer.write(htmlEscape.convert(valueString)); |
| } |
| } |
| } |
| } |