Chromium Code Reviews| 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/protocol2.dart'; |
| 8 import 'package:analysis_server/src/constants.dart'; | |
| 9 import 'package:analysis_server/src/protocol2.dart' show ElementKind; | |
| 10 import 'package:analysis_server/src/services/json.dart'; | |
| 11 import 'package:analyzer/src/generated/ast.dart'; | 8 import 'package:analyzer/src/generated/ast.dart'; |
| 12 import 'package:analyzer/src/generated/element.dart' as engine; | 9 import 'package:analyzer/src/generated/element.dart' as engine; |
| 13 import 'package:analyzer/src/generated/engine.dart'; | 10 import 'package:analyzer/src/generated/engine.dart'; |
| 14 import 'package:analyzer/src/generated/source.dart'; | 11 import 'package:analyzer/src/generated/source.dart'; |
| 15 | 12 |
| 16 | 13 |
| 17 /** | 14 /** |
| 18 * A computer for [CompilationUnit] outline. | 15 * A computer for [CompilationUnit] outline. |
| 19 */ | 16 */ |
| 20 class DartUnitOutlineComputer { | 17 class DartUnitOutlineComputer { |
| 21 final CompilationUnit _unit; | 18 final CompilationUnit _unit; |
| 22 String file; | 19 String file; |
| 23 LineInfo lineInfo; | 20 LineInfo lineInfo; |
| 24 | 21 |
| 25 DartUnitOutlineComputer(AnalysisContext context, Source source, this._unit) { | 22 DartUnitOutlineComputer(AnalysisContext context, Source source, this._unit) { |
| 26 file = source.fullName; | 23 file = source.fullName; |
| 27 lineInfo = context.getLineInfo(source); | 24 lineInfo = context.getLineInfo(source); |
| 28 } | 25 } |
| 29 | 26 |
| 30 /** | 27 /** |
| 31 * Returns the computed outline, not `null`. | 28 * Returns the computed outline, not `null`. |
| 32 */ | 29 */ |
| 33 Outline compute() { | 30 Outline compute() { |
| 34 Outline unitOutline = _newUnitOutline(); | 31 List<Outline> unitContents = <Outline>[]; |
| 35 for (CompilationUnitMember unitMember in _unit.declarations) { | 32 for (CompilationUnitMember unitMember in _unit.declarations) { |
| 36 if (unitMember is ClassDeclaration) { | 33 if (unitMember is ClassDeclaration) { |
| 37 ClassDeclaration classDeclaration = unitMember; | 34 ClassDeclaration classDeclaration = unitMember; |
| 38 Outline classOutline = _newClassOutline(unitOutline, classDeclaration); | 35 List<Outline> classContents = <Outline>[]; |
| 39 for (ClassMember classMember in classDeclaration.members) { | 36 for (ClassMember classMember in classDeclaration.members) { |
| 40 if (classMember is ConstructorDeclaration) { | 37 if (classMember is ConstructorDeclaration) { |
| 41 ConstructorDeclaration constructorDeclaration = classMember; | 38 ConstructorDeclaration constructorDeclaration = classMember; |
| 42 _newConstructorOutline(classOutline, constructorDeclaration); | 39 classContents.add(_newConstructorOutline(constructorDeclaration)); |
| 43 } | 40 } |
| 44 if (classMember is FieldDeclaration) { | 41 if (classMember is FieldDeclaration) { |
| 45 FieldDeclaration fieldDeclaration = classMember; | 42 FieldDeclaration fieldDeclaration = classMember; |
| 46 VariableDeclarationList fields = fieldDeclaration.fields; | 43 VariableDeclarationList fields = fieldDeclaration.fields; |
| 47 if (fields != null) { | 44 if (fields != null) { |
| 48 TypeName fieldType = fields.type; | 45 TypeName fieldType = fields.type; |
| 49 String fieldTypeName = fieldType != null ? fieldType.toSource() : | 46 String fieldTypeName = fieldType != null ? fieldType.toSource() : |
| 50 ''; | 47 ''; |
| 51 for (VariableDeclaration field in fields.variables) { | 48 for (VariableDeclaration field in fields.variables) { |
| 52 _newVariableOutline(classOutline, fieldTypeName, | 49 classContents.add(_newVariableOutline(fieldTypeName, |
| 53 ElementKind.FIELD, field, fieldDeclaration.isStatic); | 50 ElementKind.FIELD, field, fieldDeclaration.isStatic)); |
| 54 } | 51 } |
| 55 } | 52 } |
| 56 } | 53 } |
| 57 if (classMember is MethodDeclaration) { | 54 if (classMember is MethodDeclaration) { |
| 58 MethodDeclaration methodDeclaration = classMember; | 55 MethodDeclaration methodDeclaration = classMember; |
| 59 _newMethodOutline(classOutline, methodDeclaration); | 56 classContents.add(_newMethodOutline(methodDeclaration)); |
| 60 } | 57 } |
| 61 } | 58 } |
| 59 unitContents.add(_newClassOutline(classDeclaration, classContents)); | |
| 62 } | 60 } |
| 63 if (unitMember is TopLevelVariableDeclaration) { | 61 if (unitMember is TopLevelVariableDeclaration) { |
| 64 TopLevelVariableDeclaration fieldDeclaration = unitMember; | 62 TopLevelVariableDeclaration fieldDeclaration = unitMember; |
| 65 VariableDeclarationList fields = fieldDeclaration.variables; | 63 VariableDeclarationList fields = fieldDeclaration.variables; |
| 66 if (fields != null) { | 64 if (fields != null) { |
| 67 TypeName fieldType = fields.type; | 65 TypeName fieldType = fields.type; |
| 68 String fieldTypeName = fieldType != null ? fieldType.toSource() : ''; | 66 String fieldTypeName = fieldType != null ? fieldType.toSource() : ''; |
| 69 for (VariableDeclaration field in fields.variables) { | 67 for (VariableDeclaration field in fields.variables) { |
| 70 _newVariableOutline(unitOutline, fieldTypeName, | 68 unitContents.add(_newVariableOutline(fieldTypeName, |
| 71 ElementKind.TOP_LEVEL_VARIABLE, field, false); | 69 ElementKind.TOP_LEVEL_VARIABLE, field, false)); |
| 72 } | 70 } |
| 73 } | 71 } |
| 74 } | 72 } |
| 75 if (unitMember is FunctionDeclaration) { | 73 if (unitMember is FunctionDeclaration) { |
| 76 FunctionDeclaration functionDeclaration = unitMember; | 74 FunctionDeclaration functionDeclaration = unitMember; |
| 77 _newFunctionOutline(unitOutline, functionDeclaration, true); | 75 unitContents.add(_newFunctionOutline(functionDeclaration, true)); |
| 78 } | 76 } |
| 79 if (unitMember is ClassTypeAlias) { | 77 if (unitMember is ClassTypeAlias) { |
| 80 ClassTypeAlias alias = unitMember; | 78 ClassTypeAlias alias = unitMember; |
| 81 _newClassTypeAlias(unitOutline, alias); | 79 unitContents.add(_newClassTypeAlias(alias)); |
| 82 } | 80 } |
| 83 if (unitMember is FunctionTypeAlias) { | 81 if (unitMember is FunctionTypeAlias) { |
| 84 FunctionTypeAlias alias = unitMember; | 82 FunctionTypeAlias alias = unitMember; |
| 85 _newFunctionTypeAliasOutline(unitOutline, alias); | 83 unitContents.add(_newFunctionTypeAliasOutline(alias)); |
| 86 } | 84 } |
| 87 } | 85 } |
| 86 Outline unitOutline = _newUnitOutline(unitContents); | |
| 88 return unitOutline; | 87 return unitOutline; |
| 89 } | 88 } |
| 90 | 89 |
| 91 void _addLocalFunctionOutlines(Outline parent, FunctionBody body) { | 90 List<Outline> _addLocalFunctionOutlines(FunctionBody body) { |
| 92 body.accept(new _LocalFunctionOutlinesVisitor(this, parent)); | 91 List<Outline> contents = <Outline>[]; |
| 92 body.accept(new _LocalFunctionOutlinesVisitor(this, contents)); | |
| 93 return contents; | |
| 93 } | 94 } |
| 94 | 95 |
| 95 Location _getLocationNode(AstNode node) { | 96 Location _getLocationNode(AstNode node) { |
| 96 int offset = node.offset; | 97 int offset = node.offset; |
| 97 int length = node.length; | 98 int length = node.length; |
| 98 return _getLocationOffsetLength(offset, length); | 99 return _getLocationOffsetLength(offset, length); |
| 99 } | 100 } |
| 100 | 101 |
| 101 Location _getLocationOffsetLength(int offset, int length) { | 102 Location _getLocationOffsetLength(int offset, int length) { |
| 102 LineInfo_Location lineLocation = lineInfo.getLocation(offset); | 103 LineInfo_Location lineLocation = lineInfo.getLocation(offset); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 145 // first child: [endOfParent, endOfNode] | 146 // first child: [endOfParent, endOfNode] |
| 146 int index = siblings.indexOf(node); | 147 int index = siblings.indexOf(node); |
| 147 if (index == 0) { | 148 if (index == 0) { |
| 148 return new _SourceRegion(firstOffset, endOffset - firstOffset); | 149 return new _SourceRegion(firstOffset, endOffset - firstOffset); |
| 149 } | 150 } |
| 150 // not first child: [endOfPreviousSibling, endOfNode] | 151 // not first child: [endOfPreviousSibling, endOfNode] |
| 151 int prevSiblingEnd = siblings[index - 1].end; | 152 int prevSiblingEnd = siblings[index - 1].end; |
| 152 return new _SourceRegion(prevSiblingEnd, endOffset - prevSiblingEnd); | 153 return new _SourceRegion(prevSiblingEnd, endOffset - prevSiblingEnd); |
| 153 } | 154 } |
| 154 | 155 |
| 155 Outline _newClassOutline(Outline parent, ClassDeclaration classDeclaration) { | 156 Outline _newClassOutline(ClassDeclaration classDeclaration, |
| 157 List<Outline> classContents) { | |
| 156 SimpleIdentifier nameNode = classDeclaration.name; | 158 SimpleIdentifier nameNode = classDeclaration.name; |
| 157 String name = nameNode.name; | 159 String name = nameNode.name; |
| 158 _SourceRegion sourceRegion = _getSourceRegion(classDeclaration); | 160 _SourceRegion sourceRegion = _getSourceRegion(classDeclaration); |
| 159 Element element = new Element(ElementKind.CLASS, name, _getLocationNode( | 161 Element element = new Element(ElementKind.CLASS, name, |
| 160 nameNode), Identifier.isPrivateName(name), _isDeprecated(classDeclaratio n), | 162 Element.makeFlags(isPrivate: Identifier.isPrivateName(name), |
| 161 isAbstract: classDeclaration.isAbstract); | 163 isDeprecated: _isDeprecated(classDeclaration), |
| 162 Outline outline = new Outline(element, sourceRegion.offset, | 164 isAbstract: classDeclaration.isAbstract), |
| 163 sourceRegion.length); | 165 location: _getLocationNode(nameNode)); |
| 164 parent.children.add(outline); | 166 return new Outline(element, sourceRegion.offset, |
| 165 return outline; | 167 sourceRegion.length, |
| 168 children: classContents.isNotEmpty ? classContents : null); | |
|
scheglov
2014/08/21 18:03:22
Do we already use null instead of empty lists?
Sho
Paul Berry
2014/08/21 20:00:44
Ok, I'll look into this in a future CL.
| |
| 166 } | 169 } |
| 167 | 170 |
| 168 void _newClassTypeAlias(Outline parent, ClassTypeAlias alias) { | 171 Outline _newClassTypeAlias(ClassTypeAlias alias) { |
| 169 SimpleIdentifier nameNode = alias.name; | 172 SimpleIdentifier nameNode = alias.name; |
| 170 String name = nameNode.name; | 173 String name = nameNode.name; |
| 171 _SourceRegion sourceRegion = _getSourceRegion(alias); | 174 _SourceRegion sourceRegion = _getSourceRegion(alias); |
| 172 Element element = new Element(ElementKind.CLASS_TYPE_ALIAS, name, | 175 Element element = new Element(ElementKind.CLASS_TYPE_ALIAS, name, |
| 173 _getLocationNode(nameNode), Identifier.isPrivateName(name), _isDeprecate d( | 176 Element.makeFlags(isPrivate: Identifier.isPrivateName(name), |
| 174 alias), isAbstract: alias.isAbstract); | 177 isDeprecated: _isDeprecated(alias), isAbstract: alias.isAbstract), |
| 175 Outline outline = new Outline(element, sourceRegion.offset, | 178 location: _getLocationNode(nameNode)); |
| 179 return new Outline(element, sourceRegion.offset, | |
| 176 sourceRegion.length); | 180 sourceRegion.length); |
| 177 parent.children.add(outline); | |
| 178 } | 181 } |
| 179 | 182 |
| 180 void _newConstructorOutline(Outline parent, | 183 Outline _newConstructorOutline(ConstructorDeclaration constructor) { |
| 181 ConstructorDeclaration constructor) { | |
| 182 Identifier returnType = constructor.returnType; | 184 Identifier returnType = constructor.returnType; |
| 183 String name = returnType.name; | 185 String name = returnType.name; |
| 184 int offset = returnType.offset; | 186 int offset = returnType.offset; |
| 185 int length = returnType.length; | 187 int length = returnType.length; |
| 186 SimpleIdentifier constructorNameNode = constructor.name; | 188 SimpleIdentifier constructorNameNode = constructor.name; |
| 187 bool isPrivate = false; | 189 bool isPrivate = false; |
| 188 if (constructorNameNode != null) { | 190 if (constructorNameNode != null) { |
| 189 String constructorName = constructorNameNode.name; | 191 String constructorName = constructorNameNode.name; |
| 190 isPrivate = Identifier.isPrivateName(constructorName); | 192 isPrivate = Identifier.isPrivateName(constructorName); |
| 191 name += '.${constructorName}'; | 193 name += '.${constructorName}'; |
| 192 offset = constructorNameNode.offset; | 194 offset = constructorNameNode.offset; |
| 193 length = constructorNameNode.length; | 195 length = constructorNameNode.length; |
| 194 } | 196 } |
| 195 _SourceRegion sourceRegion = _getSourceRegion(constructor); | 197 _SourceRegion sourceRegion = _getSourceRegion(constructor); |
| 196 FormalParameterList parameters = constructor.parameters; | 198 FormalParameterList parameters = constructor.parameters; |
| 197 String parametersStr = parameters != null ? parameters.toSource() : ''; | 199 String parametersStr = parameters != null ? parameters.toSource() : ''; |
| 198 Element element = new Element(ElementKind.CONSTRUCTOR, name, | 200 Element element = new Element(ElementKind.CONSTRUCTOR, name, |
| 199 _getLocationOffsetLength(offset, length), isPrivate, _isDeprecated(const ructor), | 201 Element.makeFlags(isPrivate: isPrivate, |
| 202 isDeprecated: _isDeprecated(constructor)), | |
| 203 location: _getLocationOffsetLength(offset, length), | |
| 200 parameters: parametersStr); | 204 parameters: parametersStr); |
| 205 List<Outline> contents = _addLocalFunctionOutlines(constructor.body); | |
| 201 Outline outline = new Outline(element, sourceRegion.offset, | 206 Outline outline = new Outline(element, sourceRegion.offset, |
| 202 sourceRegion.length); | 207 sourceRegion.length, children: contents.isNotEmpty ? contents : null); |
| 203 parent.children.add(outline); | 208 return outline; |
| 204 _addLocalFunctionOutlines(outline, constructor.body); | |
| 205 } | 209 } |
| 206 | 210 |
| 207 void _newFunctionOutline(Outline parent, FunctionDeclaration function, | 211 Outline _newFunctionOutline(FunctionDeclaration function, bool isStatic) { |
| 208 bool isStatic) { | |
| 209 TypeName returnType = function.returnType; | 212 TypeName returnType = function.returnType; |
| 210 SimpleIdentifier nameNode = function.name; | 213 SimpleIdentifier nameNode = function.name; |
| 211 String name = nameNode.name; | 214 String name = nameNode.name; |
| 212 FunctionExpression functionExpression = function.functionExpression; | 215 FunctionExpression functionExpression = function.functionExpression; |
| 213 FormalParameterList parameters = functionExpression.parameters; | 216 FormalParameterList parameters = functionExpression.parameters; |
| 214 ElementKind kind; | 217 ElementKind kind; |
| 215 if (function.isGetter) { | 218 if (function.isGetter) { |
| 216 kind = ElementKind.GETTER; | 219 kind = ElementKind.GETTER; |
| 217 } else if (function.isSetter) { | 220 } else if (function.isSetter) { |
| 218 kind = ElementKind.SETTER; | 221 kind = ElementKind.SETTER; |
| 219 } else { | 222 } else { |
| 220 kind = ElementKind.FUNCTION; | 223 kind = ElementKind.FUNCTION; |
| 221 } | 224 } |
| 222 _SourceRegion sourceRegion = _getSourceRegion(function); | 225 _SourceRegion sourceRegion = _getSourceRegion(function); |
| 223 String parametersStr = parameters != null ? parameters.toSource() : ''; | 226 String parametersStr = parameters != null ? parameters.toSource() : ''; |
| 224 String returnTypeStr = returnType != null ? returnType.toSource() : ''; | 227 String returnTypeStr = returnType != null ? returnType.toSource() : ''; |
| 225 Element element = new Element(kind, name, _getLocationNode(nameNode), | 228 Element element = new Element(kind, name, |
| 226 Identifier.isPrivateName(name), _isDeprecated(function), parameters: | 229 Element.makeFlags(isPrivate: Identifier.isPrivateName(name), |
| 227 parametersStr, returnType: returnTypeStr, isStatic: isStatic); | 230 isDeprecated: _isDeprecated(function), isStatic: isStatic), |
| 231 location: _getLocationNode(nameNode), parameters: parametersStr, | |
| 232 returnType: returnTypeStr); | |
| 233 List<Outline> contents = _addLocalFunctionOutlines(functionExpression.body); | |
| 228 Outline outline = new Outline(element, sourceRegion.offset, | 234 Outline outline = new Outline(element, sourceRegion.offset, |
| 229 sourceRegion.length); | 235 sourceRegion.length, children: contents.isNotEmpty ? contents : null); |
| 230 parent.children.add(outline); | 236 return outline; |
| 231 _addLocalFunctionOutlines(outline, functionExpression.body); | |
| 232 } | 237 } |
| 233 | 238 |
| 234 void _newFunctionTypeAliasOutline(Outline parent, FunctionTypeAlias alias) { | 239 Outline _newFunctionTypeAliasOutline(FunctionTypeAlias alias) { |
| 235 TypeName returnType = alias.returnType; | 240 TypeName returnType = alias.returnType; |
| 236 SimpleIdentifier nameNode = alias.name; | 241 SimpleIdentifier nameNode = alias.name; |
| 237 String name = nameNode.name; | 242 String name = nameNode.name; |
| 238 _SourceRegion sourceRegion = _getSourceRegion(alias); | 243 _SourceRegion sourceRegion = _getSourceRegion(alias); |
| 239 FormalParameterList parameters = alias.parameters; | 244 FormalParameterList parameters = alias.parameters; |
| 240 String parametersStr = parameters != null ? parameters.toSource() : ''; | 245 String parametersStr = parameters != null ? parameters.toSource() : ''; |
| 241 String returnTypeStr = returnType != null ? returnType.toSource() : ''; | 246 String returnTypeStr = returnType != null ? returnType.toSource() : ''; |
| 242 Element element = new Element(ElementKind.FUNCTION_TYPE_ALIAS, name, | 247 Element element = new Element(ElementKind.FUNCTION_TYPE_ALIAS, name, |
| 243 _getLocationNode(nameNode), Identifier.isPrivateName(name), _isDeprecate d( | 248 Element.makeFlags(isPrivate: Identifier.isPrivateName(name), |
| 244 alias), parameters: parametersStr, returnType: returnTypeStr); | 249 isDeprecated: _isDeprecated(alias)), |
| 245 Outline outline = new Outline(element, sourceRegion.offset, | 250 location: _getLocationNode(nameNode), parameters: parametersStr, |
| 251 returnType: returnTypeStr); | |
| 252 return new Outline(element, sourceRegion.offset, | |
| 246 sourceRegion.length); | 253 sourceRegion.length); |
| 247 parent.children.add(outline); | |
| 248 } | 254 } |
| 249 | 255 |
| 250 void _newMethodOutline(Outline parent, MethodDeclaration method) { | 256 Outline _newMethodOutline(MethodDeclaration method) { |
| 251 TypeName returnType = method.returnType; | 257 TypeName returnType = method.returnType; |
| 252 SimpleIdentifier nameNode = method.name; | 258 SimpleIdentifier nameNode = method.name; |
| 253 String name = nameNode.name; | 259 String name = nameNode.name; |
| 254 FormalParameterList parameters = method.parameters; | 260 FormalParameterList parameters = method.parameters; |
| 255 ElementKind kind; | 261 ElementKind kind; |
| 256 if (method.isGetter) { | 262 if (method.isGetter) { |
| 257 kind = ElementKind.GETTER; | 263 kind = ElementKind.GETTER; |
| 258 } else if (method.isSetter) { | 264 } else if (method.isSetter) { |
| 259 kind = ElementKind.SETTER; | 265 kind = ElementKind.SETTER; |
| 260 } else { | 266 } else { |
| 261 kind = ElementKind.METHOD; | 267 kind = ElementKind.METHOD; |
| 262 } | 268 } |
| 263 _SourceRegion sourceRegion = _getSourceRegion(method); | 269 _SourceRegion sourceRegion = _getSourceRegion(method); |
| 264 String parametersStr = parameters != null ? parameters.toSource() : ''; | 270 String parametersStr = parameters != null ? parameters.toSource() : ''; |
| 265 String returnTypeStr = returnType != null ? returnType.toSource() : ''; | 271 String returnTypeStr = returnType != null ? returnType.toSource() : ''; |
| 266 Element element = new Element(kind, name, _getLocationNode(nameNode), | 272 Element element = new Element(kind, name, |
| 267 Identifier.isPrivateName(name), _isDeprecated(method), parameters: | 273 Element.makeFlags(isPrivate: Identifier.isPrivateName(name), |
| 268 parametersStr, returnType: returnTypeStr, isAbstract: method.isAbstract, | 274 isDeprecated: _isDeprecated(method), isAbstract: method.isAbstract, |
| 269 isStatic: method.isStatic); | 275 isStatic: method.isStatic), location: _getLocationNode(nameNode), |
| 276 parameters: parametersStr, returnType: returnTypeStr); | |
| 277 List<Outline> contents = _addLocalFunctionOutlines(method.body); | |
| 270 Outline outline = new Outline(element, sourceRegion.offset, | 278 Outline outline = new Outline(element, sourceRegion.offset, |
| 271 sourceRegion.length); | 279 sourceRegion.length, children: contents.isNotEmpty ? contents : null); |
| 272 parent.children.add(outline); | 280 return outline; |
| 273 _addLocalFunctionOutlines(outline, method.body); | |
| 274 } | 281 } |
| 275 | 282 |
| 276 Outline _newUnitOutline() { | 283 Outline _newUnitOutline(List<Outline> unitContents) { |
| 277 Element element = new Element(ElementKind.COMPILATION_UNIT, '<unit>', | 284 Element element = new Element(ElementKind.COMPILATION_UNIT, '<unit>', |
| 278 _getLocationNode(_unit), false, false); | 285 Element.makeFlags(), location: _getLocationNode(_unit)); |
| 279 return new Outline(element, _unit.offset, _unit.length); | 286 return new Outline(element, _unit.offset, _unit.length, |
| 287 children: unitContents.isNotEmpty ? unitContents : null); | |
| 280 } | 288 } |
| 281 | 289 |
| 282 void _newVariableOutline(Outline parent, String typeName, ElementKind kind, | 290 Outline _newVariableOutline(String typeName, ElementKind kind, |
| 283 VariableDeclaration variable, bool isStatic) { | 291 VariableDeclaration variable, bool isStatic) { |
| 284 SimpleIdentifier nameNode = variable.name; | 292 SimpleIdentifier nameNode = variable.name; |
| 285 String name = nameNode.name; | 293 String name = nameNode.name; |
| 286 _SourceRegion sourceRegion = _getSourceRegion(variable); | 294 _SourceRegion sourceRegion = _getSourceRegion(variable); |
| 287 Element element = new Element(kind, name, _getLocationNode(nameNode), | 295 Element element = new Element(kind, name, |
| 288 Identifier.isPrivateName(name), _isDeprecated(variable), returnType: typ eName, | 296 Element.makeFlags(isPrivate: Identifier.isPrivateName(name), |
| 289 isStatic: isStatic, isConst: variable.isConst, isFinal: variable.isFinal ); | 297 isDeprecated: _isDeprecated(variable), |
| 298 isStatic: isStatic, isConst: variable.isConst, | |
| 299 isFinal: variable.isFinal), location: _getLocationNode(nameNode), | |
| 300 returnType: typeName); | |
| 290 Outline outline = new Outline(element, sourceRegion.offset, | 301 Outline outline = new Outline(element, sourceRegion.offset, |
| 291 sourceRegion.length); | 302 sourceRegion.length); |
| 292 parent.children.add(outline); | 303 return outline; |
| 293 } | 304 } |
| 294 | 305 |
| 295 /** | 306 /** |
| 296 * Returns `true` if the given [element] is not `null` and deprecated. | 307 * Returns `true` if the given [element] is not `null` and deprecated. |
| 297 */ | 308 */ |
| 298 static bool _isDeprecated(Declaration declaration) { | 309 static bool _isDeprecated(Declaration declaration) { |
| 299 engine.Element element = declaration.element; | 310 engine.Element element = declaration.element; |
| 300 return element != null && element.isDeprecated; | 311 return element != null && element.isDeprecated; |
| 301 } | 312 } |
| 302 } | 313 } |
| 303 | 314 |
| 304 | 315 |
| 305 /** | 316 /** |
| 306 * An element outline. | |
| 307 */ | |
| 308 class Outline implements HasToJson { | |
| 309 static const List<Outline> EMPTY_ARRAY = const <Outline>[]; | |
| 310 | |
| 311 /** | |
| 312 * The children of the node. | |
| 313 * The field will be omitted in JSON if the node has no children. | |
| 314 */ | |
| 315 final List<Outline> children = <Outline>[]; | |
| 316 | |
| 317 /** | |
| 318 * A description of the element represented by this node. | |
| 319 */ | |
| 320 final Element element; | |
| 321 | |
| 322 /** | |
| 323 * The length of the element. | |
| 324 */ | |
| 325 final int length; | |
| 326 | |
| 327 /** | |
| 328 * The offset of the first character of the element. | |
| 329 */ | |
| 330 final int offset; | |
| 331 | |
| 332 Outline(this.element, this.offset, this.length); | |
| 333 | |
| 334 factory Outline.fromJson(Map<String, Object> map) { | |
| 335 Element element = new Element.fromJson(map[ELEMENT]); | |
| 336 Outline outline = new Outline(element, map[OFFSET], map[LENGTH]); | |
| 337 // add children | |
| 338 List<Map<String, Object>> childrenMaps = map[CHILDREN]; | |
| 339 if (childrenMaps != null) { | |
| 340 childrenMaps.forEach((childMap) { | |
| 341 outline.children.add(new Outline.fromJson(childMap)); | |
| 342 }); | |
| 343 } | |
| 344 // done | |
| 345 return outline; | |
| 346 } | |
| 347 | |
| 348 Map<String, Object> toJson() { | |
| 349 Map<String, Object> json = { | |
| 350 ELEMENT: element.toJson(), | |
| 351 OFFSET: offset, | |
| 352 LENGTH: length | |
| 353 }; | |
| 354 if (children.isNotEmpty) { | |
| 355 json[CHILDREN] = children.map((child) => child.toJson()).toList(); | |
| 356 } | |
| 357 return json; | |
| 358 } | |
| 359 } | |
| 360 | |
| 361 | |
| 362 /** | |
| 363 * A visitor for building local function outlines. | 317 * A visitor for building local function outlines. |
| 364 */ | 318 */ |
| 365 class _LocalFunctionOutlinesVisitor extends RecursiveAstVisitor { | 319 class _LocalFunctionOutlinesVisitor extends RecursiveAstVisitor { |
| 366 final DartUnitOutlineComputer outlineComputer; | 320 final DartUnitOutlineComputer outlineComputer; |
| 367 final Outline parent; | 321 final List<Outline> contents; |
| 368 | 322 |
| 369 _LocalFunctionOutlinesVisitor(this.outlineComputer, this.parent); | 323 _LocalFunctionOutlinesVisitor(this.outlineComputer, this.contents); |
| 370 | 324 |
| 371 @override | 325 @override |
| 372 visitFunctionDeclaration(FunctionDeclaration node) { | 326 visitFunctionDeclaration(FunctionDeclaration node) { |
| 373 outlineComputer._newFunctionOutline(parent, node, false); | 327 contents.add(outlineComputer._newFunctionOutline(node, false)); |
| 374 } | 328 } |
| 375 } | 329 } |
| 376 | 330 |
| 377 | 331 |
| 378 /** | 332 /** |
| 379 * A range of characters. | 333 * A range of characters. |
| 380 */ | 334 */ |
| 381 class _SourceRegion { | 335 class _SourceRegion { |
| 382 final int length; | 336 final int length; |
| 383 final int offset; | 337 final int offset; |
| 384 _SourceRegion(this.offset, this.length); | 338 _SourceRegion(this.offset, this.length); |
| 385 } | 339 } |
| OLD | NEW |