| 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 computer.outline; | 5 library computer.outline; |
| 6 | 6 |
| 7 import 'package:analysis_server/src/computer/element.dart'; | 7 import 'package:analysis_server/src/computer/element.dart'; |
| 8 import 'package:analysis_server/src/constants.dart'; | 8 import 'package:analysis_server/src/constants.dart'; |
| 9 import 'package:analyzer/src/generated/ast.dart'; | 9 import 'package:analyzer/src/generated/ast.dart'; |
| 10 import 'package:analyzer/src/generated/element.dart' as engine; | 10 import 'package:analyzer/src/generated/element.dart' as engine; |
| 11 import 'package:analyzer/src/generated/engine.dart'; |
| 12 import 'package:analyzer/src/generated/source.dart'; |
| 11 | 13 |
| 12 | 14 |
| 13 /** | 15 /** |
| 14 * A computer for [CompilationUnit] outline. | 16 * A computer for [CompilationUnit] outline. |
| 15 */ | 17 */ |
| 16 class DartUnitOutlineComputer { | 18 class DartUnitOutlineComputer { |
| 17 final CompilationUnit _unit; | 19 final CompilationUnit _unit; |
| 20 String file; |
| 21 LineInfo lineInfo; |
| 18 | 22 |
| 19 DartUnitOutlineComputer(this._unit); | 23 DartUnitOutlineComputer(AnalysisContext context, Source source, this._unit) { |
| 24 file = source.fullName; |
| 25 lineInfo = context.getLineInfo(source); |
| 26 } |
| 20 | 27 |
| 21 /** | 28 /** |
| 22 * Returns the computed outline, not `null`. | 29 * Returns the computed outline, not `null`. |
| 23 */ | 30 */ |
| 24 Map<String, Object> compute() { | 31 Map<String, Object> compute() { |
| 25 Outline unitOutline = _newUnitOutline(); | 32 Outline unitOutline = _newUnitOutline(); |
| 26 for (CompilationUnitMember unitMember in _unit.declarations) { | 33 for (CompilationUnitMember unitMember in _unit.declarations) { |
| 27 if (unitMember is ClassDeclaration) { | 34 if (unitMember is ClassDeclaration) { |
| 28 ClassDeclaration classDeclaration = unitMember; | 35 ClassDeclaration classDeclaration = unitMember; |
| 29 Outline classOutline = _newClassOutline(unitOutline, classDeclaration); | 36 Outline classOutline = _newClassOutline(unitOutline, classDeclaration); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 _newFunctionTypeAliasOutline(unitOutline, alias); | 83 _newFunctionTypeAliasOutline(unitOutline, alias); |
| 77 } | 84 } |
| 78 } | 85 } |
| 79 return unitOutline.toJson(); | 86 return unitOutline.toJson(); |
| 80 } | 87 } |
| 81 | 88 |
| 82 void _addLocalFunctionOutlines(Outline parent, FunctionBody body) { | 89 void _addLocalFunctionOutlines(Outline parent, FunctionBody body) { |
| 83 body.accept(new _LocalFunctionOutlinesVisitor(this, parent)); | 90 body.accept(new _LocalFunctionOutlinesVisitor(this, parent)); |
| 84 } | 91 } |
| 85 | 92 |
| 93 Location _getLocationNode(AstNode node) { |
| 94 int offset = node.offset; |
| 95 int length = node.length; |
| 96 return _getLocationOffsetLength(offset, length); |
| 97 } |
| 98 |
| 99 Location _getLocationOffsetLength(int offset, int length) { |
| 100 LineInfo_Location lineLocation = lineInfo.getLocation(offset); |
| 101 int startLine = lineLocation.lineNumber; |
| 102 int startColumn = lineLocation.columnNumber; |
| 103 return new Location(file, offset, length, startLine, startColumn); |
| 104 } |
| 105 |
| 86 /** | 106 /** |
| 87 * Returns the [AstNode]'s source region. | 107 * Returns the [AstNode]'s source region. |
| 88 */ | 108 */ |
| 89 _SourceRegion _getSourceRegion(AstNode node) { | 109 _SourceRegion _getSourceRegion(AstNode node) { |
| 90 int endOffset = node.end; | 110 int endOffset = node.end; |
| 91 // prepare position of the node among its siblings | 111 // prepare position of the node among its siblings |
| 92 int firstOffset; | 112 int firstOffset; |
| 93 List<AstNode> siblings; | 113 List<AstNode> siblings; |
| 94 AstNode parent = node.parent; | 114 AstNode parent = node.parent; |
| 95 // field | 115 // field |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 } | 147 } |
| 128 // not first child: [endOfPreviousSibling, endOfNode] | 148 // not first child: [endOfPreviousSibling, endOfNode] |
| 129 int prevSiblingEnd = siblings[index - 1].end; | 149 int prevSiblingEnd = siblings[index - 1].end; |
| 130 return new _SourceRegion(prevSiblingEnd, endOffset - prevSiblingEnd); | 150 return new _SourceRegion(prevSiblingEnd, endOffset - prevSiblingEnd); |
| 131 } | 151 } |
| 132 | 152 |
| 133 Outline _newClassOutline(Outline parent, ClassDeclaration classDeclaration) { | 153 Outline _newClassOutline(Outline parent, ClassDeclaration classDeclaration) { |
| 134 SimpleIdentifier nameNode = classDeclaration.name; | 154 SimpleIdentifier nameNode = classDeclaration.name; |
| 135 String name = nameNode.name; | 155 String name = nameNode.name; |
| 136 _SourceRegion sourceRegion = _getSourceRegion(classDeclaration); | 156 _SourceRegion sourceRegion = _getSourceRegion(classDeclaration); |
| 137 Element element = new Element(ElementKind.CLASS, name, nameNode.offset, | 157 Element element = new Element(ElementKind.CLASS, name, _getLocationNode( |
| 138 nameNode.length, Identifier.isPrivateName(name), _isDeprecated( | 158 nameNode), Identifier.isPrivateName(name), _isDeprecated(classDeclaratio
n), |
| 139 classDeclaration), isAbstract: classDeclaration.isAbstract); | 159 isAbstract: classDeclaration.isAbstract); |
| 140 Outline outline = new Outline(element, sourceRegion.offset, | 160 Outline outline = new Outline(element, sourceRegion.offset, |
| 141 sourceRegion.length); | 161 sourceRegion.length); |
| 142 parent.children.add(outline); | 162 parent.children.add(outline); |
| 143 return outline; | 163 return outline; |
| 144 } | 164 } |
| 145 | 165 |
| 146 void _newClassTypeAlias(Outline parent, ClassTypeAlias alias) { | 166 void _newClassTypeAlias(Outline parent, ClassTypeAlias alias) { |
| 147 SimpleIdentifier nameNode = alias.name; | 167 SimpleIdentifier nameNode = alias.name; |
| 148 String name = nameNode.name; | 168 String name = nameNode.name; |
| 149 _SourceRegion sourceRegion = _getSourceRegion(alias); | 169 _SourceRegion sourceRegion = _getSourceRegion(alias); |
| 150 Element element = new Element(ElementKind.CLASS_TYPE_ALIAS, name, | 170 Element element = new Element(ElementKind.CLASS_TYPE_ALIAS, name, |
| 151 nameNode.offset, nameNode.length, Identifier.isPrivateName(name), _isDep
recated( | 171 _getLocationNode(nameNode), Identifier.isPrivateName(name), _isDeprecate
d( |
| 152 alias), isAbstract: alias.isAbstract); | 172 alias), isAbstract: alias.isAbstract); |
| 153 Outline outline = new Outline(element, sourceRegion.offset, | 173 Outline outline = new Outline(element, sourceRegion.offset, |
| 154 sourceRegion.length); | 174 sourceRegion.length); |
| 155 parent.children.add(outline); | 175 parent.children.add(outline); |
| 156 } | 176 } |
| 157 | 177 |
| 158 void _newConstructorOutline(Outline parent, | 178 void _newConstructorOutline(Outline parent, |
| 159 ConstructorDeclaration constructor) { | 179 ConstructorDeclaration constructor) { |
| 160 Identifier returnType = constructor.returnType; | 180 Identifier returnType = constructor.returnType; |
| 161 String name = returnType.name; | 181 String name = returnType.name; |
| 162 int offset = returnType.offset; | 182 int offset = returnType.offset; |
| 163 int length = returnType.length; | 183 int length = returnType.length; |
| 164 SimpleIdentifier constructorNameNode = constructor.name; | 184 SimpleIdentifier constructorNameNode = constructor.name; |
| 165 bool isPrivate = false; | 185 bool isPrivate = false; |
| 166 if (constructorNameNode != null) { | 186 if (constructorNameNode != null) { |
| 167 String constructorName = constructorNameNode.name; | 187 String constructorName = constructorNameNode.name; |
| 168 isPrivate = Identifier.isPrivateName(constructorName); | 188 isPrivate = Identifier.isPrivateName(constructorName); |
| 169 name += '.${constructorName}'; | 189 name += '.${constructorName}'; |
| 170 offset = constructorNameNode.offset; | 190 offset = constructorNameNode.offset; |
| 171 length = constructorNameNode.length; | 191 length = constructorNameNode.length; |
| 172 } | 192 } |
| 173 _SourceRegion sourceRegion = _getSourceRegion(constructor); | 193 _SourceRegion sourceRegion = _getSourceRegion(constructor); |
| 174 FormalParameterList parameters = constructor.parameters; | 194 FormalParameterList parameters = constructor.parameters; |
| 175 String parametersStr = parameters != null ? parameters.toSource() : ''; | 195 String parametersStr = parameters != null ? parameters.toSource() : ''; |
| 176 Element element = new Element(ElementKind.CONSTRUCTOR, name, offset, length, | 196 Element element = new Element(ElementKind.CONSTRUCTOR, name, |
| 177 isPrivate, _isDeprecated(constructor), parameters: parametersStr); | 197 _getLocationOffsetLength(offset, length), isPrivate, _isDeprecated(const
ructor), |
| 198 parameters: parametersStr); |
| 178 Outline outline = new Outline(element, sourceRegion.offset, | 199 Outline outline = new Outline(element, sourceRegion.offset, |
| 179 sourceRegion.length); | 200 sourceRegion.length); |
| 180 parent.children.add(outline); | 201 parent.children.add(outline); |
| 181 _addLocalFunctionOutlines(outline, constructor.body); | 202 _addLocalFunctionOutlines(outline, constructor.body); |
| 182 } | 203 } |
| 183 | 204 |
| 184 void _newFunctionOutline(Outline parent, FunctionDeclaration function, | 205 void _newFunctionOutline(Outline parent, FunctionDeclaration function, |
| 185 bool isStatic) { | 206 bool isStatic) { |
| 186 TypeName returnType = function.returnType; | 207 TypeName returnType = function.returnType; |
| 187 SimpleIdentifier nameNode = function.name; | 208 SimpleIdentifier nameNode = function.name; |
| 188 String name = nameNode.name; | 209 String name = nameNode.name; |
| 189 FunctionExpression functionExpression = function.functionExpression; | 210 FunctionExpression functionExpression = function.functionExpression; |
| 190 FormalParameterList parameters = functionExpression.parameters; | 211 FormalParameterList parameters = functionExpression.parameters; |
| 191 ElementKind kind; | 212 ElementKind kind; |
| 192 if (function.isGetter) { | 213 if (function.isGetter) { |
| 193 kind = ElementKind.GETTER; | 214 kind = ElementKind.GETTER; |
| 194 } else if (function.isSetter) { | 215 } else if (function.isSetter) { |
| 195 kind = ElementKind.SETTER; | 216 kind = ElementKind.SETTER; |
| 196 } else { | 217 } else { |
| 197 kind = ElementKind.FUNCTION; | 218 kind = ElementKind.FUNCTION; |
| 198 } | 219 } |
| 199 _SourceRegion sourceRegion = _getSourceRegion(function); | 220 _SourceRegion sourceRegion = _getSourceRegion(function); |
| 200 String parametersStr = parameters != null ? parameters.toSource() : ''; | 221 String parametersStr = parameters != null ? parameters.toSource() : ''; |
| 201 String returnTypeStr = returnType != null ? returnType.toSource() : ''; | 222 String returnTypeStr = returnType != null ? returnType.toSource() : ''; |
| 202 Element element = new Element(kind, name, nameNode.offset, nameNode.length, | 223 Element element = new Element(kind, name, _getLocationNode(nameNode), |
| 203 Identifier.isPrivateName(name), _isDeprecated(function), parameters: | 224 Identifier.isPrivateName(name), _isDeprecated(function), parameters: |
| 204 parametersStr, returnType: returnTypeStr, isStatic: isStatic); | 225 parametersStr, returnType: returnTypeStr, isStatic: isStatic); |
| 205 Outline outline = new Outline(element, sourceRegion.offset, | 226 Outline outline = new Outline(element, sourceRegion.offset, |
| 206 sourceRegion.length); | 227 sourceRegion.length); |
| 207 parent.children.add(outline); | 228 parent.children.add(outline); |
| 208 _addLocalFunctionOutlines(outline, functionExpression.body); | 229 _addLocalFunctionOutlines(outline, functionExpression.body); |
| 209 } | 230 } |
| 210 | 231 |
| 211 void _newFunctionTypeAliasOutline(Outline parent, FunctionTypeAlias alias) { | 232 void _newFunctionTypeAliasOutline(Outline parent, FunctionTypeAlias alias) { |
| 212 TypeName returnType = alias.returnType; | 233 TypeName returnType = alias.returnType; |
| 213 SimpleIdentifier nameNode = alias.name; | 234 SimpleIdentifier nameNode = alias.name; |
| 214 String name = nameNode.name; | 235 String name = nameNode.name; |
| 215 _SourceRegion sourceRegion = _getSourceRegion(alias); | 236 _SourceRegion sourceRegion = _getSourceRegion(alias); |
| 216 FormalParameterList parameters = alias.parameters; | 237 FormalParameterList parameters = alias.parameters; |
| 217 String parametersStr = parameters != null ? parameters.toSource() : ''; | 238 String parametersStr = parameters != null ? parameters.toSource() : ''; |
| 218 String returnTypeStr = returnType != null ? returnType.toSource() : ''; | 239 String returnTypeStr = returnType != null ? returnType.toSource() : ''; |
| 219 Element element = new Element(ElementKind.FUNCTION_TYPE_ALIAS, name, | 240 Element element = new Element(ElementKind.FUNCTION_TYPE_ALIAS, name, |
| 220 nameNode.offset, nameNode.length, Identifier.isPrivateName(name), _isDep
recated( | 241 _getLocationNode(nameNode), Identifier.isPrivateName(name), _isDeprecate
d( |
| 221 alias), parameters: parametersStr, returnType: returnTypeStr); | 242 alias), parameters: parametersStr, returnType: returnTypeStr); |
| 222 Outline outline = new Outline(element, sourceRegion.offset, | 243 Outline outline = new Outline(element, sourceRegion.offset, |
| 223 sourceRegion.length); | 244 sourceRegion.length); |
| 224 parent.children.add(outline); | 245 parent.children.add(outline); |
| 225 } | 246 } |
| 226 | 247 |
| 227 void _newMethodOutline(Outline parent, MethodDeclaration method) { | 248 void _newMethodOutline(Outline parent, MethodDeclaration method) { |
| 228 TypeName returnType = method.returnType; | 249 TypeName returnType = method.returnType; |
| 229 SimpleIdentifier nameNode = method.name; | 250 SimpleIdentifier nameNode = method.name; |
| 230 String name = nameNode.name; | 251 String name = nameNode.name; |
| 231 FormalParameterList parameters = method.parameters; | 252 FormalParameterList parameters = method.parameters; |
| 232 ElementKind kind; | 253 ElementKind kind; |
| 233 if (method.isGetter) { | 254 if (method.isGetter) { |
| 234 kind = ElementKind.GETTER; | 255 kind = ElementKind.GETTER; |
| 235 } else if (method.isSetter) { | 256 } else if (method.isSetter) { |
| 236 kind = ElementKind.SETTER; | 257 kind = ElementKind.SETTER; |
| 237 } else { | 258 } else { |
| 238 kind = ElementKind.METHOD; | 259 kind = ElementKind.METHOD; |
| 239 } | 260 } |
| 240 _SourceRegion sourceRegion = _getSourceRegion(method); | 261 _SourceRegion sourceRegion = _getSourceRegion(method); |
| 241 String parametersStr = parameters != null ? parameters.toSource() : ''; | 262 String parametersStr = parameters != null ? parameters.toSource() : ''; |
| 242 String returnTypeStr = returnType != null ? returnType.toSource() : ''; | 263 String returnTypeStr = returnType != null ? returnType.toSource() : ''; |
| 243 Element element = new Element(kind, name, nameNode.offset, nameNode.length, | 264 Element element = new Element(kind, name, _getLocationNode(nameNode), |
| 244 Identifier.isPrivateName(name), _isDeprecated(method), parameters: | 265 Identifier.isPrivateName(name), _isDeprecated(method), parameters: |
| 245 parametersStr, returnType: returnTypeStr, isAbstract: method.isAbstract, | 266 parametersStr, returnType: returnTypeStr, isAbstract: method.isAbstract, |
| 246 isStatic: method.isStatic); | 267 isStatic: method.isStatic); |
| 247 Outline outline = new Outline(element, sourceRegion.offset, | 268 Outline outline = new Outline(element, sourceRegion.offset, |
| 248 sourceRegion.length); | 269 sourceRegion.length); |
| 249 parent.children.add(outline); | 270 parent.children.add(outline); |
| 250 _addLocalFunctionOutlines(outline, method.body); | 271 _addLocalFunctionOutlines(outline, method.body); |
| 251 } | 272 } |
| 252 | 273 |
| 253 Outline _newUnitOutline() { | 274 Outline _newUnitOutline() { |
| 254 Element element = new Element(ElementKind.COMPILATION_UNIT, '<unit>', | 275 Element element = new Element(ElementKind.COMPILATION_UNIT, '<unit>', |
| 255 _unit.offset, _unit.length, false, false); | 276 _getLocationNode(_unit), false, false); |
| 256 return new Outline(element, _unit.offset, _unit.length); | 277 return new Outline(element, _unit.offset, _unit.length); |
| 257 } | 278 } |
| 258 | 279 |
| 259 void _newVariableOutline(Outline parent, String typeName, ElementKind kind, | 280 void _newVariableOutline(Outline parent, String typeName, ElementKind kind, |
| 260 VariableDeclaration variable, bool isStatic) { | 281 VariableDeclaration variable, bool isStatic) { |
| 261 SimpleIdentifier nameNode = variable.name; | 282 SimpleIdentifier nameNode = variable.name; |
| 262 String name = nameNode.name; | 283 String name = nameNode.name; |
| 263 _SourceRegion sourceRegion = _getSourceRegion(variable); | 284 _SourceRegion sourceRegion = _getSourceRegion(variable); |
| 264 Element element = new Element(kind, name, nameNode.offset, nameNode.length, | 285 Element element = new Element(kind, name, _getLocationNode(nameNode), |
| 265 Identifier.isPrivateName(name), _isDeprecated(variable), returnType: typ
eName, | 286 Identifier.isPrivateName(name), _isDeprecated(variable), returnType: typ
eName, |
| 266 isStatic: isStatic, isConst: variable.isConst, isFinal: variable.isFinal
); | 287 isStatic: isStatic, isConst: variable.isConst, isFinal: variable.isFinal
); |
| 267 Outline outline = new Outline(element, sourceRegion.offset, | 288 Outline outline = new Outline(element, sourceRegion.offset, |
| 268 sourceRegion.length); | 289 sourceRegion.length); |
| 269 parent.children.add(outline); | 290 parent.children.add(outline); |
| 270 } | 291 } |
| 271 | 292 |
| 272 /** | 293 /** |
| 273 * Returns `true` if the given [element] is not `null` and deprecated. | 294 * Returns `true` if the given [element] is not `null` and deprecated. |
| 274 */ | 295 */ |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 | 374 |
| 354 | 375 |
| 355 /** | 376 /** |
| 356 * A range of characters. | 377 * A range of characters. |
| 357 */ | 378 */ |
| 358 class _SourceRegion { | 379 class _SourceRegion { |
| 359 final int length; | 380 final int length; |
| 360 final int offset; | 381 final int offset; |
| 361 _SourceRegion(this.offset, this.length); | 382 _SourceRegion(this.offset, this.length); |
| 362 } | 383 } |
| OLD | NEW |