| 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 analyzer.src.dart.element.builder; | 5 library analyzer.src.dart.element.builder; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/dart/ast/ast.dart'; | 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/visitor.dart'; | 10 import 'package:analyzer/dart/ast/visitor.dart'; |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 * stored. | 296 * stored. |
| 297 */ | 297 */ |
| 298 final CompilationUnitElement compilationUnitElement; | 298 final CompilationUnitElement compilationUnitElement; |
| 299 | 299 |
| 300 /** | 300 /** |
| 301 * The element holder associated with the element that is currently being buil
t. | 301 * The element holder associated with the element that is currently being buil
t. |
| 302 */ | 302 */ |
| 303 ElementHolder _currentHolder; | 303 ElementHolder _currentHolder; |
| 304 | 304 |
| 305 /** | 305 /** |
| 306 * A flag indicating whether a variable declaration is in the context of a fie
ld declaration. | |
| 307 */ | |
| 308 bool _inFieldContext = false; | |
| 309 | |
| 310 /** | |
| 311 * A flag indicating whether a variable declaration is within the body of a me
thod or function. | 306 * A flag indicating whether a variable declaration is within the body of a me
thod or function. |
| 312 */ | 307 */ |
| 313 bool _inFunction = false; | 308 bool _inFunction = false; |
| 314 | 309 |
| 315 /** | 310 /** |
| 316 * A collection holding the elements defined in a class that need to have | 311 * A collection holding the elements defined in a class that need to have |
| 317 * their function type fixed to take into account type parameters of the | 312 * their function type fixed to take into account type parameters of the |
| 318 * enclosing class, or `null` if we are not currently processing nodes within | 313 * enclosing class, or `null` if we are not currently processing nodes within |
| 319 * a class. | 314 * a class. |
| 320 */ | 315 */ |
| 321 List<ExecutableElementImpl> _functionTypesToFix = null; | 316 List<ExecutableElementImpl> _functionTypesToFix = null; |
| 322 | 317 |
| 323 /** | 318 /** |
| 324 * A table mapping field names to field elements for the fields defined in the
current class, or | 319 * A table mapping field names to field elements for the fields defined in the
current class, or |
| 325 * `null` if we are not in the scope of a class. | 320 * `null` if we are not in the scope of a class. |
| 326 */ | 321 */ |
| 327 HashMap<String, FieldElement> _fieldMap; | 322 HashMap<String, FieldElement> _fieldMap; |
| 328 | 323 |
| 329 /** | 324 /** |
| 330 * Initialize a newly created element builder to build the elements for a comp
ilation unit. | 325 * Initialize a newly created element builder to build the elements for a comp
ilation unit. |
| 331 * | 326 * |
| 332 * @param initialHolder the element holder associated with the compilation uni
t being built | 327 * @param initialHolder the element holder associated with the compilation uni
t being built |
| 333 */ | 328 */ |
| 334 ElementBuilder(ElementHolder initialHolder, this.compilationUnitElement) { | 329 ElementBuilder(ElementHolder initialHolder, this.compilationUnitElement) { |
| 335 _currentHolder = initialHolder; | 330 _currentHolder = initialHolder; |
| 336 } | 331 } |
| 337 | 332 |
| 338 @override | 333 @override |
| 339 Object visitBlock(Block node) { | |
| 340 bool wasInField = _inFieldContext; | |
| 341 _inFieldContext = false; | |
| 342 try { | |
| 343 node.visitChildren(this); | |
| 344 } finally { | |
| 345 _inFieldContext = wasInField; | |
| 346 } | |
| 347 return null; | |
| 348 } | |
| 349 | |
| 350 @override | |
| 351 Object visitCatchClause(CatchClause node) { | 334 Object visitCatchClause(CatchClause node) { |
| 352 SimpleIdentifier exceptionParameter = node.exceptionParameter; | 335 SimpleIdentifier exceptionParameter = node.exceptionParameter; |
| 353 if (exceptionParameter != null) { | 336 if (exceptionParameter != null) { |
| 354 // exception | 337 // exception |
| 355 LocalVariableElementImpl exception = | 338 LocalVariableElementImpl exception = |
| 356 new LocalVariableElementImpl.forNode(exceptionParameter); | 339 new LocalVariableElementImpl.forNode(exceptionParameter); |
| 357 if (node.exceptionType == null) { | 340 if (node.exceptionType == null) { |
| 358 exception.hasImplicitType = true; | 341 exception.hasImplicitType = true; |
| 359 } | 342 } |
| 360 _currentHolder.addLocalVariable(exception); | 343 _currentHolder.addLocalVariable(exception); |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 596 return super.visitEnumDeclaration(node); | 579 return super.visitEnumDeclaration(node); |
| 597 } | 580 } |
| 598 | 581 |
| 599 @override | 582 @override |
| 600 Object visitExportDirective(ExportDirective node) { | 583 Object visitExportDirective(ExportDirective node) { |
| 601 _createElementAnnotations(node.metadata); | 584 _createElementAnnotations(node.metadata); |
| 602 return super.visitExportDirective(node); | 585 return super.visitExportDirective(node); |
| 603 } | 586 } |
| 604 | 587 |
| 605 @override | 588 @override |
| 606 Object visitFieldDeclaration(FieldDeclaration node) { | |
| 607 bool wasInField = _inFieldContext; | |
| 608 _inFieldContext = true; | |
| 609 try { | |
| 610 node.visitChildren(this); | |
| 611 } finally { | |
| 612 _inFieldContext = wasInField; | |
| 613 } | |
| 614 return null; | |
| 615 } | |
| 616 | |
| 617 @override | |
| 618 Object visitFieldFormalParameter(FieldFormalParameter node) { | 589 Object visitFieldFormalParameter(FieldFormalParameter node) { |
| 619 if (node.parent is! DefaultFormalParameter) { | 590 if (node.parent is! DefaultFormalParameter) { |
| 620 SimpleIdentifier parameterName = node.identifier; | 591 SimpleIdentifier parameterName = node.identifier; |
| 621 FieldElement field = | 592 FieldElement field = |
| 622 _fieldMap == null ? null : _fieldMap[parameterName.name]; | 593 _fieldMap == null ? null : _fieldMap[parameterName.name]; |
| 623 FieldFormalParameterElementImpl parameter = | 594 FieldFormalParameterElementImpl parameter = |
| 624 new FieldFormalParameterElementImpl.forNode(parameterName); | 595 new FieldFormalParameterElementImpl.forNode(parameterName); |
| 625 parameter.const3 = node.isConst; | 596 parameter.const3 = node.isConst; |
| 626 parameter.final2 = node.isFinal; | 597 parameter.final2 = node.isFinal; |
| 627 parameter.parameterKind = node.kind; | 598 parameter.parameterKind = node.kind; |
| (...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1104 _currentHolder.addTypeParameter(typeParameter); | 1075 _currentHolder.addTypeParameter(typeParameter); |
| 1105 parameterName.staticElement = typeParameter; | 1076 parameterName.staticElement = typeParameter; |
| 1106 return super.visitTypeParameter(node); | 1077 return super.visitTypeParameter(node); |
| 1107 } | 1078 } |
| 1108 | 1079 |
| 1109 @override | 1080 @override |
| 1110 Object visitVariableDeclaration(VariableDeclaration node) { | 1081 Object visitVariableDeclaration(VariableDeclaration node) { |
| 1111 bool isConst = node.isConst; | 1082 bool isConst = node.isConst; |
| 1112 bool isFinal = node.isFinal; | 1083 bool isFinal = node.isFinal; |
| 1113 bool hasInitializer = node.initializer != null; | 1084 bool hasInitializer = node.initializer != null; |
| 1085 VariableDeclarationList varList = node.parent; |
| 1086 FieldDeclaration fieldNode = |
| 1087 varList.parent is FieldDeclaration ? varList.parent : null; |
| 1114 VariableElementImpl element; | 1088 VariableElementImpl element; |
| 1115 if (_inFieldContext) { | 1089 if (fieldNode != null) { |
| 1116 SimpleIdentifier fieldName = node.name; | 1090 SimpleIdentifier fieldName = node.name; |
| 1117 FieldElementImpl field; | 1091 FieldElementImpl field; |
| 1118 if ((isConst || isFinal) && hasInitializer) { | 1092 if ((isConst || isFinal && !fieldNode.isStatic) && hasInitializer) { |
| 1119 field = new ConstFieldElementImpl.forNode(fieldName); | 1093 field = new ConstFieldElementImpl.forNode(fieldName); |
| 1120 } else { | 1094 } else { |
| 1121 field = new FieldElementImpl.forNode(fieldName); | 1095 field = new FieldElementImpl.forNode(fieldName); |
| 1122 } | 1096 } |
| 1123 element = field; | 1097 element = field; |
| 1124 if (node.parent.parent is FieldDeclaration) { | 1098 field.static = fieldNode.isStatic; |
| 1125 setElementDocumentationComment(element, node.parent.parent); | 1099 setElementDocumentationComment(element, fieldNode); |
| 1126 } | 1100 field.hasImplicitType = varList.type == null; |
| 1127 if ((node.parent as VariableDeclarationList).type == null) { | |
| 1128 field.hasImplicitType = true; | |
| 1129 } | |
| 1130 _currentHolder.addField(field); | 1101 _currentHolder.addField(field); |
| 1131 fieldName.staticElement = field; | 1102 fieldName.staticElement = field; |
| 1132 } else if (_inFunction) { | 1103 } else if (_inFunction) { |
| 1133 SimpleIdentifier variableName = node.name; | 1104 SimpleIdentifier variableName = node.name; |
| 1134 LocalVariableElementImpl variable; | 1105 LocalVariableElementImpl variable; |
| 1135 if (isConst && hasInitializer) { | 1106 if (isConst && hasInitializer) { |
| 1136 variable = new ConstLocalVariableElementImpl.forNode(variableName); | 1107 variable = new ConstLocalVariableElementImpl.forNode(variableName); |
| 1137 } else { | 1108 } else { |
| 1138 variable = new LocalVariableElementImpl.forNode(variableName); | 1109 variable = new LocalVariableElementImpl.forNode(variableName); |
| 1139 } | 1110 } |
| 1140 element = variable; | 1111 element = variable; |
| 1141 Block enclosingBlock = node.getAncestor((node) => node is Block); | 1112 Block enclosingBlock = node.getAncestor((node) => node is Block); |
| 1142 // TODO(brianwilkerson) This isn't right for variables declared in a for | 1113 // TODO(brianwilkerson) This isn't right for variables declared in a for |
| 1143 // loop. | 1114 // loop. |
| 1144 variable.setVisibleRange(enclosingBlock.offset, enclosingBlock.length); | 1115 variable.setVisibleRange(enclosingBlock.offset, enclosingBlock.length); |
| 1145 if ((node.parent as VariableDeclarationList).type == null) { | 1116 variable.hasImplicitType = varList.type == null; |
| 1146 variable.hasImplicitType = true; | |
| 1147 } | |
| 1148 _currentHolder.addLocalVariable(variable); | 1117 _currentHolder.addLocalVariable(variable); |
| 1149 variableName.staticElement = element; | 1118 variableName.staticElement = element; |
| 1150 } else { | 1119 } else { |
| 1151 SimpleIdentifier variableName = node.name; | 1120 SimpleIdentifier variableName = node.name; |
| 1152 TopLevelVariableElementImpl variable; | 1121 TopLevelVariableElementImpl variable; |
| 1153 if (isConst && hasInitializer) { | 1122 if (isConst && hasInitializer) { |
| 1154 variable = new ConstTopLevelVariableElementImpl.forNode(variableName); | 1123 variable = new ConstTopLevelVariableElementImpl.forNode(variableName); |
| 1155 } else { | 1124 } else { |
| 1156 variable = new TopLevelVariableElementImpl.forNode(variableName); | 1125 variable = new TopLevelVariableElementImpl.forNode(variableName); |
| 1157 } | 1126 } |
| 1158 element = variable; | 1127 element = variable; |
| 1159 if (node.parent.parent is TopLevelVariableDeclaration) { | 1128 if (varList.parent is TopLevelVariableDeclaration) { |
| 1160 setElementDocumentationComment(element, node.parent.parent); | 1129 setElementDocumentationComment(element, varList.parent); |
| 1161 } | 1130 } |
| 1162 if ((node.parent as VariableDeclarationList).type == null) { | 1131 variable.hasImplicitType = varList.type == null; |
| 1163 variable.hasImplicitType = true; | |
| 1164 } | |
| 1165 _currentHolder.addTopLevelVariable(variable); | 1132 _currentHolder.addTopLevelVariable(variable); |
| 1166 variableName.staticElement = element; | 1133 variableName.staticElement = element; |
| 1167 } | 1134 } |
| 1168 element.const3 = isConst; | 1135 element.const3 = isConst; |
| 1169 element.final2 = isFinal; | 1136 element.final2 = isFinal; |
| 1170 if (hasInitializer) { | 1137 if (hasInitializer) { |
| 1171 ElementHolder holder = new ElementHolder(); | 1138 ElementHolder holder = new ElementHolder(); |
| 1172 bool wasInFieldContext = _inFieldContext; | 1139 _visit(holder, node.initializer); |
| 1173 _inFieldContext = false; | |
| 1174 try { | |
| 1175 _visit(holder, node.initializer); | |
| 1176 } finally { | |
| 1177 _inFieldContext = wasInFieldContext; | |
| 1178 } | |
| 1179 FunctionElementImpl initializer = | 1140 FunctionElementImpl initializer = |
| 1180 new FunctionElementImpl.forOffset(node.initializer.beginToken.offset); | 1141 new FunctionElementImpl.forOffset(node.initializer.beginToken.offset); |
| 1181 initializer.functions = holder.functions; | 1142 initializer.functions = holder.functions; |
| 1182 initializer.labels = holder.labels; | 1143 initializer.labels = holder.labels; |
| 1183 initializer.localVariables = holder.localVariables; | 1144 initializer.localVariables = holder.localVariables; |
| 1184 initializer.synthetic = true; | 1145 initializer.synthetic = true; |
| 1185 element.initializer = initializer; | 1146 element.initializer = initializer; |
| 1186 holder.validate(); | 1147 holder.validate(); |
| 1187 } | 1148 } |
| 1188 if (element is PropertyInducingElementImpl) { | 1149 if (element is PropertyInducingElementImpl) { |
| 1189 if (_inFieldContext) { | |
| 1190 (element as FieldElementImpl).static = | |
| 1191 (node.parent.parent as FieldDeclaration).isStatic; | |
| 1192 } | |
| 1193 PropertyAccessorElementImpl getter = | 1150 PropertyAccessorElementImpl getter = |
| 1194 new PropertyAccessorElementImpl.forVariable(element); | 1151 new PropertyAccessorElementImpl.forVariable(element); |
| 1195 getter.getter = true; | 1152 getter.getter = true; |
| 1196 if (element.hasImplicitType) { | 1153 if (element.hasImplicitType) { |
| 1197 getter.hasImplicitReturnType = true; | 1154 getter.hasImplicitReturnType = true; |
| 1198 } | 1155 } |
| 1199 _currentHolder.addAccessor(getter); | 1156 _currentHolder.addAccessor(getter); |
| 1200 element.getter = getter; | 1157 element.getter = getter; |
| 1201 if (!isConst && !isFinal) { | 1158 if (!isConst && !isFinal) { |
| 1202 PropertyAccessorElementImpl setter = | 1159 PropertyAccessorElementImpl setter = |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1420 return null; | 1377 return null; |
| 1421 } | 1378 } |
| 1422 | 1379 |
| 1423 /** | 1380 /** |
| 1424 * Return the lexical identifiers associated with the given [identifiers]. | 1381 * Return the lexical identifiers associated with the given [identifiers]. |
| 1425 */ | 1382 */ |
| 1426 static List<String> _getIdentifiers(NodeList<SimpleIdentifier> identifiers) { | 1383 static List<String> _getIdentifiers(NodeList<SimpleIdentifier> identifiers) { |
| 1427 return identifiers.map((identifier) => identifier.name).toList(); | 1384 return identifiers.map((identifier) => identifier.name).toList(); |
| 1428 } | 1385 } |
| 1429 } | 1386 } |
| OLD | NEW |