Skip to content

Commit 021d99e

Browse files
committed
Issue 29288. Resynthesize Import/Export/PartElement for every directive.
We need all of them because there might be associated annotations, which should be applied to corresponding AST nodes. #29288 #29188 [email protected] BUG= #29288 Review-Url: https://codereview.chromium.org/2809523002 .
1 parent e572bf9 commit 021d99e

File tree

12 files changed

+292
-129
lines changed

12 files changed

+292
-129
lines changed

pkg/analyzer/lib/src/dart/analysis/file_state.dart

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ import 'package:analyzer/src/dart/analysis/referenced_names.dart';
1616
import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
1717
import 'package:analyzer/src/dart/scanner/reader.dart';
1818
import 'package:analyzer/src/dart/scanner/scanner.dart';
19+
import 'package:analyzer/src/fasta/ast_builder.dart' as fasta;
20+
import 'package:analyzer/src/fasta/element_store.dart' as fasta;
21+
import 'package:analyzer/src/fasta/mock_element.dart' as fasta;
1922
import 'package:analyzer/src/generated/engine.dart';
2023
import 'package:analyzer/src/generated/parser.dart';
2124
import 'package:analyzer/src/generated/source.dart';
@@ -28,9 +31,6 @@ import 'package:analyzer/src/summary/name_filter.dart';
2831
import 'package:analyzer/src/summary/summarize_ast.dart';
2932
import 'package:convert/convert.dart';
3033
import 'package:crypto/crypto.dart';
31-
import 'package:analyzer/src/fasta/ast_builder.dart' as fasta;
32-
import 'package:analyzer/src/fasta/element_store.dart' as fasta;
33-
import 'package:analyzer/src/fasta/mock_element.dart' as fasta;
3434
import 'package:front_end/src/fasta/builder/builder.dart' as fasta;
3535
import 'package:front_end/src/fasta/parser/parser.dart' as fasta;
3636
import 'package:front_end/src/fasta/scanner.dart' as fasta;
@@ -502,28 +502,22 @@ class FileState {
502502
for (UnlinkedImport import in _unlinked.imports) {
503503
String uri = import.isImplicit ? 'dart:core' : import.uri;
504504
FileState file = _fileForRelativeUri(uri);
505-
if (file != null) {
506-
_importedFiles.add(file);
507-
}
505+
_importedFiles.add(file);
508506
}
509507
for (UnlinkedExportPublic export in _unlinked.publicNamespace.exports) {
510508
String uri = export.uri;
511509
FileState file = _fileForRelativeUri(uri);
512-
if (file != null) {
513-
_exportedFiles.add(file);
514-
_exportFilters
515-
.add(new NameFilter.forUnlinkedCombinators(export.combinators));
516-
}
510+
_exportedFiles.add(file);
511+
_exportFilters
512+
.add(new NameFilter.forUnlinkedCombinators(export.combinators));
517513
}
518514
for (String uri in _unlinked.publicNamespace.parts) {
519515
FileState file = _fileForRelativeUri(uri);
520-
if (file != null) {
521-
_partedFiles.add(file);
522-
// TODO(scheglov) Sort for stable results?
523-
_fsState._partToLibraries
524-
.putIfAbsent(file, () => <FileState>[])
525-
.add(this);
526-
}
516+
_partedFiles.add(file);
517+
// TODO(scheglov) Sort for stable results?
518+
_fsState._partToLibraries
519+
.putIfAbsent(file, () => <FileState>[])
520+
.add(this);
527521
}
528522

529523
// Compute referenced files.
@@ -554,16 +548,21 @@ class FileState {
554548
String toString() => path;
555549

556550
/**
557-
* Return the [FileState] for the given [relativeUri], or `null` if the URI
558-
* cannot be parsed, cannot correspond any file, etc.
551+
* Return the [FileState] for the given [relativeUri], maybe "unresolved"
552+
* file if the URI cannot be parsed, cannot correspond any file, etc.
559553
*/
560554
FileState _fileForRelativeUri(String relativeUri) {
555+
if (relativeUri.isEmpty) {
556+
return _fsState.unresolvedFile;
557+
}
558+
561559
Uri absoluteUri;
562560
try {
563561
absoluteUri = resolveRelativeUri(uri, Uri.parse(relativeUri));
564562
} on FormatException {
565-
return null;
563+
return _fsState.unresolvedFile;
566564
}
565+
567566
return _fsState.getFileForUri(absoluteUri);
568567
}
569568

@@ -630,6 +629,11 @@ class FileSystemState {
630629
*/
631630
final Map<FileState, List<FileState>> _partToLibraries = {};
632631

632+
/**
633+
* The [FileState] instance that correspond to an unresolved URI.
634+
*/
635+
FileState _unresolvedFile;
636+
633637
FileSystemStateTestView _testView;
634638

635639
FileSystemState(
@@ -652,6 +656,17 @@ class FileSystemState {
652656
@visibleForTesting
653657
FileSystemStateTestView get test => _testView;
654658

659+
/**
660+
* Return the [FileState] instance that correspond to an unresolved URI.
661+
*/
662+
FileState get unresolvedFile {
663+
if (_unresolvedFile == null) {
664+
_unresolvedFile = new FileState._(this, null, null, null);
665+
_unresolvedFile.refresh();
666+
}
667+
return _unresolvedFile;
668+
}
669+
655670
/**
656671
* Return the canonical [FileState] for the given absolute [path]. The
657672
* returned file has the last known state since if was last refreshed.
@@ -692,11 +707,14 @@ class FileSystemState {
692707
FileState file = _uriToFile[uri];
693708
if (file == null) {
694709
Source uriSource = _sourceFactory.resolveUri(null, uri.toString());
695-
// If the URI is invalid, for example package:/test/d.dart (note the
696-
// leading '/'), then `null` is returned. We should ignore this URI.
710+
711+
// If the URI cannot be resolved, for example because the factory
712+
// does not understand the scheme, return the unresolved file instance.
697713
if (uriSource == null) {
698-
return null;
714+
_uriToFile[uri] = unresolvedFile;
715+
return unresolvedFile;
699716
}
717+
700718
String path = uriSource.fullName;
701719
File resource = _resourceProvider.getFile(path);
702720
FileSource source = new FileSource(resource, uri);

pkg/analyzer/lib/src/dart/analysis/index.dart

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -610,8 +610,10 @@ class _IndexContributor extends GeneralizingAstVisitor {
610610

611611
@override
612612
visitPartDirective(PartDirective node) {
613-
Element element = node.element;
614-
recordUriReference(element, node);
613+
CompilationUnitElement element = node.element;
614+
if (element?.source != null) {
615+
recordUriReference(element, node);
616+
}
615617
super.visitPartDirective(node);
616618
}
617619

pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart

Lines changed: 69 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,10 @@ class LibraryAnalyzer {
158158
}
159159

160160
void _computeHints(FileState file, CompilationUnit unit) {
161+
if (file.source == null) {
162+
return;
163+
}
164+
161165
AnalysisErrorListener errorListener = _getErrorListener(file);
162166
ErrorReporter errorReporter = _getErrorReporter(file);
163167

@@ -209,6 +213,10 @@ class LibraryAnalyzer {
209213
}
210214

211215
void _computeLints(FileState file, CompilationUnit unit) {
216+
if (file.source == null) {
217+
return;
218+
}
219+
212220
ErrorReporter errorReporter = _getErrorReporter(file);
213221

214222
List<AstVisitor> visitors = <AstVisitor>[];
@@ -239,6 +247,10 @@ class LibraryAnalyzer {
239247
}
240248

241249
void _computeVerifyErrors(FileState file, CompilationUnit unit) {
250+
if (file.source == null) {
251+
return;
252+
}
253+
242254
RecordingErrorListener errorListener = _getErrorListener(file);
243255

244256
if (_analysisOptions.strongMode) {
@@ -377,24 +389,14 @@ class LibraryAnalyzer {
377389

378390
void _resolveDirectives(Map<FileState, CompilationUnit> units) {
379391
CompilationUnit definingCompilationUnit = units[_library];
380-
381-
var uriToElement = <Uri, CompilationUnitElement>{};
382-
for (CompilationUnitElement partElement in _libraryElement.units) {
383-
uriToElement[partElement.source.uri] = partElement;
384-
}
385-
386-
var sourceToUnit = <Source, CompilationUnit>{};
387-
units.forEach((file, unit) {
388-
Source source = file.source;
389-
unit.element = uriToElement[source.uri];
390-
sourceToUnit[source] = unit;
391-
});
392+
definingCompilationUnit.element = _libraryElement.definingCompilationUnit;
392393

393394
ErrorReporter libraryErrorReporter = _getErrorReporter(_library);
394395
LibraryIdentifier libraryNameNode = null;
395396
bool hasPartDirective = false;
396397
var seenPartSources = new Set<Source>();
397398
var directivesToResolve = <Directive>[];
399+
int partIndex = 0;
398400
for (Directive directive in definingCompilationUnit.directives) {
399401
if (directive is LibraryDirective) {
400402
libraryNameNode = directive.name;
@@ -403,7 +405,8 @@ class LibraryAnalyzer {
403405
for (ImportElement importElement in _libraryElement.imports) {
404406
if (importElement.nameOffset == directive.offset) {
405407
directive.element = importElement;
406-
if (!_isLibrarySource(importElement.importedLibrary.source)) {
408+
Source source = importElement.importedLibrary?.source;
409+
if (source != null && !_isLibrarySource(source)) {
407410
ErrorCode errorCode = importElement.isDeferred
408411
? StaticWarningCode.IMPORT_OF_NON_LIBRARY
409412
: CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY;
@@ -416,7 +419,8 @@ class LibraryAnalyzer {
416419
for (ExportElement exportElement in _libraryElement.exports) {
417420
if (exportElement.nameOffset == directive.offset) {
418421
directive.element = exportElement;
419-
if (!_isLibrarySource(exportElement.exportedLibrary.source)) {
422+
Source source = exportElement.exportedLibrary?.source;
423+
if (source != null && !_isLibrarySource(source)) {
420424
libraryErrorReporter.reportErrorForNode(
421425
CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
422426
directive.uri,
@@ -427,46 +431,55 @@ class LibraryAnalyzer {
427431
} else if (directive is PartDirective) {
428432
hasPartDirective = true;
429433
StringLiteral partUri = directive.uri;
434+
435+
FileState partFile = _library.partedFiles[partIndex];
436+
CompilationUnit partUnit = units[partFile];
437+
CompilationUnitElement partElement = _libraryElement.parts[partIndex];
438+
partUnit.element = partElement;
439+
directive.element = partElement;
440+
partIndex++;
441+
430442
Source partSource = directive.uriSource;
431-
CompilationUnit partUnit = sourceToUnit[partSource];
432-
if (partUnit != null) {
433-
directive.element = partUnit.element;
434-
//
435-
// Validate that the part source is unique in the library.
436-
//
437-
if (!seenPartSources.add(partSource)) {
443+
if (partSource == null) {
444+
continue;
445+
}
446+
447+
//
448+
// Validate that the part source is unique in the library.
449+
//
450+
if (!seenPartSources.add(partSource)) {
451+
libraryErrorReporter.reportErrorForNode(
452+
CompileTimeErrorCode.DUPLICATE_PART, partUri, [partSource.uri]);
453+
}
454+
455+
//
456+
// Validate that the part contains a part-of directive with the same
457+
// name or uri as the library.
458+
//
459+
if (_context.exists(partSource)) {
460+
_NameOrSource nameOrSource = _getPartLibraryNameOrUri(
461+
partSource, partUnit, directivesToResolve);
462+
if (nameOrSource == null) {
438463
libraryErrorReporter.reportErrorForNode(
439-
CompileTimeErrorCode.DUPLICATE_PART, partUri, [partSource.uri]);
440-
}
441-
//
442-
// Validate that the part contains a part-of directive with the same
443-
// name as the library.
444-
//
445-
if (_context.exists(partSource)) {
446-
_NameOrSource nameOrSource = _getPartLibraryNameOrUri(
447-
partSource, partUnit, directivesToResolve);
448-
if (nameOrSource == null) {
449-
libraryErrorReporter.reportErrorForNode(
450-
CompileTimeErrorCode.PART_OF_NON_PART,
451-
partUri,
452-
[partUri.toSource()]);
464+
CompileTimeErrorCode.PART_OF_NON_PART,
465+
partUri,
466+
[partUri.toSource()]);
467+
} else {
468+
String name = nameOrSource.name;
469+
if (name != null) {
470+
if (libraryNameNode != null && libraryNameNode.name != name) {
471+
libraryErrorReporter.reportErrorForNode(
472+
StaticWarningCode.PART_OF_DIFFERENT_LIBRARY,
473+
partUri,
474+
[libraryNameNode.name, name]);
475+
}
453476
} else {
454-
String name = nameOrSource.name;
455-
if (name != null) {
456-
if (libraryNameNode != null && libraryNameNode.name != name) {
457-
libraryErrorReporter.reportErrorForNode(
458-
StaticWarningCode.PART_OF_DIFFERENT_LIBRARY,
459-
partUri,
460-
[libraryNameNode.name, name]);
461-
}
462-
} else {
463-
Source source = nameOrSource.source;
464-
if (source != _library.source) {
465-
libraryErrorReporter.reportErrorForNode(
466-
StaticWarningCode.PART_OF_DIFFERENT_LIBRARY,
467-
partUri,
468-
[_library.uriStr, source.uri]);
469-
}
477+
Source source = nameOrSource.source;
478+
if (source != _library.source) {
479+
libraryErrorReporter.reportErrorForNode(
480+
StaticWarningCode.PART_OF_DIFFERENT_LIBRARY,
481+
partUri,
482+
[_library.uriStr, source.uri]);
470483
}
471484
}
472485
}
@@ -492,10 +505,14 @@ class LibraryAnalyzer {
492505
}
493506

494507
void _resolveFile(FileState file, CompilationUnit unit) {
508+
Source source = file.source;
509+
if (source == null) {
510+
return;
511+
}
512+
495513
RecordingErrorListener errorListener = _getErrorListener(file);
496514

497515
CompilationUnitElement unitElement = unit.element;
498-
Source source = file.source;
499516

500517
// TODO(scheglov) Hack: set types for top-level variables
501518
// Otherwise TypeResolverVisitor will set declared types, and because we

pkg/analyzer/lib/src/dart/element/element.dart

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5880,16 +5880,11 @@ class LibraryElementImpl extends ElementImpl implements LibraryElement {
58805880
for (int i = 0; i < length; i++) {
58815881
UnlinkedExportPublic serializedExportPublic =
58825882
unlinkedPublicExports[i];
5883-
LibraryElement exportedLibrary = resynthesizerContext
5884-
.buildExportedLibrary(serializedExportPublic.uri);
5885-
if (exportedLibrary != null) {
5886-
UnlinkedExportNonPublic serializedExportNonPublic =
5887-
unlinkedNonPublicExports[i];
5888-
ExportElementImpl exportElement =
5889-
new ExportElementImpl.forSerialized(
5890-
serializedExportPublic, serializedExportNonPublic, library);
5891-
exports.add(exportElement);
5892-
}
5883+
UnlinkedExportNonPublic serializedExportNonPublic =
5884+
unlinkedNonPublicExports[i];
5885+
ExportElementImpl exportElement = new ExportElementImpl.forSerialized(
5886+
serializedExportPublic, serializedExportNonPublic, library);
5887+
exports.add(exportElement);
58935888
}
58945889
_exports = exports;
58955890
} else {
@@ -5970,14 +5965,9 @@ class LibraryElementImpl extends ElementImpl implements LibraryElement {
59705965
LinkedLibrary linkedLibrary = resynthesizerContext.linkedLibrary;
59715966
for (int i = 0; i < length; i++) {
59725967
int dependency = linkedLibrary.importDependencies[i];
5973-
LibraryElement importedLibrary =
5974-
resynthesizerContext.buildImportedLibrary(dependency);
5975-
if (importedLibrary != null) {
5976-
ImportElementImpl importElement =
5977-
new ImportElementImpl.forSerialized(
5978-
unlinkedImports[i], dependency, library);
5979-
imports.add(importElement);
5980-
}
5968+
ImportElementImpl importElement = new ImportElementImpl.forSerialized(
5969+
unlinkedImports[i], dependency, library);
5970+
imports.add(importElement);
59815971
}
59825972
_imports = imports;
59835973
} else {

0 commit comments

Comments
 (0)