-
Notifications
You must be signed in to change notification settings - Fork 203
/
errors.dart
142 lines (118 loc) · 4.8 KB
/
errors.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:async';
import 'package:analyzer/dart/analysis/utilities.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:build/build.dart';
import 'package:collection/collection.dart';
import 'module_library.dart';
import 'module_library_builder.dart';
import 'modules.dart';
/// An [Exception] that is thrown when a worker returns an error.
abstract class _WorkerException implements Exception {
final AssetId failedAsset;
final String error;
/// A message to prepend to [toString] output.
String get message;
_WorkerException(this.failedAsset, this.error);
@override
String toString() => '$message:$failedAsset\n\nResponse:$error\n';
}
/// An [Exception] that is thrown when the analyzer fails to create a summary.
class AnalyzerSummaryException extends _WorkerException {
@override
final String message = 'Error creating summary for module';
AnalyzerSummaryException(AssetId summaryId, String error)
: super(summaryId, error);
}
/// An [Exception] that is thrown when the common frontend fails to create a
/// kernel summary.
class KernelException extends _WorkerException {
@override
final String message = 'Error creating kernel summary for module';
KernelException(AssetId summaryId, String error) : super(summaryId, error);
}
/// An [Exception] that is thrown when there are some missing modules.
class MissingModulesException implements Exception {
final String message;
@override
String toString() => message;
MissingModulesException._(this.message);
static Future<MissingModulesException> create(Set<AssetId> missingSources,
Iterable<Module> transitiveModules, AssetReader reader) async {
var buffer = StringBuffer('''
Unable to find modules for some sources, this is usually the result of either a
bad import, a missing dependency in a package (or possibly a dev_dependency
needs to move to a real dependency), or a build failure (if importing a
generated file).
Please check the following imports:\n
''');
var checkedSourceDependencies = <AssetId, Set<AssetId>>{};
for (var module in transitiveModules) {
var missingIds = module.directDependencies.intersection(missingSources);
for (var missingId in missingIds) {
var checkedAlready =
checkedSourceDependencies.putIfAbsent(missingId, () => <AssetId>{});
for (var sourceId in module.sources) {
if (checkedAlready.contains(sourceId)) {
continue;
}
checkedAlready.add(sourceId);
var message =
await _missingImportMessage(sourceId, missingId, reader);
if (message != null) buffer.writeln(message);
}
}
}
return MissingModulesException._(buffer.toString());
}
}
/// Checks if [sourceId] directly imports [missingId], and returns an error
/// message if so.
Future<String?> _missingImportMessage(
AssetId sourceId, AssetId missingId, AssetReader reader) async {
var contents = await reader.readAsString(sourceId);
var parsed = parseString(content: contents, throwIfDiagnostics: false).unit;
var import = parsed.directives
.whereType<UriBasedDirective>()
.firstWhereOrNull((directive) {
var uriString = directive.uri.stringValue;
if (uriString == null) return false;
if (uriString.startsWith('dart:')) return false;
var id = AssetId.resolve(Uri.parse(uriString), from: sourceId);
return id == missingId;
});
if (import == null) return null;
var lineInfo = parsed.lineInfo.getLocation(import.offset);
return '`$import` from $sourceId at $lineInfo';
}
/// An [Exception] that is thrown when there are some unsupported modules.
class UnsupportedModules implements Exception {
final Set<Module> unsupportedModules;
UnsupportedModules(this.unsupportedModules);
Stream<ModuleLibrary> exactLibraries(AssetReader reader) async* {
for (var module in unsupportedModules) {
for (var source in module.sources) {
var libraryId = source.changeExtension(moduleLibraryExtension);
ModuleLibrary library;
if (await reader.canRead(libraryId)) {
library = ModuleLibrary.deserialize(
libraryId, await reader.readAsString(libraryId));
} else {
// A missing .module.library file indicates a part file, which can't
// have import statements, so we just skip them.
continue;
}
if (library.sdkDeps
.any((lib) => !module.platform.supportsLibrary(lib))) {
yield library;
}
}
}
}
@override
String toString() =>
'Some modules contained libraries that were incompatible '
'with the current platform.';
}