| // Copyright (c) 2019, 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 'package:kernel/ast.dart' as ir; |
| import 'package:kernel/type_environment.dart' as ir; |
| |
| import 'package:front_end/src/api_unstable/dart2js.dart' as ir |
| show LocatedMessage; |
| |
| import '../diagnostics/diagnostic_listener.dart'; |
| import '../diagnostics/messages.dart'; |
| import '../diagnostics/source_span.dart'; |
| import '../ir/impact_data.dart'; |
| import '../ir/static_type.dart'; |
| import '../js_backend/annotations.dart'; |
| import '../kernel/element_map.dart'; |
| import '../serialization/serialization.dart'; |
| import '../util/enumset.dart'; |
| import 'annotations.dart'; |
| import 'impact.dart'; |
| import 'scope.dart'; |
| |
| export 'modular_migrated.dart'; |
| |
| class ModularMemberData { |
| final ScopeModel scopeModel; |
| final ImpactBuilderData impactBuilderData; |
| |
| ModularMemberData(this.scopeModel, this.impactBuilderData); |
| } |
| |
| abstract class ModularStrategy { |
| List<PragmaAnnotationData> getPragmaAnnotationData(ir.Member node); |
| |
| // TODO(johnniwinther): Avoid the need for passing [pragmaAnnotations]. |
| ModularMemberData getModularMemberData( |
| ir.Member node, EnumSet<PragmaAnnotation> pragmaAnnotations); |
| } |
| |
| /// [ModuleData] is the data computed modularly, i.e. modularly computed impact |
| /// data. Currently, we aggregate this data when computing the closed world, so it |
| /// reflects all of the modularly computed data across the entire program. |
| class ModuleData { |
| static const String tag = 'ModuleData'; |
| |
| // TODO(joshualitt) Support serializing ModularMemberData; |
| final Map<Uri, Map<ir.Member, ImpactBuilderData>> impactData; |
| |
| ModuleData([Map<Uri, Map<ir.Member, ImpactBuilderData>>? impactData]) |
| : this.impactData = impactData ?? {}; |
| |
| factory ModuleData.fromImpactData( |
| Map<Uri, Map<ir.Member, ImpactBuilderData>> impactData) => |
| ModuleData(impactData); |
| |
| ModuleData readMoreFromDataSource(DataSourceReader source) { |
| source.begin(tag); |
| int uriCount = source.readInt(); |
| for (int i = 0; i < uriCount; i++) { |
| Uri uri = source.readUri(); |
| impactData[uri] = source |
| .readMemberNodeMap(() => ImpactBuilderData.fromDataSource(source)); |
| } |
| source.end(tag); |
| return this; |
| } |
| |
| factory ModuleData.fromDataSource(DataSourceReader source) => |
| ModuleData().readMoreFromDataSource(source); |
| |
| void toDataSink(DataSinkWriter sink) { |
| sink.begin(tag); |
| sink.writeInt(impactData.keys.length); |
| impactData.forEach((uri, data) { |
| sink.writeUri(uri); |
| sink.writeMemberNodeMap<ImpactBuilderData>( |
| data, (e) => e.toDataSink(sink)); |
| }); |
| sink.end(tag); |
| } |
| } |
| |
| /// Compute [ModularMemberData] from the IR. |
| ModularMemberData computeModularMemberData( |
| KernelToElementMap elementMap, |
| ir.Member node, |
| ScopeModel scopeModel, |
| EnumSet<PragmaAnnotation> annotations) { |
| var staticTypeCache = StaticTypeCacheImpl(); |
| var impactBuilderData = ImpactBuilder( |
| elementMap, |
| ir.StaticTypeContext(node, elementMap.typeEnvironment, |
| cache: staticTypeCache), |
| staticTypeCache, |
| elementMap.classHierarchy, |
| scopeModel.variableScopeModel, |
| useAsserts: elementMap.options.enableUserAssertions, |
| inferEffectivelyFinalVariableTypes: |
| !annotations.contains(PragmaAnnotation.disableFinal)) |
| .computeImpact(node); |
| return ModularMemberData(scopeModel, impactBuilderData); |
| } |
| |
| void reportLocatedMessage(DiagnosticReporter reporter, |
| ir.LocatedMessage message, List<ir.LocatedMessage> context) { |
| DiagnosticMessage diagnosticMessage = |
| _createDiagnosticMessage(reporter, message); |
| var infos = <DiagnosticMessage>[]; |
| for (ir.LocatedMessage message in context) { |
| infos.add(_createDiagnosticMessage(reporter, message)); |
| } |
| reporter.reportError(diagnosticMessage, infos); |
| } |
| |
| DiagnosticMessage _createDiagnosticMessage( |
| DiagnosticReporter reporter, ir.LocatedMessage message) { |
| var sourceSpan = SourceSpan( |
| message.uri!, message.charOffset, message.charOffset + message.length); |
| return reporter.createMessage( |
| sourceSpan, MessageKind.GENERIC, {'text': message.problemMessage}); |
| } |