| 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 engine.incremental_resolver; | 5 library engine.incremental_resolver; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'ast.dart'; | 9 import 'ast.dart'; |
| 10 import 'element.dart'; | 10 import 'element.dart'; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 } | 85 } |
| 86 | 86 |
| 87 @override | 87 @override |
| 88 visitBlockFunctionBody(BlockFunctionBody node) { | 88 visitBlockFunctionBody(BlockFunctionBody node) { |
| 89 // ignore bodies | 89 // ignore bodies |
| 90 } | 90 } |
| 91 | 91 |
| 92 @override | 92 @override |
| 93 visitClassDeclaration(ClassDeclaration node) { | 93 visitClassDeclaration(ClassDeclaration node) { |
| 94 String name = node.name.name; | 94 String name = node.name.name; |
| 95 ClassElement clazz = _findElement(_enclosingUnit.types, name); | 95 ClassElement element = _findElement(_enclosingUnit.types, name); |
| 96 _enclosingClass = clazz; | 96 _enclosingClass = element; |
| 97 _processElement(clazz); | 97 _processElement(element); |
| 98 // check for missing clauses | 98 // check for missing clauses |
| 99 if (node.extendsClause == null) { | 99 if (node.extendsClause == null) { |
| 100 _assertTrue(clazz.supertype.name == 'Object'); | 100 _assertTrue(element.supertype.name == 'Object'); |
| 101 } | 101 } |
| 102 if (node.implementsClause == null) { | 102 if (node.implementsClause == null) { |
| 103 _assertTrue(clazz.interfaces.isEmpty); | 103 _assertTrue(element.interfaces.isEmpty); |
| 104 } | 104 } |
| 105 if (node.withClause == null) { | 105 if (node.withClause == null) { |
| 106 _assertTrue(clazz.mixins.isEmpty); | 106 _assertTrue(element.mixins.isEmpty); |
| 107 } | 107 } |
| 108 // process clauses and members | 108 // process clauses and members |
| 109 _hasConstructor = false; | 109 _hasConstructor = false; |
| 110 super.visitClassDeclaration(node); | 110 super.visitClassDeclaration(node); |
| 111 // process default constructor | 111 // process default constructor |
| 112 if (!_hasConstructor) { | 112 if (!_hasConstructor) { |
| 113 ConstructorElement constructor = clazz.unnamedConstructor; | 113 ConstructorElement constructor = element.unnamedConstructor; |
| 114 _processElement(constructor); | 114 _processElement(constructor); |
| 115 if (!constructor.isSynthetic) { | 115 if (!constructor.isSynthetic) { |
| 116 _assertEquals(constructor.parameters.length, 0); | 116 _assertEquals(constructor.parameters.length, 0); |
| 117 } | 117 } |
| 118 } | 118 } |
| 119 } | 119 } |
| 120 | 120 |
| 121 @override | 121 @override |
| 122 visitClassTypeAlias(ClassTypeAlias node) { | 122 visitClassTypeAlias(ClassTypeAlias node) { |
| 123 ClassElement outerClass = _enclosingClass; | 123 String name = node.name.name; |
| 124 try { | 124 ClassElement element = _findElement(_enclosingUnit.types, name); |
| 125 SimpleIdentifier className = node.name; | 125 _enclosingClass = element; |
| 126 _enclosingClass = _findIdentifier(_enclosingUnit.types, className); | 126 _processElement(element); |
| 127 _processElement(_enclosingClass); | 127 _processElement(element.unnamedConstructor); |
| 128 super.visitClassTypeAlias(node); | 128 super.visitClassTypeAlias(node); |
| 129 } finally { | |
| 130 _enclosingClass = outerClass; | |
| 131 } | |
| 132 } | 129 } |
| 133 | 130 |
| 134 @override | 131 @override |
| 135 visitCompilationUnit(CompilationUnit node) { | 132 visitCompilationUnit(CompilationUnit node) { |
| 136 _processElement(_enclosingUnit); | 133 _processElement(_enclosingUnit); |
| 137 super.visitCompilationUnit(node); | 134 super.visitCompilationUnit(node); |
| 138 } | 135 } |
| 139 | 136 |
| 140 @override | 137 @override |
| 141 visitConstructorDeclaration(ConstructorDeclaration node) { | 138 visitConstructorDeclaration(ConstructorDeclaration node) { |
| 142 _hasConstructor = true; | 139 _hasConstructor = true; |
| 143 SimpleIdentifier constructorName = node.name; | 140 SimpleIdentifier constructorName = node.name; |
| 144 ConstructorElement element = constructorName == null ? | 141 ConstructorElement element = constructorName == null ? |
| 145 _enclosingClass.unnamedConstructor : | 142 _enclosingClass.unnamedConstructor : |
| 146 _enclosingClass.getNamedConstructor(constructorName.name); | 143 _enclosingClass.getNamedConstructor(constructorName.name); |
| 147 _processElement(element); | 144 _processElement(element); |
| 148 _assertCompatibleParameters(node.parameters, element.parameters); | 145 _assertCompatibleParameters(node.parameters, element.parameters); |
| 149 } | 146 } |
| 150 | 147 |
| 151 @override | 148 @override |
| 152 visitEnumDeclaration(EnumDeclaration node) { | 149 visitEnumDeclaration(EnumDeclaration node) { |
| 153 ClassElement enclosingEnum = | 150 String name = node.name.name; |
| 154 _findIdentifier(_enclosingUnit.enums, node.name); | 151 ClassElement element = _findElement(_enclosingUnit.enums, name); |
| 155 _processElement(enclosingEnum); | 152 _enclosingClass = element; |
| 156 List<FieldElement> constants = enclosingEnum.fields; | 153 _processElement(element); |
| 157 for (EnumConstantDeclaration constant in node.constants) { | 154 _assertTrue(element.isEnum); |
| 158 FieldElement constantElement = _findIdentifier(constants, constant.name); | |
| 159 _processElement(constantElement); | |
| 160 } | |
| 161 super.visitEnumDeclaration(node); | 155 super.visitEnumDeclaration(node); |
| 162 } | 156 } |
| 163 | 157 |
| 164 @override | 158 @override |
| 159 visitEnumConstantDeclaration(EnumConstantDeclaration node) { |
| 160 String name = node.name.name; |
| 161 FieldElement element = _findElement(_enclosingClass.fields, name); |
| 162 _processElement(element); |
| 163 } |
| 164 |
| 165 @override |
| 165 visitExportDirective(ExportDirective node) { | 166 visitExportDirective(ExportDirective node) { |
| 166 String uri = _getStringValue(node.uri); | 167 String uri = _getStringValue(node.uri); |
| 167 if (uri != null) { | 168 if (uri != null) { |
| 168 LibraryElement library = _enclosingUnit.library; | 169 LibraryElement library = _enclosingUnit.library; |
| 169 ExportElement exportElement = _findExport( | 170 ExportElement exportElement = _findExport( |
| 170 library.exports, | 171 library.exports, |
| 171 _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source,
uri)); | 172 _enclosingUnit.context.sourceFactory.resolveUri(_enclosingUnit.source,
uri)); |
| 172 _processElement(exportElement); | 173 _processElement(exportElement); |
| 173 } | 174 } |
| 174 super.visitExportDirective(node); | 175 super.visitExportDirective(node); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 _inTopLevelVariableDeclaration = true; | 302 _inTopLevelVariableDeclaration = true; |
| 302 try { | 303 try { |
| 303 super.visitTopLevelVariableDeclaration(node); | 304 super.visitTopLevelVariableDeclaration(node); |
| 304 } finally { | 305 } finally { |
| 305 _inTopLevelVariableDeclaration = false; | 306 _inTopLevelVariableDeclaration = false; |
| 306 } | 307 } |
| 307 } | 308 } |
| 308 | 309 |
| 309 @override | 310 @override |
| 310 visitTypeParameter(TypeParameter node) { | 311 visitTypeParameter(TypeParameter node) { |
| 311 SimpleIdentifier parameterName = node.name; | 312 String name = node.name.name; |
| 312 TypeParameterElement element = null; | 313 TypeParameterElement element = null; |
| 313 if (_enclosingClass != null) { | 314 if (_enclosingClass != null) { |
| 314 element = _findIdentifier(_enclosingClass.typeParameters, parameterName); | 315 element = _findElement(_enclosingClass.typeParameters, name); |
| 315 } else if (_enclosingAlias != null) { | 316 } else if (_enclosingAlias != null) { |
| 316 element = _findIdentifier(_enclosingAlias.typeParameters, parameterName); | 317 element = _findElement(_enclosingAlias.typeParameters, name); |
| 317 } | 318 } |
| 318 _processElement(element); | 319 _processElement(element); |
| 319 super.visitTypeParameter(node); | 320 _assertSameType(node.bound, element.bound); |
| 320 } | 321 } |
| 321 | 322 |
| 322 @override | 323 @override |
| 323 visitVariableDeclaration(VariableDeclaration node) { | 324 visitVariableDeclaration(VariableDeclaration node) { |
| 324 // prepare variable | 325 // prepare variable |
| 325 String name = node.name.name; | 326 String name = node.name.name; |
| 326 PropertyInducingElement variable; | 327 PropertyInducingElement element; |
| 327 if (_inTopLevelVariableDeclaration) { | 328 if (_inTopLevelVariableDeclaration) { |
| 328 variable = _findElement(_enclosingUnit.topLevelVariables, name); | 329 element = _findElement(_enclosingUnit.topLevelVariables, name); |
| 329 } else { | 330 } else { |
| 330 variable = _findElement(_enclosingClass.fields, name); | 331 element = _findElement(_enclosingClass.fields, name); |
| 331 } | 332 } |
| 332 // verify | 333 // verify |
| 333 _assertNotNull(variable); | 334 _assertNotNull(element); |
| 334 _processElement(variable); | 335 _processElement(element); |
| 335 _assertEquals(node.isConst, variable.isConst); | 336 _assertEquals(node.isConst, element.isConst); |
| 336 _assertEquals(node.isFinal, variable.isFinal); | 337 _assertEquals(node.isFinal, element.isFinal); |
| 337 if (_enclosingFieldNode != null) { | 338 if (_enclosingFieldNode != null) { |
| 338 _assertEquals(_enclosingFieldNode.isStatic, variable.isStatic); | 339 _assertEquals(_enclosingFieldNode.isStatic, element.isStatic); |
| 339 } | 340 } |
| 340 _assertSameType( | 341 _assertSameType( |
| 341 (node.parent as VariableDeclarationList).type, | 342 (node.parent as VariableDeclarationList).type, |
| 342 variable.type); | 343 element.type); |
| 343 } | 344 } |
| 344 | 345 |
| 345 @override | 346 @override |
| 346 visitWithClause(WithClause node) { | 347 visitWithClause(WithClause node) { |
| 347 List<TypeName> nodes = node.mixinTypes; | 348 List<TypeName> nodes = node.mixinTypes; |
| 348 List<InterfaceType> types = _enclosingClass.mixins; | 349 List<InterfaceType> types = _enclosingClass.mixins; |
| 349 _assertSameTypes(nodes, types); | 350 _assertSameTypes(nodes, types); |
| 350 } | 351 } |
| 351 | 352 |
| 352 void _assertCompatibleParameter(FormalParameter node, | 353 void _assertCompatibleParameter(FormalParameter node, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 | 385 |
| 385 void _assertNotNull(Element element) { | 386 void _assertNotNull(Element element) { |
| 386 if (element == null) { | 387 if (element == null) { |
| 387 throw new _DeclarationMismatchException(); | 388 throw new _DeclarationMismatchException(); |
| 388 } | 389 } |
| 389 } | 390 } |
| 390 | 391 |
| 391 void _assertSameType(TypeName node, DartType type) { | 392 void _assertSameType(TypeName node, DartType type) { |
| 392 // no return type == dynamic | 393 // no return type == dynamic |
| 393 if (node == null) { | 394 if (node == null) { |
| 394 return _assertTrue(type.isDynamic); | 395 return _assertTrue(type == null || type.isDynamic); |
| 395 } | 396 } |
| 396 // check specific type kinds | 397 // check specific type kinds |
| 397 String nodeName = node.name.name; | 398 String nodeName = node.name.name; |
| 398 if (type is InterfaceType) { | 399 if (type is InterfaceType) { |
| 399 _assertEquals(nodeName, type.name); | 400 _assertEquals(nodeName, type.name); |
| 400 // check arguments | 401 // check arguments |
| 401 TypeArgumentList nodeArgumentList = node.typeArguments; | 402 TypeArgumentList nodeArgumentList = node.typeArguments; |
| 402 List<DartType> typeArguments = type.typeArguments; | 403 List<DartType> typeArguments = type.typeArguments; |
| 403 if (nodeArgumentList == null) { | 404 if (nodeArgumentList == null) { |
| 404 _assertTrue(typeArguments.isEmpty); | 405 _assertTrue(typeArguments.isEmpty); |
| 405 } else { | 406 } else { |
| 406 List<TypeName> nodeArguments = nodeArgumentList.arguments; | 407 List<TypeName> nodeArguments = nodeArgumentList.arguments; |
| 407 _assertSameTypes(nodeArguments, typeArguments); | 408 _assertSameTypes(nodeArguments, typeArguments); |
| 408 } | 409 } |
| 410 } else if (type is TypeParameterType) { |
| 411 _assertEquals(nodeName, type.name); |
| 412 // TODO(scheglov) it should be possible to rename type parameters |
| 409 } else { | 413 } else { |
| 410 // TODO(scheglov) support other types | 414 // TODO(scheglov) support other types |
| 411 _assertTrue(false); | 415 _assertTrue(false); |
| 412 } | 416 } |
| 413 } | 417 } |
| 414 | 418 |
| 415 void _assertSameTypes(List<TypeName> nodes, List<DartType> types) { | 419 void _assertSameTypes(List<TypeName> nodes, List<DartType> types) { |
| 416 int length = nodes.length; | 420 int length = nodes.length; |
| 417 _assertEquals(length, types.length); | 421 _assertEquals(length, types.length); |
| 418 for (int i = 0; i < length; i++) { | 422 for (int i = 0; i < length; i++) { |
| (...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 956 // Don't visit children (such as property accessors). | 960 // Don't visit children (such as property accessors). |
| 957 } | 961 } |
| 958 | 962 |
| 959 void _addElement(Element element) { | 963 void _addElement(Element element) { |
| 960 if (element != null) { | 964 if (element != null) { |
| 961 matcher._allElements.add(element); | 965 matcher._allElements.add(element); |
| 962 matcher._unmatchedElements.add(element); | 966 matcher._unmatchedElements.add(element); |
| 963 } | 967 } |
| 964 } | 968 } |
| 965 } | 969 } |
| OLD | NEW |