Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(441)

Side by Side Diff: pkg/analyzer/lib/src/generated/resolver.dart

Issue 1737203002: Don't throw exceptions for unresolved/not-existing URIs in directives. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/declaration_resolver_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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.generated.resolver; 5 library analyzer.src.generated.resolver;
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/token.dart'; 10 import 'package:analyzer/dart/ast/token.dart';
(...skipping 592 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 if (!_typeSystem.isAssignableTo(bestRightType, leftType)) { 603 if (!_typeSystem.isAssignableTo(bestRightType, leftType)) {
604 _errorReporter.reportTypeErrorForNode( 604 _errorReporter.reportTypeErrorForNode(
605 HintCode.INVALID_ASSIGNMENT, rhs, [bestRightType, leftType]); 605 HintCode.INVALID_ASSIGNMENT, rhs, [bestRightType, leftType]);
606 return true; 606 return true;
607 } 607 }
608 } 608 }
609 return false; 609 return false;
610 } 610 }
611 611
612 /** 612 /**
613 * Produces a hint if the given identifier is a protected field or getter
614 * accessed outside a subclass.
615 */
616 void _checkForInvalidProtectedPropertyAccess(SimpleIdentifier identifier) {
617 if (identifier.inDeclarationContext()) {
618 return;
619 }
620 Element element = identifier.bestElement;
621 if (element is PropertyAccessorElement &&
622 (element.isProtected || element.variable.isProtected)) {
623 ClassElement definingClass = element.enclosingElement;
624 if (definingClass == null) {
625 return;
626 }
627 ClassDeclaration accessingClass =
628 identifier.getAncestor((AstNode node) => node is ClassDeclaration);
629
630 if (accessingClass == null) {
631 _errorReporter.reportErrorForNode(
632 HintCode.INVALID_USE_OF_PROTECTED_MEMBER,
633 identifier,
634 [identifier.name.toString(), definingClass.name]);
635 } else if (!_hasSuperClassOrMixin(
636 accessingClass.element, definingClass.type)) {
637 _errorReporter.reportErrorForNode(
638 HintCode.INVALID_USE_OF_PROTECTED_MEMBER,
639 identifier,
640 [identifier.name.toString(), definingClass.name]);
641 }
642 }
643 }
644
645 /**
646 * Produces a hint if the given invocation is of a protected method outside 613 * Produces a hint if the given invocation is of a protected method outside
647 * a subclass instance method. 614 * a subclass instance method.
648 */ 615 */
649 void _checkForInvalidProtectedMethodCalls(MethodInvocation node) { 616 void _checkForInvalidProtectedMethodCalls(MethodInvocation node) {
650 Element element = node.methodName.bestElement; 617 Element element = node.methodName.bestElement;
651 if (element == null || !element.isProtected) { 618 if (element == null || !element.isProtected) {
652 return; 619 return;
653 } 620 }
654 621
655 ClassElement definingClass = element.enclosingElement; 622 ClassElement definingClass = element.enclosingElement;
(...skipping 13 matching lines...) Expand all
669 if (!_hasSuperClassOrMixin(invokingClass, definingClass.type)) { 636 if (!_hasSuperClassOrMixin(invokingClass, definingClass.type)) {
670 _errorReporter.reportErrorForNode( 637 _errorReporter.reportErrorForNode(
671 HintCode.INVALID_USE_OF_PROTECTED_MEMBER, 638 HintCode.INVALID_USE_OF_PROTECTED_MEMBER,
672 node, 639 node,
673 [node.methodName.toString(), definingClass.name]); 640 [node.methodName.toString(), definingClass.name]);
674 } 641 }
675 } 642 }
676 } 643 }
677 644
678 /** 645 /**
646 * Produces a hint if the given identifier is a protected field or getter
647 * accessed outside a subclass.
648 */
649 void _checkForInvalidProtectedPropertyAccess(SimpleIdentifier identifier) {
650 if (identifier.inDeclarationContext()) {
651 return;
652 }
653 Element element = identifier.bestElement;
654 if (element is PropertyAccessorElement &&
655 (element.isProtected || element.variable.isProtected)) {
656 ClassElement definingClass = element.enclosingElement;
657 if (definingClass == null) {
658 return;
659 }
660 ClassDeclaration accessingClass =
661 identifier.getAncestor((AstNode node) => node is ClassDeclaration);
662
663 if (accessingClass == null) {
664 _errorReporter.reportErrorForNode(
665 HintCode.INVALID_USE_OF_PROTECTED_MEMBER,
666 identifier,
667 [identifier.name.toString(), definingClass.name]);
668 } else if (!_hasSuperClassOrMixin(
669 accessingClass.element, definingClass.type)) {
670 _errorReporter.reportErrorForNode(
671 HintCode.INVALID_USE_OF_PROTECTED_MEMBER,
672 identifier,
673 [identifier.name.toString(), definingClass.name]);
674 }
675 }
676 }
677
678 /**
679 * Check that the imported library does not define a loadLibrary function. The import has already 679 * Check that the imported library does not define a loadLibrary function. The import has already
680 * been determined to be deferred when this is called. 680 * been determined to be deferred when this is called.
681 * 681 *
682 * @param node the import directive to evaluate 682 * @param node the import directive to evaluate
683 * @param importElement the [ImportElement] retrieved from the node 683 * @param importElement the [ImportElement] retrieved from the node
684 * @return `true` if and only if an error code is generated on the passed node 684 * @return `true` if and only if an error code is generated on the passed node
685 * See [CompileTimeErrorCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION]. 685 * See [CompileTimeErrorCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION].
686 */ 686 */
687 bool _checkForLoadLibraryFunction( 687 bool _checkForLoadLibraryFunction(
688 ImportDirective node, ImportElement importElement) { 688 ImportDirective node, ImportElement importElement) {
(...skipping 1428 matching lines...) Expand 10 before | Expand all | Expand 10 after
2117 } 2117 }
2118 } 2118 }
2119 } 2119 }
2120 2120
2121 /** 2121 /**
2122 * A visitor that resolves declarations in an AST structure to already built 2122 * A visitor that resolves declarations in an AST structure to already built
2123 * elements. 2123 * elements.
2124 */ 2124 */
2125 class DeclarationResolver extends RecursiveAstVisitor<Object> { 2125 class DeclarationResolver extends RecursiveAstVisitor<Object> {
2126 /** 2126 /**
2127 * The analysis context containing the sources to be analyzed.
2128 */
2129 AnalysisContext _context;
2130
2131 /**
2127 * The elements that are reachable from the compilation unit element. When a 2132 * The elements that are reachable from the compilation unit element. When a
2128 * compilation unit has been resolved, this set should be empty. 2133 * compilation unit has been resolved, this set should be empty.
2129 */ 2134 */
2130 Set<Element> _expectedElements; 2135 Set<Element> _expectedElements;
2131 2136
2132 /** 2137 /**
2133 * The compilation unit containing the AST nodes being visited. 2138 * The compilation unit containing the AST nodes being visited.
2134 */ 2139 */
2135 CompilationUnitElement _enclosingUnit; 2140 CompilationUnitElement _enclosingUnit;
2136 2141
(...skipping 20 matching lines...) Expand all
2157 * not in the scope of a parameter. 2162 * not in the scope of a parameter.
2158 */ 2163 */
2159 ParameterElement _enclosingParameter; 2164 ParameterElement _enclosingParameter;
2160 2165
2161 /** 2166 /**
2162 * Resolve the declarations within the given compilation [unit] to the 2167 * Resolve the declarations within the given compilation [unit] to the
2163 * elements rooted at the given [element]. Throw an [ElementMismatchException] 2168 * elements rooted at the given [element]. Throw an [ElementMismatchException]
2164 * if the element model and compilation unit do not match each other. 2169 * if the element model and compilation unit do not match each other.
2165 */ 2170 */
2166 void resolve(CompilationUnit unit, CompilationUnitElement element) { 2171 void resolve(CompilationUnit unit, CompilationUnitElement element) {
2172 _context = element.context;
2167 ElementGatherer gatherer = new ElementGatherer(); 2173 ElementGatherer gatherer = new ElementGatherer();
2168 element.accept(gatherer); 2174 element.accept(gatherer);
2169 _expectedElements = gatherer.elements; 2175 _expectedElements = gatherer.elements;
2170 _enclosingUnit = element; 2176 _enclosingUnit = element;
2171 _expectedElements.remove(element); 2177 _expectedElements.remove(element);
2172 unit.element = element; 2178 unit.element = element;
2173 unit.accept(this); 2179 unit.accept(this);
2174 _validateResolution(); 2180 _validateResolution();
2175 } 2181 }
2176 2182
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
2294 _resolveMetadata(node.metadata, enclosingEnum); 2300 _resolveMetadata(node.metadata, enclosingEnum);
2295 return null; 2301 return null;
2296 } 2302 }
2297 2303
2298 @override 2304 @override
2299 Object visitExportDirective(ExportDirective node) { 2305 Object visitExportDirective(ExportDirective node) {
2300 String uri = _getStringValue(node.uri); 2306 String uri = _getStringValue(node.uri);
2301 ExportElement exportElement; 2307 ExportElement exportElement;
2302 if (uri != null) { 2308 if (uri != null) {
2303 LibraryElement library = _enclosingUnit.library; 2309 LibraryElement library = _enclosingUnit.library;
2304 exportElement = _findExport( 2310 Source source = _enclosingUnit.context.sourceFactory
2305 node, 2311 .resolveUri(_enclosingUnit.source, uri);
2306 library.exports, 2312 exportElement = _findExport(node, library.exports, source);
2307 _enclosingUnit.context.sourceFactory
2308 .resolveUri(_enclosingUnit.source, uri));
2309 node.element = exportElement; 2313 node.element = exportElement;
2310 } 2314 }
2311 super.visitExportDirective(node); 2315 super.visitExportDirective(node);
2312 _resolveMetadata(node.metadata, exportElement); 2316 _resolveMetadata(node.metadata, exportElement);
2313 return null; 2317 return null;
2314 } 2318 }
2315 2319
2316 @override 2320 @override
2317 Object visitFieldDeclaration(FieldDeclaration node) { 2321 Object visitFieldDeclaration(FieldDeclaration node) {
2318 super.visitFieldDeclaration(node); 2322 super.visitFieldDeclaration(node);
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
2435 return super.visitFunctionTypedFormalParameter(node); 2439 return super.visitFunctionTypedFormalParameter(node);
2436 } 2440 }
2437 } 2441 }
2438 2442
2439 @override 2443 @override
2440 Object visitImportDirective(ImportDirective node) { 2444 Object visitImportDirective(ImportDirective node) {
2441 String uri = _getStringValue(node.uri); 2445 String uri = _getStringValue(node.uri);
2442 ImportElement importElement; 2446 ImportElement importElement;
2443 if (uri != null) { 2447 if (uri != null) {
2444 LibraryElement library = _enclosingUnit.library; 2448 LibraryElement library = _enclosingUnit.library;
2445 importElement = _findImport( 2449 Source source = _enclosingUnit.context.sourceFactory
2446 node, 2450 .resolveUri(_enclosingUnit.source, uri);
2447 library.imports, 2451 importElement = _findImport(node, library.imports, source);
2448 _enclosingUnit.context.sourceFactory
2449 .resolveUri(_enclosingUnit.source, uri));
2450 node.element = importElement; 2452 node.element = importElement;
2451 } 2453 }
2452 super.visitImportDirective(node); 2454 super.visitImportDirective(node);
2453 _resolveMetadata(node.metadata, importElement); 2455 _resolveMetadata(node.metadata, importElement);
2454 return null; 2456 return null;
2455 } 2457 }
2456 2458
2457 @override 2459 @override
2458 Object visitLabeledStatement(LabeledStatement node) { 2460 Object visitLabeledStatement(LabeledStatement node) {
2459 for (Label label in node.labels) { 2461 for (Label label in node.labels) {
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
2650 Element _findAtOffset(List<Element> elements, AstNode node, int offset) => 2652 Element _findAtOffset(List<Element> elements, AstNode node, int offset) =>
2651 _findWithNameAndOffset(elements, node, '', offset); 2653 _findWithNameAndOffset(elements, node, '', offset);
2652 2654
2653 /** 2655 /**
2654 * Return the export element from the given list of [exports] whose library 2656 * Return the export element from the given list of [exports] whose library
2655 * has the given [source]. Throw an [ElementMismatchException] if an element 2657 * has the given [source]. Throw an [ElementMismatchException] if an element
2656 * corresponding to the identifier cannot be found. 2658 * corresponding to the identifier cannot be found.
2657 */ 2659 */
2658 ExportElement _findExport( 2660 ExportElement _findExport(
2659 ExportDirective node, List<ExportElement> exports, Source source) { 2661 ExportDirective node, List<ExportElement> exports, Source source) {
2662 if (source == null || !_context.exists(source)) {
2663 return null;
2664 }
2660 for (ExportElement export in exports) { 2665 for (ExportElement export in exports) {
2661 if (export.exportedLibrary.source == source) { 2666 if (export.exportedLibrary.source == source) {
2662 return export; 2667 return export;
2663 } 2668 }
2664 } 2669 }
2665 _mismatch("Could not find export element for '$source'", node); 2670 _mismatch("Could not find export element for '$source'", node);
2666 return null; // Never reached 2671 return null; // Never reached
2667 } 2672 }
2668 2673
2669 /** 2674 /**
2670 * Return the element in the given list of [elements] that was created for the 2675 * Return the element in the given list of [elements] that was created for the
2671 * declaration with the given [identifier]. As a side-effect, associate the 2676 * declaration with the given [identifier]. As a side-effect, associate the
2672 * returned element with the identifier. Throw an [ElementMismatchException] 2677 * returned element with the identifier. Throw an [ElementMismatchException]
2673 * if an element corresponding to the identifier cannot be found unless 2678 * if an element corresponding to the identifier cannot be found unless
2674 * [required] is `false`, in which case return `null`. 2679 * [required] is `false`, in which case return `null`.
2675 */ 2680 */
2676 Element _findIdentifier(List<Element> elements, SimpleIdentifier identifier, 2681 Element _findIdentifier(List<Element> elements, SimpleIdentifier identifier,
2677 {bool required: true}) { 2682 {bool required: true}) {
2678 Element element = _findWithNameAndOffset( 2683 Element element = _findWithNameAndOffset(
2679 elements, identifier, identifier.name, identifier.offset, 2684 elements, identifier, identifier.name, identifier.offset,
2680 required: required); 2685 required: required);
2681 _expectedElements.remove(element); 2686 _expectedElements.remove(element);
2682 identifier.staticElement = element; 2687 identifier.staticElement = element;
2683 return element; 2688 return element;
2684 } 2689 }
2685 2690
2686 /** 2691 /**
2687 * Return the import element from the given list of [imports] whose library 2692 * Return the import element from the given list of [imports] whose library
2688 * has the given [source] and that has the given [prefix]. Throw an 2693 * has the given [source]. Throw an [ElementMismatchException] if an element
2689 * [ElementMismatchException] if an element corresponding to the identifier 2694 * corresponding to the [source] cannot be found.
2690 * cannot be found.
2691 */ 2695 */
2692 ImportElement _findImport( 2696 ImportElement _findImport(
2693 ImportDirective node, List<ImportElement> imports, Source source) { 2697 ImportDirective node, List<ImportElement> imports, Source source) {
2698 if (source == null || !_context.exists(source)) {
2699 return null;
2700 }
2694 SimpleIdentifier prefix = node.prefix; 2701 SimpleIdentifier prefix = node.prefix;
2695 bool foundSource = false; 2702 bool foundSource = false;
2696 for (ImportElement element in imports) { 2703 for (ImportElement element in imports) {
2697 if (element.importedLibrary.source == source) { 2704 if (element.importedLibrary.source == source) {
2698 foundSource = true; 2705 foundSource = true;
2699 PrefixElement prefixElement = element.prefix; 2706 PrefixElement prefixElement = element.prefix;
2700 if (prefix == null) { 2707 if (prefix == null) {
2701 if (prefixElement == null) { 2708 if (prefixElement == null) {
2702 return element; 2709 return element;
2703 } 2710 }
(...skipping 10276 matching lines...) Expand 10 before | Expand all | Expand 10 after
12980 nonFields.add(node); 12987 nonFields.add(node);
12981 return null; 12988 return null;
12982 } 12989 }
12983 12990
12984 @override 12991 @override
12985 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this); 12992 Object visitNode(AstNode node) => node.accept(TypeResolverVisitor_this);
12986 12993
12987 @override 12994 @override
12988 Object visitWithClause(WithClause node) => null; 12995 Object visitWithClause(WithClause node) => null;
12989 } 12996 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analyzer/test/generated/declaration_resolver_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698